如何在 GLSL 中创建纬度(水平)等高线?
How to create latitudinal (horizontal) contour lines in GLSL?
我的目标是这种效果:(仅水平轮廓线):
我确实找到了 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);
}
fwidth
不完全是生成行,主要是 fract
是。 fwidth
仅用于保持屏幕中的线宽不变space。
如果您尝试仅使用 fract 绘制 1px 的线条,它会起作用。但是如果你想要宽线或抗锯齿线,你需要 fwidth 来进行合理的插值。
要只有水平线,您可能只需要删除 fract/fwidth 计算中的一个坐标。尽管也许您应该首先尝试使用 link 中的简单版本(更容易理解 :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);
}
我的目标是这种效果:(仅水平轮廓线):
我确实找到了 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);
}
fwidth
不完全是生成行,主要是 fract
是。 fwidth
仅用于保持屏幕中的线宽不变space。
如果您尝试仅使用 fract 绘制 1px 的线条,它会起作用。但是如果你想要宽线或抗锯齿线,你需要 fwidth 来进行合理的插值。
要只有水平线,您可能只需要删除 fract/fwidth 计算中的一个坐标。尽管也许您应该首先尝试使用 link 中的简单版本(更容易理解 :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);
}