Files
FlaxEngine/Content/Editor/MaterialTemplates/Decal.shader

208 lines
5.5 KiB
GLSL

// File generated by Flax Materials Editor
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 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 WorldMatrix;
float4x4 InvWorld;
float4x4 SVPositionToWorld;
@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;
}
@8
// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}
// 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(0.5 - abs(positionOS.xyz));
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, material.Opacity);
#endif
#elif USE_NORMAL
// GBuffer1
Out2 = float4(material.WorldNormal * 0.5f + 0.5f, material.Opacity);
#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, material.Opacity);
#elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_EMISSIVE
Out0 = float4(material.Emissive * material.Opacity, material.Opacity);
#else
#error "Invalid decal blending mode"
#endif
}
@9