在 WebGPU 中,我正在尝试绘制一个 alpha 混合四边形。有些东西不见了,但我不知道是什么。
我做了什么
add/src:src-alpha/dest:one-minus-src-alpha
现在,它会变黑!一旦设置了
srcFactor
,白色背景上的白色形状就会变成黑色。这是为什么?缺少一些标志?或者这是一个错误?它应该是全白的。发生在当前的 Chrome Canary 中。
srcFactor
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
打错了。将 destFactor 替换为 dstFactor