Преглед изворни кода

GLSL variant of the GPU skinning/morph shader

BearishSun пре 9 година
родитељ
комит
889c4341b1

BIN
Data/Engine/GUISkin.asset


BIN
Data/Engine/Includes/DeferredBasePass.bslinc.asset


BIN
Data/Engine/Includes/NormalVertexInput.bslinc.asset


BIN
Data/Engine/Includes/SkinnedVertexInput.bslinc.asset


BIN
Data/Engine/ResourceManifest.asset


BIN
Data/Engine/Shaders/Default.bsl.asset


BIN
Data/Engine/Shaders/Diffuse.bsl.asset


BIN
Data/Engine/Timestamp.asset


BIN
Data/Engine/arial.ttf.asset


+ 1 - 1
Data/Raw/Engine/Includes/DeferredBasePass.bslinc

@@ -61,7 +61,7 @@ Technique =
 				getVertexIntermediate(intermediate);
 				getVertexIntermediate(intermediate);
 			
 			
 				vec4 worldPos;
 				vec4 worldPos;
-				getVertexWorldPosition(worldPos, intermediate);
+				getVertexWorldPosition(intermediate, worldPos);
 			
 			
 				gl_Position = gMatViewProj * worldPos;
 				gl_Position = gMatViewProj * worldPos;
 				populateVertexOutput(intermediate);
 				populateVertexOutput(intermediate);

+ 3 - 3
Data/Raw/Engine/Includes/NormalVertexInput.bslinc

@@ -119,15 +119,15 @@ Technique =
 				tangentToLocal[2] = normal;
 				tangentToLocal[2] = normal;
 			}
 			}
 
 
-			void getVertexIntermediate(out VertexIntermediate result)
+			void getVertexWorldPosition(VertexIntermediate intermediate, out vec4 result)
 			{
 			{
 				float tangentSign;
 				float tangentSign;
 				mat3 tangentToLocal;
 				mat3 tangentToLocal;
 				getTangentToLocal(bs_normal, bs_tangent, tangentSign, tangentToLocal);
 				getTangentToLocal(bs_normal, bs_tangent, tangentSign, tangentToLocal);
 				
 				
 				mat3 tangentToWorld = mat3(gMatWorldNoScale) * tangentToLocal;
 				mat3 tangentToWorld = mat3(gMatWorldNoScale) * tangentToLocal;
-				result.worldNormal = intermediate.tangentToWorld[2]; // Normal basis vector
-				result.worldTangent = vec4(intermediate.tangentToWorld[0].xyz, intermediate.tangentSign); // Tangent basis vector
+				result.worldNormal = tangentToWorld[2]; // Normal basis vector
+				result.worldTangent = vec4(tangentToWorld[0].xyz, tangentSign); // Tangent basis vector
 			}
 			}
 			
 			
 			void getVertexWorldPosition(out vec4 result)
 			void getVertexWorldPosition(out vec4 result)

+ 88 - 25
Data/Raw/Engine/Includes/SkinnedVertexInput.bslinc

@@ -54,10 +54,10 @@ Technique =
 			
 			
 			float3x4 getBlendMatrix(VertexInput input)
 			float3x4 getBlendMatrix(VertexInput input)
 			{
 			{
-				float3x4 result = input.blendWeights.x * boneMatrices[input.blendIndices.x];
-				result += input.blendWeights.y * boneMatrices[input.blendIndices.y];
-				result += input.blendWeights.z * boneMatrices[input.blendIndices.z];
-				result += input.blendWeights.w * boneMatrices[input.blendIndices.w];
+				float3x4 result = input.blendWeights.x * getBoneMatrix(input.blendIndices.x);
+				result += input.blendWeights.y * getBoneMatrix(input.blendIndices.y);
+				result += input.blendWeights.z * getBoneMatrix(input.blendIndices.z);
+				result += input.blendWeights.w * getBoneMatrix(input.blendIndices.w);
 				
 				
 				return result;
 				return result;
 			}
 			}
@@ -66,15 +66,12 @@ Technique =
 			{
 			{
 				tangentSign = input.tangent.w;
 				tangentSign = input.tangent.w;
 			
 			
+				float3 normal = input.normal;
+				float3 tangent = input.tangent.xyz;
+				
 				#if USE_BLEND_SHAPES
 				#if USE_BLEND_SHAPES
-					float3 normal = input.normal;
-					float3 tangent = input.tangent.xyz;
-					
 					normal = normalize(normal + input.deltaNormal * input.deltaNormal.w);
 					normal = normalize(normal + input.deltaNormal * input.deltaNormal.w);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
-				#else
-					float3 normal = input.normal;
-					float3 tangent = input.tangent.xyz;
 				#endif
 				#endif
 				
 				
 				normal = mul(blendMatrix, float4(normal, 0.0f)).xyz;
 				normal = mul(blendMatrix, float4(normal, 0.0f)).xyz;
@@ -148,37 +145,103 @@ Technique =
 			in vec4 bs_tangent;
 			in vec4 bs_tangent;
 			in vec2 bs_texcoord0;
 			in vec2 bs_texcoord0;
 		
 		
+			in uvec4 bs_blendindices;
+			in vec4 bs_blendweights;
+				
+			#if USE_BLEND_SHAPES
+				in vec3 bs_position1;
+				in vec4 bs_normal1;
+			#endif
+			
+			uniform samplerBuffer boneMatrices;
+		
 			struct VertexIntermediate
 			struct VertexIntermediate
 			{
 			{
-				mat3 tangentToLocal;
-				mat3 tangentToWorld;
-				float tangentSign;
+				mat4x3 blendMatrix;
+			
+				vec3 worldNormal;
+				vec4 worldTangent;
 			};
 			};
 		
 		
 			out gl_PerVertex
 			out gl_PerVertex
 			{
 			{
 				vec4 gl_Position;
 				vec4 gl_Position;
 			};
 			};
-							
-			void getTangentToLocal(vec3 normal, vec4 tangent, out float tangentSign, out mat3 tangentToObject)
+			
+			void getBoneMatrix(uint idx, out mat4x3 result)
 			{
 			{
-				vec3 bitangent = cross(normal, tangent.xyz) * tangent.w;
-				tangentSign = tangent.w * gWorldDeterminantSign;
+				mat3x4 temp;
+			
+				temp[0] = texelFetch(boneMatrices, idx * 3 + 0);
+				temp[1] = texelFetch(boneMatrices, idx * 3 + 1);
+				temp[2] = texelFetch(boneMatrices, idx * 3 + 2);
 				
 				
-				tangentToObject[0] = tangent.xyz;
-				tangentToObject[1] = bitangent;
-				tangentToObject[2] = normal;
+				result = transpose(temp);				
 			}
 			}
-
+			
+			void getBlendMatrix(out mat4x3 result)
+			{
+				mat4x3 boneMatrix;
+				
+				getBoneMatrix(bs_blendindices.x, out boneMatrix);
+				result = bs_blendweights.x * boneMatrix;
+				
+				getBoneMatrix(bs_blendindices.y, out boneMatrix);
+				result += bs_blendweights.y * boneMatrix;
+				
+				getBoneMatrix(bs_blendindices.z, out boneMatrix);
+				result += bs_blendweights.z * boneMatrix;
+				
+				getBoneMatrix(bs_blendindices.w, out boneMatrix);
+				result += bs_blendweights.w * boneMatrix;
+			}
+			
+			void getSkinnedTangentToLocal(mat4x3 blendMatrix, out float tangentSign, out mat3x3 tangentToLocal)
+			{
+				tangentSign = bs_tangent.w;
+			
+				vec3 normal = bs_normal;
+				vec3 tangent = bs_tangent.xyz;
+				
+				#if USE_BLEND_SHAPES
+					normal = normalize(normal + bs_normal1 * bs_normal1.w);
+					tangent = normalize(tangent - dot(tangent, normal) * normal);
+				#endif
+				
+				normal = (blendMatrix * vec4(normal, 0.0f)).xyz;
+				tangent = (blendMatrix * vec4(tangent, 0.0f)).xyz;
+				
+				vec3 bitangent = cross(normal, tangent) * tangentSign;
+				tangentSign *= gWorldDeterminantSign;
+				
+				tangentToLocal[0] = tangent.xyz;
+				tangentToLocal[1] = bitangent;
+				tangentToLocal[2] = normal;
+			}			
+			
 			void getVertexIntermediate(out VertexIntermediate result)
 			void getVertexIntermediate(out VertexIntermediate result)
 			{
 			{
-				getTangentToLocal(bs_normal, bs_tangent, result.tangentSign, result.tangentToLocal);
-				result.tangentToWorld = mat3(gMatWorldNoScale) * result.tangentToLocal;
+				getBlendMatrix(result.blendMatrix);
+				
+				float tangentSign;
+				mat3 tangentToLocal;
+				getSkinnedTangentToLocal(tangentSign, tangentToLocal);
+				
+				mat3 tangentToWorld = mat3(gMatWorldNoScale) * tangentToLocal;
+				result.worldNormal = tangentToWorld[2]; // Normal basis vector
+				result.worldTangent = vec4(tangentToWorld[0].xyz, tangentSign); // Tangent basis vector				
 			}
 			}
 			
 			
-			void getVertexWorldPosition(out vec4 result)
+			void getVertexWorldPosition(VertexIntermediate intermediate, out vec4 result)
 			{
 			{
-				result = gMatWorld * vec4(bs_position, 1);
+				#if USE_BLEND_SHAPES
+					vec4 position = vec4(bs_position + bs_position1, 1.0f);
+				#else
+					vec4 position = vec4(bs_position, 1.0f);
+				#endif
+			
+				position = intermediate.blendMatrix * position;
+				result = gMatWorld * position;
 			}
 			}
 			
 			
 			void populateVertexOutput(VertexIntermediate intermediate)
 			void populateVertexOutput(VertexIntermediate intermediate)