1

在此处输入图像描述

我正在尝试使用我自己在 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;
                }
        }
}

我的距离估计函数是一个非常直译的翻译,看起来像这样:

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);
}

并且输出看起来完全像拆箱一样:

如何设置眼睛变换以便正确看到立方体?

在此处输入图像描述

4

2 回答 2

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;
    ...
于 2012-07-11T10:38:01.410 回答
0

您可以使用此处概述的方法生成正确的光线(及其长度)。

于 2012-07-09T21:23:47.530 回答