Jelajahi Sumber

MeshSpawn on skinned objects.

clementlandrin 9 bulan lalu
induk
melakukan
136db83c8f

+ 5 - 13
hrt/prefab/fx/gpuemitter/GPUEmitter.hx

@@ -104,10 +104,6 @@ class GPUEmitterObject extends h3d.scene.MeshBatch {
 
 		simulationPass = new h3d.mat.Pass("simulation");
 		simulationPass.addShader(new BaseSimulation());
-
-		begin();
-		for ( _ in 0...data.maxCount )
-			emitInstance();
 	}
 
 	override function flush(ctx : h3d.scene.RenderContext) {
@@ -197,6 +193,10 @@ class GPUEmitterObject extends h3d.scene.MeshBatch {
 			}
 			paramTexture.uploadPixels(pxls);
 		}
+
+		begin();
+		for ( _ in 0...this.data.maxCount )
+			emitInstance();
 	}
 
 	function createUpdateParamShader() {
@@ -332,7 +332,7 @@ class GPUEmitterObject extends h3d.scene.MeshBatch {
 					p.shader.batchBuffer = b;
 					p.shader.particleBuffer = particleBuffer.buffer;
 					p.shader.stride = b.format.stride;
-					p.shader.row = row;
+					p.shader.row = (row + 0.5) / shaderParams.length;
 					var pos = 0;
 					for ( i in b.format.getInputs() ) {
 						if ( i.name == p.param.def.name )
@@ -405,14 +405,6 @@ class GPUEmitter extends Object3D {
 		return new h3d.scene.Object(parent3d);
 	}
 
-	override function makeChild(c : hrt.prefab.Prefab) {
-		#if !editor
-		if ( Std.isOfType(c, hrt.prefab.Object3D) )
-			return;
-		#end
-		super.makeChild(c);
-	}
-
 	function updateEmitters() {
 		#if editor
 		return;

+ 25 - 12
hrt/prefab/fx/gpuemitter/MeshSpawn.hx

@@ -29,7 +29,9 @@ class MeshSpawnShader extends ComputeUtils {
 		} else {
 			hxd.BufferFormat.make([
 				{ name : "position", type : DVec3 },
+				{ name : "padding", type : DFloat },
 				{ name : "normal", type : DVec3 },
+				{ name : "padding2", type : DFloat },
 			]);
 		}
 		vbuf = alloc.allocBuffer(vertexCount, fmt, UniformReadWrite);
@@ -44,17 +46,22 @@ class MeshSpawnShader extends ComputeUtils {
 		vbuf.uploadFloats(floatBuffer, 0, vertexCount);
 	}
 
+	var tmpMat : h3d.Matrix = new h3d.Matrix();
 	override function onUpdate(emitter : GPUEmitter.GPUEmitterObject, buffer : h3d.Buffer, index : Int) {
 		super.onUpdate(emitter, buffer, index);
 		var parentInvert = new h3d.Matrix();
 		parentInvert.load(emitter.parent.getAbsPos());
 		parentInvert.invert();
-		parentInvert.multiply3x4inline(mesh.getAbsPos(), parentInvert);
+		tmpMat.load(mesh.getAbsPos());
+		if ( mesh.defaultTransform != null )
+			tmpMat.multiply3x4inline(mesh.getAbsPos(), mesh.defaultTransform.getInverse());
+		parentInvert.multiply3x4inline(tmpMat, parentInvert);
 		emitter.setTransform(parentInvert);
 
 		var skinShader = mesh.material.mainPass.getShader(h3d.shader.SkinBase);
 		bonesMatrixes = skinShader.bonesMatrixes;
 		MaxBones = skinShader.MaxBones;
+		defaultMatrix = mesh.getAbsPos();
 	}
 
 	static var SRC = {
@@ -70,7 +77,9 @@ class MeshSpawnShader extends ComputeUtils {
 			indexes : Bytes4
 		}>;
 		@param var bonesMatrixes : Array<Mat3x4,MaxBones>;
+		@param var defaultMatrix : Mat4;
 
+		var speed : Vec3;
 		var emitNormal : Vec3;
 		var lifeTime : Float;
 		var relativeTransform : Mat4;
@@ -78,19 +87,23 @@ class MeshSpawnShader extends ComputeUtils {
 			var idx = computeVar.globalInvocation.x;
 			var vertexId = idx % vertexCount;
 			var vertexData = vbuf[vertexId];
-			emitNormal = vertexData.normal;
+			speed = vec3(1.0);
 			var relativePosition = vertexData.position;
+			var relativeNormal = vertexData.normal;
+			
+			var weights = vertexData.weights;
+			weights = weights / (weights.x + weights.y + weights.z);
+			var transformedPosition = (relativePosition * bonesMatrixes[int(vertexData.indexes.x * 127.0)]) * weights.x +
+				(relativePosition * bonesMatrixes[int(vertexData.indexes.y * 127.0)]) * weights.y +
+				(relativePosition * bonesMatrixes[int(vertexData.indexes.z * 127.0)]) * weights.z;
 
-			relativePosition =
-				(relativePosition * bonesMatrixes[int(vertexData.indexes.x)]) * vertexData.weights.x +
-				(relativePosition * bonesMatrixes[int(vertexData.indexes.y)]) * vertexData.weights.y +
-				(relativePosition * bonesMatrixes[int(vertexData.indexes.z)]) * vertexData.weights.z;
-			// transformedNormal = 
-			// 	(vertexData.normal * mat3(bonesMatrixes[int(vertexData.indexes.x)])) * vertexData.weights.x +
-			// 	(vertexData.normal * mat3(bonesMatrixes[int(vertexData.indexes.y)])) * vertexData.weights.y +
-			// 	(vertexData.normal * mat3(bonesMatrixes[int(vertexData.indexes.z)])) * vertexData.weights.z;
-				
-			relativeTransform = translationMatrix(relativePosition);
+			var transformedNormal =
+				(vertexData.normal * mat3(bonesMatrixes[int(vertexData.indexes.x * 127.0)])) * vertexData.weights.x +
+				(vertexData.normal * mat3(bonesMatrixes[int(vertexData.indexes.y * 127.0)])) * vertexData.weights.y +
+				(vertexData.normal * mat3(bonesMatrixes[int(vertexData.indexes.z * 127.0)])) * vertexData.weights.z;
+			emitNormal = transformedNormal;
+			
+			relativeTransform = translationMatrix(transformedPosition);
 		}
 	}
 }

+ 2 - 2
hrt/prefab/fx/gpuemitter/UpdateParamShader.hx

@@ -5,7 +5,7 @@ class UpdateParamShader extends hxsl.Shader {
 
 		@param var batchBuffer : RWBuffer<Float>;
 
-		@param var particleBuffer : RWPartialBuffer<{ speed : Vec3, lifeTime : Float, lifeRatio : Float }>;
+		@param var particleBuffer : RWPartialBuffer<{ lifeTime : Float, lifeRatio : Float }>;
 
 		@param var paramTexture : Sampler2D;
 		@param var stride : Int;
@@ -15,7 +15,7 @@ class UpdateParamShader extends hxsl.Shader {
 
 		function main() {
 			var idx = computeVar.globalInvocation.x;
-			batchBuffer[idx * stride + pos] = paramTexture.get(vec2(particleBuffer[idx].lifeTime * particleBuffer[idx].lifeRatio, row)).x;
+			batchBuffer[idx * stride + pos] = paramTexture.get(vec2(1.0 - particleBuffer[idx].lifeTime * particleBuffer[idx].lifeRatio, row)).x;
 		}
 	}
 }