2011-12-12 73 views
2

我是一名CS学生,对于我们的最终决定,我们被告知通过光线跟踪在多个球体上构建反射。这几乎是字面上我们得到的方向,除了一张图片的完成后的外观。所以我需要球体,它们是用光线上适当的阴影映射在它们上面的反射(使用光线追踪)。C++ OpenGL:光线跟踪阴影不适当着色

好吧,我有所有的工作,除了有多个领域和事实,它看起来不像他给我们的图片。

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

我认为是修改sphere_intersect和find_reflect以包括正在分析哪个球体。接下来,修改find​​_reflect,以便在计算新的向量u时,其起始点(P0)也会更新。然后,如果射线碰到球体,则必须计算射线的反射次数。在某个点终止(也许10次之后),然后我将绘制像素。为了增加触觉,我想为球体添加纯色,这将需要找到我相信的球体的法线。

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

在此先感谢!

教授的领域

enter image description here

我的球

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; 
} 
+0

嗨,我可以有关于你的射线示踪剂的更多信息吗?我现在开始了解射线追踪的工作原理 –

回答

3

教授没有告诉你太多,因为这样的话题被覆盖成千上万的时间在网上,只是退房“Whitted Raytracing”;)这是作业,5百万的谷歌搜索将解决这个问题......一些线索,以帮助不做作业你

做一步一步来,不要尝试重现画面一步到位

  • 获取一个领域工作,如果打飞机绿色像素,球红色像素,没有什么,黑色。这足以让交叉计算正确。从你的图片看来,你没有正确的交叉路口,开始吧
  • 和以前一样,有几个球体。与一个球体相同:检查所有对象的交点,从视点保留最近的交点。
  • 与以前相同,但也计算每个找到的交点所接收到的光量,使球体具有红色阴影,以及平面具有绿色阴影。 (提示:点积^^)
  • 纹理为飞机
  • 球的反射。 Protip:镜子不能反射100%的光线,只是其中的一小部分。
+3

仅仅因为它覆盖了成千上万次并不意味着它更容易:)射线追踪是一个相当复杂的事情来实现,我希望教授会尝试去把它变成一个细节,而不仅仅是说“好吧,现在就去做吧。” –

+1

嗡嗡声,我个人认为,Whitted光线追踪(每光一光,完全确定性)不*复杂,您可以在几百行C或任何其他语言中获得基本场景。没有难写的线条,大约2到3个小时的严肃对焦。球体和检查器是计算机图形学的“你好世界”。另一方面,我同意,获得随机/分布式光线追踪是很困难的(特别是验证你的实现)。即使如此,有些人还是用99行代替了它http://kevinbeason.com/smallpt/ ^^ – Monkey

+2

*教学*的目的是让你不必随意去随机找出网站。教学的存在是为了逐步指导你如何做某件事。这是一位可怜的教授,他说:“执行光线追踪,我不会为我的实际工作而烦心,因为有线上资源可以告诉你怎么做。”那时,教授已经使自己与这个过程无关。 –