GLSL盒内点测试 [英] GLSL point inside box test
问题描述
下面是一个输出纹理像素的GLSL片段着色器 如果给定的纹理坐标位于框内,则否则 颜色输出.这感觉很傻,在那里 一定是一种无需分支的方法吗?
Below is a GLSL fragment shader that outputs a texel if the given texture coord is inside a box, otherwise a color is output. This just feels silly and the there must be a way to do this without branching?
uniform sampler2D texUnit;
varying vec4 color;
varying vec2 texCoord;
void main() {
vec4 texel = texture2D(texUnit, texCoord);
if (any(lessThan(texCoord, vec2(0.0, 0.0))) ||
any(greaterThan(texCoord, vec2(1.0, 1.0))))
gl_FragColor = color;
else
gl_FragColor = texel;
}
以下是没有分支的版本,但仍然感到笨拙. 纹理坐标夹紧"的最佳实践是什么?
Below is a version without branching, but it still feels clumsy. What is the best practice for "texture coord clamping"?
uniform sampler2D texUnit;
varying vec4 color;
varying vec4 labelColor;
varying vec2 texCoord;
void main() {
vec4 texel = texture2D(texUnit, texCoord);
bool outside = any(lessThan(texCoord, vec2(0.0, 0.0))) ||
any(greaterThan(texCoord, vec2(1.0, 1.0)));
gl_FragColor = mix(texel*labelColor, color,
vec4(outside,outside,outside,outside));
}
我将纹理像素夹紧到标签为的区域-纹理s&在这种情况下,t坐标将介于0和1之间.否则,我会使用棕色而不是标签.
I am clamping texels to the region with the label is -- the texture s & t coordinates will be between 0 and 1 in this case. Otherwise, I use a brown color where the label ain't.
请注意,我还可以构造代码的分支版本,该分支版本在不需要时不执行纹理查找.这会比总是执行纹理查找的非分支版本更快吗?也许是时候进行一些测试了……
Note that I could also construct a branching version of the code that does not perform a texture lookup when it doesn't need to. Would this be faster than a non-branching version that always performed a texture lookup? Maybe time for some tests...
推荐答案
使用step
函数避免分支并获得最佳性能:
Use step
function to avoid branching and get the best performance:
// return 1 if v inside the box, return 0 otherwise
float insideBox(vec2 v, vec2 bottomLeft, vec2 topRight) {
vec2 s = step(bottomLeft, v) - step(topRight, v);
return s.x * s.y;
}
float insideBox3D(vec3 v, vec3 bottomLeft, vec3 topRight) {
vec3 s = step(bottomLeft, v) - step(topRight, v);
return s.x * s.y * s.z;
}
void main() {
vec4 texel = texture2D(texUnit, texCoord);
float t = insideBox(v_position, vec2(0, 0), vec2(1, 1));
gl_FragColor = t * texel + (1 - t) * color;
}
这篇关于GLSL盒内点测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!