2 Stimmen

C++ OpenGL: Ray Trace Shading ist nicht richtig schattiert

Ich studiere CS und für unsere Abschlussarbeit sollten wir die Reflexionen an mehreren Kugeln mittels Raytracing konstruieren. Das ist fast wortwörtlich das, was wir als Anleitung bekamen, außer einem Bild, wie es nach der Fertigstellung aussehen sollte. So brauche ich Kugeln, mit ihnen sind Reflexionen (mit Ray-Tracing) auf sie mit der richtigen Schattierung von einem Licht zugeordnet.

Nun, es funktioniert alles, außer dass ich mehrere Kugeln habe und dass es nicht wie das Bild aussieht, das er uns für die Rubrik gegeben hat.

Die mehrere Kugeln Sache, die ich nicht zu sicher, wie zu tun, aber ich würde sagen, ich muss sie in einem 2D-Array speichern und ändern Sie ein paar Abschnitte des Codes.

Ich dachte daran, die Funktionen sphere_intersect und find_reflect so zu ändern, dass sie die zu analysierende Sphäre berücksichtigen. Als nächstes sollte find_reflect so modifiziert werden, dass bei der Berechnung des neuen Vektors u auch dessen Startpunkt (P0) aktualisiert wird. Wenn der Strahl dann auf eine Kugel trifft, muss gezählt werden, wie oft der Strahl reflektiert wurde. Irgendwann ist Schluss (vielleicht nach 10 Mal) und dann zeichne ich einfach das Pixel. Für einen zusätzlichen Touch möchte ich den Sphären solide Farben hinzufügen, was das Finden der Normalen einer Sphäre erfordern würde, glaube ich.

Wie auch immer, ich werde ein Bild von ihm, ein Bild von mir und den Quellcode anhängen. Hoffentlich kann jemand mir helfen, auf diese ein.

Vielen Dank im Voraus!

Die Sphären des Professors

enter image description here

Meine Sphären

enter image description here

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#include <string>

#define screen_width 750
#define screen_height 750
#define true 1
#define false 0
#define perpendicular 0

int gridXsize = 20;
int gridZsize = 20;
float plane[] = {0.0, 1.0, 0.0, -50.0,};
float sphere[] = {250.0, 270.0, -100.0, 100.0};
float eye[] = {0.0, 400.0, 550.0};
float light[] = {250.0, 550.0, -200.0};

float dot(float *u, float *v)
{
   return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
}

void norm(float *u)
{
   float norm = sqrt(abs(dot(u,u)));

   for (int i =0; i <3; i++)
   {
      u[i] = u[i]/norm;
   }

}

float plane_intersect(float *u, float *pO)
{
   float normt[3] = {plane[0], plane[1], plane[2]};

   float s;

   if (dot(u,normt) == 0)
   {
      s = -10;
   }

   else
   {
      s = (plane[3]-(dot(pO,normt)))/(dot(u,normt));
   }

   return s;
}

float sphere_intersect(float *u, float *pO)
{

   float deltaP[3] = {sphere[0]-pO[0],sphere[1]-pO[1],sphere[2]-pO[2]};
   float deltLen = sqrt(abs(dot(deltaP,deltaP)));
   float t=0;
   float answer;
   float det;

   if ((det =(abs(dot(u,deltaP)*dot(u,deltaP))- (deltLen*deltLen)+sphere[3]*sphere[3])) < 0)
   {
      answer = -10;
   }

   else
   {
      t =-1*dot(u,deltaP)- sqrt(det) ;

          if (t>0)
      {
         answer = t;
      }

      else
      {
         answer = -10;
      }
   }

   return answer;
}

void find_reflect(float *u, float s, float *pO)
{
   float n[3] = {pO[0]+s *u[0]-sphere[0],pO[1]+s *u[1]-sphere[1],pO[2]+s *u[2]- sphere[2]};
   float l[3] = {s *u[0],s *u[1],s *u[2]};
   u[0] =(2*dot(l,n)*n[0])-l[0];
   u[1] = (2*dot(l,n)*n[1])-l[1];
   u[2] = (2*dot(l,n)*n[2])-l[2];
}

float find_shade(float *u,float s, float *pO)
{
   float answer;
   float lightVec[3] = {light[0]-(pO[0]+s *u[0]), light[1]-(pO[1]+s *u[1]), light[2]-(pO[2]+s *u[2])};
   float n[3] = {pO[0]+s *u[0]-sphere[0],pO[1]+s *u[1]-sphere[1],pO[2]+s *u[2]-sphere[2]};
   answer = -1*dot(lightVec,n)/(sqrt(abs(dot(lightVec,lightVec)))*sqrt(abs(dot(n,n))));
   return answer;
}

void init()
{
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0,screen_width,0,screen_height);
}

void display()
{
   glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   for (int i=0; i < screen_width; i++)
   {
      for (int j=0; j < screen_height; j++)
      {
         float ray[3] = {1*(eye[0]-i),-1*(eye[1]-j),1*eye[2]};
         float point[3] = {i,j,0};
         norm(ray);
         int plotted = false;

         while (!plotted)
         {
            float s_plane = plane_intersect(ray, point);
            float s_sphere = sphere_intersect(ray, point);

            if (s_plane <= 0 && s_sphere <=0)
            {
               glColor3f(0,0,0);
               glBegin(GL_POINTS);
               glVertex3f(i,j,0);
               glEnd();
               plotted = true;
            }

            else if (s_sphere >= 0  && (s_plane <=0 || s_sphere <= s_plane))
            {
               find_reflect(ray, s_sphere, point);
            }

            else if (s_plane >=0 && (s_sphere <=0 ||s_plane <= s_sphere))
            {
               float shade = find_shade(ray, s_plane, point);
               float xx = s_plane*ray[0] + eye[0];
               float z = s_plane*ray[2] + eye[2];

               if (abs((int)xx/gridXsize)%2 == abs((int)z/gridZsize)%2)
               {
                  glColor3f(shade,0,0);
               }

               else
               {
                  glColor3f(shade,shade,shade);
               }

               glBegin(GL_POINTS);
               glVertex3f(i,j,0);
               glEnd();
               plotted = true;
            }
         }
      }
   }

   glFlush();
}

int main(int argc, char **argv)
{
   glutInit(&argc, argv);
   glutCreateWindow("Ray Trace with Sphere.");
   glutInitWindowSize(screen_width,screen_height);
   glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
   glutDisplayFunc(display);
   init();
   glutMainLoop();
   return 0;
}

3voto

Monkey Punkte 1812

Der Professor hat dir nicht zu viel erzählt, denn dieses Thema wird schon tausendfach im Internet behandelt, schau dir einfach mal "Whitted Raytracing" an ;) Es ist eine Hausaufgabe, und 5 Minuten googeln würde das Problem lösen... Einige Hinweise, die dir helfen können, ohne dass du deine Hausaufgaben machen musst

Machen Sie es Schritt für Schritt, versuchen Sie nicht, das Bild in einem Schritt zu reproduzieren.

  • Eine Kugel funktioniert, wenn sie die Ebene trifft, grüne Pixel, die Kugel rote Pixel, nichts, schwarz. Das reicht, um die Schnittpunkte richtig zu berechnen. Auf deinem Bild sieht es so aus, als ob du die Schnittpunkte nicht richtig berechnet hast, für den Anfang
  • Wie zuvor, mit mehreren Kugeln. Wie bei einer Kugel: Schnittpunkt für alle Objekte prüfen, den vom Standpunkt aus nächstgelegenen Schnittpunkt behalten.
  • Wie zuvor, aber auch Berechnung der Lichtmenge, die für jeden gefundenen Schnittpunkt empfangen wird, um einen roten Farbton für Kugeln und einen grünen Farbton für die Ebene zu erhalten. (Hinweis: Punktprodukt ^^)
  • Textur für das Flugzeug
  • Reflexion für die Sphären. Tipp: Ein Spiegel reflektiert nicht 100% des Lichts, sondern nur einen Teil davon.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X