使用GLSL着色器将X、Z坐标转换为RGB



我有一个Three-js场景,它包含一个以原点为中心的100x100平面(即最小坐标:(-50,-50(,最大坐标:(50:50((。我正试图通过在自定义glsl着色器中使用x和z坐标来使平面显示为色轮。使用此指南(请参阅页面底部极坐标中的HSB(,我已经获得了Three.js场景的着色器代码但这并不完全正确。

我试着调整了所有对我有意义的变量,但正如你在屏幕截图中看到的,颜色的变化频率是应该的两倍。我的数学直觉是把角度除以2,但当我尝试时,它完全不正确。

我知道这个解决方案很简单,但我已经试了几个小时了,但我没有得到

如何将我目前拥有的着色器转换为在2pi弧度内进行1次全色旋转的着色器?

编辑:这是纯文本中的相关着色器代码

varying vec3 vColor;
const float PI = 3.1415926535897932384626433832795;
uniform float delta;
uniform float scale;
uniform float size;
vec3 hsb2rgb( in vec3 c ){
vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
6.0)-3.0)-1.0,
0.0,
1.0 );
rgb = rgb*rgb*(3.0-2.0*rgb);
return c.z * mix( vec3(1.0), rgb, c.y);
}
void main()
{
vec4 worldPosition = modelMatrix * vec4(position, 1.0);
float r = 0.875;
float g = 0.875;
float b = 0.875;
if (worldPosition.y > 0.06 || worldPosition.y < -0.06) {
vec2 toCenter = vec2(0.5) - vec2((worldPosition.z+50.0)/100.0, (worldPosition.x+50.0)/100.0);
float angle = atan(worldPosition.z/worldPosition.x);
float radius = length(toCenter) * 2.0;
vColor = hsb2rgb(vec3((angle/(PI))+0.5,radius,1.0));
} else {
vColor = vec3(r,g,b);
}
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_PointSize = size * (scale/length(mvPosition.xyz));
gl_Position = projectionMatrix * mvPosition;
}

我发现我遵循的指南不正确。我没有好好思考我的数学,但我现在知道问题出在哪里了。

atan的范围从-PI/2到PI/2,只占一个圆的一半。当worldPosition.x为负时,atan将不会返回正确的角度,因为它超出了函数的范围。需要根据它在平面中的象限来调整角度。

Q1:什么都不做Q2:将PI添加到角度Q3:将PI添加到角度Q4:将2PI添加到角度

在此之后,对角度进行归一化(除以2PI(,然后将其传递给hsb2rgb函数。

最新更新