Переглянути джерело

Refactor: Vertex input shaders are now handled in a much cleaner way
- Overriding Surface mixin is no longer necessary for custom child shaders
- All code unified under a single VertexInput mixin
- No need to define and tag separate techniques for each variation, in every shader that uses vertex inputs

BearishSun 8 роки тому
батько
коміт
12c294d9c1

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


+ 18 - 36
Data/Engine/ShaderDependencies.json

@@ -9,15 +9,6 @@
         {
             "Path": "BasePass.bslinc"
         },
-        {
-            "Path": "Surface.bslinc"
-        },
-        {
-            "Path": "SurfaceData.bslinc"
-        },
-        {
-            "Path": "NormalVertexInput.bslinc"
-        },
         {
             "Path": "PerCameraData.bslinc"
         },
@@ -25,7 +16,10 @@
             "Path": "PerObjectData.bslinc"
         },
         {
-            "Path": "SkinnedVertexInput.bslinc"
+            "Path": "VertexInput.bslinc"
+        },
+        {
+            "Path": "SurfaceData.bslinc"
         }
     ],
     "DeferredDirectionalLight.bsl": [
@@ -146,15 +140,6 @@
         {
             "Path": "BasePass.bslinc"
         },
-        {
-            "Path": "Surface.bslinc"
-        },
-        {
-            "Path": "SurfaceData.bslinc"
-        },
-        {
-            "Path": "NormalVertexInput.bslinc"
-        },
         {
             "Path": "PerCameraData.bslinc"
         },
@@ -162,7 +147,10 @@
             "Path": "PerObjectData.bslinc"
         },
         {
-            "Path": "SkinnedVertexInput.bslinc"
+            "Path": "VertexInput.bslinc"
+        },
+        {
+            "Path": "SurfaceData.bslinc"
         }
     ],
     "FlatFramebufferToTexture.bsl": null,
@@ -618,18 +606,6 @@
         }
     ],
     "Transparent.bsl": [
-        {
-            "Path": "BasePass.bslinc"
-        },
-        {
-            "Path": "LightGridCommon.bslinc"
-        },
-        {
-            "Path": "GBufferOutput.bslinc"
-        },
-        {
-            "Path": "Surface.bslinc"
-        },
         {
             "Path": "ImageBasedLighting.bslinc"
         },
@@ -640,19 +616,25 @@
             "Path": "LightingCommon.bslinc"
         },
         {
-            "Path": "NormalVertexInput.bslinc"
+            "Path": "SurfaceData.bslinc"
+        },
+        {
+            "Path": "BasePass.bslinc"
         },
         {
-            "Path": "SurfaceData.bslinc"
+            "Path": "LightGridCommon.bslinc"
         },
         {
             "Path": "PerCameraData.bslinc"
         },
         {
-            "Path": "SkinnedVertexInput.bslinc"
+            "Path": "PerObjectData.bslinc"
         },
         {
-            "Path": "PerObjectData.bslinc"
+            "Path": "VertexInput.bslinc"
+        },
+        {
+            "Path": "GBufferOutput.bslinc"
         }
     ]
 }

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


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


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


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


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


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


+ 0 - 12
Data/Raw/Engine/DataList.json

@@ -48,10 +48,6 @@
         }
     ],
     "Includes": [
-        {
-            "Path": "NormalVertexInput.bslinc",
-            "UUID": "967325e7-262b-49bf-8c90-032a8bbc8ce2"
-        },
         {
             "Path": "PerCameraData.bslinc",
             "UUID": "c1e4d309-8c20-4fd4-bf14-eb129af39d4e"
@@ -76,18 +72,10 @@
             "Path": "ReflectionCubemapCommon.bslinc",
             "UUID": "eef92578-b8ed-45d6-8eed-d85697ade3c5"
         },
-        {
-            "Path": "SkinnedVertexInput.bslinc",
-            "UUID": "d6a2ea27-5f4c-41ad-88bc-cad7dd7adc8d"
-        },
         {
             "Path": "SpriteImage.bslinc",
             "UUID": "0114b1da-9899-45ca-8486-a9791482d3c5"
         },
-        {
-            "Path": "Surface.bslinc",
-            "UUID": "468be285-026c-49d8-99ea-5f1709ea605a"
-        },
         {
             "Path": "VolumeRenderBase.bslinc",
             "UUID": "6d0dfe4e-45ef-4fe1-9344-33b8b9e69048"

+ 7 - 44
Data/Raw/Engine/Includes/BasePass.bslinc

@@ -1,16 +1,15 @@
 #include "$ENGINE$\GBufferOutput.bslinc"
 #include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\PerObjectData.bslinc"
+#include "$ENGINE$\VertexInput.bslinc"
 
-#include "$ENGINE$\SkinnedVertexInput.bslinc"
-#include "$ENGINE$\NormalVertexInput.bslinc"
-#define USE_BLEND_SHAPES
-#include "$ENGINE$\SkinnedVertexInput.bslinc"
-#include "$ENGINE$\NormalVertexInput.bslinc"
-#undef USE_BLEND_SHAPES
-
-mixin BasePassCommon
+mixin BasePass
 {
+	mixin GBufferOutput;
+	mixin PerCameraData;
+	mixin PerObjectData;
+	mixin VertexInput;
+
 	code
 	{			
 		VStoFS vsmain(VertexInput input)
@@ -39,40 +38,4 @@ mixin BasePassCommon
 			return normalize(mul(surfaceNormal, tangentToWorld));			
 		}
 	};
-};
-
-mixin BasePass
-{ 
-	mixin GBufferOutput;
-	mixin PerCameraData;
-	mixin PerObjectData;
-	mixin NormalVertexInput;
-	mixin BasePassCommon;
-};
-
-mixin BasePassSkinned
-{
-	mixin GBufferOutput;
-	mixin PerCameraData;
-	mixin PerObjectData;
-	mixin SkinnedVertexInput;
-	mixin BasePassCommon;
-};
-
-mixin BasePassMorph
-{
-	mixin GBufferOutput;
-	mixin PerCameraData;
-	mixin PerObjectData;
-	mixin MorphVertexInput;
-	mixin BasePassCommon;
-};
-
-mixin BasePassSkinnedMorph
-{
-	mixin GBufferOutput;
-	mixin PerCameraData;
-	mixin PerObjectData;
-	mixin SkinnedMorphVertexInput;
-	mixin BasePassCommon;
 };

+ 0 - 116
Data/Raw/Engine/Includes/NormalVertexInput.bslinc

@@ -1,116 +0,0 @@
-#ifdef USE_BLEND_SHAPES
-mixin MorphVertexInput
-#else
-mixin NormalVertexInput
-#endif
-{
-	code
-	{
-		struct VStoFS
-		{
-			float4 position : SV_Position;
-			float2 uv0 : TEXCOORD0;
-			float3 worldPosition : TEXCOORD1;
-			
-			float3 tangentToWorldZ : NORMAL; // Note: Half-precision could be used
-			float4 tangentToWorldX : TANGENT; // Note: Half-precision could be used
-		};
-
-		struct VertexInput
-		{
-			float3 position : POSITION;
-			float3 normal : NORMAL; // Note: Half-precision could be used
-			float4 tangent : TANGENT; // Note: Half-precision could be used
-			float2 uv0 : TEXCOORD0;
-			
-			#ifdef USE_BLEND_SHAPES
-				float3 deltaPosition : POSITION1;
-				float4 deltaNormal : NORMAL1;
-			#endif				
-		};
-		
-		// Vertex input containing only position data
-		struct VertexInput_PO
-		{
-			float3 position : POSITION;
-			
-			#ifdef USE_BLEND_SHAPES
-				float3 deltaPosition : POSITION1;
-			#endif	
-		};			
-		
-		struct VertexIntermediate
-		{
-			float3 worldNormal; // Note: Half-precision could be used
-			float4 worldTangent; // Note: Half-precision could be used
-			
-			float tangentSign;
-		};
-		
-		float3x3 getTangentToLocal(VertexInput input, out float tangentSign)
-		{
-			float3 normal = input.normal * 2.0f - 1.0f;
-			float3 tangent = input.tangent.xyz * 2.0f - 1.0f;
-			
-			#ifdef USE_BLEND_SHAPES
-				float3 deltaNormal = (input.deltaNormal.xyz * 2.0f - 1.0f) * 2.0f;
-				normal = normalize(normal + deltaNormal * input.deltaNormal.w);
-				tangent = normalize(tangent - dot(tangent, normal) * normal);
-			#endif
-			
-			float3 bitangent = cross(normal, tangent) * input.tangent.w;
-			tangentSign = input.tangent.w * gWorldDeterminantSign;
-			
-			// Note: Maybe it's better to store everything in row vector format?
-			float3x3 result = float3x3(tangent, bitangent, normal);
-			result = transpose(result);
-											
-			return result;
-		}
-		
-		VertexIntermediate getVertexIntermediate(VertexInput input)
-		{
-			VertexIntermediate result;
-			
-			float tangentSign;
-			float3x3 tangentToLocal = getTangentToLocal(input, tangentSign);
-			float3x3 tangentToWorld = mul((float3x3)gMatWorldNoScale, tangentToLocal);
-			
-			// Note: Consider transposing these externally, for easier reads
-			result.worldNormal = float3(tangentToWorld[0][2], tangentToWorld[1][2], tangentToWorld[2][2]); // Normal basis vector
-			result.worldTangent = float4(tangentToWorld[0][0], tangentToWorld[1][0], tangentToWorld[2][0], tangentSign); // Tangent basis vector
-			
-			return result;
-		}
-		
-		float4 getVertexWorldPosition(VertexInput input, VertexIntermediate intermediate)
-		{
-			#ifdef USE_BLEND_SHAPES
-				float4 position = float4(input.position + input.deltaPosition, 1.0f);
-			#else
-				float4 position = float4(input.position, 1.0f);
-			#endif			
-		
-			return mul(gMatWorld, position);
-		}
-		
-		float4 getVertexWorldPosition(VertexInput_PO input)
-		{
-			#ifdef USE_BLEND_SHAPES
-				float4 position = float4(input.position + input.deltaPosition, 1.0f);
-			#else
-				float4 position = float4(input.position, 1.0f);
-			#endif			
-		
-			return mul(gMatWorld, position);
-		}		
-		
-		void populateVertexOutput(VertexInput input, VertexIntermediate intermediate, inout VStoFS result)
-		{
-			result.uv0 = input.uv0;
-			
-			result.tangentToWorldZ = intermediate.worldNormal;
-			result.tangentToWorldX = intermediate.worldTangent;
-		}
-	};
-};

+ 0 - 150
Data/Raw/Engine/Includes/SkinnedVertexInput.bslinc

@@ -1,150 +0,0 @@
-#ifdef USE_BLEND_SHAPES
-mixin SkinnedMorphVertexInput
-#else
-mixin SkinnedVertexInput
-#endif
-{
-	code
-	{
-		struct VStoFS
-		{
-			float4 position : SV_Position;
-			float2 uv0 : TEXCOORD0;
-			float3 worldPosition : TEXCOORD1;
-			
-			float3 tangentToWorldZ : NORMAL; // Note: Half-precision could be used
-			float4 tangentToWorldX : TANGENT; // Note: Half-precision could be used
-		};
-
-		Buffer<float4> boneMatrices;
-	
-		struct VertexInput
-		{
-			float3 position : POSITION;
-			float3 normal : NORMAL; // Note: Half-precision could be used
-			float4 tangent : TANGENT; // Note: Half-precision could be used
-			float2 uv0 : TEXCOORD0;
-			uint4 blendIndices : BLENDINDICES;
-			float4 blendWeights : BLENDWEIGHT;
-			
-			#ifdef USE_BLEND_SHAPES
-				float3 deltaPosition : POSITION1;
-				float4 deltaNormal : NORMAL1;
-			#endif
-		};
-		
-		// Vertex input containing only position data
-		struct VertexInput_PO
-		{
-			float3 position : POSITION;
-			uint4 blendIndices : BLENDINDICES;
-			float4 blendWeights : BLENDWEIGHT;
-			
-			#ifdef USE_BLEND_SHAPES
-				float3 deltaPosition : POSITION1;
-			#endif
-		};		
-		
-		struct VertexIntermediate
-		{
-			float3x4 blendMatrix;
-		
-			float3 worldNormal; // Note: Half-precision could be used
-			float4 worldTangent; // Note: Half-precision could be used
-		};
-		
-		float3x4 getBoneMatrix(uint idx)
-		{
-			float4 row0 = boneMatrices[idx * 3 + 0];
-			float4 row1 = boneMatrices[idx * 3 + 1];
-			float4 row2 = boneMatrices[idx * 3 + 2];
-			
-			return float3x4(row0, row1, row2);
-		}
-		
-		float3x4 getBlendMatrix(float4 blendWeights, uint4 blendIndices)
-		{
-			float3x4 result = blendWeights.x * getBoneMatrix(blendIndices.x);
-			result += blendWeights.y * getBoneMatrix(blendIndices.y);
-			result += blendWeights.z * getBoneMatrix(blendIndices.z);
-			result += blendWeights.w * getBoneMatrix(blendIndices.w);
-			
-			return result;
-		}
-		
-		float3x3 getSkinnedTangentToLocal(VertexInput input, float3x4 blendMatrix, out float tangentSign)
-		{
-			tangentSign = input.tangent.w * 2.0f - 1.0f;
-		
-			float3 normal = input.normal * 2.0f - 1.0f;
-			float3 tangent = input.tangent.xyz * 2.0f - 1.0f;
-
-			#ifdef USE_BLEND_SHAPES
-				float3 deltaNormal = (input.deltaNormal.xyz * 2.0f - 1.0f) * 2.0f;
-				normal = normalize(normal + deltaNormal * input.deltaNormal.w);
-				tangent = normalize(tangent - dot(tangent, normal) * normal);
-			#endif
-			
-			normal = mul(blendMatrix, float4(normal, 0.0f)).xyz;
-			tangent = mul(blendMatrix, float4(tangent, 0.0f)).xyz;
-			
-			float3 bitangent = cross(normal, tangent) * tangentSign;
-			tangentSign *= gWorldDeterminantSign;
-			
-			float3x3 result = float3x3(tangent, bitangent, normal);
-			result = transpose(result);
-											
-			return result;
-		}
-		
-		VertexIntermediate getVertexIntermediate(VertexInput input)
-		{
-			VertexIntermediate result;
-			
-			result.blendMatrix = getBlendMatrix(input.blendWeights, input.blendIndices);
-			
-			float tangentSign;
-			float3x3 tangentToLocal = getSkinnedTangentToLocal(input, result.blendMatrix, tangentSign);
-			float3x3 tangentToWorld = mul((float3x3)gMatWorldNoScale, tangentToLocal);
-
-			// Note: Consider transposing these externally, for easier reads
-			result.worldNormal = float3(tangentToWorld[0][2], tangentToWorld[1][2], tangentToWorld[2][2]); // Normal basis vector
-			result.worldTangent = float4(tangentToWorld[0][0], tangentToWorld[1][0], tangentToWorld[2][0], tangentSign); // Tangent basis vector
-			
-			return result;
-		}
-		
-		float4 getVertexWorldPosition(VertexInput input, VertexIntermediate intermediate)
-		{
-			#ifdef USE_BLEND_SHAPES
-				float4 position = float4(input.position + input.deltaPosition, 1.0f);
-			#else
-				float4 position = float4(input.position, 1.0f);
-			#endif
-		
-			position = float4(mul(intermediate.blendMatrix, position), 1.0f);
-			return mul(gMatWorld, position);
-		}
-		
-		float4 getVertexWorldPosition(VertexInput_PO input)
-		{
-			#ifdef USE_BLEND_SHAPES
-				float4 position = float4(input.position + input.deltaPosition, 1.0f);
-			#else
-				float4 position = float4(input.position, 1.0f);
-			#endif
-		
-			float3x4 blendMatrix = getBlendMatrix(input.blendWeights, input.blendIndices);
-			position = float4(mul(blendMatrix, position), 1.0f);
-			return mul(gMatWorld, position);
-		}		
-		
-		void populateVertexOutput(VertexInput input, VertexIntermediate intermediate, inout VStoFS result)
-		{
-			result.uv0 = input.uv0;
-			
-			result.tangentToWorldZ = intermediate.worldNormal;
-			result.tangentToWorldX = intermediate.worldTangent;
-		}
-	};
-};

+ 0 - 29
Data/Raw/Engine/Includes/Surface.bslinc

@@ -1,29 +0,0 @@
-technique Surface1
-{
-	mixin BasePass;
-	mixin Surface;
-};
-
-technique Surface2
-{
-	mixin BasePassSkinned;
-	mixin Surface;
-
-	tags = { "Skinned" };
-};
-
-technique Surface3
-{
-	mixin BasePassMorph;
-	mixin Surface;
-
-	tags = { "Morph" };
-};
-
-technique Surface4
-{
-	mixin BasePassSkinnedMorph;
-	mixin Surface;
-
-	tags = { "SkinnedMorph" };
-};

+ 3 - 2
Data/Raw/Engine/Shaders/Default.bsl

@@ -1,8 +1,9 @@
 #include "$ENGINE$\BasePass.bslinc"
-#include "$ENGINE$\Surface.bslinc"
 
-mixin Surface
+technique Surface
 {
+	mixin BasePass;
+
 	code
 	{
 		void fsmain(

+ 3 - 2
Data/Raw/Engine/Shaders/Diffuse.bsl

@@ -1,8 +1,9 @@
 #include "$ENGINE$\BasePass.bslinc"
-#include "$ENGINE$\Surface.bslinc"
 
-mixin Surface
+technique Surface
 {
+	mixin BasePass;
+
 	code
 	{
 		SamplerState gAlbedoSamp;

+ 2 - 2
Data/Raw/Engine/Shaders/Transparent.bsl

@@ -4,15 +4,15 @@
 #define USE_LIGHT_GRID_INDICES 1
 #include "$ENGINE$\LightingCommon.bslinc"
 #include "$ENGINE$\ImageBasedLighting.bslinc"
-#include "$ENGINE$\Surface.bslinc"
 
 options
 {
 	transparent = true;
 };
 
-mixin Surface
+technique Surface
 {
+	mixin BasePass;
 	mixin LightingCommon;
 	mixin LightGridCommon;
 	mixin ReflectionCubemapCommon;

+ 1 - 3
Source/RenderBeast/BsRendererScene.cpp

@@ -259,7 +259,6 @@ namespace bs {	namespace ct
 					renElement.material = Material::create(DefaultMaterial::get()->getShader());
 
 				// Determine which technique to use
-				static StringID techniqueIDLookup[4] = { StringID::NONE, RTag_Skinned, RTag_Morph, RTag_SkinnedMorph };
 				static const ShaderVariation* variationLookup[4] = { &SVar_Static, &SVar_Skinned, &SVar_Morph, &SVar_SkinnedMorph };
 				static_assert((UINT32)RenderableAnimType::Count == 4, "RenderableAnimType is expected to have four sequential entries.");
 
@@ -267,8 +266,7 @@ namespace bs {	namespace ct
 				RenderableAnimType animType = renderable->getAnimType();
 				renElement.vertexInputVariation = variationLookup[(int)animType];
 
-				if (animType != RenderableAnimType::None)
-					techniqueIdx = renElement.material->findTechnique(techniqueIDLookup[(int)animType]);
+				techniqueIdx = renElement.material->findTechnique(*renElement.vertexInputVariation);
 
 				if (techniqueIdx == (UINT32)-1)
 					techniqueIdx = renElement.material->getDefaultTechnique();