Проблема полосатости в многошаговом шейдере с буферами пинг-понга, не возникает в ShaderToy - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь реализовать шейдер Streak, который описан здесь: http://www.chrisoat.com/papers/Oat-SteerableStreakFilter.pdf

Краткое объяснение: Образцы точки с ядром 1d в заданном направлении.Размер ядра растет экспоненциально на каждом этапе.Значения цвета взвешиваются на основе расстояния до точки выборки и суммируются.Результатом является гладкий эффект хвоста / мазка / легкой полосы в этом направлении.Вот фрагмент шейдера:

precision highp float;

uniform sampler2D u_texture;

varying vec2 v_texCoord;

uniform float u_Pass;

const float kernelSize = 4.0;
const float atten = 0.95;

vec4 streak(in float pass, in vec2 texCoord, in vec2 dir, in vec2 pixelStep) {

    float kernelStep = pow(kernelSize, pass - 1.0);

    vec4 color = vec4(0.0);

    for(int i = 0; i < 4; i++) {
        float sampleNum = float(i);

        float weight = pow(atten, kernelStep * sampleNum);

        vec2 sampleTexCoord = texCoord + ((sampleNum * kernelStep) * (dir * pixelStep));
        vec4 texColor = texture2D(u_texture, sampleTexCoord) * weight;
        color += texColor;

    }
    return color;
}


void main() {
    vec2 iResolution = vec2(512.0, 512.0);

    vec2 pixelStep = vec2(1.0, 1.0) / iResolution.xy;

    vec2 dir = vec2(1.0, 0.0);

    float pass = u_Pass;

    vec4 streakColor = streak(pass, v_texCoord, dir, pixelStep);

    gl_FragColor = vec4(streakColor.rgb, 1.0);
}

Он собирался использоваться для эффекта типа звездного поля.И вот реализация на ShaderToy, которая прекрасно работает:

https://www.shadertoy.com/view/ll2BRG

(Примечание: не обращайте внимания на первый шейдер в буфере A, он просто отфильтровывает тусклые цвета во входной текстуре для эмуляциизвездное поле, так как afaik ShaderToy не позволяет загружать пользовательские текстуры)

Но когда я использую один и тот же шейдер в своем собственном коде и выполняю рендеринг с использованием пинг-понга FrameBuffers, он выглядит иначе.Вот моя собственная реализация, портированная на WebGL:

https://jsfiddle.net/1b68eLdr/87755/

Я в основном создаю 2 буфера 512x512, пинг-понг шейдера в 4 раза, увеличивая размер ядра на каждой итерации в соответствии с алгоритмом иОтобразите последнюю итерацию на экране.

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

Я некоторое время боролся с этим в Desktop OpenGl / LWJGL, я перенес его в WebGL / Javascript и загрузилна JSFiddle в надежде, что кто-то может определить, в чем проблема.Я подозреваю, что речь идет либо о текстурных координатах, либо о конфигурации FrameBuffer, поскольку шейдеры точно такие же.

1 Ответ

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

Причина, по которой он работает с Shadertoys, заключается в том, что он использует цель рендеринга с плавающей точкой.Просто используйте gl.FLOAT в качестве типа вашей текстуры кадрового буфера, и проблема исправлена ​​(я мог бы проверить это с помощью указанной модификации на вашем JSFiddle).

Так что сделайте это в вашей createBackingTexture ():

// Just request the extension (MUST be done).
gl.getExtension('OES_texture_float');
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._width, this._height, 0, gl.RGBA, gl.FLOAT, null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...