一旦启用 alpha 混合,在白色背景上绘制白色形状就会变成黑色?

问题描述 投票:0回答:1

在 WebGPU 中,我正在尝试绘制一个 alpha 混合四边形。有些东西不见了,但我不知道是什么。

我做了什么

  • 将管道片段目标中的混合模式设置为
    add/src:src-alpha/dest:one-minus-src-alpha
  • 将片段 alpha 设置为零(因此它应该是不可见的)
  • 在白色背景上画一个白色形状

现在,它会变黑!一旦设置了

srcFactor
,白色背景上的白色形状就会变成黑色。这是为什么?缺少一些标志?或者这是一个错误?它应该是全白的。发生在当前的 Chrome Canary 中。

  • 将片段 alpha 更改为 1 有效(全白),无论
    srcFactor
  • 将片段 alpha 更改为 0.5 不起作用(白色背景上的灰色四边形),无论
    srcFactor
  • srcFactor
    one
    是白色

这似乎是 Chrome Canary 中的一个错误。 alpha 混合似乎无法从目标渲染附件中读取实际像素值,而是始终使用黑色作为背景?还是我遗漏了一些明显的东西?

完整代码如下:

    const canvas = document.querySelector('#canvas');
    canvas.width = canvas.height = 500;
    
    const adapter = await navigator.gpu.requestAdapter();
    const device = await adapter.requestDevice();
    
    
    const context = canvas.getContext('webgpu');
    const swapChainFormat = navigator.gpu.getPreferredCanvasFormat();
    
    const swapChain = context.configure({
        device,
        format: swapChainFormat,
        alphaMode: "opaque",
    });
    
    function render() {
        const commandEncoder = device.createCommandEncoder({});
        const textureView = context.getCurrentTexture().createView();
    
        const module = device.createShaderModule({
            label: 'generated accunulation shader',
            code: `
                @vertex fn vs(
                    @builtin(vertex_index) vertexIndex : u32
                ) -> @builtin(position) vec4f {
                    var pos = array<vec2f, 6>(
                        vec2f(-1.0, -1.0),  // center
                        vec2f( 1.0, -1.0),  // right, center
                        vec2f(-1.0,  1.0),  // center, top
                    
                        vec2f(-1.0,  1.0),  // center, top
                        vec2f( 1.0, -1.0),  // right, center
                        vec2f( 1.0,  1.0),  // right, top
                    );
            
                    return vec4f(pos[vertexIndex]*0.5, 0.0, 1.0);
                }
    
                @fragment fn fs() -> @location(0) vec4f {
                    var color = vec4f(1,1,1,0); // color set to white
    
                    color.a = 0; // alpha set to zero, should be invisible
                    return color;
                }
            `,
        });
    
        const pipeline = device.createRenderPipeline({
            label: 'transparent shader',
            layout: 'auto',
            vertex: {
                module,
                entryPoint: 'vs',
            },
            fragment: {
                module,
                entryPoint: 'fs',
                targets: [{ 
                    format: swapChainFormat,
                    blend: {
                        color: {
                            operation: 'add',
                            srcFactor: 'src-alpha',
                            //destFactor: 'one-minus-src-alpha',
                        },
                        alpha: {},
                    }
                }],
            },
        });
    
        const renderPassDescriptor = {
            colorAttachments: [{
                view: textureView,
                loadOp:'clear',
                storeOp: 'store',
                clearValue: [1,1,1,1]
            }],
        };
    
        const accumulationPass = commandEncoder.beginRenderPass(renderPassDescriptor);
        accumulationPass.setPipeline(pipeline);
        accumulationPass.draw(6); // number of vertices
        accumulationPass.end();
    
        device.queue.submit([commandEncoder.finish()]);
    }
    
    render()

查看这个简洁的网站进行现场试用: https://06wj.github.io/WebGPU-Playground/#/Samples/HelloCanvas

javascript alphablending webgpu
1个回答
0
投票

打错了。将 destFactor 替换为 dstFactor

© www.soinside.com 2019 - 2024. All rights reserved.