GLSL盒内点测试 [英] GLSL point inside box test

查看:66
本文介绍了GLSL盒内点测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个输出纹理像素的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆