2

我是一名 CS 学生,在我们的期末考试中,我们被告知要通过光线追踪在多个球体上构建反射。这几乎就是我们得到的指示,除了一张完成后应该是什么样子的图片。所以我需要球体,它们是反射(使用光线追踪)映射到它们上,并带有适当的灯光阴影。

好吧,我已经完成了所有工作,除了有多个球体,而且它看起来不像他给我们的标题图片。

多个球体的事情我不太确定该怎么做,但我想说我需要将它们存储在二维数组中并修改几段代码。

我的想法是修改 sphere_intersect 和 find_reflect 以包括正在分析的球体。接下来,修改 find_reflect 以便在计算新向量 u 时,它的起点 (P0) 也会更新。然后,如果光线击中球体,则必须计算光线被反射了多少次。在某个时候终止(可能在 10 次之后),然后我将只绘制像素。为了增加触感,我想为球体添加纯色,这将需要找到我相信的球体的法线。

无论如何,我将附上他的照片,我的照片和源代码。希望有人可以帮助我解决这个问题。

提前致谢!

教授的领域

在此处输入图像描述

我的领域

在此处输入图像描述

#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;
}
4

1 回答 1

3

教授没有告诉你太多,因为这样的话题在网上已经被报道了数千次,只需查看“Whitted Raytracing”;)这是家庭作业,500 万次谷歌搜索将解决这个问题......一些线索无需为您做作业即可提供帮助

一步一步做,不要试图一步步重现图片

  • 让一个球体工作,如果碰到平面绿色像素,球体红色像素,什么都没有,黑色。正确计算交叉点就足够了。从你的照片看来,你没有正确的十字路口,一开始
  • 和以前一样,有几个球体。与一个球体相同:检查所有对象的交点,从视点保持最近的交点。
  • 与前面相同,但还要计算找到的每个交叉点接收到的光量,球体为红色,平面为绿色。(提示:点积^^)
  • 飞机的纹理
  • 球体的反射。提示:镜子不会反射 100% 的光,只是反射的一小部分。
于 2011-12-12T03:37:52.923 回答