如何在GLSL中创建纬度(水平)轮廓线?
我要达到这种效果:(仅水平轮廓线):
I'm aiming for this effect: (horizontal-only contour lines):
我确实找到了此示例,但是会创建水平和垂直轮廓线.我不太了解fwidth()
的调用是如何生成行的.
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?
有更好的解决方案吗?
更新:
来自以下修改的着色器的解决方案.仅使用y
值使用浮点数.
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);
}
fwidth
不能完全生成行,主要是fract
是. fwidth
仅用于在屏幕空间中保持线宽恒定.
fwidth
is not exactly generating the lines, mainly fract
is. fwidth
is only used to keep the line width constant in screen space.
如果您尝试仅使用fract绘制1px线,它将起作用.但是,如果您想要宽线或抗锯齿线,则需要使用fwidth进行明智的插值.
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.
要只包含水平线,您可能只需要删除fract/fwidth计算中的坐标之一.尽管也许您应该首先从链接中尝试使用简单版本(更容易理解:D):
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);
}