2012-07-09 112 views
1

enter image description here繪製一個立方體的角度

我想用我自己的ray marching在CPU上繪製Mandelbox

我有一個width * height位圖渲染。

對於每個像素,我想對立方行軍:

static float eye = 0.0f; eye = glm::clamp(eye+0.005f,0.0f,1.0f); // animate 
const glm::mat4 projection = glm::perspective(35.0f, (float)width/height, 0.1f, 10.0f), 
     modelview = glm::lookAt(glm::vec3(cos(eye),sin(eye),-1),glm::vec3(0,0,0),glm::vec3(0,0,1));  
const float epsilon = sqrt(1.0f/std::max(width,height))/2.0f; 
for(int y=0; y<height; y++) { 
     for(int x=0; x<width; x++) { 
       glm::vec3 p = glm::unProject(glm::vec3(x,y,0),modelview,projection,glm::vec4(0,0,width,height)), 
         dir = glm::unProject(glm::vec3(x,y,1),modelview,projection,glm::vec4(0,0,width,height))-p, 
         P0 = p; 
       //std::cout << x << "," << y << " " << p.x << "," << p.y << "," << p.z << " " << dir.x << "," << dir.y << "," << dir.z << std::endl; 
       float D = 0; 
       for(int i=0; i<MAX_ITER; i++) { 
         const float d = DE(p); 
         D += d; 
         if(d<epsilon) { 
           depth_bmp[y*width+x] = 255.0f/i; 
           break; 
         } 
         p = dir*D + P0; 
       } 
     } 
} 

我的距離估計的功能是一個非常literal translation,看起來像這樣:

float DE(glm::vec3 p) { 
    const float Scale = -1.77f, fixedRadius2 = 1.0f, minRadius2 = (0.5f*0.5f); 
    const glm::vec3 p0 = p; 
    float dr = 1.0f; 
    for(int n = 0; n < 13; n++) { 
     // Reflect 
     p = (glm::clamp(p,-1.0f,1.0f) * 2.0f) - p; 
     // Sphere Inversion 
     const float r2 = glm::dot(p,p); 
     if(r2<minRadius2) { 
      const float t = (fixedRadius2/minRadius2); 
      p *= t; 
      dr *= t; 
     } else if(r2<fixedRadius2) { 
      const float t = (fixedRadius2/r2); 
      p *= t; 
      dr *= t; 
     } 
     // Scale & Translate 
       p = p * Scale + p0; 
       dr = dr * abs(Scale) + 1.0f; 
    } 
    return glm::length(p)/abs(dr); 
} 

和輸出看起來完全unbox-如:

如何設置眼睛變形,以便正確地看到立方體?

enter image description here

回答

1

的問題是,光線的長度必須歸:

glm::vec3 p = glm::unProject(glm::vec3(x,y,0),modelview,projection,glm::vec4(0,0,width,height)), 
    dir = glm::unProject(glm::vec3(x,y,1),modelview,projection,glm::vec4(0,0,width,height))-p; 
const float len = glm::length(dir); 
dir = glm::normalise(dir); 
float D = 0; 
for(int i=0; i<MAX_ITER; i++) { 
    const float d = DE(p + dir*D); 
    D += d; 
    if(D > len) break; 
    ... 
0

可以使用概述here的方法來生成正確的射線(及它們的長度)。