如何在GLSL中创建纬度(水平)轮廓线?

win*_*toy 4 opengl glsl webgl

我的目标是这个效果:(仅水平轮廓线):

水平轮廓

我确实找到了这个例子,但它创建了水平垂直轮廓线.我无法完全理解调用fwidth()生成线的方式.

uniform float gsize;//size of the grid
uniform float gwidth;//grid lines'width in pixels
varying vec3 P;

void main()
{
    vec3 f  = abs(fract (P * gsize)-0.5);
    vec3 df = fwidth(P * gsize);
    float mi=max(0.0,gwidth-1.0), ma=max(1.0,gwidth);//should be uniforms
    vec3 g=clamp((f-df*mi)/(df*(ma-mi)),max(0.0,1.0-gwidth),1.0);//max(0.0,1.0-gwidth) should also be sent as uniform
    float c = g.x * g.y * g.z;
    gl_FragColor = vec4(c, c, c, 1.0);
    gl_FragColor = gl_FragColor * gl_Color;
}
Run Code Online (Sandbox Code Playgroud)

如何将该示例修改为仅水平线?

有更好的解决方案吗?

更新:

修改后的着色器解决方案.仅使用y值来使用浮点数.

void main() {
            float f  = fract (_pos.y * 15.0);
            float df = fwidth(_pos.y * 15.0);

            float g = smoothstep(df * 1.0, df * 2.0, f);

            float c = g;

            gl_FragColor = vec4(c, c, c, 1.0);
    }
Run Code Online (Sandbox Code Playgroud)

Jer*_*rem 5

fwidth并不完全是生成线,主要fract是.fwidth仅用于在屏幕空间中保持线宽恒定.

如果你尝试仅使用fract绘制1px行,它将起作用.但是如果你想要宽线或抗锯齿线,你需要使用fwidth来进行合理的插值.

要只有水平线,您可能只需要删除fract/fwidth计算中的一个坐标.虽然也许您应该首先从链接尝试使用简单版本(更容易理解:D):

varying vec3 k;

void main()
{
    vec3 f  = fract (k * 100.0);
    vec3 df = fwidth(k * 100.0);

    vec3 g = smoothstep(df * 1.0, df * 2.0, f);

    float c = g.x * g.y * g.z;

    gl_FragColor = vec4(c, c, c, 1.0);
}
Run Code Online (Sandbox Code Playgroud)