// 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 InvWorld; float4x4 SVPositionToWorld; float3 ViewPos; float ViewFar; float3 ViewDir; float TimeParam; float4 ViewInfo; float4 ScreenSize; @1META_CB_END // Use depth buffer for per-pixel decal layering Texture2D DepthBuffer : register(t0); // Material shader resources @2 // Material properties generation input struct MaterialInput { float3 WorldPosition; float TwoSidedSign; float2 TexCoord; float3x3 TBN; float4 SvPosition; float3 PreSkinnedPosition; float3 PreSkinnedNormal; }; // 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)WorldMatrix; return mul(localVector, localToWorld); } // Transforms a vector from local space to world space float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector) { float3x3 localToWorld = (float3x3)WorldMatrix; return mul(localToWorld, worldVector); } // Gets the current object position (supports instancing) float3 GetObjectPosition(MaterialInput input) { return WorldMatrix[3].xyz; } // Gets the current object size float3 GetObjectSize(MaterialInput input) { return float3(1, 1, 1); } // Get the current object random value supports instancing) float GetPerInstanceRandom(MaterialInput input) { return 0; } // Get the current object LOD transition dither factor (supports instancing) float GetLODDitherFactor(MaterialInput input) { return 0; } // Gets the interpolated vertex color (in linear space) float4 GetVertexColor(MaterialInput input) { return 1; } // Get material properties function (for pixel shader) Material GetMaterialPS(MaterialInput input) { @4 } // Programmatically set the line number after all the material inputs which have a variable number of line endings // This allows shader error line numbers after this point to be the same regardless of which material is being compiled #line 1000 // Input macro specified by the material: DECAL_BLEND_MODE #define DECAL_BLEND_MODE_TRANSLUCENT 0 #define DECAL_BLEND_MODE_STAIN 1 #define DECAL_BLEND_MODE_NORMAL 2 #define DECAL_BLEND_MODE_EMISSIVE 3 // Vertex Shader function for decals rendering META_VS(true, FEATURE_LEVEL_ES2) META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true) void VS_Decal(in float3 Position : POSITION0, out float4 SvPosition : SV_Position) { // Compute world space vertex position float3 worldPosition = mul(float4(Position.xyz, 1), WorldMatrix).xyz; // Compute clip space position SvPosition = mul(float4(worldPosition.xyz, 1), ViewProjectionMatrix); } // Pixel Shader function for decals rendering META_PS(true, FEATURE_LEVEL_ES2) void PS_Decal( in float4 SvPosition : SV_Position , out float4 Out0 : SV_Target0 #if DECAL_BLEND_MODE == DECAL_BLEND_MODE_TRANSLUCENT , out float4 Out1 : SV_Target1 #if USE_NORMAL || USE_EMISSIVE , out float4 Out2 : SV_Target2 #endif #if USE_NORMAL && USE_EMISSIVE , out float4 Out3 : SV_Target3 #endif #endif ) { float2 screenUV = SvPosition.xy * ScreenSize.zw; SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r; float4 positionHS = mul(float4(SvPosition.xyz, 1), SVPositionToWorld); float3 positionWS = positionHS.xyz / positionHS.w; float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz; // Clip content outside the decal clip(0.5 - abs(positionOS.xyz)); // By default, map textures using the vectors perpendicular to the projection direction float2 decalUVs = positionOS.xz + 0.5f; // Setup material input MaterialInput materialInput = (MaterialInput)0; materialInput.WorldPosition = positionWS; materialInput.TexCoord = decalUVs; materialInput.TwoSidedSign = 1; materialInput.SvPosition = SvPosition; // Build tangent to world transformation matrix float3 ddxWp = ddx(positionWS); float3 ddyWp = ddy(positionWS); materialInput.TBN[0] = normalize(ddyWp); materialInput.TBN[1] = normalize(ddxWp); materialInput.TBN[2] = normalize(cross(ddxWp, ddyWp)); // Sample material Material material = GetMaterialPS(materialInput); // Masking #if MATERIAL_MASKED clip(material.Mask - MATERIAL_MASK_THRESHOLD); #endif // Set the output #if DECAL_BLEND_MODE == DECAL_BLEND_MODE_TRANSLUCENT // GBuffer0 Out0 = float4(material.Color, material.Opacity); // GBuffer2 Out1 = float4(material.Roughness, material.Metalness, material.Specular, material.Opacity); #if USE_EMISSIVE // Light Buffer Out2 = float4(material.Emissive, material.Opacity); #if USE_NORMAL // GBuffer1 Out3 = float4(material.WorldNormal * 0.5f + 0.5f, 1); #endif #elif USE_NORMAL // GBuffer1 Out2 = float4(material.WorldNormal * 0.5f + 0.5f, 1); #endif #elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_STAIN Out0 = float4(material.Color, material.Opacity); #elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_NORMAL Out0 = float4(material.WorldNormal * 0.5f + 0.5f, 1); #elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_EMISSIVE Out0 = float4(material.Emissive * material.Opacity, material.Opacity); #else #error "Invalid decal blending mode" #endif }