Как мне создать серию цветных прямоугольников, используя шум?

#opengl #glsl #rectangles #fragment-shader #noise

#opengl #glsl #прямоугольники #фрагмент-шейдер #шум

Вопрос:

В настоящее время я изучаю создание шаблонов шума в GLSL.

Я пытаюсь создать композицию из прямоугольников, цветов и шума, используя фрагментный шейдер в GLSL. Вот мой текущий код:

 #ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;

// 2D Random
float random (in vec2 st) {
    return fract(sin(dot(st.xy,
                     vec2(12.9898, 79)))
             * 43758.5453123);
}

float noise (in vec2 st) 
{
    vec2 i = floor(st   1.0);
    vec2 f = fract(st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i   vec2(1.0, 0.0));
    float c = random(i   vec2(0.0, 1.0));
    float d = random(i   vec2(1.0, 1.0));

    vec2 u = f*f*(3.0-2.0*f);
    u = smoothstep(0.6, 1.0, f);

    // Mix 4 coorners percentages
    return mix(a, b, u.x)  
        (c - a)* u.y * (1.0 - u.x)  
        (d - b) * u.x * u.y;
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;

    vec3 color = vec3(0.423,0.459,1.000);

    vec2 pos = vec2(st * 4.0);

    // Use the noise function
    float n = noise(pos);

    gl_FragColor = vec4(vec3(n), color);
}
  

В настоящее время все, что я могу заставить его генерировать, — это черно-белые квадраты и прямоугольники, и независимо от того, как я настраиваю свою переменную «vec3 color», я не могу заставить ее отображать прямоугольники в разных цветах.

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

Комментарии:

1. Что вы подразумеваете под «как я могу настроить свой код так, чтобы он разбивался на несколько прямоугольников вместо квадратов и прямоугольников» ?

Ответ №1:

как я могу применить свой цвет к этим прямоугольникам

Вы должны умножить color на градиент n :

 gl_FragColor = vec4(color * n, 1.0);
  

Смещение прямоугольников связано с линией

 u = smoothstep(0.6, 1.0, f)
  

Вы должны сдвигать прямоугольники в зависимости от размера гладкой области:

 float noise (in vec2 st) 
{
    float smoothsize = 0.2;  
    st -= smoothsize;
    vec2 i = floor(st   1.0);
    vec2 f = fract(st);

    // [...]

    vec2 u = f*f*(3.0-2.0*f);
    u = smoothstep(1.0- 2.0*smoothsize, 1.0, f);
    
    // [...]
}
  

Если вы хотите генерировать квадраты вместо прямоугольников, то вам нужно масштабировать st.x по соотношению сторон:

 vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y; 
  

Завершенный фрагментный шейдер:

 #ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;

// 2D Random
float random (in vec2 st)
{
    return fract(sin(dot(st.xy, vec2(12.9898, 79))) * 43758.5453123);
}

float noise (in vec2 st) 
{
    float smoothsize = 0.2;
    st -= smoothsize;
    vec2 i = floor(st   1.0);
    vec2 f = fract(st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i   vec2(1.0, 0.0));
    float c = random(i   vec2(0.0, 1.0));
    float d = random(i   vec2(1.0, 1.0));

    vec2 u = f*f*(3.0-2.0*f);
    u = smoothstep(1.0- 2.0*smoothsize, 1.0, f);

    // Mix 4 corners percentages
    return mix(a, b, u.x)   (c-a) * u.y * (1.0-u.x)   (d-b) * u.x * u.y;
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    // st.x *= u_resolution.x/u_resolution.y; <--- optional

    // Use the noise function
    float n = noise(st * 4.0);

    vec3 color = vec3(0.423,0.459,1.000);
    gl_FragColor = vec4(color * n, 1.0);
}
  

Комментарии:

1. Большое вам спасибо. Это очень помогает. 🙂

2. Допустим, я хотел использовать несколько цветов. Мне просто добавить больше цветовых переменных в функцию main() и смешать их с градиентом?

3. @Garrus Вы хотите использовать фиксированные или случайные цвета?

4. Исправлены цвета. Я не хочу сдвигаться или меняться.

5. @Garrus gl_FragColor = vec4(mix(color, color2, n), 1.0); — градиент между 2 цветами