Преобразование координат X, Z в RGB с использованием шейдеров GLSL - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть сцена Three js, которая содержит плоскость 100x100 с центром в начале координат (то есть мин. Координаты: (-50, -50), максимальные координаты: (50,50)).Я пытаюсь отобразить плоскость в виде цветового круга, используя координаты x и z в пользовательском шейдере glsl.Используя это руководство (см. HSB в полярных координатах внизу страницы), я получил свой код шейдера с Three.js Scene , но это не совсем правильно.

Я пытался настроить все переменные, которые имеют для меня смысл, но, как вы можете видеть на скриншоте, цвета меняются в два раза чаще, чем должны.Моя математическая интуиция говорит, что просто разделите угол на 2, но когда я попробовал, это было совершенно неправильно.

Я знаю, что решение очень простое, но я пробовал пару часов, но у меня его нет.

Как превратить имеющийся у меня шейдер в тот, который делает ровно 1 полноцветное вращение в 2pi радианах?

РЕДАКТИРОВАТЬ: вот соответствующий код шейдера в виде обычного текста

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;
                }

1 Ответ

0 голосов
/ 01 декабря 2018

Я обнаружил, что руководство, которому я следовал, было неверным.Я не думал о своей математике должным образом, но теперь я знаю, в чем проблема.

atan имеет диапазон от -PI / 2 до PI / 2, который составляет только половину круга.Когда worldPosition.x отрицательно, atan не вернет правильный угол, поскольку он находится вне диапазона функции.Угол необходимо отрегулировать в зависимости от того, какой он находится в плоскости.

Q1: ничего не делать Q2: добавить PI к углу Q3: добавить PI к углу Q4: добавить 2PI к углу

После этого нормализуйте угол (разделите на 2PI), затем передайте его функции hsb2rgb.

...