240 lines
6.6 KiB
GLSL
240 lines
6.6 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 InverseViewProjectionMatrix;
|
|
float4x4 WorldMatrix;
|
|
float4x4 WorldMatrixInverseTransposed;
|
|
float3 GridSize;
|
|
float PerInstanceRandom;
|
|
float Dummy0;
|
|
float VolumetricFogMaxDistance;
|
|
int ParticleStride;
|
|
int ParticleIndex;
|
|
@1META_CB_END
|
|
|
|
// Particles attributes buffer
|
|
ByteAddressBuffer ParticlesData : register(t0);
|
|
|
|
// Shader resources
|
|
@2
|
|
// 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
|
|
};
|
|
|
|
#define GetInstanceTransform(input) WorldMatrix;
|
|
|
|
// 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)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
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), WorldMatrix).xyz;
|
|
}
|
|
|
|
float3 TransformParticleVector(float3 input)
|
|
{
|
|
return mul(float4(input, 0.0f), 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
|
|
}
|
|
|
|
// Pixel Shader function for Volumetric Fog material injection (local fog)
|
|
META_PS(true, FEATURE_LEVEL_SM5)
|
|
void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out float4 VBufferB : SV_Target1)
|
|
{
|
|
uint3 gridCoordinate = uint3(input.Vertex.Position.xy, input.LayerIndex);
|
|
float3 cellOffset = 0.5f;
|
|
float2 volumeUV = (gridCoordinate.xy + cellOffset.xy) / GridSize.xy;
|
|
float zSlice = gridCoordinate.z + cellOffset.z;
|
|
float sceneDepth = (zSlice / GridSize.z) * VolumetricFogMaxDistance / ViewFar;
|
|
float deviceDepth = (ViewInfo.w / sceneDepth) + ViewInfo.z;
|
|
float4 clipPos = float4(volumeUV * float2(2.0, -2.0) + float2(-1.0, 1.0), deviceDepth, 1.0);
|
|
float4 wsPos = mul(clipPos, InverseViewProjectionMatrix);
|
|
float3 positionWS = wsPos.xyz / wsPos.w;
|
|
|
|
// Get material parameters
|
|
MaterialInput materialInput = (MaterialInput)0;
|
|
materialInput.WorldPosition = positionWS;
|
|
materialInput.TexCoord = input.Vertex.TexCoord;
|
|
materialInput.ParticleIndex = ParticleIndex;
|
|
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
|
materialInput.TwoSidedSign = 1.0f;
|
|
materialInput.InstanceOrigin = WorldMatrix[3].xyz;
|
|
materialInput.InstanceParams = PerInstanceRandom;
|
|
materialInput.SvPosition = clipPos;
|
|
Material material = GetMaterialPS(materialInput);
|
|
|
|
// Compute fog properties
|
|
float3 albedo = material.Color;
|
|
float extinction = material.Opacity * material.Mask * 0.001f;
|
|
float3 emission = material.Emissive;
|
|
float3 scattering = albedo * extinction;
|
|
float absorption = max(0.0f, extinction - Luminance(scattering));
|
|
|
|
// Write fog properties
|
|
VBufferA = float4(scattering, absorption);
|
|
VBufferB = float4(emission, 0);
|
|
}
|
|
|
|
@9
|