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

701 lines
22 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"
#include "./Flax/Matrix.hlsl"
@7
struct SpriteInput
{
float2 Position : POSITION;
float2 TexCoord : TEXCOORD;
};
struct RibbonInput
{
uint Order : TEXCOORD0;
uint ParticleIndex : TEXCOORD1;
uint PrevParticleIndex : TEXCOORD2;
float Distance : TEXCOORD3;
};
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x3 WorldMatrix;
uint SortedIndicesOffset;
float PerInstanceRandom;
int ParticleStride;
int PositionOffset;
int SpriteSizeOffset;
int SpriteFacingModeOffset;
int SpriteFacingVectorOffset;
int VelocityOffset;
int RotationOffset;
int ScaleOffset;
int ModelFacingModeOffset;
float RibbonUVTilingDistance;
float2 RibbonUVScale;
float2 RibbonUVOffset;
int RibbonWidthOffset;
int RibbonTwistOffset;
int RibbonFacingVectorOffset;
uint RibbonSegmentCount;
float4x3 WorldMatrixInverseTransposed;
@1META_CB_END
// Particles attributes buffer
ByteAddressBuffer ParticlesData : register(t0);
// Sorted particles indices
Buffer<uint> SortedIndices : register(t1);
// Shader resources
@2
// Interpolants passed from the vertex shader
struct VertexOutput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
uint ParticleIndex : 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
nointerpolation float3 InstanceOrigin : TEXCOORD6;
nointerpolation float InstanceParams : TEXCOORD7; // x-PerInstanceRandom
};
// Interpolants passed to the pixel shader
struct PixelInput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
uint ParticleIndex : 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
nointerpolation float3 InstanceOrigin : TEXCOORD6;
nointerpolation float InstanceParams : TEXCOORD7; // x-PerInstanceRandom
bool IsFrontFace : SV_IsFrontFace;
};
// Material properties generation input
struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
uint ParticleIndex;
#if USE_VERTEX_COLOR
half4 VertexColor;
#endif
float3x3 TBN;
float4 SvPosition;
float3 PreSkinnedPosition;
float3 PreSkinnedNormal;
float3 InstanceOrigin;
float InstanceParams;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT];
#endif
};
MaterialInput GetMaterialInput(PixelInput input)
{
MaterialInput result = (MaterialInput)0;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
result.ParticleIndex = input.ParticleIndex;
#if USE_VERTEX_COLOR
result.VertexColor = input.VertexColor;
#endif
result.TBN = input.TBN;
result.TwoSidedSign = 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;
}
// Gets the local to world transform matrix (supports instancing)
#if USE_INSTANCING
#define GetInstanceTransform(input) 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 GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
#endif
// Removes the scale vector from the local to world transformation matrix (supports instancing)
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
{
// 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);
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
float3 GetObjectSize(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value (supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
return input.InstanceParams;
}
// 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)
{
#if USE_VERTEX_COLOR
return input.VertexColor;
#else
return 1;
#endif
}
uint GetParticleUint(uint particleIndex, int offset)
{
return ParticlesData.Load(particleIndex * ParticleStride + offset);
}
int GetParticleInt(uint particleIndex, int offset)
{
return asint(ParticlesData.Load(particleIndex * ParticleStride + offset));
}
float GetParticleFloat(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load(particleIndex * ParticleStride + offset));
}
float2 GetParticleVec2(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load2(particleIndex * ParticleStride + offset));
}
float3 GetParticleVec3(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load3(particleIndex * ParticleStride + offset));
}
float4 GetParticleVec4(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load4(particleIndex * ParticleStride + offset));
}
float3 TransformParticlePosition(float3 input)
{
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
}
float3 TransformParticleVector(float3 input)
{
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
}
@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 (half3x3)float3x3(tangent, bitangent, normal);
}
half3x3 CalcTangentToWorld(in float4x4 world, in half3x3 tangentToLocal)
{
half3x3 localToWorld = (half3x3)RemoveScaleFromLocalToWorld((float3x3)world);
return mul(tangentToLocal, localToWorld);
}
float3 GetParticlePosition(uint particleIndex)
{
return TransformParticlePosition(GetParticleVec3(particleIndex, PositionOffset));
}
// Vertex Shader function for Sprite Rendering
META_VS(true, FEATURE_LEVEL_ES2)
VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
{
VertexOutput output;
// Sorted particles mapping
if (SortedIndicesOffset != 0xFFFFFFFF)
{
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
}
// Read particle data
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
float4x4 world = ToMatrix4x4(WorldMatrix);
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
float3x3 viewRot = transpose((float3x3)ViewMatrix);
float3 position = mul(float4(particlePosition, 1), world).xyz;
// Orient sprite
float3 axisX, axisY, axisZ;
if (spriteFacingMode == 0)
{
// Face Camera Position
axisZ = normalize(ViewPos - position);
axisX = -normalize(cross(viewRot[1].xyz, axisZ));
axisY = cross(axisZ, axisX);
}
else if (spriteFacingMode == 1)
{
// Face Camera Plane
axisX = viewRot[0].xyz;
axisY = -viewRot[1].xyz;
axisZ = viewRot[2].xyz;
}
else if (spriteFacingMode == 2)
{
// Along Velocity
float3 velocity = GetParticleVec3(particleIndex, VelocityOffset);
axisY = normalize(velocity);
axisZ = ViewPos - position;
axisX = normalize(cross(axisY, axisZ));
axisZ = cross(axisX, axisY);
}
else if (spriteFacingMode == 3)
{
// Custom Facing Vector
float3 spriteFacingVector = GetParticleVec3(particleIndex, SpriteFacingVectorOffset);
axisZ = spriteFacingVector;
axisX = normalize(cross(viewRot[1].xyz, axisZ));
axisY = cross(axisZ, axisX);
}
else if (spriteFacingMode == 4)
{
// Fixed Axis
float3 spriteFacingVector = GetParticleVec3(particleIndex, SpriteFacingVectorOffset);
axisY = spriteFacingVector;
axisZ = ViewPos - position;
axisX = normalize(cross(axisY, axisZ));
axisZ = cross(axisX, axisY);
}
else
{
// Default
axisX = float3(1, 0, 0);
axisY = float3(0, 1, 0);
axisZ = float3(0, 0, 1);
}
// Compute world space vertex position
float3 spriteVertexPosition = float3(input.Position.xy * spriteSize, 0);
spriteVertexPosition = mul(spriteVertexPosition, eulerMatrix);
spriteVertexPosition = mul(spriteVertexPosition, float3x3(axisX, axisY, axisZ));
output.WorldPosition = position + spriteVertexPosition;
// Compute clip space position
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.TexCoord = input.TexCoord;
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = 1;
#endif
output.InstanceOrigin = world[3].xyz;
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = half3x3(axisX, axisY, axisZ);
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
materialInput.ParticleIndex = output.ParticleIndex;
#if USE_VERTEX_COLOR
materialInput.VertexColor = output.VertexColor;
#endif
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = float3(input.Position.xy, 0);
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;
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
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Vertex Shader function for Model Rendering
META_VS(true, FEATURE_LEVEL_ES2)
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)
VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
{
VertexOutput output;
// Sorted particles mapping
if (SortedIndicesOffset != 0xFFFFFFFF)
{
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
}
// Read particle data
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
float3 position = mul(float4(particlePosition, 1), worldMatrix).xyz;
// Compute final vertex position in the world
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
float4 transform0 = float4(eulerMatrix[0], particlePosition.x);
float4 transform1 = float4(eulerMatrix[1], particlePosition.y);
float4 transform2 = float4(eulerMatrix[2], particlePosition.z);
float4x4 scaleMatrix = float4x4(float4(particleScale.x, 0.0f, 0.0f, 0.0f), float4(0.0f, particleScale.y, 0.0f, 0.0f), float4(0.0f, 0.0f, particleScale.z, 0.0f), float4(0.0f, 0.0f, 0.0f, 1.0f));
float4x4 world = float4x4(transform0, transform1, transform2, float4(0.0f, 0.0f, 0.0f, 1.0f));
if (modelFacingMode == 0)
{
// Face Camera Position
float3 direction = normalize(ViewPos - position);
float4 alignmentQuat = FindQuatBetween(float3(1.0f, 0.0f, 0.0f), direction);
float4x4 alignmentMat = QuaternionToMatrix(alignmentQuat);
world = mul(world, mul(alignmentMat, scaleMatrix));
}
else if (modelFacingMode == 1)
{
// Face Camera Plane
float3 direction = -ViewDir;
float4 alignmentQuat = FindQuatBetween(float3(1.0f, 0.0f, 0.0f), direction);
float4x4 alignmentMat = QuaternionToMatrix(alignmentQuat);
world = mul(world, mul(alignmentMat, scaleMatrix));
}
else if (modelFacingMode == 2)
{
// Along Velocity
float3 direction = GetParticleVec3(particleIndex, VelocityOffset);
float4 alignmentQuat = FindQuatBetween(float3(1.0f, 0.0f, 0.0f), normalize(direction));
float4x4 alignmentMat = QuaternionToMatrix(alignmentQuat);
world = mul(world, mul(alignmentMat, scaleMatrix));
}
else
{
// Default
world = mul(world, scaleMatrix);
}
world = transpose(world);
world = mul(world, worldMatrix);
// Calculate the vertex position in world space
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
// Compute clip space position
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.TexCoord = input.TexCoord0;
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = input.Color;
#endif
output.InstanceOrigin = worldMatrix[3].xyz;
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = CalcTangentToLocal(input);
half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
materialInput.ParticleIndex = output.ParticleIndex;
#if USE_VERTEX_COLOR
materialInput.VertexColor = output.VertexColor;
#endif
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = input.Position.xyz;
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;
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
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Vertex Shader function for Ribbon Rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32_UINT, 0, 0, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R32_UINT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 2, R32_UINT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 3, R32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
{
VertexOutput output;
// Get particle data
uint particleIndex = input.ParticleIndex;
int vertexSign = (((int)vertexIndex & 0x1) * 2) - 1;
float3 position = GetParticlePosition(particleIndex);
float ribbonWidth = RibbonWidthOffset != -1 ? GetParticleFloat(particleIndex, RibbonWidthOffset) : 20.0f;
float ribbonTwist = RibbonTwistOffset != -1 ? GetParticleFloat(particleIndex, RibbonTwistOffset) : 0.0f;
// Calculate ribbon direction
float3 direction;
if (input.Order == 0)
{
direction = GetParticlePosition(input.PrevParticleIndex) - position;
}
else
{
direction = position - GetParticlePosition(input.PrevParticleIndex);
}
// Calculate particle orientation (tangent vectors)
float3 cameraDirection = SafeNormalize(ViewPos - position);
float3 tangentUp = SafeNormalize(direction);
float3 facing = RibbonFacingVectorOffset != -1 ? GetParticleVec3(particleIndex, RibbonFacingVectorOffset) : cameraDirection;
float twistSine, twistCosine;
sincos(radians(ribbonTwist), twistSine, twistCosine);
facing = facing * twistCosine + cross(facing, tangentUp) * twistSine + tangentUp * dot(tangentUp, facing) * (1 - twistCosine);
float3 tangentRight = SafeNormalize(cross(tangentUp, facing));
if (!any(tangentRight))
{
tangentRight = SafeNormalize(cross(tangentUp, float3(0.0f, 0.0f, 1.0f)));
}
// Calculate texture coordinates
if (RibbonUVTilingDistance != 0.0f)
{
output.TexCoord.x = input.Distance / RibbonUVTilingDistance;
}
else
{
output.TexCoord.x = (float)input.Order / (float)RibbonSegmentCount;
}
output.TexCoord.y = (float)((vertexIndex + 1) & 0x1);
output.TexCoord = output.TexCoord * RibbonUVScale + RibbonUVOffset;
// Compute world space vertex position
output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f);
// Compute clip space position
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = 1;
#endif
float4x4 world = ToMatrix4x4(WorldMatrix);
output.InstanceOrigin = world[3].xyz;
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = half3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
materialInput.ParticleIndex = output.ParticleIndex;
#if USE_VERTEX_COLOR
materialInput.VertexColor = output.VertexColor;
#endif
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = position;
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;
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
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Pixel Shader function for Depth Pass
META_PS(true, FEATURE_LEVEL_ES2)
void PS_Depth(PixelInput input)
{
// 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_TRANSPARENT
clip(material.Opacity - MATERIAL_OPACITY_THRESHOLD);
#endif
}
#if _PS_QuadOverdraw
#include "./Flax/Editor/QuadOverdraw.hlsl"
// Pixel Shader function for Quad Overdraw Pass (editor-only)
[earlydepthstencil]
META_PS(USE_EDITOR, FEATURE_LEVEL_SM5)
void PS_QuadOverdraw(float4 svPos : SV_Position, uint primId : SV_PrimitiveID)
{
DoQuadOverdraw(svPos, primId);
}
#endif
@9