为什么 fwidth 表现不同?
Why fwidth behaves differently?
我正在开发一个 WebGL 项目,以在 macOS/amd GPU 上的 3D 表面上创建等值线。我的想法是根据片段着色器中的高程为像素着色。通过一些优化,我可以获得相对一致的线宽,对此我很高兴。但是,当我在 windows 上对其进行测试时,它的行为有所不同。
然后我发现这是因为 fwidth()。我使用 fwidth() 来防止片段着色器在恰好位于等值层时为整个水平面着色。请看截图:
我通过添加以下 glsl 行解决了这个问题:
if (fwidth(vPositionZ) < 0.001) { /**then do not colour isoline on these pixels**/ };
它在 macOS 上工作得很好,因为我得到了这个:
。
但是,在 windows/nvidia GPU 上,所有等值线都消失了,因为 fwidth(vPositionZ) 始终计算为 0.0。这对我来说没有意义。
我做错了什么?有没有更好的方法来解决第一个屏幕截图中出现的问题?谢谢大家!
编辑:
在这里我附加了我的片段着色器。它被简化了,但我认为这都是相关的。我知道循环很慢,但现在我不担心它。
uniform float zmin; // min elevation
uniform vec3 lineColor;
varying float vPositionZ; // elevation value for each vertex
float interval;
vec3 originColor = finalColor.rgb; // original surface color
for ( int i = 0; i < COUNT; i ++ ) {
float elevation = zmin + float( i + 1 ) * interval;
lineColor = mix( originColor, lineColor, step( 0.001, fwidth(vPositionZ)));
if ( vPositionZ <= elevation + lineWidth && vPositionZ >= elevation - lineWidth ) {
finalColor.rgb = lineColor;
}
// same thing but without condition:
// finalColor.rgb = mix( mix( originColor, lineColor, step(elevation - lineWidth, vPositionZ) ),
// originColor,
// step(elevation + lineWidth, vPositionZ) );
}
gl_FragColor = finalColor;
环境:WebGL2.0,es版本300,chrome浏览器。
在循环工作之前放置 fwidth(vPosistionZ)。否则,如果在循环内,fwidth() 会将任何值计算为 0。
我怀疑这是 Nvidia GPU 的错误。
我正在开发一个 WebGL 项目,以在 macOS/amd GPU 上的 3D 表面上创建等值线。我的想法是根据片段着色器中的高程为像素着色。通过一些优化,我可以获得相对一致的线宽,对此我很高兴。但是,当我在 windows 上对其进行测试时,它的行为有所不同。
然后我发现这是因为 fwidth()。我使用 fwidth() 来防止片段着色器在恰好位于等值层时为整个水平面着色。请看截图:
我通过添加以下 glsl 行解决了这个问题:
if (fwidth(vPositionZ) < 0.001) { /**then do not colour isoline on these pixels**/ };
它在 macOS 上工作得很好,因为我得到了这个:
我做错了什么?有没有更好的方法来解决第一个屏幕截图中出现的问题?谢谢大家!
编辑: 在这里我附加了我的片段着色器。它被简化了,但我认为这都是相关的。我知道循环很慢,但现在我不担心它。
uniform float zmin; // min elevation
uniform vec3 lineColor;
varying float vPositionZ; // elevation value for each vertex
float interval;
vec3 originColor = finalColor.rgb; // original surface color
for ( int i = 0; i < COUNT; i ++ ) {
float elevation = zmin + float( i + 1 ) * interval;
lineColor = mix( originColor, lineColor, step( 0.001, fwidth(vPositionZ)));
if ( vPositionZ <= elevation + lineWidth && vPositionZ >= elevation - lineWidth ) {
finalColor.rgb = lineColor;
}
// same thing but without condition:
// finalColor.rgb = mix( mix( originColor, lineColor, step(elevation - lineWidth, vPositionZ) ),
// originColor,
// step(elevation + lineWidth, vPositionZ) );
}
gl_FragColor = finalColor;
环境:WebGL2.0,es版本300,chrome浏览器。
在循环工作之前放置 fwidth(vPosistionZ)。否则,如果在循环内,fwidth() 会将任何值计算为 0。 我怀疑这是 Nvidia GPU 的错误。