From 300f948515d487266e6bd7c74429f01cce5c0b4b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 5 Feb 2021 13:57:00 +0100 Subject: [PATCH] Refactor material shaders generator to use modular features as extensions --- ...{SurfaceDeferred.shader => Surface.shader} | 55 +- .../MaterialTemplates/SurfaceForward.shader | 568 ------------------ .../Materials/DeferredMaterialShader.cpp | 2 +- .../Materials/ForwardMaterialShader.cpp | 3 +- .../MaterialGenerator/MaterialGenerator.cpp | 8 +- 5 files changed, 45 insertions(+), 591 deletions(-) rename Content/Editor/MaterialTemplates/{SurfaceDeferred.shader => Surface.shader} (94%) delete mode 100644 Content/Editor/MaterialTemplates/SurfaceForward.shader diff --git a/Content/Editor/MaterialTemplates/SurfaceDeferred.shader b/Content/Editor/MaterialTemplates/Surface.shader similarity index 94% rename from Content/Editor/MaterialTemplates/SurfaceDeferred.shader rename to Content/Editor/MaterialTemplates/Surface.shader index 17f88e179..8c09e7611 100644 --- a/Content/Editor/MaterialTemplates/SurfaceDeferred.shader +++ b/Content/Editor/MaterialTemplates/Surface.shader @@ -229,28 +229,38 @@ MaterialInput GetMaterialInput(PixelInput input) return result; } -#if USE_INSTANCING -#define INSTANCE_TRANS_WORLD float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)) -#else -#define INSTANCE_TRANS_WORLD WorldMatrix -#endif - // Gets the local to world transform matrix (supports instancing) float4x4 GetInstanceTransform(ModelInput input) { - return INSTANCE_TRANS_WORLD; +#if USE_INSTANCING + return float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)); +#else + return WorldMatrix; +#endif } float4x4 GetInstanceTransform(ModelInput_Skinned input) { - return INSTANCE_TRANS_WORLD; +#if USE_INSTANCING + return float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)); +#else + return WorldMatrix; +#endif } float4x4 GetInstanceTransform(ModelInput_PosOnly input) { - return INSTANCE_TRANS_WORLD; +#if USE_INSTANCING + return float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)); +#else + return WorldMatrix; +#endif } float4x4 GetInstanceTransform(MaterialInput input) { - return INSTANCE_TRANS_WORLD; +#if USE_INSTANCING + return float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)); +#else + return WorldMatrix; +#endif } // Removes the scale vector from the local to world transformation matrix (supports instancing) @@ -390,7 +400,7 @@ float3x3 CalcTangentToWorld(float4x4 world, float3x3 tangentToLocal) } // Vertex Shader function for GBuffer Pass and Depth Pass (with full vertex data) -META_VS(IS_SURFACE, FEATURE_LEVEL_ES2) +META_VS(true, FEATURE_LEVEL_ES2) META_PERMUTATION_1(USE_INSTANCING=0) META_PERMUTATION_1(USE_INSTANCING=1) META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true) @@ -426,7 +436,11 @@ VertexOutput VS(ModelInput input) output.Geometry.LightmapUV = input.LightmapUV * input.InstanceLightmapArea.zw + input.InstanceLightmapArea.xy; output.Geometry.InstanceParams = float2(input.InstanceOrigin.w, input.InstanceTransform1.w); #else +#if USE_LIGHTMAP output.Geometry.LightmapUV = input.LightmapUV * LightmapArea.zw + LightmapArea.xy; +#else + output.Geometry.LightmapUV = input.LightmapUV; +#endif output.Geometry.InstanceParams = float2(PerInstanceRandom, LODDitherFactor); #endif @@ -463,7 +477,7 @@ VertexOutput VS(ModelInput input) } // Vertex Shader function for Depth Pass -META_VS(IS_SURFACE, FEATURE_LEVEL_ES2) +META_VS(true, FEATURE_LEVEL_ES2) META_PERMUTATION_1(USE_INSTANCING=0) META_PERMUTATION_1(USE_INSTANCING=1) META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true) @@ -559,7 +573,7 @@ float3x3 SkinTangents(ModelInput_Skinned input, SkinningData data) } // Vertex Shader function for GBuffers/Depth Pass (skinned mesh rendering) -META_VS(IS_SURFACE, FEATURE_LEVEL_ES2) +META_VS(true, FEATURE_LEVEL_ES2) META_PERMUTATION_1(USE_SKINNING=1) META_PERMUTATION_2(USE_SKINNING=1, PER_BONE_MOTION_BLUR=1) META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true) @@ -654,7 +668,7 @@ void ClipLODTransition(PixelInput input) #endif // Pixel Shader function for Depth Pass -META_PS(IS_SURFACE, FEATURE_LEVEL_ES2) +META_PS(true, FEATURE_LEVEL_ES2) void PS_Depth(PixelInput input #if GLSL , out float4 OutColor : SV_Target0 @@ -666,12 +680,19 @@ void PS_Depth(PixelInput input ClipLODTransition(input); #endif -#if MATERIAL_MASKED - // Perform per pixel clipping if material requries it +#if MATERIAL_MASKED || MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE + // Get material parameters MaterialInput materialInput = GetMaterialInput(input); Material material = GetMaterialPS(materialInput); + + // Perform per pixel clipping +#if MATERIAL_MASKED clip(material.Mask - MATERIAL_MASK_THRESHOLD); #endif +#if MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE + clip(material.Opacity - MATERIAL_OPACITY_THRESHOLD); +#endif +#endif #if GLSL OutColor = 0; @@ -679,7 +700,7 @@ void PS_Depth(PixelInput input } // Pixel Shader function for Motion Vectors Pass -META_PS(true, FEATURE_LEVEL_ES2) +META_PS(USE_DEFERRED, FEATURE_LEVEL_ES2) float4 PS_MotionVectors(PixelInput input) : SV_Target0 { #if USE_DITHERED_LOD_TRANSITION diff --git a/Content/Editor/MaterialTemplates/SurfaceForward.shader b/Content/Editor/MaterialTemplates/SurfaceForward.shader deleted file mode 100644 index e7a86fb81..000000000 --- a/Content/Editor/MaterialTemplates/SurfaceForward.shader +++ /dev/null @@ -1,568 +0,0 @@ -// File generated by Flax Materials Editor -// Version: @0 - -#define MATERIAL 1 -@3 -#include "./Flax/Common.hlsl" -#include "./Flax/MaterialCommon.hlsl" -#include "./Flax/GBufferCommon.hlsl" -@7 -// Primary constant buffer (with additional material parameters) -META_CB_BEGIN(0, Data) -float4x4 ViewProjectionMatrix; -float4x4 WorldMatrix; -float4x4 ViewMatrix; -float4x4 PrevViewProjectionMatrix; -float4x4 PrevWorldMatrix; -float3 ViewPos; -float ViewFar; -float3 ViewDir; -float TimeParam; -float4 ViewInfo; -float4 ScreenSize; -float3 WorldInvScale; -float WorldDeterminantSign; -float2 Dummy0; -float LODDitherFactor; -float PerInstanceRandom; -float3 GeometrySize; -float Dummy1; -@1META_CB_END - -// Shader resources -@2 -// Interpolants passed from the vertex shader -struct VertexOutput -{ - float4 Position : SV_Position; - float3 WorldPosition : TEXCOORD0; - float2 TexCoord : TEXCOORD1; - float2 LightmapUV : TEXCOORD2; -#if USE_VERTEX_COLOR - half4 VertexColor : COLOR; -#endif - float3x3 TBN : TEXCOORD3; -#if USE_CUSTOM_VERTEX_INTERPOLATORS - float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9; -#endif - float3 InstanceOrigin : TEXCOORD6; - float2 InstanceParams : TEXCOORD7; // x-PerInstanceRandom, y-LODDitherFactor -#if USE_TESSELLATION - float TessellationMultiplier : TESS; -#endif -}; - -// Interpolants passed to the pixel shader -struct PixelInput -{ - float4 Position : SV_Position; - float3 WorldPosition : TEXCOORD0; - float2 TexCoord : TEXCOORD1; - float2 LightmapUV : TEXCOORD2; -#if USE_VERTEX_COLOR - half4 VertexColor : COLOR; -#endif - float3x3 TBN : TEXCOORD3; -#if USE_CUSTOM_VERTEX_INTERPOLATORS - float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9; -#endif - float3 InstanceOrigin : TEXCOORD6; - float2 InstanceParams : TEXCOORD7; // x-PerInstanceRandom, y-LODDitherFactor - bool IsFrontFace : SV_IsFrontFace; -}; - -// Material properties generation input -struct MaterialInput -{ - float3 WorldPosition; - float TwoSidedSign; - float2 TexCoord; -#if USE_LIGHTMAP - float2 LightmapUV; -#endif -#if USE_VERTEX_COLOR - half4 VertexColor; -#endif - float3x3 TBN; - float4 SvPosition; - float3 PreSkinnedPosition; - float3 PreSkinnedNormal; - float3 InstanceOrigin; - float2 InstanceParams; -#if USE_INSTANCING - float3 InstanceTransform1; - float3 InstanceTransform2; - float3 InstanceTransform3; -#endif -#if USE_CUSTOM_VERTEX_INTERPOLATORS - float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT]; -#endif -}; - -MaterialInput GetMaterialInput(ModelInput input, VertexOutput output, float3 localNormal) -{ - MaterialInput result = (MaterialInput)0; - result.WorldPosition = output.WorldPosition; - result.TexCoord = output.TexCoord; -#if USE_LIGHTMAP - result.LightmapUV = output.LightmapUV; -#endif -#if USE_VERTEX_COLOR - result.VertexColor = output.VertexColor; -#endif - result.TBN = output.TBN; - result.TwoSidedSign = WorldDeterminantSign; - result.SvPosition = output.Position; - result.PreSkinnedPosition = input.Position.xyz; - result.PreSkinnedNormal = localNormal; -#if USE_INSTANCING - result.InstanceOrigin = input.InstanceOrigin.xyz; - result.InstanceParams = float2(input.InstanceOrigin.w, input.InstanceTransform1.w); - result.InstanceTransform1 = input.InstanceTransform1.xyz; - result.InstanceTransform2 = input.InstanceTransform2.xyz; - result.InstanceTransform3 = input.InstanceTransform3.xyz; -#else - result.InstanceOrigin = WorldMatrix[3].xyz; - result.InstanceParams = float2(PerInstanceRandom, LODDitherFactor); -#endif - return result; -} - -MaterialInput GetMaterialInput(VertexOutput output, float3 localPosition, float3 localNormal) -{ - MaterialInput result = (MaterialInput)0; - result.WorldPosition = output.WorldPosition; - result.TexCoord = output.TexCoord; -#if USE_LIGHTMAP - result.LightmapUV = output.LightmapUV; -#endif -#if USE_VERTEX_COLOR - result.VertexColor = output.VertexColor; -#endif - result.TBN = output.TBN; - result.TwoSidedSign = WorldDeterminantSign; - result.InstanceOrigin = WorldMatrix[3].xyz; - result.InstanceParams = float2(PerInstanceRandom, LODDitherFactor); - result.SvPosition = output.Position; - result.PreSkinnedPosition = localPosition; - result.PreSkinnedNormal = localNormal; - return result; -} - -MaterialInput GetMaterialInput(PixelInput input) -{ - MaterialInput result = (MaterialInput)0; - result.WorldPosition = input.WorldPosition; - result.TexCoord = input.TexCoord; -#if USE_LIGHTMAP - result.LightmapUV = input.LightmapUV; -#endif -#if USE_VERTEX_COLOR - result.VertexColor = input.VertexColor; -#endif - result.TBN = input.TBN; - result.TwoSidedSign = WorldDeterminantSign * (input.IsFrontFace ? 1.0 : -1.0); - result.InstanceOrigin = input.InstanceOrigin; - result.InstanceParams = input.InstanceParams; - result.SvPosition = input.Position; -#if USE_CUSTOM_VERTEX_INTERPOLATORS - result.CustomVSToPS = input.CustomVSToPS; -#endif - return result; -} - -#if USE_INSTANCING -#define INSTANCE_TRANS_WORLD float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)) -#else -#define INSTANCE_TRANS_WORLD WorldMatrix -#endif - -// Gets the local to world transform matrix (supports instancing) -float4x4 GetInstanceTransform(ModelInput input) -{ - return INSTANCE_TRANS_WORLD; -} -float4x4 GetInstanceTransform(ModelInput_Skinned input) -{ - return INSTANCE_TRANS_WORLD; -} -float4x4 GetInstanceTransform(MaterialInput input) -{ - return INSTANCE_TRANS_WORLD; -} - -// Removes the scale vector from the local to world transformation matrix (supports instancing) -float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld) -{ -#if USE_INSTANCING - // Extract per axis scales from localToWorld transform - float scaleX = length(localToWorld[0]); - float scaleY = length(localToWorld[1]); - float scaleZ = length(localToWorld[2]); - float3 invScale = float3( - scaleX > 0.00001f ? 1.0f / scaleX : 0.0f, - scaleY > 0.00001f ? 1.0f / scaleY : 0.0f, - scaleZ > 0.00001f ? 1.0f / scaleZ : 0.0f); -#else - float3 invScale = WorldInvScale; -#endif - localToWorld[0] *= invScale.x; - localToWorld[1] *= invScale.y; - localToWorld[2] *= invScale.z; - return localToWorld; -} - -// Transforms a vector from tangent space to world space -float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector) -{ - return mul(tangentVector, input.TBN); -} - -// Transforms a vector from world space to tangent space -float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector) -{ - return mul(input.TBN, worldVector); -} - -// Transforms a vector from world space to view space -float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector) -{ - return mul(worldVector, (float3x3)ViewMatrix); -} - -// Transforms a vector from view space to world space -float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector) -{ - return mul((float3x3)ViewMatrix, viewVector); -} - -// Transforms a vector from local space to world space -float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector) -{ - float3x3 localToWorld = (float3x3)GetInstanceTransform(input); - //localToWorld = RemoveScaleFromLocalToWorld(localToWorld); - return mul(localVector, localToWorld); -} - -// Transforms a vector from local space to world space -float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector) -{ - float3x3 localToWorld = (float3x3)GetInstanceTransform(input); - //localToWorld = RemoveScaleFromLocalToWorld(localToWorld); - return mul(localToWorld, worldVector); -} - -// Gets the current object position (supports instancing) -float3 GetObjectPosition(MaterialInput input) -{ - return input.InstanceOrigin.xyz; -} - -// Gets the current object size (supports instancing) -float3 GetObjectSize(MaterialInput input) -{ - float4x4 world = GetInstanceTransform(input); - return GeometrySize * float3(world._m00, world._m11, world._m22); -} - -// Get the current object random value (supports instancing) -float GetPerInstanceRandom(MaterialInput input) -{ - return input.InstanceParams.x; -} - -// Get the current object LOD transition dither factor (supports instancing) -float GetLODDitherFactor(MaterialInput input) -{ -#if USE_DITHERED_LOD_TRANSITION - return input.InstanceParams.y; -#else - return 0; -#endif -} - -// Gets the interpolated vertex color (in linear space) -float4 GetVertexColor(MaterialInput input) -{ -#if USE_VERTEX_COLOR - return input.VertexColor; -#else - return 1; -#endif -} - -@8 - -// Get material properties function (for vertex shader) -Material GetMaterialVS(MaterialInput input) -{ -@5 -} - -// Get material properties function (for domain shader) -Material GetMaterialDS(MaterialInput input) -{ -@6 -} - -// Get material properties function (for pixel shader) -Material GetMaterialPS(MaterialInput input) -{ -@4 -} - -// Calculates the transform matrix from mesh tangent space to local space -half3x3 CalcTangentToLocal(ModelInput input) -{ - float bitangentSign = input.Tangent.w ? -1.0f : +1.0f; - float3 normal = input.Normal.xyz * 2.0 - 1.0; - float3 tangent = input.Tangent.xyz * 2.0 - 1.0; - float3 bitangent = cross(normal, tangent) * bitangentSign; - return float3x3(tangent, bitangent, normal); -} - -half3x3 CalcTangentToWorld(in float4x4 world, in half3x3 tangentToLocal) -{ - half3x3 localToWorld = RemoveScaleFromLocalToWorld((float3x3)world); - return mul(tangentToLocal, localToWorld); -} - -// Vertex Shader function for Forward/Depth Pass -META_VS(IS_SURFACE, FEATURE_LEVEL_ES2) -META_PERMUTATION_1(USE_INSTANCING=0) -META_PERMUTATION_1(USE_INSTANCING=1) -META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 1, 0, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(NORMAL, 0, R10G10B10A2_UNORM, 1, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(TANGENT, 0, R10G10B10A2_UNORM, 1, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(TEXCOORD, 1, R16G16_FLOAT, 1, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(COLOR, 0, R8G8B8A8_UNORM, 2, 0, PER_VERTEX, 0, USE_VERTEX_COLOR) -META_VS_IN_ELEMENT(ATTRIBUTE,0, R32G32B32A32_FLOAT,3, 0, PER_INSTANCE, 1, USE_INSTANCING) -META_VS_IN_ELEMENT(ATTRIBUTE,1, R32G32B32A32_FLOAT,3, ALIGN, PER_INSTANCE, 1, USE_INSTANCING) -META_VS_IN_ELEMENT(ATTRIBUTE,2, R32G32B32_FLOAT, 3, ALIGN, PER_INSTANCE, 1, USE_INSTANCING) -META_VS_IN_ELEMENT(ATTRIBUTE,3, R32G32B32_FLOAT, 3, ALIGN, PER_INSTANCE, 1, USE_INSTANCING) -META_VS_IN_ELEMENT(ATTRIBUTE,4, R16G16B16A16_FLOAT,3, ALIGN, PER_INSTANCE, 1, USE_INSTANCING) -VertexOutput VS(ModelInput input) -{ - VertexOutput output; - - // Compute world space vertex position - float4x4 world = GetInstanceTransform(input); - output.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz; - - // Compute clip space position - output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); - - // Pass vertex attributes - output.TexCoord = input.TexCoord; -#if USE_VERTEX_COLOR - output.VertexColor = input.Color; -#endif - output.LightmapUV = input.LightmapUV; -#if USE_INSTANCING - output.InstanceOrigin = world[3].xyz; - output.InstanceParams = float2(input.InstanceOrigin.w, input.InstanceTransform1.w); -#else - output.InstanceOrigin = WorldMatrix[3].xyz; - output.InstanceParams = float2(PerInstanceRandom, LODDitherFactor); -#endif - - // Calculate tanget space to world space transformation matrix for unit vectors - half3x3 tangentToLocal = CalcTangentToLocal(input); - half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal); - output.TBN = tangentToWorld; - - // Get material input params if need to evaluate any material property -#if USE_POSITION_OFFSET || USE_TESSELLATION || USE_CUSTOM_VERTEX_INTERPOLATORS - MaterialInput materialInput = GetMaterialInput(input, output, tangentToLocal[2].xyz); - Material material = GetMaterialVS(materialInput); -#endif - - // Apply world position offset per-vertex -#if USE_POSITION_OFFSET - output.WorldPosition += material.PositionOffset; - output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); -#endif - - // Get tessalation multiplier (per vertex) -#if USE_TESSELLATION - output.TessellationMultiplier = material.TessellationMultiplier; -#endif - - // Copy interpolants for other shader stages -#if USE_CUSTOM_VERTEX_INTERPOLATORS - output.CustomVSToPS = material.CustomVSToPS; -#endif - - return output; -} - -#if USE_SKINNING - -// The skeletal bones matrix buffer (stored as 4x3, 3 float4 behind each other) -Buffer BoneMatrices : register(t0); - -// Cached skinning data to avoid multiple calculation -struct SkinningData -{ - float3x4 BlendMatrix; -}; - -// Calculates the transposed transform matrix for the given bone index -float3x4 GetBoneMatrix(int index) -{ - float4 a = BoneMatrices[index * 3]; - float4 b = BoneMatrices[index * 3 + 1]; - float4 c = BoneMatrices[index * 3 + 2]; - return float3x4(a, b, c); -} - -// Calculates the transposed transform matrix for the given vertex (uses blending) -float3x4 GetBoneMatrix(ModelInput_Skinned input) -{ - float3x4 boneMatrix = input.BlendWeights.x * GetBoneMatrix(input.BlendIndices.x); - boneMatrix += input.BlendWeights.y * GetBoneMatrix(input.BlendIndices.y); - boneMatrix += input.BlendWeights.z * GetBoneMatrix(input.BlendIndices.z); - boneMatrix += input.BlendWeights.w * GetBoneMatrix(input.BlendIndices.w); - return boneMatrix; -} - -// Transforms the vertex position by weighted sum of the skinning matrices -float3 SkinPosition(ModelInput_Skinned input, SkinningData data) -{ - float4 position = float4(input.Position.xyz, 1); - return mul(data.BlendMatrix, position); -} - -// Transforms the vertex position by weighted sum of the skinning matrices -half3x3 SkinTangents(ModelInput_Skinned input, SkinningData data) -{ - // Unpack vertex tangent frame - float bitangentSign = input.Tangent.w ? -1.0f : +1.0f; - float3 normal = input.Normal.xyz * 2.0 - 1.0; - float3 tangent = input.Tangent.xyz * 2.0 - 1.0; - - // Apply skinning - tangent = mul(data.BlendMatrix, float4(tangent, 0)); - normal = mul(data.BlendMatrix, float4(normal, 0)); - - float3 bitangent = cross(normal, tangent) * bitangentSign; - return half3x3(tangent, bitangent, normal); -} - -// Vertex Shader function for Forward/Depth Pass (skinned mesh rendering) -META_VS(IS_SURFACE, FEATURE_LEVEL_ES2) -META_PERMUTATION_1(USE_SKINNING=1) -META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 0, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(NORMAL, 0, R10G10B10A2_UNORM, 0, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(TANGENT, 0, R10G10B10A2_UNORM, 0, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(BLENDINDICES, 0, R8G8B8A8_UINT, 0, ALIGN, PER_VERTEX, 0, true) -META_VS_IN_ELEMENT(BLENDWEIGHT, 0, R16G16B16A16_FLOAT,0, ALIGN, PER_VERTEX, 0, true) -VertexOutput VS_Skinned(ModelInput_Skinned input) -{ - VertexOutput output; - - // Perform skinning - SkinningData data; - data.BlendMatrix = GetBoneMatrix(input); - float3 position = SkinPosition(input, data); - half3x3 tangentToLocal = SkinTangents(input, data); - - // Compute world space vertex position - float4x4 world = GetInstanceTransform(input); - output.WorldPosition = mul(float4(position, 1), world).xyz; - - // Compute clip space position - output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); - - // Pass vertex attributes - output.TexCoord = input.TexCoord; -#if USE_VERTEX_COLOR - output.VertexColor = float4(0, 0, 0, 1); -#endif - output.LightmapUV = float2(0, 0); -#if USE_INSTANCING - output.InstanceOrigin = world[3].xyz; - output.InstanceParams = float2(input.InstanceOrigin.w, input.InstanceTransform1.w); -#else - output.InstanceOrigin = WorldMatrix[3].xyz; - output.InstanceParams = float2(PerInstanceRandom, LODDitherFactor); -#endif - - // Calculate tanget space to world space transformation matrix for unit vectors - half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal); - output.TBN = tangentToWorld; - - // Get material input params if need to evaluate any material property -#if USE_POSITION_OFFSET || USE_TESSELLATION || USE_CUSTOM_VERTEX_INTERPOLATORS - MaterialInput materialInput = GetMaterialInput(output, input.Position.xyz, tangentToLocal[2].xyz); - Material material = GetMaterialVS(materialInput); -#endif - - // Apply world position offset per-vertex -#if USE_POSITION_OFFSET - output.WorldPosition += material.PositionOffset; - output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); -#endif - - // Get tessalation multiplier (per vertex) -#if USE_TESSELLATION - output.TessellationMultiplier = material.TessellationMultiplier; -#endif - - // Copy interpolants for other shader stages -#if USE_CUSTOM_VERTEX_INTERPOLATORS - output.CustomVSToPS = material.CustomVSToPS; -#endif - - return output; -} - -#endif - -#if USE_DITHERED_LOD_TRANSITION - -void ClipLODTransition(PixelInput input) -{ - float ditherFactor = input.InstanceParams.y; - if (abs(ditherFactor) > 0.001) - { - float randGrid = cos(dot(floor(input.Position.xy), float2(347.83452793, 3343.28371863))); - float randGridFrac = frac(randGrid * 1000.0); - half mask = (ditherFactor < 0.0) ? (ditherFactor + 1.0 > randGridFrac) : (ditherFactor < randGridFrac); - clip(mask - 0.001); - } -} - -#endif - -// Pixel Shader function for Depth Pass -META_PS(true, FEATURE_LEVEL_ES2) -void PS_Depth(PixelInput input -#if GLSL - , out float4 OutColor : SV_Target0 -#endif - ) -{ -#if USE_DITHERED_LOD_TRANSITION - // LOD masking - ClipLODTransition(input); -#endif - - // Get material parameters - MaterialInput materialInput = GetMaterialInput(input); - Material material = GetMaterialPS(materialInput); - - // Perform per pixel clipping -#if MATERIAL_MASKED - clip(material.Mask - MATERIAL_MASK_THRESHOLD); -#endif - clip(material.Opacity - MATERIAL_OPACITY_THRESHOLD); - -#if GLSL - OutColor = 0; -#endif -} - -@9 diff --git a/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp b/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp index 3bd71290d..4afbdd60d 100644 --- a/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp @@ -67,7 +67,7 @@ void DeferredMaterialShader::Bind(BindParameters& params) byte* cb = _cb0Data.Get(); auto materialData = reinterpret_cast(cb); cb += sizeof(DeferredMaterialShaderData); - int32 srv = 0; + int32 srv = 2; // Setup features const bool useLightmap = _info.BlendMode == MaterialBlendMode::Opaque && LightmapFeature::Bind(params, cb, srv); diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index 0d9108566..bf9f566ef 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -36,6 +36,7 @@ PACK_STRUCT(struct ForwardMaterialShaderData { Vector2 Dummy0; float LODDitherFactor; float PerInstanceRandom; + Vector4 TemporalAAJitter; Vector3 GeometrySize; float Dummy1; }); @@ -63,7 +64,7 @@ void ForwardMaterialShader::Bind(BindParameters& params) byte* cb = _cb0Data.Get(); auto materialData = reinterpret_cast(cb); cb += sizeof(ForwardMaterialShaderData); - int32 srv = 0; + int32 srv = 2; // Setup features ForwardShadingFeature::Bind(params, cb, srv); diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index 531efe315..fb0585f83 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -396,6 +396,9 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo int32 srv = 0; switch (baseLayer->Domain) { + case MaterialDomain::Surface: + srv = 2; // Skinning Bones + Prev Bones + break; case MaterialDomain::Decal: srv = 1; // Depth buffer break; @@ -467,10 +470,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo switch (materialInfo.Domain) { case MaterialDomain::Surface: - if (materialInfo.BlendMode == MaterialBlendMode::Opaque) - path /= TEXT("SurfaceDeferred.shader"); - else - path /= TEXT("SurfaceForward.shader"); + path /= TEXT("Surface.shader"); break; case MaterialDomain::PostProcess: path /= TEXT("PostProcess.shader");