Пост-эффекты и прозрачный фон в three.js - PullRequest
0 голосов
/ 21 мая 2018

Попытка использовать прозрачный фон с некоторыми постэффектами, такими как Unreal Bloom, SMAA и Tonemapping, представленными в примерах, но кажется, что это нарушает прозрачность моего рендера.

renderer = new THREE.WebGLRenderer({ canvas, alpha: true });
renderer.setClearColor(0xFF0000, 0);

composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));

// Bloom pass
canvasSize = new THREE.Vector2(canvas.width, canvas.height);
pass = new UnrealBloomPass(canvasSize, strength, radius, threshhold);
composer.addPass(pass);

// SMAA pass
size = canvasSize.multiplyScalar(this.renderer.getPixelRatio());
pass = new SMAAPass(size.x, size.y);
pass.renderToScreen = true
composer.addPass(pass);

// Tonemapping
renderer.toneMappingExposure = exposure;
renderer.toneMappingWhitePoint = whitePoint;
renderer.toneMapping = type;

composer.render();

Если я деактивирую цветpass Я получаю правильный прозрачный фон, но при активации я получаю черный фон.Я посмотрел на источники, и кажется, что он должен правильно обрабатывать канал альфа-текстуры, так как формат правильно установлен на THREE.RGBAFormat.

Редактировать : После некоторых исследований я нашел, где этопроисходит от.Он берется из getSeperableBlurMaterial в js \ postprocessing \ UnrealBloomPass.js .

Альфа-канал фрагмента всегда имеет значение 1,0, что приводит к полному удалению предыдущих альфа-значений при выполненииаддитивное смешивание в конце.

Круто было бы найти правильный способ применения альфы внутри размытия по Гауссу.Есть идеи как?

1 Ответ

0 голосов
/ 23 мая 2018

Я нашел решение, и это можно отсортировать так: https://github.com/mrdoob/three.js/issues/14104

void main()
{
    vec2 invSize = 1.0 / texSize;
    float fSigma = float(SIGMA);
    float weightSum = gaussianPdf(0.0, fSigma);
    float alphaSum = 0.0;
    vec3 diffuseSum = texture2D(colorTexture, vUv).rgb * weightSum;
    for( int i = 1; i < KERNEL_RADIUS; i ++ )
    {
        float x = float(i);
        float weight = gaussianPdf(x, fSigma);
        vec2 uvOffset = direction * invSize * x;

        vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);
        float weightAlpha = sample1.a * weight;
        diffuseSum += sample1.rgb * weightAlpha;
        alphaSum += weightAlpha;
        weightSum += weight;

        vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);
        weightAlpha = sample2.a * weight;
        diffuseSum += sample2.rgb * weightAlpha;
        alphaSum += weightAlpha;
        weightSum += weight;

    }
    alphaSum /= weightSum;
    diffuseSum /= alphaSum; // Should apply discard here if alphaSum is 0
    gl_FragColor = vec4(diffuseSum.rgb, alphaSum);
}
...