【发布时间】:2016-05-02 04:03:42
【问题描述】:
我正在开发一个实现阴影映射的 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 中的分支是如何工作的,我有什么遗漏吗?
【问题讨论】:
-
您是否尝试过将颜色累积到一个单独的
vec4变量并仅将gl_FragColor分配一次该另一个变量的值。应该支持在着色器中多次写入gl_FragColor以及读取它的值(这是实现+=所必需的),但从所有方面来看,这个问题似乎与给定的这些操作中的一个或两个有关你的控制流。 -
我尝试用累加器
vec4 acc;替换上述sn-ps 中gl_FragColor的所有实例。我只在着色器末尾分配了gl_FragColor = acc;在上述任何情况下都没有变化。 -
能否提供完整的 fs 代码?另外,如果您将代码更改为
gl_FragColor += vec4( calcLight(..), 1.0 ),会有什么不同吗? [注意 1.0 alpha 值] -
将 alpha 从 0.0 更改为 1.0 无效。这是一大块代码,所以我把它放在pastebin上。顶点着色器:pastebin.com/XLYSwvL7 片段着色器:pastebin.com/bYdvuRjj 有问题的 sn-p 来自片段着色器的底部。
-
由于这是 WebGL,如果您可以创建一个页面,如果我们设法重现错误,我们可以在其中尝试/更改内容,这将很有帮助。这似乎是驱动程序问题。
标签: opengl-es glsl webgl shader