Refactor material shaders generator to use modular features as extensions

This commit is contained in:
Wojtek Figat
2021-02-05 13:57:00 +01:00
parent 2da9ed4556
commit 300f948515
5 changed files with 45 additions and 591 deletions

View File

@@ -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

View File

@@ -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<float4> 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

View File

@@ -67,7 +67,7 @@ void DeferredMaterialShader::Bind(BindParameters& params)
byte* cb = _cb0Data.Get();
auto materialData = reinterpret_cast<DeferredMaterialShaderData*>(cb);
cb += sizeof(DeferredMaterialShaderData);
int32 srv = 0;
int32 srv = 2;
// Setup features
const bool useLightmap = _info.BlendMode == MaterialBlendMode::Opaque && LightmapFeature::Bind(params, cb, srv);

View File

@@ -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<ForwardMaterialShaderData*>(cb);
cb += sizeof(ForwardMaterialShaderData);
int32 srv = 0;
int32 srv = 2;
// Setup features
ForwardShadingFeature::Bind(params, cb, srv);

View File

@@ -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");