2011-12-12 3 views
2

저는 CS 학생이며 최종적으로 광선 추적을 통해 여러 영역에서 반사를 구성해야한다고 들었습니다. 그것은 말 그대로 길을 찾은 것입니다. 끝날 때 어떻게 보일 것인가를위한 그림을 제외하고 말입니다. 그래서 저는 빛으로부터 적절한 음영으로 반사 된 광선 (광선 추적 사용)을 사용하여 구체가 필요합니다.C++ OpenGL : 광선 추적 쉐이딩이 적절하게 음영 처리되지 않았습니다

여러 개의 구체와 그것이 루 브릭을 위해 우리에게 준 그림처럼 보이지 않는다는 것을 제외하고는 모두 잘 작동합니다.

여러 분야에서 어떻게해야할지 모르겠지만 2D 배열에 저장하고 코드의 일부 섹션을 수정해야한다고 말하고 싶습니다.

나는 sphere_intersect와 find_reflect를 수정하여 어느 영역이 분석되고 있는지 생각하고 있었다. 다음으로 find_reflect를 수정하여 새로운 벡터 u가 계산 될 때 시작점 (P0)도 업데이트되도록하십시오. 그런 다음 광선이 구와 충돌하면 광선이 반사 된 횟수를 세어 봐야합니다. 어떤 시점에서 (어쩌면 10 번) 종료 한 다음 픽셀을 그립니다. 추가 된 터치를 위해 나는 구형의 정상적인 것을 찾는 것을 요구할 구체에 단색을 더하고 싶습니다.

어쨌든 그의 사진, 내 사진, 소스 코드를 첨부 할 것입니다. 잘만되면 누군가 나를 도와 줄 수 있습니다.

미리 감사드립니다.

교수의 구체와 같은 주제는 웹을 통해 시간의 수천을 덮여 있기 때문에 교수가, 너무 많이 말하지 않았다

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

enter image description here

내 구 , 그냥 체크 아웃 "Whitted Raytracing";) 그것은 숙제이며, 주위 5 백만명의 인터넷 검색 문제를 해결할 것입니다 ... 일부 단서는 한 단계

  • 받기 하나 구 명 작업, 비행기 녹색 픽셀을 칠 경우 영역에서 사진을 재현하려고하지 않습니다, 당신은

    이 단계적으로 수행하기위한 숙제를하지 않고 도움 빨간색 픽셀, 아무것도, 검정. 교차점을 올바르게 계산하는 것으로 충분합니다. 그림에서 보았을 때 교차로가 처음부터없는 것 같습니다.

  • 여러 분야로 이전과 같습니다. 하나의 구체와 동일 : 모든 오브젝트의 교차점을 확인하고 가장 가까운 교차점을 시점에서 유지합니다.
  • 이전과 동일하지만 발견 된 각 교차점에 대해 수신 된 빛의 양을 계산하고, 구면에 빨간색 음영을, 평면에 녹색 음영을 계산합니다. (힌트 : 내적 제품 ^^)
  • 평면에 대한 텍스처
  • 구에 대한 반사. Protip : 거울은 빛의 100 %를 반영하지 않으며 단지 그것의 일부분을 반영합니다.
+3

그것은 수천 번에 걸쳐서 다루어 졌기 때문에 그것이 더 쉽다는 것을 의미하지는 않는다 :) 광선 추적은 구현하기에 상당히 복잡한 것이고, 교수가 갈려고한다. "Okay, now do this this."라고 말하는 것보다는 작동하는 방법에 대해 자세히 설명합니다. –

+1

흠, 나는 개인적으로 Whitted raytracing (빛 당 1 레이, 완전히 결정론적인)이 복잡하지 않다고 믿는다. C의 몇 백 라인이나 다른 언어로 기본 장면을 얻을 수있다. 쓰는 단단한 선, 심각한 집중의 대략 2 3 시간이 없다. 구체 & 검수원은 컴퓨터 도표의 "안녕하세요 세계"이다. 반면 확률 적/분산 적 레이 트레이싱을 얻는 것은 어렵습니다 (특히 구현의 유효성 검사). 그리고 심지어 일부는 99 줄로 만들었습니다. http://kevinbeason.com/smallpt/ ^^ – Monkey

+2

* teaching *의 목적은 임의의 웹 사이트로 나가서 알아낼 필요가 없도록하기 위해서입니다. 어떻게 행동 하는지를 단계별로 안내하는 교육이 있습니다. 가라 앉은 교수님은 "레이 트레이싱을 구현하십시오. 어떻게하는지 보여주는 온라인 리소스가 있기 때문에 실제 업무를 수행하지 않아도됩니다." 그 시점에서 교수는 그 과정에 무관하게 만들었습니다. –

관련 문제