2011-12-12 71 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

*教學*的目的是讓你不必隨意去隨機找出網站。教學的存在是爲了逐步指導你如何做某件事。這是一位可憐的教授,他說:「執行光線追蹤,我不會爲我的實際工作而煩心,因爲有線上資源可以告訴你怎麼做。」那時,教授已經使自己與這個過程無關。 –