轻量封装WebGPU渲染系统示例<26>- PingpongBlur模糊效果(源码)

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/PingpongBlur.ts

当前示例运行效果:

轻量封装WebGPU渲染系统示例<26>- PingpongBlur模糊效果(源码)_第1张图片

WGSL片段shader

@group(0) @binding(0) var param: vec4f;
@group(0) @binding(1) var sampler0: sampler;
@group(0) @binding(2) var texture0: texture_2d;

const weight = array(0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
fn calcBlurColor(uv: vec2f) -> vec4f {
    var dv = vec2f(param.z, 0.0) / param.xy;
    let dx = dv.x;

    var result = textureSample(texture0, sampler0, uv) * weight[0];
	for (var i: i32 = 1; i < 5; i++)  {
        dv.x = dx * f32(i);
        result += textureSample(texture0, sampler0, uv + dv) * weight[i];
        result += textureSample(texture0, sampler0, uv - dv) * weight[i];
    }
    return result;
}

@fragment
fn main(
	@location(0) uv: vec2f
	) -> @location(0) vec4f {
	var color4 = calcBlurColor( uv );
    return color4;
}
@group(0) @binding(0) var param: vec4f;
@group(0) @binding(1) var sampler0: sampler;
@group(0) @binding(2) var texture0: texture_2d;

const weight = array(0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
fn calcBlurColor(uv: vec2f) -> vec4f {
    var dv = vec2f(0.0, param.z) / param.xy;
    let dy = dv.y;

    var result = textureSample(texture0, sampler0, uv) * weight[0];
	for (var i: i32 = 1; i < 5; i++)  {
        dv.y = dy * f32(i);
        result += textureSample(texture0, sampler0, uv + dv) * weight[i];
        result += textureSample(texture0, sampler0, uv - dv) * weight[i];
    }
    return result;
}

@fragment
fn main(
	@location(0) uv: vec2f
	) -> @location(0) vec4f {
	var color4 = calcBlurColor( uv );
    return color4;
}

此示例基于此渲染系统实现,当前示例TypeScript源码如下:

const rttTex0 = { diffuse: { uuid: "rtt0", rttTexture: {} } };
const rttTex1 = { diffuse: { uuid: "rtt1", rttTexture: {} } };
const rtts = [rttTex0, rttTex1];
const attachment = {
	texture: rttTex0,
	clearValue: [] as ColorDataType,
	loadOp: "clear",
	storeOp: "store"
};
const colorAttachments = [attachment];

class PassGraph extends WGRPassNodeGraph {
	blurEntity: FixScreenPlaneEntity;
	constructor() {
		super();
	}

	run(): void {
		let pass = this.passes[0];

		const entity = this.blurEntity;
		let ms = entity.materials;

		for (let i = 0; i < 15; ++i) {
			pass.colorAttachments[0].clearEnabled = i < 1;
			attachment.texture = rtts[i % 2];
			ms[i % 2].visible = false;
			ms[(i + 1) % 2].visible = true;
			pass.render();
		}
	}
}

export class PingpongBlur {
	private mRscene = new RendererScene();
	initialize(): void {

		let multisampleEnabled = true;
		let depthTestEnabled = false;
		let rpassparam = { multisampleEnabled, depthTestEnabled };
		this.mRscene.initialize({ rpassparam });
		this.initScene();
	}

	private mGraph = new PassGraph();
	private uniformValues = [{ data: new Float32Array([512, 512, 3.0, 0]) }];
	private createMaterial(shadinguuid: string, textures: WGTextureDataDescriptor[], type: number): WGMaterial {
		let shaderCodeSrc = {
			vert: { code: vertWGSL, uuid: "vert" },
			frag: { code: type > 0 ? blurVWGSL : blurHWGSL, uuid: "frag" }
		};
		shadinguuid += "-" + type;
		const material = new WGMaterial({
			shadinguuid,
			shaderCodeSrc
		});
		material.uniformValues = this.uniformValues;
		material.addTextures(textures);
		return material;
	}
	private applyBlurPass(clearColor: ColorDataType, extent = [0.4, 0.3, 0.5, 0.5]): void {
		let rs = this.mRscene;

		const graph = this.mGraph;

		attachment.clearValue = clearColor;

		let rPass = rs.renderer.appendRenderPass({ separate: true, colorAttachments });

		const diffuseTex = { diffuse: { url: "static/assets/huluwa.jpg", flipY: true } };

		let materials = [this.createMaterial("shd-01", [rttTex0], 0), this.createMaterial("shd-02", [rttTex1], 1)];

		let rttEntity = new FixScreenPlaneEntity({ extent: [-1, -1, 2, 2], textures: [diffuseTex] });
		rPass.addEntity(rttEntity);

		graph.passes = [rPass];
		rs.setPassNodeGraph(graph);

		let entity = new FixScreenPlaneEntity({ extent, flipY: true, materials });
		entity.materials[0].visible = false;
		rs.addEntity(entity);
		graph.blurEntity = entity;

		extent = [-0.9, -0.9, 0.6, 0.6];
		entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [diffuseTex] });
		rs.addEntity(entity);
	}
	private initScene(): void {
		this.applyBlurPass([0.1, 0.1, 0.1, 1.0], [-1, -1, 2, 2]);
	}

	run(): void {
		this.mRscene.run();
	}
}

你可能感兴趣的:(GPU/CPU,WebGL/WebGPU,3D引擎,3d,WebGPU)