UNPKG

matrix-engine-wgpu

Version:

Networking implemented - based on kurento openvidu server. fix arcball camera,instanced draws added also effect pipeline blend with instancing option.Normalmap added, Fixed shadows casting vs camera/video texture, webGPU powered pwa application. Crazy fas

145 lines (123 loc) 4.69 kB
import {mat4} from "wgpu-matrix"; import {hpBarEffectShaders} from "../../shaders/energy-bars/energy-bar-shader.js"; export class HPBarEffect { constructor(device, format) { this.device = device; this.format = format; this.progress = 1.0; this.color = [0.1, 0.9, 0.1, 1.0]; this.offsetY = 48; this.enabled = true; this._initPipeline(); } _initPipeline() { // Simple flat bar (width 100, height 10) const W = 40; const H = 3; const vertexData = new Float32Array([ -0.5 * W, 0.5 * H, 0.0, 0.5 * W, 0.5 * H, 0.0, -0.5 * W, -0.5 * H, 0.0, 0.5 * W, -0.5 * H, 0.0, ]); const uvData = new Float32Array([ 0, 1, 1, 1, 0, 0, 1, 0 ]); const indexData = new Uint16Array([0, 2, 1, 1, 2, 3]); // Buffers this.vertexBuffer = this.device.createBuffer({ size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }); this.device.queue.writeBuffer(this.vertexBuffer, 0, vertexData); this.uvBuffer = this.device.createBuffer({ size: uvData.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }); this.device.queue.writeBuffer(this.uvBuffer, 0, uvData); this.indexBuffer = this.device.createBuffer({ size: Math.ceil(indexData.byteLength / 4) * 4, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST }); this.device.queue.writeBuffer(this.indexBuffer, 0, indexData); this.indexCount = indexData.length; // Uniforms this.cameraBuffer = this.device.createBuffer({ size: 64, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }); // model + color + progress (64 + 16 + 4) this.modelBuffer = this.device.createBuffer({ size: 64 + 16 + 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }); // BindGroup const bindGroupLayout = this.device.createBindGroupLayout({ entries: [ {binding: 0, visibility: GPUShaderStage.VERTEX, buffer: {}}, {binding: 1, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: {}} ] }); this.bindGroup = this.device.createBindGroup({ layout: bindGroupLayout, entries: [ {binding: 0, resource: {buffer: this.cameraBuffer}}, {binding: 1, resource: {buffer: this.modelBuffer}} ] }); // Pipeline const shaderModule = this.device.createShaderModule({code: hpBarEffectShaders}); const pipelineLayout = this.device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]}); this.pipeline = this.device.createRenderPipeline({ layout: pipelineLayout, vertex: { module: shaderModule, entryPoint: 'vsMain', buffers: [ {arrayStride: 3 * 4, attributes: [{shaderLocation: 0, offset: 0, format: 'float32x3'}]}, {arrayStride: 2 * 4, attributes: [{shaderLocation: 1, offset: 0, format: 'float32x2'}]} ] }, fragment: { module: shaderModule, entryPoint: 'fsMain', targets: [{format: this.format}] }, primitive: {topology: 'triangle-list'}, depthStencil: {depthWriteEnabled: false, depthCompare: 'always', format: 'depth24plus'} }); } setProgress(value) { this.progress = Math.max(0.0, Math.min(1.0, value)); } setColor(r, g, b, a = 1.0) { this.color = [r, g, b, a]; } draw(pass, cameraMatrix, modelMatrix) { const color = new Float32Array(this.color); const progressData = new Float32Array([this.progress]); // Pack uniforms manually const buffer = new ArrayBuffer(64 + 16 + 4); const f32 = new Float32Array(buffer); f32.set(cameraMatrix, 0); // not needed here this.device.queue.writeBuffer(this.cameraBuffer, 0, cameraMatrix); this.device.queue.writeBuffer(this.modelBuffer, 0, modelMatrix); this.device.queue.writeBuffer(this.modelBuffer, 64, color); this.device.queue.writeBuffer(this.modelBuffer, 64 + 16, progressData); pass.setPipeline(this.pipeline); pass.setBindGroup(0, this.bindGroup); pass.setVertexBuffer(0, this.vertexBuffer); pass.setVertexBuffer(1, this.uvBuffer); pass.setIndexBuffer(this.indexBuffer, 'uint16'); pass.drawIndexed(this.indexCount); } render(pass, mesh, viewProjMatrix, ) { const pos = mesh.position; const modelMatrix = mat4.identity(); mat4.translate(modelMatrix, [pos.x, pos.y + this.offsetY, pos.z], modelMatrix); this.draw(pass, viewProjMatrix, modelMatrix); } }