【问题标题】:Converting X, Z coords to RGB using GLSL shaders使用 GLSL 着色器将 X、Z 坐标转换为 RGB
【发布时间】:2018-11-20 03:30:09
【问题描述】:

我有一个三个 js 场景,其中包含一个以原点为中心的 100x100 平面(即最小坐标:(-50,-50),最大坐标:(50,50))。我试图通过在自定义 glsl 着色器中使用 x 和 z 坐标来使平面显示为色轮。使用this guide(参见页面底部的极坐标HSB)我得到了我的 Shader Code with Three.js Scene 但这并不完全正确。

我已经尝试调整所有对我有意义的变量,但正如您在屏幕截图中看到的那样,颜色变化的频率是它们应该变化的两倍。我的数学直觉说只需将角度除以 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;
                }

【问题讨论】:

  • 在着色器的书中,有color = hsb2rgb(vec3((angle/TWO_PI)+0.5,radius,1.0));,它使用TWO_PI定义,即PI * 2,而在你的代码中你只使用PIvColor = hsb2rgb(vec3((angle/(PI))+0.5,radius,1.0));。跨度>
  • 我知道,我注意到了。当我尝试 2PI 时,情况会更糟。没有偏红的色调,一切都是蓝色/绿色。

标签: colors three.js glsl rgb


【解决方案1】:

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

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

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

在此归一化角度后(除以 2PI)然后将其传递给 hsb2rgb 函数。

【讨论】:

    猜你喜欢
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    相关资源
    最近更新 更多