【问题标题】:How to create latitudinal (horizontal) contour lines in GLSL?如何在 GLSL 中创建纬度(水平)等高线?
【发布时间】:2015-06-20 05:27:15
【问题描述】:

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

我确实找到了 this example,但它会创建水平 垂直轮廓线。我无法完全理解对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;
}

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

有没有更好的解决方案?

更新:

来自下面修改的着色器的解决方案。仅使用 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);
    }

【问题讨论】:

    标签: opengl glsl webgl


    【解决方案1】:

    fwidth 不完全生成行,主要是fractfwidth 仅用于在屏幕空间中保持线宽不变。

    如果您尝试仅使用 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);
    }
    

    【讨论】:

    • 谢谢,这个比较容易理解。删除其中一个坐标是什么意思?只需将其设置为零,例如vec3 pos = vec3(k.x, 0.0, k.y)?我不确定我是否理解这将如何使其仅水平工作。
    • 不,我的意思是将 f、df 和 g 更改为 vec2,并且只使用 k.xz。
    • 啊!你就是那个男人!我已经更新了我的问题以显示有效的方法。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    相关资源
    最近更新 更多