import { RenderPass } from "/framework/RenderPass.js"; import Shader from "/framework/WebGpu.js"; import Matrix4 from "/framework/Matrix4.js"; export class OceanRenderPass extends RenderPass { async create( ) { this.shader = new Shader( this.device ); this.shader.topology = "line-list"; this.shader.setCanvas( this.pipeline.canvas ); this._configureCanvasContext(); await this.shader.setup( "shaders/ocean_render.wgsl" ); this.shader.setAttribute( "position", this.pipeline.memory.positions ); this.shader.setAttribute( "uv", this.pipeline.memory.uvs ); this.shader.setIndices( this.pipeline.memory.lineIndices ); } async bindBuffers( ) { const memory = this.pipeline.memory; const oceanBlock = this.pipeline.getBlockByName( "ocean" ); const colPass = oceanBlock.getPass( "ColFFT" ); const heightBuffer = colPass.shader.getBuffer( "heightField" ); const viewMatrixData = this.pipeline.camera.getViewMatrix(); const projectionMatrixData = Matrix4.createProjectionMatrix( this.pipeline.camera, this.pipeline.canvas ); const viewProjectionMatrix = Matrix4.multiply( projectionMatrixData, viewMatrixData ); const cameraWorldMatrix = Matrix4.invert( viewMatrixData ); const cameraPosition = Matrix4.getColumn( cameraWorldMatrix, 3 ); await this.shader.setBuffer( "heightField", heightBuffer ); this.shader.setVariable( "renderParams", memory.renderParams ); this.shader.setVariable( "viewProjection", viewProjectionMatrix ); this.shader.setVariable( "cameraPosition", cameraPosition ); this.shader.createBindGroups(); } async execute( ) { await this.shader.renderToCanvas( this.shader.indexCount, 1 ); } _configureCanvasContext( ) { if ( this.pipeline.canvasConfigured ) { return; } const context = this.pipeline.canvas.getContext( "webgpu" ); const format = navigator.gpu.getPreferredCanvasFormat(); context.configure( { device: this.device, format: format, alphaMode: "opaque" } ); this.pipeline.canvasConfigured = true; } }