0

OK so i have a really big square (grid) that I have made up using triangles, then applied a heightmap to bump it. What im trying to do now is get grid lines on it. I have figured out a way to do this but this results in 33 if statements in the fragment shader just for x and then another 33 for y. I have been told I can use what im doing now and implement it slightly differently (using some GLSL function) to only need 1 or 2 if statements. This is my current code (not all finished but gives you the idea of what im doing.)

#version 330

uniform sampler2D texture;

in vec2 texCoord;

layout (location=0) out vec4 fragColour;



void main(void) {

vec4 newColor;
vec2 line = texCoord * 32; // makes texCoords easier to number (as divided by 32 in the C++array)


if(line.x > 0 && line.x < 0.9)
{
    newColor = vec4(1.0,1.0,1.0,1.0);
}
else if(line.x > 1 && line.x < 1.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 2 && line.x < 2.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 3 && line.x < 3.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 4 && line.x < 4.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 5 && line.x < 5.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 6 && line.x < 6.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 7 && line.x < 7.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 8 && line.x < 8.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 9 && line.x < 9.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 10 && line.x < 10.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 11 && line.x < 11.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 12 && line.x < 12.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 13 && line.x < 13.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 14 && line.x < 14.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 15 && line.x < 15.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 16 && line.x < 16.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 17 && line.x < 17.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 18 && line.x < 18.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 19 && line.x < 19.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 20 && line.x < 20.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 21 && line.x < 21.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 22 && line.x < 22.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 23 && line.x < 23.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}
    else if(line.x > 24 && line.x < 24.9)
{
     newColor = vec4(1.0,1.0,1.0,1.0);
}

else
{
    newColor = vec4(0.0,0.0,0.0,1.0);
}

fragColour = newColor;
}
4

2 回答 2

6

除非绝对必要(至少这是我上次编写 glsl 着色器时的标准建议),否则您不应使用控制流(依赖于统一以外的其他东西)。在您的情况下,不需要控制流。使用stepsmoothstepmix乘法来避免控制流。

您的“if/else”代码段可以使用类似这样的东西(未经测试的代码)来实现:

fragColor = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), step(fract(line.x), 0.9));

或使用纹理查找。纹理查找可能比数值计算更快,具体取决于硬件(和纹理大小)

请注意,使用“step”可能会在远处的表面上产生锯齿状的非抗锯齿边缘和噪点/摩尔纹图案。“OpenGL 橙皮书”(“OpenGL 着色语言”)有一些例子可以解释如何处理它。但是,使用纹理查找可能更容易。首先,您可以尝试使用“smoothstep”而不是“step”。

或者,或者,您可以在实体渲染的景观之上以线框模式重新绘制整个景观。

于 2012-11-15T17:07:12.643 回答
0

这很容易通过简单地扔下投影纹理来完成。它甚至不必“投射”;只需根据您的line. 事实上,那些看起来很像是你的纹理坐标。因此,只需创建一个内部为白色,外部为适当宽度的黑色的纹理。您甚至可以将其设为单通道以节省内存。

当然,您将需要纹理在 S 和 T 方向上重复。

于 2012-11-15T17:28:21.380 回答