作为学习片段着色器/矢量数学的练习,我正在尝试编写一个后处理着色器,它根据 P 和屏幕 C 中心之间的矢量 PC 的角度(以弧度为单位)为屏幕上的每个点 P 着色。
为了简单起见,我将在灰度中进行此操作,但是可以在这里看到我想要的效果的一个很好的说明,色调随着角度的变化而变化,并且色调形成一个循环。
http://demosthenes.info/assets/images/hsl-color-wheel-trans.png
我四处搜索,寻找有关查找向量之间的角度的信息,并从这些示例中我得到了这里:
#version 110
uniform sampler2D tex0; //Color info
void main()
{
vec2 ScreenCenter = vec2(0.5 , 0.5);
vec2 texCoord = gl_TexCoord[0].st;
vec2 deltaTexCoord = ( texCoord - ScreenCenter.xy);
float angle = dot(deltaTexCoord , vec2(0,-1));
//I've made attempts here to mess with acos as well as angle=pow(angle, somefloat) and
//have not gotten desired results
gl_FragColor = vec4( angle , angle, angle, 1.0 );
}
Run Code Online (Sandbox Code Playgroud)
然而,这段代码产生线性渐变,而不是我想要的效果。
最简单的方法是使用带有两个参数的内置 GLSL 函数atan():
float angle = atan(deltaTexCoord.y, deltaTexCoord.x);
Run Code Online (Sandbox Code Playgroud)
这对应于您可能在 C/C++ 中熟悉的atan2 函数。与使用 相比acos(),主要优点是,这可以为您提供完整的角度范围 [-pi, pi],而 产生的角度acos()仅在 [0, pi] 范围内,因此对于下半部分来说是不正确的圆圈。使用atan(y, x),也无需对输入值进行标准化。