轻量封装WebGPU渲染系统示例<10>- 容器(源码)

当前示例源码github地址:

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

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

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

        细节请见:引擎系统设计思路 - 用户态与系统态隔离-CSDN博客

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

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

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

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

6. 保证逻辑意图在系统内外的一致性。

更多系统设计思路的细节请见:

        支撑高效能3D虚拟视觉系统的六个维度-CSDN博客

关于3D引擎中容器的更多作用请见: 3D系统中可渲染实体容器(Renderable Entity Container)-CSDN博客

当前示例运行效果:

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

export class REntity3DContainerTest {
	private mRscene = new RendererScene();
	geomData = new GeomDataBuilder();
	initialize(): void {
		console.log("REntity3DContainerTest::initialize() ...");

		this.initEvent();
		this.initScene();
	}
	private initEvent(): void {
		const rc = this.mRscene;
		rc.addEventListener(MouseEvent.MOUSE_DOWN, 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?: WGTextureDataDescriptor[],
		color?: Color4,
		blendModes: string[] = ["solid"],
		faceCullMode = "back"
	): WGMaterial {
		color = color ? color : new Color4();

		let pipelineDefParam = {
			depthWriteEnabled: true,
			faceCullMode,
			blendModes: [] as string[]
		};

		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, 1]));
		material.uniformValues = [ufv];
		material.addTextures(texDatas);

		return material;
	}

	private createGeom(rgd: GeomRDataType, normalEnabled = false): WGGeometry {
		const geometry = new WGGeometry()
			.addAttribute({ position: rgd.vs })
			.addAttribute({ uv: rgd.uvs })
			.setIndices(rgd.ivs);
		if (normalEnabled) {
			geometry.addAttribute({ normal: rgd.nvs });
		}
		return geometry;
	}
	private mContainers: Entity3DContainer[] = [];
	private createCircle(
		radius: number,
		total: number,
		scale: number,
		materials: WGMaterial[],
		geometry: WGGeometry,
		pv?: Vector3
	): Entity3DContainer {
		const rc = this.mRscene;

		pv = pv ? pv : new Vector3();

		let mContainer = new Entity3DContainer();
		mContainer.setPosition(pv);
		for (let i = 0; i < total; ++i) {
			const factor = i / total;
			const rad = Math.PI * 2.0 * factor;
			const px = radius * Math.cos(rad);
			const py = radius * Math.sin(rad);

			let entity = new Entity3D();
			entity.materials = materials;
			entity.geometry = geometry;
			entity.transform.setXYZ(px, py, 0);
			entity.transform.setRotationZ(factor * 360.0);
			entity.transform.setScaleAll(scale);

			mContainer.addChild(entity);
		}
		return mContainer;
	}
	private initScene(): void {
		const rc = this.mRscene;

		const geometry = this.createGeom(this.geomData.createCube(80));

		const shdSrc = {
			vertShaderSrc: { code: vertWGSL, uuid: "vertShdCode" },
			fragShaderSrc: { code: fragWGSL, uuid: "fragShdCode" }
		};
		const diffuseMap = { diffuse: { url: "static/assets/box.jpg" } };
		let materials0 = [this.createMaterial(shdSrc, [diffuseMap], new Color4(1.0, 0.0, 0.0))];
		let materials1 = [this.createMaterial(shdSrc, [diffuseMap], new Color4(0.0, 1.0, 0.0))];
		let materials2 = [this.createMaterial(shdSrc, [diffuseMap], new Color4(1.0, 0.0, 1.0))];

		const container0 = this.createCircle(100, 10, 0.5, materials0, geometry);
		const container1 = this.createCircle(180, 15, 0.5, materials1, geometry);
		const container2 = this.createCircle(260, 25, 0.5, materials2, geometry);

		let container = new Entity3DContainer();
		container.addChild(container0);
		container.addChild(container1);
		container.addChild(container2);
		rc.addEntity(container);

		this.mContainers.push(container0, container1, container2, container);
	}

	private mRotValue = 0.0;
	run(): void {
		this.mRotValue += 0.5;

		const ls = this.mContainers;
		ls[0].setRotationZ(this.mRotValue * 1.2);
		ls[1].setRotationZ(this.mRotValue * 0.4 + 15.0);
		ls[2].setRotationZ(this.mRotValue * 0.2 + 30.0);
		ls[3].setRotationY(this.mRotValue * 0.2);
		ls[3].update();

		this.mRscene.run();
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值