first commit
This commit is contained in:
186
passes/OceanSolidRenderPass.js
Normal file
186
passes/OceanSolidRenderPass.js
Normal file
@@ -0,0 +1,186 @@
|
||||
import { RenderPass } from "/framework/RenderPass.js";
|
||||
|
||||
import Shader from "/framework/WebGpu.js";
|
||||
|
||||
import Matrix4 from "/framework/Matrix4.js";
|
||||
|
||||
|
||||
export class OceanSolidRenderPass extends RenderPass {
|
||||
|
||||
async create( ) {
|
||||
|
||||
this.shader = new Shader( this.device );
|
||||
|
||||
this.shader.topology = "triangle-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.indices );
|
||||
|
||||
await this._loadBottomTexture();
|
||||
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
async _loadBottomTexture( ) {
|
||||
|
||||
if ( this._bottomTextureLoaded ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( typeof document === "undefined" ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const canvas = document.createElement( "canvas" );
|
||||
|
||||
const ctx = canvas.getContext( "2d" );
|
||||
|
||||
if ( !ctx ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const colorImage = await this._loadImage( "resources/textures/ground/Ground093C_2K-PNG_Color.png" );
|
||||
|
||||
const heightImage = await this._loadImage( "resources/textures/heightmap/Terrain003_1K_Height512.png" );
|
||||
|
||||
// COLOR
|
||||
canvas.width = colorImage.width;
|
||||
canvas.height = colorImage.height;
|
||||
|
||||
ctx.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
|
||||
ctx.drawImage( colorImage, 0, 0 );
|
||||
|
||||
let imageData = ctx.getImageData( 0, 0, canvas.width, canvas.height );
|
||||
|
||||
let pixels = new Uint8Array( imageData.data );
|
||||
|
||||
const colorTex = this.shader.createTextureFromData( canvas.width, canvas.height, pixels );
|
||||
|
||||
this.shader.setVariable( "bottomColorTex", colorTex );
|
||||
|
||||
// HEIGHTMAP
|
||||
canvas.width = heightImage.width;
|
||||
canvas.height = heightImage.height;
|
||||
|
||||
ctx.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
|
||||
ctx.drawImage( heightImage, 0, 0 );
|
||||
|
||||
imageData = ctx.getImageData( 0, 0, canvas.width, canvas.height );
|
||||
|
||||
pixels = new Uint8Array( imageData.data );
|
||||
|
||||
const heightTex = this.shader.createTextureFromData( canvas.width, canvas.height, pixels );
|
||||
|
||||
this.shader.setVariable( "bottomHeightTex", heightTex );
|
||||
|
||||
const sampler = this.device.createSampler( {
|
||||
minFilter: "linear",
|
||||
magFilter: "linear",
|
||||
mipmapFilter: "linear",
|
||||
addressModeU: "repeat",
|
||||
addressModeV: "repeat"
|
||||
} );
|
||||
|
||||
this.shader.setVariable( "bottomSampler", sampler );
|
||||
|
||||
|
||||
this._bottomTextureLoaded = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
async _loadImage( url ) {
|
||||
|
||||
return await new Promise( function( resolve, reject ) {
|
||||
|
||||
const img = new Image( );
|
||||
|
||||
img.onload = function( ) { resolve( img ); };
|
||||
|
||||
img.onerror = function( event ) { reject( event ); };
|
||||
|
||||
img.src = url;
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user