From 3851c74c89bf8d9684438d9b052ae51666db5753 Mon Sep 17 00:00:00 2001 From: kris temmerman Date: Tue, 28 Nov 2023 09:30:35 +0100 Subject: [PATCH] skinShadows --- frontend/src/lib/Renderer.ts | 2 + frontend/src/lib/animation/Skin.ts | 2 +- frontend/src/renderPasses/ShadowCubePass.ts | 42 +++++++--- frontend/src/shaders/DepthShader.ts | 2 +- frontend/src/shaders/DepthSkinShader.ts | 85 +++++++++++++++++++++ 5 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 frontend/src/shaders/DepthSkinShader.ts diff --git a/frontend/src/lib/Renderer.ts b/frontend/src/lib/Renderer.ts index ffcd2f0f..17a54092 100644 --- a/frontend/src/lib/Renderer.ts +++ b/frontend/src/lib/Renderer.ts @@ -11,6 +11,7 @@ import Camera from "./Camera"; import Model from "./model/Model"; import {IResizable} from "./IResizable"; import {Vector2} from "math.gl"; +import Skin from "./animation/Skin"; export default class Renderer { public device: GPUDevice; @@ -36,6 +37,7 @@ export default class Renderer { private first: boolean = true; private resizables:Array=[]; public pixelRatio: number; + public skin: Skin; constructor() { } diff --git a/frontend/src/lib/animation/Skin.ts b/frontend/src/lib/animation/Skin.ts index 8481a2b1..c2b98976 100644 --- a/frontend/src/lib/animation/Skin.ts +++ b/frontend/src/lib/animation/Skin.ts @@ -11,7 +11,7 @@ export default class Skin extends UniformGroup{ private dataArray:Float32Array constructor(renderer:Renderer,label:string,objects:Array,invBindMatrices:Array) { super(renderer,label,"skin") - + this.renderer.skin = this; this.objects=objects; this.invBindMatrices =invBindMatrices; this.dataArray =new Float32Array(16*this.objects.length) diff --git a/frontend/src/renderPasses/ShadowCubePass.ts b/frontend/src/renderPasses/ShadowCubePass.ts index 5367aa27..7426e6a4 100644 --- a/frontend/src/renderPasses/ShadowCubePass.ts +++ b/frontend/src/renderPasses/ShadowCubePass.ts @@ -8,6 +8,7 @@ import ModelRenderer from "../lib/model/ModelRenderer"; import Model from "../lib/model/Model"; import Material from "../lib/core/Material"; import DepthShader from "../shaders/DepthShader"; +import DepthSkinShader from "../shaders/DepthSkinShader"; @@ -17,6 +18,7 @@ export default class ShadowCubePass extends RenderPass { private camera: any; models: Array; private material: Material; + private materialSkin: Material; @@ -27,10 +29,12 @@ export default class ShadowCubePass extends RenderPass { super(renderer, "ShadowCubePass"); - this.material =new Material(this.renderer,"shadowCube",new DepthShader(this.renderer,"depthshader")) - - - this.colorAttachments =[new ColorAttachment(colorTexture,{arrayLayerCount:1,baseArrayLayer:index})]; + this.material =new Material(this.renderer,"shadowCube",new DepthShader(this.renderer,"depthShader")) + if(this.renderer.skin) { + this.materialSkin = new Material(this.renderer, "shadowCubeSkin", new DepthSkinShader(this.renderer, "depthSkinShader")) + this.materialSkin.skin = this.renderer.skin; + } + this.colorAttachments =[new ColorAttachment(colorTexture,{arrayLayerCount:1,baseArrayLayer:index})]; this.depthStencilAttachment = new DepthStencilAttachment(depthTexture,{arrayLayerCount:1,baseArrayLayer:index}); this.camera =camera; @@ -43,23 +47,37 @@ export default class ShadowCubePass extends RenderPass { passEncoder.setBindGroup(0,this.camera.bindGroup); this.material.makePipeLine(this); - - passEncoder.setPipeline(this.material.pipeLine); + this.materialSkin.makePipeLine(this); + //passEncoder.setPipeline(this.material.pipeLine); for (let model of this.models) { if(!model.visible)continue if(!model.castShadow)continue passEncoder.setBindGroup(1,model.modelTransform.bindGroup); + if(model.material.skin != undefined){ + passEncoder.setPipeline(this.materialSkin.pipeLine); + passEncoder.setBindGroup(2,model.material.skin.bindGroup); + for (let attribute of this.materialSkin.shader.attributes) { + passEncoder.setVertexBuffer( + attribute.slot, + model.mesh.getBufferByName(attribute.name) + ); + } + }else{ + passEncoder.setPipeline(this.material.pipeLine); + for (let attribute of this.material.shader.attributes) { + passEncoder.setVertexBuffer( + attribute.slot, + model.mesh.getBufferByName(attribute.name) + ); + } + } + + - for (let attribute of this.material.shader.attributes) { - passEncoder.setVertexBuffer( - attribute.slot, - model.mesh.getBufferByName(attribute.name) - ); - } if (model.mesh.hasIndices) { diff --git a/frontend/src/shaders/DepthShader.ts b/frontend/src/shaders/DepthShader.ts index c2146fe8..bfb7bc1d 100644 --- a/frontend/src/shaders/DepthShader.ts +++ b/frontend/src/shaders/DepthShader.ts @@ -13,7 +13,7 @@ export default class DepthShader extends Shader{ if(this.attributes.length==0) { this.addAttribute("aPos", ShaderType.vec3); - this.addAttribute("aNormal", ShaderType.vec3); + } diff --git a/frontend/src/shaders/DepthSkinShader.ts b/frontend/src/shaders/DepthSkinShader.ts new file mode 100644 index 00000000..82aaf592 --- /dev/null +++ b/frontend/src/shaders/DepthSkinShader.ts @@ -0,0 +1,85 @@ +import Shader from "../lib/core/Shader"; + + +import {ShaderType} from "../lib/core/ShaderTypes"; +import Camera from "../lib/Camera"; +import ModelTransform from "../lib/model/ModelTransform"; + +export default class DepthSkinShader extends Shader{ + private needsFragment: boolean=true; + + + init(){ + + if(this.attributes.length==0) { + this.addAttribute("aPos", ShaderType.vec3); + this.addAttribute("aWeights", ShaderType.vec4); + this.addAttribute("aJoints", ShaderType.vec4i); + + } + + + this.needsTransform =true; + this.needsCamera=true; + + } + getShaderCode(): string { + return /* wgsl */ ` +/////////////////////////////////////////////////////////// +struct VertexOutput +{ + @location(0) model : vec3f, + @builtin(position) position : vec4f + +} + + +${Camera.getShaderText(0)} +${ModelTransform.getShaderText(1)} +struct Skin +{ + matrices : array,49> +} +@group(2) @binding(0) var skin : Skin ; + +@vertex +fn mainVertex( ${this.getShaderAttributes()} ) -> VertexOutput +{ + var output : VertexOutput; + + var skinMatrix = skin.matrices[aJoints.x]*aWeights.x; + skinMatrix+= skin.matrices[aJoints.y]*aWeights.y; + skinMatrix+= skin.matrices[aJoints.z]*aWeights.z; + skinMatrix+= skin.matrices[aJoints.w]*aWeights.w; + + + output.model =( skinMatrix*vec4( aPos,1.0)).xyz; + output.position =camera.viewProjectionMatrix*skinMatrix *vec4( aPos,1.0); + + + return output; +} +@fragment +fn mainFragment(@location(0) model: vec3f) -> @location(0) vec4f +{ + + + + return vec4(distance(model,camera.worldPosition.xyz),0.0,0.0,1.0); + +} + + + + + + + + + + ` + } + + + +}