How to create latitudinal (horizontal) contour lin

2019-04-09 20:43发布

I'm aiming for this effect: (horizontal-only contour lines):

Horizontal Contours

I did find this example, however it creates horizontal and vertical contour lines. I can't quite wrap my head around how the call to fwidth() is generating the lines.

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;
}

How would I modify that example to be horizontal-only lines?

Is there a better solution?

Update:

Solution from modified shader below. Use floats using only the y value.

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);
    }

1条回答
Anthone
2楼-- · 2019-04-09 21:06

fwidth is not exactly generating the lines, mainly fract is. fwidth is only used to keep the line width constant in screen space.

If you try to draw 1px lines only using fract, it will work. But if you want wide lines or antialiased lines, you'll need fwidth to make sensible interpolations.

To only have horizontal lines, you probably just need to remove one of the coordinates in the fract/fwidth calculation. Although maybe you should try with the simple version first from your link (a lot easier to understand :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);
}
查看更多
登录 后发表回答