体积光线投射不';t工作正常(Webgl+;GLSL+;Three.js)
我已尝试使我的体积光线投射算法具有更好的质量。我设置了一个较小的raycast步骤(质量更好),但它会导致问题。它在下面的图片上(不应该在黑色区域) 我使用RGB立方体获得光线在体积中的方向。 我想,我也有类似的算法: 有人有什么想法吗?哪里会有问题?我需要解决这个问题,因为我的diplom论文的最后期限即将结束:(我真的不知道,为什么它不起作用:( 编辑: 我无法在那里显示我所有的代码(如果我在交给学校之前提供,可能会有问题)。但是阅读本书的关键代码:体积光线投射不';t工作正常(Webgl+;GLSL+;Three.js),three.js,glsl,webgl,raycasting,volume-rendering,Three.js,Glsl,Webgl,Raycasting,Volume Rendering,我已尝试使我的体积光线投射算法具有更好的质量。我设置了一个较小的raycast步骤(质量更好),但它会导致问题。它在下面的图片上(不应该在黑色区域) 我使用RGB立方体获得光线在体积中的方向。 我想,我也有类似的算法: 有人有什么想法吗?哪里会有问题?我需要解决这个问题,因为我的diplom论文的最后期限即将结束:(我真的不知道,为什么它不起作用:( 编辑: 我无法在那里显示我所有的代码(如果我在交给学校之前提供,可能会有问题)。但是阅读本书的关键代码: // All variables
// All variables neede to rays
vec3 rayDirection = texture2D(backFaceCube, texCoo).xyz - varcolor.xyz;
float lenRay = length(rayDirection);
vec3 normDir = normalize(rayDirection);
float d = qualitySteps; //quality steps is size of steps defined by user -> example: 0.01, 0.001, 0.0001 etc.
vec3 step = normDir * d;
float lenStep = length(step);
float accumulatedLength = 0.0;
然后在循环中:
posInCube.xyz += step;
accumulatedLength += lenStep;
...
...
...
if(accumulatedLength >= lenRay || accumulatedColor.a > 1.0 ) {
break;
}
EDIT2:(抱歉,像评论一样,它太长了)
是的,纹理有噪声…我尝试用alpha:if(accumulatedColor.a>1.0)
删除条件,但结果相同。
我认为这和光线的长度和步长有直接的关系。我尝试了很多组合,我发现了这些东西。
如果步长很大,我可以通过所有的体积,但如果步长很小,我就真的无法通过体积(可能)。如果步长很大,我可以看到变形的对象(如果我在GPU上脱离纹理,可能是重复纹理造成的)。如果步长太小,我只能映射纹理的一小部分->看起来,光线太短,但实际上他不是。奎斯汀是,为什么三维坐标到二维纹理的映射是错误的,取决于步长的大小。你能提供片段着色器的代码吗 您是否从前端位置遍历整个向量?下面是一个示例着色器(代码可能包含一些错误,因为我只是从头开始编写的。很遗憾,我目前无法在计算机上测试代码): vec2 texCoord中的
;
外显vec4外显色;
均匀浮动步长;
统一整数步;
纹理均匀;
均匀的二维背景纹理;
均匀采样三维体积结构;
均匀取样器1D transferTexture;//将密度转换为RGB
void main()
{
vec4颜色=vec4(0.0);
vec3 startPosition=纹理(frontTexture,texCoord);
vec3 endPosition=纹理(背面纹理,texCoord);
vec3 delta=规格化(起始位置-结束位置)*步长;
vec3位置=起始位置;
对于(int i=0;i=1.0)
{
打破
}
//前进
位置+=方向;
如果(位置.x>1.0 | |位置.y>1.0 | | |位置.z>1.0)
{
打破
}
}
outColor=颜色;
}
我已经在上面发布了我的着色器的一部分。我认为,你的解决方案与我的完全相同……我不知道我做错了什么:(谢谢!:-)似乎,如果步长较小,光线的长度也较小。问题是,为什么?我用2D纹理分段模拟3D纹理(WebGL没有3D纹理)。步长大小可能有问题吗?是否有噪声纹理?根据您的描述,如果步长较小,则会出现第二个屏幕截图。如果步长较小,则会在相同距离内计算更多样本。如果纹理有噪声,则可能会导致alpha值很早就超过1.0(因此是暗区?)。您是否使用像上面代码一样的采样距离校正?正如旁注,在您的示例代码中,lenStep与qualityStep的值相同。规范化向量的长度为1,因此lenStep=Length(step)=Length(normDir*d)=d*Length(normDir)=d*1=qualityStep
。响应在EDIT2中。它太长了:(你有机会修复它吗?如果有,代码是开源的吗?我对此非常感兴趣。谢谢
in vec2 texCoord;
out vec4 outColor;
uniform float stepSize;
uniform int numSteps;
uniform sampler2d frontTexture;
uniform sampler2d backTexture;
uniform sampler3d volumeTexture;
uniform sampler1d transferTexture; // Density to RGB
void main()
{
vec4 color = vec4(0.0);
vec3 startPosition = texture(frontTexture, texCoord);
vec3 endPosition = texture(backTexture, texCoord);
vec3 delta = normalize(startPosition - endPosition) * stepSize;
vec3 position = startPosition;
for (int i = 0; i < numSteps; ++i)
{
float density = texture(volumeTexture, position).r;
vec3 voxelColor = texture(transferTexture, density);
// Sampling distance correction
color.a = 1.0 - pow((1.0 - color.a), stepSize * 500.0);
// Front to back blending (no shading done)
color.rgb = color.rgb + (1.0 - color.a) * voxelColor.a * voxelColor.rgb;
color.a = color.a + (1.0 - color.a) * voxelColor.a;
if (color.a >= 1.0)
{
break;
}
// Advance
position += direction;
if (position.x > 1.0 || position.y > 1.0 || position.z > 1.0)
{
break;
}
}
outColor = color;
}