奇怪的体素圆锥跟踪结果

时间:2018-08-04 19:25:21

标签: c++ opengl glsl shader voxel

我目前正在用C ++和OpenGL编写Voxel圆锥跟踪渲染引擎。一切都进行得很好,只是对于更大的锥角我得到了相当奇怪的结果。

现在,出于测试目的,我要做的是垂直于碎片法线射出一个奇异圆锥。我只是在计算“间接光”。作为参考,这是我正在使用的相当简单的片段着色器:

#version 450 core

out vec4 FragColor;

in vec3 pos_fs;
in vec3 nrm_fs;

uniform sampler3D tex3D;

vec3 indirectDiffuse();

vec3 voxelTraceCone(const vec3 from, vec3 direction);

void main()
{
    FragColor = vec4(0, 0, 0, 1);
    FragColor.rgb += indirectDiffuse();
}

vec3 indirectDiffuse(){
    // singular cone in direction of the normal
    vec3 ret = voxelTraceCone(pos_fs, nrm);

    return ret;
}

vec3 voxelTraceCone(const vec3 origin, vec3 dir) {
    float max_dist = 1f;
    dir = normalize(dir);

    float current_dist = 0.01f;

    float apperture_angle = 0.01f; //Angle in Radians.

    vec3 color = vec3(0.0f);
    float occlusion = 0.0f;

    float vox_size = 128.0f; //voxel map size

    while(current_dist < max_dist && occlusion < 1) {
        //Get cone diameter (tan = cathetus / cathetus)
        float current_coneDiameter = 2.0f * current_dist * tan(apperture_angle * 0.5f);

        //Get mipmap level which should be sampled according to the cone diameter
        float vlevel = log2(current_coneDiameter * vox_size);

        vec3 pos_worldspace = origin + dir * current_dist;
        vec3 pos_texturespace = (pos_worldspace + vec3(1.0f)) * 0.5f; //[-1,1] Coordinates to [0,1]

        vec4 voxel = textureLod(tex3D, pos_texturespace, vlevel); //get voxel

        vec3 color_read = voxel.rgb;
        float occlusion_read = voxel.a;

        color = occlusion*color + (1 - occlusion) * occlusion_read * color_read;
        occlusion = occlusion + (1 - occlusion) * occlusion_read;

        float dist_factor = 0.3f; //Lower = better results but higher performance hit
        current_dist += current_coneDiameter * dist_factor; 
    }

    return color;
}

tex3D制服是三维3d纹理。

在常规的Phong着色器(用于计算体素值)下,场景如下所示: Scene

作为参考,这是可视化时的体素贴图(tex3D)(128x128x128)的样子:Voxelmap

现在,我们要解决我遇到的实际问题。如果将上面的着色器应用于场景,则会得到以下结果:

对于非常小的锥角(apperture_angle = 0.01),我大致可以预期:体素化的场景实质上是在每个表面上垂直地“反射”: Small Apperture

现在,如果我将拍角增加到例如30度(apperture_angle = 0.52),我会得到一个看起来很奇怪的“波浪形”结果:

Large Appeture

我期望与早期的结果更加相似,而镜面反射更少。取而代之的是,我得到的每个对象的轮廓大多以镜面反射的方式出现,轮廓内偶尔有一些像素。考虑到这是场景中的“间接照明”,即使我添加了直接照明,效果也不会很好。

我尝试过为max_dist,current_dist等设置不同的值,以及拍摄多个圆锥体而不是一个。结果仍然相似,甚至更糟。

有人知道我在这里做错了什么,以及如何获取实际的远程逼真的间接光?

我怀疑对于大于0的任何LOD级别,textureLod函数都会以某种方式产生错误的结果,但是我无法确认这一点。

1 个答案:

答案 0 :(得分:0)

未正确生成3D纹理的Mipmap。 另外,vlevel上没有硬性限制,导致所有textureLod调用返回#000000颜色,该颜色访问了高于1的任何mipmaplevel。