2

Я реализовал шейдер для поверхности солнца, который использует шум simplex от ashima/webgl-noise. Но это стоит слишком много времени GPU, особенно если я собираюсь использовать его на мобильных устройствах. Мне нужно сделать тот же эффект, но с использованием текстуры шума. Мой пиксельный шейдер ниже:GLSL - Использование 2D-текстуры для 3D-шума Perlin вместо процедурного 3D-шума

#ifdef GL_ES 
precision highp float; 
#endif 
precision mediump float; 

varying vec2 v_texCoord; 
varying vec3 v_normal; 

uniform sampler2D u_planetDay; 
uniform sampler2D u_noise; //noise texture (not used yet) 
uniform float u_time; 

#include simplex_noise_source from Ashima 

float noise(vec3 position, int octaves, float frequency, float persistence) { 
float total = 0.0; // Total value so far 
float maxAmplitude = 0.0; // Accumulates highest theoretical amplitude 
float amplitude = 1.0; 
for (int i = 0; i < octaves; i++) { 
    // Get the noise sample 
    total += ((1.0 - abs(snoise(position * frequency))) * 2.0 - 1.0) * amplitude; 
    //I USE LINE BELOW FOR 2D NOISE 
    total += ((1.0 - abs(snoise(position.xy * frequency))) * 2.0 - 1.0) * amplitude; 
    // Make the wavelength twice as small 
    frequency *= 2.0; 
    // Add to our maximum possible amplitude 
    maxAmplitude += amplitude; 
    // Reduce amplitude according to persistence for the next octave 
    amplitude *= persistence; 
} 
// Scale the result by the maximum amplitude 
return total/maxAmplitude; 
} 

void main() 
{ 
    vec3 position = v_normal *2.5+ vec3(u_time, u_time, u_time); 
    float n1 = noise(position.xyz, 2, 7.7, 0.75) * 0.001; 

    vec3 ground = texture2D(u_planetDay, v_texCoord+n1).rgb; 
    gl_FragColor = vec4 (color, 1.0); 
} 

Как я могу исправить это шейдер работать с текстурой шума и что должно текстура выглядеть?

Насколько я знаю, OpenGL ES 2.0 не поддерживает 3D-текстуры. Более того, я не знаю, как создать 3D-текстуру.

ответ

0

Я написал этот 3D-шум из функции 2D-текстуры. Он по-прежнему использует аппаратную интерполяцию для направлений x/y, а затем вручную интерполирует для z. Чтобы получить шум вдоль направления z, я пробовал одну и ту же текстуру при разных смещениях. Это, вероятно, приведет к некоторому повторению, но я не заметил ни одного в своем приложении, и моя догадка использует простые справки.

То, что у меня было в тупик на shadertoy.com, заключалось в том, что было реализовано mipmapping текстуры, которое вызвало швы при изменении значения функции floor(). Быстрое решение проходило смещение -999 до texture2D.

Это было жестко закодировано для текстуры шума 256x256, поэтому соответствующим образом отрегулируйте.

float noise3D(vec3 p) 
{ 
    p.z = fract(p.z)*256.0; 
    float iz = floor(p.z); 
    float fz = fract(p.z); 
    vec2 a_off = vec2(23.0, 29.0)*(iz)/256.0; 
    vec2 b_off = vec2(23.0, 29.0)*(iz+1.0)/256.0; 
    float a = texture2D(iChannel0, p.xy + a_off, -999.0).r; 
    float b = texture2D(iChannel0, p.xy + b_off, -999.0).r; 
    return mix(a, b, fz); 
} 

Update: Чтобы продлить до Перлин шума, образцы сумм на разных частотах:

float perlinNoise3D(vec3 p) 
{ 
    float x = 0.0; 
    for (float i = 0.0; i < 6.0; i += 1.0) 
     x += noise3D(p * pow(2.0, i)) * pow(0.5, i); 
    return x; 
} 
+0

Как выглядит ваша шумовая текстура? – Nolesh

+0

@Nolesh просто случайные значения (т. Е. 'Rand()% 255'), но требуется фильтрация GL_LINEAR. – jozxyqk

+0

Возможно, я использую его неправильно. vec3 position = v_normal + vec3 (время, 0, 0); float n1 = noise3D (позиция); gl_FragColor = vec4 (vec3 (n1, n1, n1), 1.0); Я получаю аналогичный результат, как если бы я использовал texture2D (u_noise, position.xy) .x; – Nolesh

0

Пытаясь оценить шум во время выполнения часто плохая практика, если вы не хотите выполнять некоторые исследовательские работы или быстро проверять/отлаживать вашу шумовую функцию (или посмотреть, как выглядят ваши параметры шума).

Он всегда будет потреблять слишком большой бюджет на обработку (не стоит этого), поэтому просто забывайте об оценке шума во время выполнения.

Если вы сохраняете ваши результаты шума в автономном режиме, вы уменьшите заряд (скажем, более 95%) до простого доступа к памяти.

Я предлагаю сократить все это до текстурного поиска по предварительно искривленному 2D-шумовому изображению. Вы до сих пор влияли только на конвейер фрагмента, так что текстура 2D-шума определенно способ пойти (вы также можете использовать этот 2D-поиск для деформации положений вершин).

Для того, чтобы отобразить его на сфере без каких-либо проблем с непрерывностью, вы можете создать петлевое двумерное изображение с 4D-шумом, подавая функцию с координатами двух 2D-кругов.

Что касается анимации, существуют различные хакерские трюки, деформируя результаты поиска с семантикой времени в конвейере фрагментов или выпекая последовательность изображений, если вам действительно нужен шум, «анимированный шумом».

3D-текстуры - это всего лишь стеки 2D-текстур, поэтому они слишком тяжелы, чтобы манипулировать (даже без анимации) тем, что вы хотите делать, и поскольку вам, по-видимому, нужна только приличная солнечная поверхность, это было бы излишним.

 Смежные вопросы

  • Нет связанных вопросов^_^