The WebGPU rainPass now performs a high pass filter on its own fragments. I think I prefer this to a separate high pass filter, because this one is pre-blendfunc, ie. fragments will only be added to the texture if they are individually bright enough to contribute.

This commit is contained in:
Rezmason
2021-11-09 07:08:07 -08:00
parent 786c83cca0
commit 6586badf42
2 changed files with 32 additions and 0 deletions

View File

@@ -74,6 +74,11 @@ export default (context, getInputs) => {
loadValue: { r: 0, g: 0, b: 0, a: 1 }, loadValue: { r: 0, g: 0, b: 0, a: 1 },
storeOp: "store", storeOp: "store",
}, },
{
view: null,
loadValue: { r: 0, g: 0, b: 0, a: 1 },
storeOp: "store",
},
], ],
}; };
@@ -87,6 +92,7 @@ export default (context, getInputs) => {
let computeBindGroup; let computeBindGroup;
let renderBindGroup; let renderBindGroup;
let output; let output;
let highPassOutput;
const ready = (async () => { const ready = (async () => {
const [msdfTexture, rainShader] = await Promise.all(assets); const [msdfTexture, rainShader] = await Promise.all(assets);
@@ -126,6 +132,13 @@ export default (context, getInputs) => {
alpha: additiveBlendComponent, alpha: additiveBlendComponent,
}, },
}, },
{
format: presentationFormat,
blend: {
color: additiveBlendComponent,
alpha: additiveBlendComponent,
},
},
], ],
}, },
}); });
@@ -152,10 +165,14 @@ export default (context, getInputs) => {
// Update // Update
output?.destroy(); output?.destroy();
output = makePassFBO(device, width, height, presentationFormat); output = makePassFBO(device, width, height, presentationFormat);
highPassOutput?.destroy();
highPassOutput = makePassFBO(device, width, height, presentationFormat);
}; };
const getOutputs = () => ({ const getOutputs = () => ({
primary: output, primary: output,
highPass: highPassOutput,
}); });
const execute = (encoder) => { const execute = (encoder) => {
@@ -168,6 +185,7 @@ export default (context, getInputs) => {
computePass.endPass(); computePass.endPass();
renderPassConfig.colorAttachments[0].view = output.createView(); renderPassConfig.colorAttachments[0].view = output.createView();
renderPassConfig.colorAttachments[1].view = highPassOutput.createView();
const renderPass = encoder.beginRenderPass(renderPassConfig); const renderPass = encoder.beginRenderPass(renderPassConfig);
renderPass.setPipeline(renderPipeline); renderPass.setPipeline(renderPipeline);
renderPass.setBindGroup(0, renderBindGroup); renderPass.setBindGroup(0, renderBindGroup);

View File

@@ -37,6 +37,7 @@
slantScale : f32; slantScale : f32;
slantVec : vec2<f32>; slantVec : vec2<f32>;
volumetric : i32; volumetric : i32;
highPassThreshold : f32;
}; };
// The properties that change over time get their own buffer. // The properties that change over time get their own buffer.
@@ -89,6 +90,7 @@ struct VertOutput {
struct FragOutput { struct FragOutput {
[[location(0)]] color : vec4<f32>; [[location(0)]] color : vec4<f32>;
[[location(1)]] highPassColor : vec4<f32>;
}; };
// Constants // Constants
@@ -432,5 +434,17 @@ fn getSymbolUV(glyphCycle : f32) -> vec2<f32> {
output.color = vec4<f32>(input.channel * brightness * alpha, 1.0); output.color = vec4<f32>(input.channel * brightness * alpha, 1.0);
} }
var highPassColor = output.color;
if (highPassColor.r < config.highPassThreshold) {
highPassColor.r = 0.0;
}
if (highPassColor.g < config.highPassThreshold) {
highPassColor.g = 0.0;
}
if (highPassColor.b < config.highPassThreshold) {
highPassColor.b = 0.0;
}
output.highPassColor = highPassColor;
return output; return output;
} }