轻量封装WebGPU渲染系统示例<9>- 基本光照(源码)

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/main/src/voxgpu/sample/SimpleLightTest.ts

此示例渲染系统实现的特性:

1. 用户态与系统态隔离。

2. 高频调用与低频调用隔离。

3. 面向用户的易用性封装。

4. 渲染数据和渲染机制分离。

5. 用户操作和渲染系统调度并行机制。

当前示例运行效果:

轻量封装WebGPU渲染系统示例<9>- 基本光照(源码)_第1张图片

顶点shader:

@group(0) @binding(0) var objMat : mat4x4;
@group(0) @binding(1) var viewMat : mat4x4;
@group(0) @binding(2) var projMat : mat4x4;

struct VertexOutput {
  @builtin(position) Position : vec4,
  @location(0) pos: vec4,
  @location(1) uv : vec2,
  @location(2) normal : vec3
}

fn inverseM33(m: mat3x3)-> mat3x3 {
    let a00 = m[0][0]; let a01 = m[0][1]; let a02 = m[0][2];
    let a10 = m[1][0]; let a11 = m[1][1]; let a12 = m[1][2];
    let a20 = m[2][0]; let a21 = m[2][1]; let a22 = m[2][2];
    let b01 = a22 * a11 - a12 * a21;
    let b11 = -a22 * a10 + a12 * a20;
    let b21 = a21 * a10 - a11 * a20;
    let det = a00 * b01 + a01 * b11 + a02 * b21;
    return mat3x3(
		vec3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11)) / det,
                vec3(b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10)) / det,
                vec3(b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det);
}

@vertex
fn main(
  @location(0) position : vec3,
  @location(1) uv : vec2,
  @location(2) normal : vec3
) -> VertexOutput {
  var output : VertexOutput;
  output.Position = projMat * viewMat * objMat * vec4(position.xyz, 1.0);
  output.uv = uv;

  let mat33 = mat3x3(objMat[0].xyz, objMat[1].xyz, objMat[2].xyz);
  let invMat33 = inverseM33(mat33);
  output.normal = normalize( normal * invMat33 );

  var pv: vec4;
  pv = vec4(position, 1.0);
  output.pos = pv;
  return output;
}

片段shader:

@group(0) @binding(3) var param: vec4f;
@group(0) @binding(4) var sampler0: sampler;
@group(0) @binding(5) var texture0: texture_2d;

const lightDirec = vec3(0.3,0.6,0.9);

@fragment
fn main(
  @location(0) pos: vec4,
  @location(1) uv: vec2,
  @location(2) normal: vec3
) -> @location(0) vec4 {

  let nDotL = max(dot(normal, lightDirec), 0.0);
  var color4 = textureSample(texture0, sampler0, uv) * param;
  color4 = vec4(color4.xyz * (vec3(1.0 - param.w) + vec3((param.w) * nDotL) * param.xyz), color4.w);
  return color4;
}

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

export class SimpleLightTest {
	private mObjs: TransObject[] = [];

	private mRscene = new RendererScene();

	geomData = new GeomDataBuilder();

	initialize(): void {
		console.log("SimpleLightTest::initialize() ...");

		const rc = this.mRscene;
		rc.initialize();

		this.initEvent();

		const shdSrc = {
			vertShaderSrc: { code: vertWGSL, uuid: "vertShdCode" },
			fragShaderSrc: { code: fragWGSL, uuid: "fragShdCode" }
		};

		for (let i = 0; i < 10; ++i) {
			let material = this.createMaterial(shdSrc, [new WGImage2DTextureData("static/assets/white.jpg")], new Color4().randomRGB(1.0, 0.2));
			let scale = Math.random() * 0.5 + 0.5;
			const entity = this.createEntity([material]);
			const obj = new TransObject();
			obj.entity = entity;
			obj.scale.setXYZ(scale, scale, scale);
			obj.rotationSpdv.setXYZ(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
			obj.initialize(800);
			this.mObjs.push(obj);
		}
	}
	private initEvent(): void {
		const rc = this.mRscene;
		rc.addEventListener(MouseEvent.MOUSE_DOWN, this, this.mouseDown);

		new MouseInteraction().initialize(rc, 0, false).setAutoRunning(true);
	}

	private mouseDown(evt: MouseEvent): void {
		console.log("mousedown evt call ...");
	}
	private createMaterial(
		shdSrc: WGRShderSrcType,
		texDatas?: WGImage2DTextureData[],
		color?: Color4,
		blendModes: string[] = ["solid"],
		faceCullMode = "back"
	): WGMaterial {
		let pipelineDefParam = {
			depthWriteEnabled: true,
			faceCullMode,
			blendModes: [] as string[]
		};

		if (!color) color = new Color4(1.0, 1.0, 1.0);

		pipelineDefParam.blendModes = blendModes;

		const texTotal = texDatas ? texDatas.length : 0;

		const material = new WGMaterial({
			shadinguuid: "base-material-tex" + texTotal,
			shaderCodeSrc: shdSrc,
			pipelineDefParam
		});

		let ufv = new WGRStorageValue(new Float32Array([color.r, color.g, color.b, 0.9]));
		material.uniformValues = [ufv];
		material.addTextureWithDatas(texDatas);

		return material;
	}

	private createGeom(rgd: GeomRDataType): WGGeometry {
		const geometry = new WGGeometry()
			.addAttribute({ shdVarName: "position", data: rgd.vs, strides: [3] })
			.addAttribute({ shdVarName: "uv", data: rgd.uvs, strides: [2] })
			.addAttribute({ shdVarName: "normal", data: rgd.nvs, strides: [3] })
			.setIndexBuffer({ name: "geomIndex", data: rgd.ivs });
		return geometry;
	}
	private createEntity(materials: WGMaterial[], pv?: Vector3): Entity3D {
		const rc = this.mRscene;
		let geometry = this.mObjs.length > 0 ? this.mObjs[0].entity.geometry : null;
		geometry = geometry ? geometry : this.createGeom(this.geomData.createCube(200));

		const entity = new Entity3D();
		entity.materials = materials;
		entity.geometry = geometry;
		entity.transform.setPosition(pv ? pv : new Vector3());


		rc.addEntity(entity);
		return entity;
	}

	run(): void {
		for (let i = 0; i < this.mObjs.length; ++i) {
			this.mObjs[i].run();
		}
		this.mRscene.run();
	}
}

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