playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
114 lines (107 loc) • 3.31 kB
JavaScript
import { UniformBufferFormat, UniformFormat } from "../uniform-buffer-format.js";
import { BlendState } from "../blend-state.js";
import {
PRIMITIVE_TRISTRIP,
SHADERLANGUAGE_WGSL,
UNIFORMTYPE_FLOAT,
UNIFORMTYPE_VEC4,
BINDGROUP_MESH,
CLEARFLAG_COLOR,
CLEARFLAG_DEPTH,
CLEARFLAG_STENCIL,
BINDGROUP_MESH_UB
} from "../constants.js";
import { Shader } from "../shader.js";
import { DynamicBindGroup } from "../bind-group.js";
import { UniformBuffer } from "../uniform-buffer.js";
import { DepthState } from "../depth-state.js";
const primitive = {
type: PRIMITIVE_TRISTRIP,
base: 0,
baseVertex: 0,
count: 4,
indexed: false
};
class WebgpuClearRenderer {
constructor(device) {
const code = `
struct ub_mesh {
color : vec4f,
depth: f32
}
var<uniform> ubMesh : ub_mesh;
var<private> pos : array<vec2f, 4> = array<vec2f, 4>(
vec2(-1.0, 1.0), vec2(1.0, 1.0),
vec2(-1.0, -1.0), vec2(1.0, -1.0)
);
struct VertexOutput {
position : vec4f
}
fn vertexMain( vertexIndex : u32) -> VertexOutput {
var output : VertexOutput;
output.position = vec4(pos[vertexIndex], ubMesh.depth, 1.0);
return output;
}
fn fragmentMain() -> vec4f {
return ubMesh.color;
}
`;
this.shader = new Shader(device, {
name: "WebGPUClearRendererShader",
shaderLanguage: SHADERLANGUAGE_WGSL,
vshader: code,
fshader: code
});
this.uniformBuffer = new UniformBuffer(device, new UniformBufferFormat(device, [
new UniformFormat("color", UNIFORMTYPE_VEC4),
new UniformFormat("depth", UNIFORMTYPE_FLOAT)
]), false);
this.dynamicBindGroup = new DynamicBindGroup();
this.colorData = new Float32Array(4);
}
destroy() {
this.shader.destroy();
this.shader = null;
this.uniformBuffer.destroy();
this.uniformBuffer = null;
}
clear(device, renderTarget, options, defaultOptions) {
options = options || defaultOptions;
const flags = options.flags ?? defaultOptions.flags;
if (flags !== 0) {
const { uniformBuffer, dynamicBindGroup } = this;
uniformBuffer.startUpdate(dynamicBindGroup);
device.setBindGroup(BINDGROUP_MESH_UB, dynamicBindGroup.bindGroup, dynamicBindGroup.offsets);
device.setBindGroup(BINDGROUP_MESH, device.emptyBindGroup);
let blendState;
if (flags & CLEARFLAG_COLOR && (renderTarget.colorBuffer || renderTarget.impl.assignedColorTexture)) {
const color = options.color ?? defaultOptions.color;
this.colorData.set(color);
blendState = BlendState.NOBLEND;
} else {
blendState = BlendState.NOWRITE;
}
uniformBuffer.set("color", this.colorData);
let depthState;
if (flags & CLEARFLAG_DEPTH && renderTarget.depth) {
const depth = options.depth ?? defaultOptions.depth;
uniformBuffer.set("depth", depth);
depthState = DepthState.WRITEDEPTH;
} else {
uniformBuffer.set("depth", 1);
depthState = DepthState.NODEPTH;
}
if (flags & CLEARFLAG_STENCIL && renderTarget.stencil) {
}
uniformBuffer.endUpdate();
device.setDrawStates(blendState, depthState);
device.setShader(this.shader);
device.draw(primitive);
}
}
}
export {
WebgpuClearRenderer
};