我正在开发一个实现阴影贴图的WebGL程序。在计算每个片段的深度值之后,我在末尾有一个if语句,根据片段是否在阴影中来计算光照。
gl_FragColor = vec4(calcLighting(light0, eye_dir, eye_dir_norm, normal), 1);
if (light_tex_coord.z - depth <= 0.0) {
gl_FragColor += vec4
( calcLighting(light1, eye_dir, eye_dir_norm, normal)
, 0.0
);
}
其中depth
是阴影贴图的深度,light_tex_coord
是片段在light1
的场景空间中的位置。 light1
是围绕模型旋转的点光源,light0
是静态定位在相机处的点光源。
这里的问题是从不采用if分支,因此场景只应用了light0
。我已检查depth
,light_tex_coord
和calculateLighting
是否正常工作。
但是,这是奇怪的事情,用以下代码替换上面的内容:
if (light_tex_coord.z - depth <= 0.0) {
gl_FragColor = vec4(0,1,0,1);
} else {
gl_FragColor = vec4(1,0,0,1);
}
使阴影区域以红色正确绘制,并且不带阴影以绿色绘制。也就是说,正确评估分支。用它替换它:
gl_FragColor = vec4(calcLighting(light0, eye_dir, eye_dir_norm, normal), 1);
gl_FragColor += vec4
( calcLighting(light1, eye_dir, eye_dir_norm, normal)
, 0.0
);
导致正确计算光照(尽管没有阴影)。看来,当我在if语句中调用更昂贵的calcLighting函数时,它甚至不打扰它。
此外,我尝试过以多种方式应用照明,包括使用clamp
功能;总是进行添加并使用三元运算符将第二个calcLighting
调用乘以1或0,并以不同的方式排列我的if语句。似乎没什么用。
对于webgl中的分支是如何工作的,我有什么遗漏吗?
答案 0 :(得分:0)
也许WebGl上下文不支持深度。然后使用它的表达式将被忽略。
您可以使用getContextAttributes()
进行检查答案 1 :(得分:0)
而不是分支,你是否考虑过像这样激进的东西:
gl_FragColor += vec4 (
calcLighting(light1, eye_dir, eye_dir_norm, normal)
, 0.0
) * abs (min (sign (light_tex_coord.z - depth), 0.0));
这不是世界上最漂亮的解决方案,但它可能会让你得到更多符合你所寻找的东西。它基本上采用你的light_tex_coord.z - depth <= 0.0
条件表达式并使其成为一个漂亮的浮点 0.0 或 1.0 ,你可以将灯光乘以 keep 或丢弃分支结果。在引入动态流控制之前,着色器 使用 的方式有效。
答案 2 :(得分:0)
主题是2岁,但这是我的2美分:
我遇到了类似的问题,并在互联网上找到了一个包含以下句子的讨论页面:
[...](除非你做像条件中的图像写入等疯狂的东西 块)。 [...]
所以我尝试将像素颜色放在临时变量
中vec4 col;
本地到main(),在“if”语句中我只修改了col,并且我只在最后设置了像素颜色:
gl_FragColor = col;
这解决了我的问题。当然,可能需要烦人的额外编程才能使流量在每种情况下都到达最后一行。