You're breathtaking!
This commit is contained in:
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Camera/O_Camera.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Camera/O_Camera.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Camera/T_Camera.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Camera/T_Camera.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/EditorIcon.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/EditorIcon.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Fonts/Inconsolata-Regular.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Fonts/Inconsolata-Regular.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Fonts/Roboto-Regular.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Fonts/Roboto-Regular.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Fonts/SegMDL2.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Fonts/SegMDL2.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Fonts/Segoe Media Center Regular.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Fonts/Segoe Media Center Regular.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/Axis.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/Axis.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialAxisFocus.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/MaterialAxisFocus.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialAxisX.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/MaterialAxisX.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialAxisY.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/MaterialAxisY.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialAxisZ.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/MaterialAxisZ.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWireFocus.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/MaterialWireFocus.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/ScaleAxis.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/ScaleAxis.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/TranslateAxis.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/TranslateAxis.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/WireBox.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/WireBox.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Gizmo/WireCircle.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Gizmo/WireCircle.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/AudioListener.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/AudioListener.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/AudioSource.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/AudioSource.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Decal.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Decal.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/DirectionalLight.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/DirectionalLight.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/EnvironmentProbe.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/EnvironmentProbe.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/ParticleEffect.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/ParticleEffect.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/PointLight.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/PointLight.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/SceneAnimationPlayer.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/SceneAnimationPlayer.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Skybox.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Skybox.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Skylight.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Skylight.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/AudioListner.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/AudioListner.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/AudioSource.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/AudioSource.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/Decal.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/Decal.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/DirectionalLight.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/DirectionalLight.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/EnvironmentProbe.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/EnvironmentProbe.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/ParticleEffect.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/ParticleEffect.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/PointLight.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/PointLight.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/SceneAnimationPlayer.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/SceneAnimationPlayer.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/SkyLight.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/SkyLight.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Icons/Textures/Skybox.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Icons/Textures/Skybox.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/IconsAtlas.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/IconsAtlas.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
23
Content/Editor/LayoutDefault.xml
Normal file
23
Content/Editor/LayoutDefault.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<DockPanelLayout Version="4">
|
||||
<MainWindow IsMaximized="True">
|
||||
<Bounds X="0" Y="23" Width="1920" Height="1017" />
|
||||
</MainWindow>
|
||||
<MasterPanel SelectedTab="0">
|
||||
<Window Typename="::FlaxEditor.Windows.EditGameWindow" />
|
||||
<Window Typename="::FlaxEditor.Windows.GameWindow" />
|
||||
<Panel DockState="10" SplitterValue="0.24" SelectedTab="0">
|
||||
<Window Typename="::FlaxEditor.Windows.PropertiesWindow" />
|
||||
<Panel DockState="7" SplitterValue="0.25" SelectedTab="0">
|
||||
<Window Typename="::FlaxEditor.Windows.ToolboxWindow" />
|
||||
</Panel>
|
||||
</Panel>
|
||||
<Panel DockState="9" SplitterValue="0.37" SelectedTab="0">
|
||||
<Window Typename="::FlaxEditor.Windows.ContentWindow" />
|
||||
<Window Typename="::FlaxEditor.Windows.DebugLogWindow" />
|
||||
<Window Typename="::FlaxEditor.Windows.OutputLogWindow" />
|
||||
</Panel>
|
||||
<Panel DockState="8" SplitterValue="0.25" SelectedTab="0">
|
||||
<Window Typename="::FlaxEditor.Windows.SceneTreeWindow" />
|
||||
</Panel>
|
||||
</MasterPanel>
|
||||
</DockPanelLayout>
|
||||
217
Content/Editor/MaterialTemplates/Decal.shader
Normal file
217
Content/Editor/MaterialTemplates/Decal.shader
Normal file
@@ -0,0 +1,217 @@
|
||||
// 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
|
||||
}
|
||||
239
Content/Editor/MaterialTemplates/GPUParticles.shader
Normal file
239
Content/Editor/MaterialTemplates/GPUParticles.shader
Normal file
@@ -0,0 +1,239 @@
|
||||
// File generated by Flax Editor
|
||||
// Version: @0
|
||||
|
||||
@3
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
#include "./Flax/Matrix.hlsl"
|
||||
@7
|
||||
// Primary constant buffer
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 ViewProjectionMatrix;
|
||||
float4x4 InvViewProjectionMatrix;
|
||||
float4x4 InvViewMatrix;
|
||||
float4x4 ViewMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 InvWorldMatrix;
|
||||
float3 ViewPos;
|
||||
float ViewFar;
|
||||
float3 ViewDir;
|
||||
float Time;
|
||||
float4 ViewInfo;
|
||||
float4 ScreenSize;
|
||||
float3 EffectPosition;
|
||||
float DeltaTime;
|
||||
float4 EffectRotation;
|
||||
float3 EffectScale;
|
||||
uint ParticleCounterOffset;
|
||||
float3 Dummy0;
|
||||
uint SpawnCount;
|
||||
@1META_CB_END
|
||||
|
||||
// Particles data buffers
|
||||
ByteAddressBuffer SrcParticlesData : register(t0);
|
||||
RWByteAddressBuffer DstParticlesData : register(u0);
|
||||
|
||||
// The GPU particles simulation context data
|
||||
struct Context
|
||||
{
|
||||
uint ParticleIndex;
|
||||
uint ParticlesCount;
|
||||
uint Seed;
|
||||
};
|
||||
|
||||
@6
|
||||
// Seed generation function
|
||||
uint WangHash(uint seed)
|
||||
{
|
||||
seed = (seed ^ 61) ^ (seed >> 16);
|
||||
seed += (seed << 3);
|
||||
seed = seed ^ (seed >> 4);
|
||||
seed *= 0x27d4eb2d;
|
||||
seed = seed ^ (seed >> 15);
|
||||
return seed;
|
||||
}
|
||||
|
||||
// Random number generation function
|
||||
float Rand(inout uint seed)
|
||||
{
|
||||
const uint multiplier = 0x0019660d;
|
||||
const uint increment = 0x3c6ef35f;
|
||||
seed = multiplier * seed + increment;
|
||||
return asfloat((seed >> 9) | 0x3f800000) - 1.0f;
|
||||
}
|
||||
|
||||
float4 Mod289(float4 x)
|
||||
{
|
||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||
}
|
||||
|
||||
float4 Perm(float4 x)
|
||||
{
|
||||
return Mod289(((x * 34.0) + 1.0) * x);
|
||||
}
|
||||
|
||||
float Noise(float3 p)
|
||||
{
|
||||
float3 a = floor(p);
|
||||
float3 d = p - a;
|
||||
d = d * d * (3.0 - 2.0 * d);
|
||||
|
||||
float4 b = a.xxyy + float4(0.0, 1.0, 0.0, 1.0);
|
||||
float4 k1 = Perm(b.xyxy);
|
||||
float4 k2 = Perm(k1.xyxy + b.zzww);
|
||||
|
||||
float4 c = k2 + a.zzzz;
|
||||
float4 k3 = Perm(c);
|
||||
float4 k4 = Perm(c + 1.0);
|
||||
|
||||
float4 o1 = frac(k3 * (1.0 / 41.0));
|
||||
float4 o2 = frac(k4 * (1.0 / 41.0));
|
||||
|
||||
float4 o3 = o2 * d.z + o1 * (1.0 - d.z);
|
||||
float2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
|
||||
|
||||
return o4.y * d.y + o4.x * (1.0 - d.y);
|
||||
}
|
||||
|
||||
float3 Noise3D(float3 p)
|
||||
{
|
||||
float o = Noise(p);
|
||||
float a = Noise(p + float3(0.0001f, 0.0f, 0.0f));
|
||||
float b = Noise(p + float3(0.0f, 0.0001f, 0.0f));
|
||||
float c = Noise(p + float3(0.0f, 0.0f, 0.0001f));
|
||||
|
||||
float3 grad = float3(o - a, o - b, o - c);
|
||||
float3 other = abs(grad.zxy);
|
||||
return normalize(cross(grad,other));
|
||||
}
|
||||
|
||||
float3 Noise3D(float3 position, int octaves, float roughness)
|
||||
{
|
||||
float weight = 0.0f;
|
||||
float3 noise = float3(0.0, 0.0, 0.0);
|
||||
float scale = 1.0f;
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
float curWeight = pow((1.0-((float)i / octaves)), lerp(2.0, 0.2, roughness));
|
||||
|
||||
noise += Noise3D(position * scale) * curWeight;
|
||||
weight += curWeight;
|
||||
|
||||
scale *= 1.72531;
|
||||
}
|
||||
return noise / weight;
|
||||
}
|
||||
|
||||
// Reprojects the world space position from the given UV and raw device depth
|
||||
float3 ReprojectPosition(float2 uv, float rawDepth)
|
||||
{
|
||||
uv = uv * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
||||
float4 pos = mul(float4(uv.x, uv.y, rawDepth, 1.0f), InvViewProjectionMatrix);
|
||||
return pos.xyz / pos.w;
|
||||
}
|
||||
|
||||
// Random values generation wrapper macros
|
||||
#define RAND Rand(context.Seed)
|
||||
#define RAND2 float2(RAND, RAND)
|
||||
#define RAND3 float3(RAND, RAND, RAND)
|
||||
#define RAND4 float4(RAND, RAND, RAND, RAND)
|
||||
|
||||
@2uint GetParticleUint(uint particleIndex, int offset)
|
||||
{
|
||||
return SrcParticlesData.Load(particleIndex * PARTICLE_STRIDE + offset);
|
||||
}
|
||||
|
||||
int GetParticleInt(uint particleIndex, int offset)
|
||||
{
|
||||
return asint(SrcParticlesData.Load(particleIndex * PARTICLE_STRIDE + offset));
|
||||
}
|
||||
|
||||
float GetParticleFloat(uint particleIndex, int offset)
|
||||
{
|
||||
return asfloat(SrcParticlesData.Load(particleIndex * PARTICLE_STRIDE + offset));
|
||||
}
|
||||
|
||||
float2 GetParticleVec2(uint particleIndex, int offset)
|
||||
{
|
||||
return asfloat(SrcParticlesData.Load2(particleIndex * PARTICLE_STRIDE + offset));
|
||||
}
|
||||
|
||||
float3 GetParticleVec3(uint particleIndex, int offset)
|
||||
{
|
||||
return asfloat(SrcParticlesData.Load3(particleIndex * PARTICLE_STRIDE + offset));
|
||||
}
|
||||
|
||||
float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
{
|
||||
return asfloat(SrcParticlesData.Load4(particleIndex * PARTICLE_STRIDE + offset));
|
||||
}
|
||||
|
||||
void SetParticleUint(uint particleIndex, int offset, uint value)
|
||||
{
|
||||
DstParticlesData.Store(particleIndex * PARTICLE_STRIDE + offset, value);
|
||||
}
|
||||
|
||||
void SetParticleInt(uint particleIndex, int offset, int value)
|
||||
{
|
||||
DstParticlesData.Store(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
|
||||
}
|
||||
|
||||
void SetParticleFloat(uint particleIndex, int offset, float value)
|
||||
{
|
||||
DstParticlesData.Store(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
|
||||
}
|
||||
|
||||
void SetParticleVec2(uint particleIndex, int offset, float2 value)
|
||||
{
|
||||
DstParticlesData.Store2(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
|
||||
}
|
||||
|
||||
void SetParticleVec3(uint particleIndex, int offset, float3 value)
|
||||
{
|
||||
DstParticlesData.Store3(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
|
||||
}
|
||||
|
||||
void SetParticleVec4(uint particleIndex, int offset, float4 value)
|
||||
{
|
||||
DstParticlesData.Store4(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
|
||||
}
|
||||
|
||||
bool AddParticle(out uint dstIndex)
|
||||
{
|
||||
// Acquire the particle index in the destination buffer
|
||||
DstParticlesData.InterlockedAdd(ParticleCounterOffset, 1, dstIndex);
|
||||
|
||||
// Prevent overflow
|
||||
return dstIndex >= PARTICLE_CAPACITY;
|
||||
}
|
||||
|
||||
void UpdateParticle(Context context)
|
||||
{
|
||||
@5}
|
||||
|
||||
void SpawnParticle(Context context)
|
||||
{
|
||||
if (AddParticle(context.ParticleIndex))
|
||||
return;
|
||||
|
||||
@4}
|
||||
|
||||
// Main entry point for the particles simulation and spawning
|
||||
META_CS(true, FEATURE_LEVEL_SM5)
|
||||
[numthreads(THREAD_GROUP_SIZE, 1, 1)]
|
||||
void CS_Main(uint3 dispatchThreadId : SV_DispatchThreadID)
|
||||
{
|
||||
Context context;
|
||||
context.ParticleIndex = dispatchThreadId.x;
|
||||
context.ParticlesCount = min(SrcParticlesData.Load(ParticleCounterOffset), PARTICLE_CAPACITY);
|
||||
context.Seed = WangHash(context.ParticleIndex ^ asuint(Time));
|
||||
|
||||
if (context.ParticleIndex < context.ParticlesCount)
|
||||
{
|
||||
UpdateParticle(context);
|
||||
}
|
||||
else if (context.ParticleIndex < context.ParticlesCount + SpawnCount)
|
||||
{
|
||||
SpawnParticle(context);
|
||||
}
|
||||
}
|
||||
260
Content/Editor/MaterialTemplates/GUI.shader
Normal file
260
Content/Editor/MaterialTemplates/GUI.shader
Normal file
@@ -0,0 +1,260 @@
|
||||
// File generated by Flax Materials Editor
|
||||
// Version: @0
|
||||
|
||||
#define MATERIAL 1
|
||||
@3
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/MaterialCommon.hlsl"
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
#include "./Flax/GUICommon.hlsl"
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 ViewProjectionMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 ViewMatrix;
|
||||
float3 ViewPos;
|
||||
float ViewFar;
|
||||
float3 ViewDir;
|
||||
float TimeParam;
|
||||
float4 ViewInfo;
|
||||
float4 ScreenSize;
|
||||
@1META_CB_END
|
||||
|
||||
// Material shader resources
|
||||
@2
|
||||
// Interpolants passed from the vertex shader
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 WorldPosition : TEXCOORD0;
|
||||
float2 TexCoord : TEXCOORD1;
|
||||
float2 WindowPos : TEXCOORD2;
|
||||
#if USE_VERTEX_COLOR
|
||||
half4 VertexColor : COLOR;
|
||||
#endif
|
||||
float4 ClipExtents : TEXCOORD3;
|
||||
float2 ClipOrigin : TEXCOORD4;
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Interpolants passed to the pixel shader
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 WorldPosition : TEXCOORD0;
|
||||
float2 TexCoord : TEXCOORD1;
|
||||
float2 WindowPos : TEXCOORD2;
|
||||
#if USE_VERTEX_COLOR
|
||||
half4 VertexColor : COLOR;
|
||||
#endif
|
||||
float4 ClipExtents : TEXCOORD3;
|
||||
float2 ClipOrigin : TEXCOORD4;
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||
#endif
|
||||
bool IsFrontFace : SV_IsFrontFace;
|
||||
};
|
||||
|
||||
// Material properties generation input
|
||||
struct MaterialInput
|
||||
{
|
||||
float3 WorldPosition;
|
||||
float TwoSidedSign;
|
||||
float2 TexCoord;
|
||||
#if USE_VERTEX_COLOR
|
||||
half4 VertexColor;
|
||||
#endif
|
||||
float3x3 TBN;
|
||||
float4 SvPosition;
|
||||
float3 PreSkinnedPosition;
|
||||
float3 PreSkinnedNormal;
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT];
|
||||
#endif
|
||||
};
|
||||
|
||||
MaterialInput GetMaterialInput(Render2DVertex input, VertexOutput output)
|
||||
{
|
||||
MaterialInput result;
|
||||
result.WorldPosition = output.WorldPosition;
|
||||
result.TexCoord = output.TexCoord;
|
||||
#if USE_VERTEX_COLOR
|
||||
result.VertexColor = output.VertexColor;
|
||||
#endif
|
||||
result.TBN[0] = float3(1, 0, 0);
|
||||
result.TBN[1] = float3(0, 1, 0);
|
||||
result.TBN[2] = float3(0, 0, 1);
|
||||
result.TwoSidedSign = 1.0;
|
||||
result.SvPosition = output.Position;
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
result.CustomVSToPS = output.CustomVSToPS;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
MaterialInput GetMaterialInput(PixelInput input)
|
||||
{
|
||||
MaterialInput result;
|
||||
result.WorldPosition = input.WorldPosition;
|
||||
result.TexCoord = input.TexCoord;
|
||||
#if USE_VERTEX_COLOR
|
||||
result.VertexColor = input.VertexColor;
|
||||
#endif
|
||||
result.TBN[0] = float3(1, 0, 0);
|
||||
result.TBN[1] = float3(0, 1, 0);
|
||||
result.TBN[2] = float3(0, 0, 1);
|
||||
result.TwoSidedSign = input.IsFrontFace ? 1.0 : -1.0;
|
||||
result.SvPosition = input.Position;
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
result.CustomVSToPS = input.CustomVSToPS;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return localVector;
|
||||
}
|
||||
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
{
|
||||
return worldVector;
|
||||
}
|
||||
|
||||
// Gets the current object position (supports instancing)
|
||||
float3 GetObjectPosition(MaterialInput input)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
#if USE_VERTEX_COLOR
|
||||
return input.VertexColor;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get material properties function (for vertex shader)
|
||||
Material GetMaterialVS(MaterialInput input)
|
||||
{
|
||||
@5
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// Vertex Shader function for GUI materials rendering
|
||||
META_VS(true, FEATURE_LEVEL_ES2)
|
||||
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(COLOR, 0, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 1, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 2, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
VertexOutput VS_GUI(Render2DVertex input)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
// Render2D::RenderingFeatures::VertexSnapping
|
||||
if ((int)input.CustomDataAndClipOrigin.y & 1)
|
||||
input.Position = (int2)input.Position;
|
||||
|
||||
output.Position = mul(float4(input.Position, 0, 1), ViewProjectionMatrix);
|
||||
output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz;
|
||||
output.TexCoord = input.TexCoord;
|
||||
output.WindowPos = input.Position;
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = input.Color;
|
||||
#endif
|
||||
output.ClipOrigin = input.CustomDataAndClipOrigin.zw;
|
||||
output.ClipExtents = input.ClipExtents;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
MaterialInput materialInput = GetMaterialInput(input, output);
|
||||
Material material = GetMaterialVS(materialInput);
|
||||
#endif
|
||||
|
||||
// Copy interpolants for other shader stages
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
output.CustomVSToPS = material.CustomVSToPS;
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader function for GUI materials rendering
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
float4 PS_GUI(PixelInput input) : SV_Target0
|
||||
{
|
||||
// 2D per pixel clipping
|
||||
PerformClipping(input.ClipOrigin, input.WindowPos, input.ClipExtents);
|
||||
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
return float4(material.Emissive, material.Opacity);
|
||||
}
|
||||
868
Content/Editor/MaterialTemplates/Particle.shader
Normal file
868
Content/Editor/MaterialTemplates/Particle.shader
Normal file
@@ -0,0 +1,868 @@
|
||||
// File generated by Flax Materials Editor
|
||||
// Version: @0
|
||||
|
||||
#define MATERIAL 1
|
||||
#define MAX_LOCAL_LIGHTS 4
|
||||
@3
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/MaterialCommon.hlsl"
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
#include "./Flax/LightingCommon.hlsl"
|
||||
#if USE_REFLECTIONS
|
||||
#include "./Flax/ReflectionsCommon.hlsl"
|
||||
#endif
|
||||
#include "./Flax/Lighting.hlsl"
|
||||
#include "./Flax/ShadowsSampling.hlsl"
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
#include "./Flax/Matrix.hlsl"
|
||||
@7
|
||||
struct SpriteInput
|
||||
{
|
||||
float2 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 ViewProjectionMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 ViewMatrix;
|
||||
float3 ViewPos;
|
||||
float ViewFar;
|
||||
float3 ViewDir;
|
||||
float TimeParam;
|
||||
float4 ViewInfo;
|
||||
float4 ScreenSize;
|
||||
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;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
@1META_CB_END
|
||||
|
||||
// Secondary constantant buffer (for lighting)
|
||||
META_CB_BEGIN(1, LightingData)
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
float3 Dummy1;
|
||||
uint LocalLightsCount;
|
||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
META_CB_END
|
||||
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
|
||||
// Particles attributes buffer
|
||||
ByteAddressBuffer ParticlesData : register(t0);
|
||||
|
||||
// Ribbons don't use sorted indices so overlap the segment distances buffer on the slot
|
||||
#define HAS_SORTED_INDICES (!defined(_VS_Ribbon))
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
|
||||
// Sorted particles indices
|
||||
Buffer<uint> SortedIndices : register(t1);
|
||||
|
||||
#else
|
||||
|
||||
// Ribbon particles segments distances buffer
|
||||
Buffer<float> SegmentDistances : register(t1);
|
||||
|
||||
#endif
|
||||
|
||||
// Shader resources
|
||||
TextureCube EnvProbe : register(t2);
|
||||
TextureCube SkyLightTexture : register(t3);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t4);
|
||||
@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
|
||||
float3 InstanceOrigin : TEXCOORD6;
|
||||
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
|
||||
float3 InstanceOrigin : TEXCOORD6;
|
||||
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)
|
||||
float4x4 GetInstanceTransform(ModelInput input)
|
||||
{
|
||||
return WorldMatrix;
|
||||
}
|
||||
float4x4 GetInstanceTransform(MaterialInput input)
|
||||
{
|
||||
return 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)
|
||||
{
|
||||
#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), WorldMatrix).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
float3 GetParticlePosition(uint ParticleIndex)
|
||||
{
|
||||
return TransformParticlePosition(GetParticleVec3(ParticleIndex, PositionOffset));
|
||||
}
|
||||
|
||||
// Vertex Shader function for Sprite Rendering
|
||||
META_VS(true, FEATURE_LEVEL_ES2)
|
||||
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT, 0, 0, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
// Sorted particles mapping
|
||||
if (SortedIndicesOffset != 0xFFFFFFFF)
|
||||
{
|
||||
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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 = 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 = float3x3(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;
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
// Sorted particles mapping
|
||||
if (SortedIndicesOffset != 0xFFFFFFFF)
|
||||
{
|
||||
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read particle data
|
||||
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.TexCoord;
|
||||
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)
|
||||
VertexOutput VS_Ribbon(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
// Get particle data
|
||||
uint particleIndex = vertexIndex / 2;
|
||||
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 (particleIndex == 0)
|
||||
{
|
||||
float3 nextParticlePos = GetParticlePosition(particleIndex + 1);
|
||||
direction = nextParticlePos - position;
|
||||
}
|
||||
else
|
||||
{
|
||||
float3 previousParticlePos = GetParticlePosition(particleIndex - 1);
|
||||
direction = position - previousParticlePos;
|
||||
}
|
||||
|
||||
// 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
|
||||
float texCoordU;
|
||||
#ifdef _VS_Ribbon
|
||||
if (RibbonUVTilingDistance != 0.0f)
|
||||
{
|
||||
texCoordU = SegmentDistances[particleIndex] / RibbonUVTilingDistance;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texCoordU = (float)particleIndex / RibbonSegmentCount;
|
||||
}
|
||||
float texCoordV = (vertexIndex + 1) & 0x1;
|
||||
output.TexCoord = float2(texCoordU, texCoordV) * 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
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
||||
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 = 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 Forward Pass
|
||||
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Forward(PixelInput input) : SV_Target0
|
||||
{
|
||||
float4 output = 0;
|
||||
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
// Add emissive light
|
||||
output = float4(material.Emissive, material.Opacity);
|
||||
|
||||
#if MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
|
||||
|
||||
// Setup GBuffer data as proxy for lighting
|
||||
GBufferSample gBuffer;
|
||||
gBuffer.Normal = material.WorldNormal;
|
||||
gBuffer.Roughness = material.Roughness;
|
||||
gBuffer.Metalness = material.Metalness;
|
||||
gBuffer.Color = material.Color;
|
||||
gBuffer.Specular = material.Specular;
|
||||
gBuffer.AO = material.AO;
|
||||
gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz;
|
||||
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#else
|
||||
gBuffer.CustomData = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
gBuffer.WorldPos = materialInput.WorldPosition;
|
||||
gBuffer.ShadingModel = MATERIAL_SHADING_MODEL;
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
light += GetSkyLightLighting(SkyLight, gBuffer, SkyLightTexture);
|
||||
|
||||
// Calculate lighting from local lights
|
||||
LOOP
|
||||
for (uint localLightIndex = 0; localLightIndex < LocalLightsCount; localLightIndex++)
|
||||
{
|
||||
const LightData localLight = LocalLights[localLightIndex];
|
||||
bool isSpotLight = localLight.SpotAngles.x > -2.0f;
|
||||
shadowMask = 1.0f;
|
||||
light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight);
|
||||
}
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
// Calculate reflections
|
||||
light.rgb += GetEnvProbeLighting(ViewPos, EnvProbe, EnvironmentProbe, gBuffer) * light.a;
|
||||
#endif
|
||||
|
||||
// Add lighting (apply ambient occlusion)
|
||||
output.rgb += light.rgb * gBuffer.AO;
|
||||
|
||||
#if USE_FOG
|
||||
// Calculate exponential height fog
|
||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0);
|
||||
|
||||
// Apply fog to the output color
|
||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_TRANSPARENT
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_ADDITIVE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a * fog.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_MULTIPLY
|
||||
output = float4(lerp(float3(1, 1, 1), output.rgb, fog.aaa * fog.aaa), output.a);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#if USE_DISTORTION
|
||||
|
||||
// Pixel Shader function for Distortion Pass
|
||||
META_PS(USE_DISTORTION, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Distortion(PixelInput input) : SV_Target0
|
||||
{
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
float3 viewNormal = normalize(TransformWorldVectorToView(materialInput, material.WorldNormal));
|
||||
float airIOR = 1.0f;
|
||||
#if USE_PIXEL_NORMAL_OFFSET_REFRACTION
|
||||
float3 viewVertexNormal = TransformWorldVectorToView(materialInput, TransformTangentVectorToWorld(materialInput, float3(0, 0, 1)));
|
||||
float2 distortion = (viewVertexNormal.xy - viewNormal.xy) * (material.Refraction - airIOR);
|
||||
#else
|
||||
float2 distortion = viewNormal.xy * (material.Refraction - airIOR);
|
||||
#endif
|
||||
|
||||
// Clip if the distortion distance (squared) is too small to be noticed
|
||||
clip(dot(distortion, distortion) - 0.00001);
|
||||
|
||||
// Scale up for better precision in low/subtle refractions at the expense of artefacts at higher refraction
|
||||
distortion *= 4.0f;
|
||||
|
||||
// Store positive and negative offsets separately
|
||||
float2 addOffset = max(distortion, 0);
|
||||
float2 subOffset = abs(min(distortion, 0));
|
||||
return float4(addOffset.x, addOffset.y, subOffset.x, subOffset.y);
|
||||
}
|
||||
|
||||
#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
|
||||
)
|
||||
{
|
||||
// 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 GLSL
|
||||
OutColor = 0;
|
||||
#endif
|
||||
}
|
||||
150
Content/Editor/MaterialTemplates/PostProcess.shader
Normal file
150
Content/Editor/MaterialTemplates/PostProcess.shader
Normal file
@@ -0,0 +1,150 @@
|
||||
// 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 ViewMatrix;
|
||||
float3 ViewPos;
|
||||
float ViewFar;
|
||||
float3 ViewDir;
|
||||
float TimeParam;
|
||||
float4 ViewInfo;
|
||||
float4 ScreenSize;
|
||||
float4 TemporalAAJitter;
|
||||
@1META_CB_END
|
||||
|
||||
// Material shader resources
|
||||
@2
|
||||
// Interpolants passed to the pixel shader
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 WorldPosition : TEXCOORD0;
|
||||
float2 TexCoord : TEXCOORD1;
|
||||
bool IsFrontFace : SV_IsFrontFace;
|
||||
};
|
||||
|
||||
// Material properties generation input
|
||||
struct MaterialInput
|
||||
{
|
||||
float3 WorldPosition;
|
||||
float TwoSidedSign;
|
||||
float2 TexCoord;
|
||||
#if USE_VERTEX_COLOR
|
||||
half4 VertexColor;
|
||||
#endif
|
||||
float3x3 TBN;
|
||||
float4 SvPosition;
|
||||
float3 PreSkinnedPosition;
|
||||
float3 PreSkinnedNormal;
|
||||
};
|
||||
|
||||
MaterialInput GetMaterialInput(PixelInput input)
|
||||
{
|
||||
MaterialInput result = (MaterialInput)0;
|
||||
result.WorldPosition = input.WorldPosition;
|
||||
result.TexCoord = input.TexCoord;
|
||||
#if USE_VERTEX_COLOR
|
||||
result.VertexColor = float4(0, 0, 0, 1);
|
||||
#endif
|
||||
result.TBN[0] = float3(1, 0, 0);
|
||||
result.TBN[1] = float3(0, 1, 0);
|
||||
result.TBN[2] = float3(0, 0, 1);
|
||||
result.TwoSidedSign = input.IsFrontFace ? 1.0 : -1.0;
|
||||
result.SvPosition = input.Position;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return localVector;
|
||||
}
|
||||
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
{
|
||||
return worldVector;
|
||||
}
|
||||
|
||||
// Gets the current object position (supports instancing)
|
||||
float3 GetObjectPosition(MaterialInput input)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// Pixel Shader function for PostFx materials rendering
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
float4 PS_PostFx(PixelInput input) : SV_Target0
|
||||
{
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
return float4(material.Emissive, material.Opacity);
|
||||
}
|
||||
1085
Content/Editor/MaterialTemplates/SurfaceDeferred.shader
Normal file
1085
Content/Editor/MaterialTemplates/SurfaceDeferred.shader
Normal file
File diff suppressed because it is too large
Load Diff
1013
Content/Editor/MaterialTemplates/SurfaceForward.shader
Normal file
1013
Content/Editor/MaterialTemplates/SurfaceForward.shader
Normal file
File diff suppressed because it is too large
Load Diff
785
Content/Editor/MaterialTemplates/Terrain.shader
Normal file
785
Content/Editor/MaterialTemplates/Terrain.shader
Normal file
@@ -0,0 +1,785 @@
|
||||
// File generated by Flax Materials Editor
|
||||
// Version: @0
|
||||
|
||||
#define MATERIAL 1
|
||||
@3
|
||||
|
||||
// Enables/disables smooth terrain chunks LOD transitions (with morphing higher LOD near edges to the lower LOD in the neighbour)
|
||||
#define USE_SMOOTH_LOD_TRANSITION 1
|
||||
|
||||
// Switches between using 0, 4 or 8 heightmap layers (values: 0, 1, 2)
|
||||
#define TERRAIN_LAYERS_DATA_SIZE 2
|
||||
#define USE_TERRAIN_LAYERS (TERRAIN_LAYERS_DATA_SIZE > 0)
|
||||
|
||||
#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;
|
||||
float3 ViewPos;
|
||||
float ViewFar;
|
||||
float3 ViewDir;
|
||||
float TimeParam;
|
||||
float4 ViewInfo;
|
||||
float4 ScreenSize;
|
||||
float4 LightmapArea;
|
||||
float3 WorldInvScale;
|
||||
float WorldDeterminantSign;
|
||||
float PerInstanceRandom;
|
||||
float CurrentLOD;
|
||||
float ChunkSizeNextLOD;
|
||||
float TerrainChunkSizeLOD0;
|
||||
float4 HeightmapUVScaleBias;
|
||||
float4 NeighborLOD;
|
||||
float2 OffsetUV;
|
||||
float2 Dummy0;
|
||||
@1META_CB_END
|
||||
|
||||
#if CAN_USE_LIGHTMAP
|
||||
|
||||
// Irradiance and directionality prebaked lightmaps
|
||||
Texture2D Lightmap0 : register(t0);
|
||||
Texture2D Lightmap1 : register(t1);
|
||||
Texture2D Lightmap2 : register(t2);
|
||||
|
||||
#endif
|
||||
|
||||
// Terrain data
|
||||
Texture2D Heightmap : register(t3);
|
||||
Texture2D Splatmap0 : register(t4);
|
||||
Texture2D Splatmap1 : register(t5);
|
||||
|
||||
// Material shader resources
|
||||
@2
|
||||
|
||||
// Interpolants passed from the vertex shader
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 WorldPosition : TEXCOORD0;
|
||||
float2 TexCoord : TEXCOORD1;
|
||||
float2 LightmapUV : TEXCOORD2;
|
||||
float3 WorldNormal : TEXCOORD3;
|
||||
float HolesMask : TEXCOORD4;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||
#endif
|
||||
#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;
|
||||
float3 WorldNormal : TEXCOORD3;
|
||||
float HolesMask : TEXCOORD4;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||
#endif
|
||||
bool IsFrontFace : SV_IsFrontFace;
|
||||
};
|
||||
|
||||
// Material properties generation input
|
||||
struct MaterialInput
|
||||
{
|
||||
float3 WorldPosition;
|
||||
float TwoSidedSign;
|
||||
float2 TexCoord;
|
||||
#if USE_LIGHTMAP
|
||||
float2 LightmapUV;
|
||||
#endif
|
||||
float3x3 TBN;
|
||||
float4 SvPosition;
|
||||
float3 PreSkinnedPosition;
|
||||
float3 PreSkinnedNormal;
|
||||
float HolesMask;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 Layers[TERRAIN_LAYERS_DATA_SIZE];
|
||||
#endif
|
||||
#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;
|
||||
#if USE_LIGHTMAP
|
||||
result.LightmapUV = input.LightmapUV;
|
||||
#endif
|
||||
result.TBN = CalcTangentBasisFromWorldNormal(input.WorldNormal);
|
||||
result.TwoSidedSign = WorldDeterminantSign * (input.IsFrontFace ? 1.0 : -1.0);
|
||||
result.SvPosition = input.Position;
|
||||
result.HolesMask = input.HolesMask;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
result.Layers = input.Layers;
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
result.CustomVSToPS = input.CustomVSToPS;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix
|
||||
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
||||
{
|
||||
localToWorld[0] *= WorldInvScale.x;
|
||||
localToWorld[1] *= WorldInvScale.y;
|
||||
localToWorld[2] *= WorldInvScale.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)WorldMatrix;
|
||||
//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)WorldMatrix;
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localToWorld, worldVector);
|
||||
}
|
||||
|
||||
// Gets the current object position
|
||||
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
|
||||
float GetPerInstanceRandom(MaterialInput input)
|
||||
{
|
||||
return PerInstanceRandom;
|
||||
}
|
||||
|
||||
// Get the current object LOD transition dither factor
|
||||
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 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
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// Calculates LOD value (with fractional part for blending)
|
||||
float CalcLOD(float2 xy, float4 morph)
|
||||
{
|
||||
#if USE_SMOOTH_LOD_TRANSITION
|
||||
// Use LOD value based on Barycentric coordinates to morph to the lower LOD near chunk edges
|
||||
float4 lodCalculated = morph * CurrentLOD + NeighborLOD * (float4(1, 1, 1, 1) - morph);
|
||||
|
||||
// Pick a quadrant (top, left, right or bottom)
|
||||
float lod;
|
||||
if ((xy.x + xy.y) > 1)
|
||||
{
|
||||
if (xy.x < xy.y)
|
||||
{
|
||||
lod = lodCalculated.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
lod = lodCalculated.z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xy.x < xy.y)
|
||||
{
|
||||
lod = lodCalculated.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
lod = lodCalculated.x;
|
||||
}
|
||||
}
|
||||
|
||||
return lod;
|
||||
#else
|
||||
return CurrentLOD;
|
||||
#endif
|
||||
}
|
||||
|
||||
float3x3 CalcTangentToWorld(float4x4 world, float3x3 tangentToLocal)
|
||||
{
|
||||
float3x3 localToWorld = RemoveScaleFromLocalToWorld((float3x3)world);
|
||||
return mul(tangentToLocal, localToWorld);
|
||||
}
|
||||
|
||||
// Must match structure defined in TerrainManager.cpp
|
||||
struct TerrainVertexInput
|
||||
{
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float4 Morph : TEXCOORD1;
|
||||
};
|
||||
|
||||
// Vertex Shader function for terrain rendering
|
||||
META_VS(true, FEATURE_LEVEL_ES2)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 1, R8G8B8A8_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
VertexOutput VS(TerrainVertexInput input)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
// Calculate terrain LOD for this chunk
|
||||
float lodCalculated = CalcLOD(input.TexCoord, input.Morph);
|
||||
float lodValue = CurrentLOD;
|
||||
float morphAlpha = lodCalculated - CurrentLOD;
|
||||
|
||||
// Sample heightmap
|
||||
float2 heightmapUVs = input.TexCoord * HeightmapUVScaleBias.xy + HeightmapUVScaleBias.zw;
|
||||
#if USE_SMOOTH_LOD_TRANSITION
|
||||
float4 heightmapValueThisLOD = Heightmap.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
|
||||
float2 nextLODPos = round(input.TexCoord * ChunkSizeNextLOD) / ChunkSizeNextLOD;
|
||||
float2 heightmapUVsNextLOD = nextLODPos * HeightmapUVScaleBias.xy + HeightmapUVScaleBias.zw;
|
||||
float4 heightmapValueNextLOD = Heightmap.SampleLevel(SamplerPointClamp, heightmapUVsNextLOD, lodValue + 1);
|
||||
float4 heightmapValue = lerp(heightmapValueThisLOD, heightmapValueNextLOD, morphAlpha);
|
||||
bool isHole = max(heightmapValueThisLOD.b + heightmapValueThisLOD.a, heightmapValueNextLOD.b + heightmapValueNextLOD.a) >= 1.9f;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 splatmapValueThisLOD = Splatmap0.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
|
||||
float4 splatmapValueNextLOD = Splatmap0.SampleLevel(SamplerPointClamp, heightmapUVsNextLOD, lodValue + 1);
|
||||
float4 splatmap0Value = lerp(splatmapValueThisLOD, splatmapValueNextLOD, morphAlpha);
|
||||
#if TERRAIN_LAYERS_DATA_SIZE > 1
|
||||
splatmapValueThisLOD = Splatmap1.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
|
||||
splatmapValueNextLOD = Splatmap1.SampleLevel(SamplerPointClamp, heightmapUVsNextLOD, lodValue + 1);
|
||||
float4 splatmap1Value = lerp(splatmapValueThisLOD, splatmapValueNextLOD, morphAlpha);
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
float4 heightmapValue = Heightmap.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
|
||||
bool isHole = (heightmapValue.b + heightmapValue.a) >= 1.9f;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 splatmap0Value = Splatmap0.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
|
||||
#if TERRAIN_LAYERS_DATA_SIZE > 1
|
||||
float4 splatmap1Value = Splatmap1.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
float height = (float)((int)(heightmapValue.x * 255.0) + ((int)(heightmapValue.y * 255) << 8)) / 65535.0;
|
||||
|
||||
// Extract normal and the holes mask
|
||||
float2 normalTemp = float2(heightmapValue.b, heightmapValue.a) * 2.0f - 1.0f;
|
||||
float3 normal = float3(normalTemp.x, sqrt(1.0 - saturate(dot(normalTemp, normalTemp))), normalTemp.y);
|
||||
normal = normalize(normal);
|
||||
output.HolesMask = isHole ? 0 : 1;
|
||||
if (isHole)
|
||||
{
|
||||
normal = float3(0, 1, 0);
|
||||
}
|
||||
|
||||
// Construct vertex position
|
||||
#if USE_SMOOTH_LOD_TRANSITION
|
||||
float2 positionXZThisLOD = input.TexCoord * TerrainChunkSizeLOD0;
|
||||
float2 positionXZNextLOD = nextLODPos * TerrainChunkSizeLOD0;
|
||||
float2 positionXZ = lerp(positionXZThisLOD, positionXZNextLOD, morphAlpha);
|
||||
#else
|
||||
float2 positionXZ = input.TexCoord * TerrainChunkSizeLOD0;
|
||||
#endif
|
||||
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
||||
|
||||
// Compute world space vertex position
|
||||
output.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
||||
|
||||
// Pass vertex attributes
|
||||
#if USE_SMOOTH_LOD_TRANSITION
|
||||
float2 texCoord = lerp(input.TexCoord, nextLODPos, morphAlpha);
|
||||
#else
|
||||
float2 texCoord = input.TexCoord;
|
||||
#endif
|
||||
output.TexCoord = positionXZ * (1.0f / TerrainChunkSizeLOD0) + OffsetUV;
|
||||
output.LightmapUV = texCoord * LightmapArea.zw + LightmapArea.xy;
|
||||
|
||||
// Extract terrain layers weights from the splatmap
|
||||
#if USE_TERRAIN_LAYERS
|
||||
output.Layers[0] = splatmap0Value;
|
||||
#if TERRAIN_LAYERS_DATA_SIZE > 1
|
||||
output.Layers[1] = splatmap1Value;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Compute world space normal vector
|
||||
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
output.WorldNormal = tangentToWorld[2];
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
#if USE_POSITION_OFFSET || USE_TESSELLATION || USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
MaterialInput materialInput = (MaterialInput)0;
|
||||
materialInput.WorldPosition = output.WorldPosition;
|
||||
materialInput.TexCoord = output.TexCoord;
|
||||
#if USE_LIGHTMAP
|
||||
materialInput.LightmapUV = output.LightmapUV;
|
||||
#endif
|
||||
materialInput.TBN = CalcTangentBasisFromWorldNormal(output.WorldNormal);
|
||||
materialInput.TwoSidedSign = WorldDeterminantSign;
|
||||
materialInput.SvPosition = output.Position;
|
||||
materialInput.PreSkinnedPosition = position;
|
||||
materialInput.PreSkinnedNormal = normal;
|
||||
materialInput.HolesMask = output.HolesMask;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
materialInput.Layers = output.Layers;
|
||||
#endif
|
||||
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_TESSELLATION
|
||||
|
||||
// Interpolants passed from the hull shader to the domain shader
|
||||
struct TessalationHSToDS
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 WorldPosition : TEXCOORD0;
|
||||
float2 TexCoord : TEXCOORD1;
|
||||
float2 LightmapUV : TEXCOORD2;
|
||||
float3 WorldNormal : TEXCOORD3;
|
||||
float HolesMask : TEXCOORD4;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||
#endif
|
||||
float TessellationMultiplier : TESS;
|
||||
};
|
||||
|
||||
// Interpolants passed from the domain shader and to the pixel shader
|
||||
struct TessalationDSToPS
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 WorldPosition : TEXCOORD0;
|
||||
float2 TexCoord : TEXCOORD1;
|
||||
float2 LightmapUV : TEXCOORD2;
|
||||
float3 WorldNormal : TEXCOORD3;
|
||||
float HolesMask : TEXCOORD4;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||
#endif
|
||||
};
|
||||
|
||||
MaterialInput GetMaterialInput(TessalationDSToPS input)
|
||||
{
|
||||
MaterialInput result = (MaterialInput)0;
|
||||
result.WorldPosition = input.WorldPosition;
|
||||
result.TexCoord = input.TexCoord;
|
||||
#if USE_LIGHTMAP
|
||||
result.LightmapUV = input.LightmapUV;
|
||||
#endif
|
||||
result.TBN = CalcTangentBasisFromWorldNormal(input.WorldNormal);
|
||||
result.TwoSidedSign = WorldDeterminantSign;
|
||||
result.SvPosition = input.Position;
|
||||
result.HolesMask = input.HolesMask;
|
||||
#if USE_TERRAIN_LAYERS
|
||||
result.Layers = input.Layers;
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
result.CustomVSToPS = input.CustomVSToPS;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
struct TessalationPatch
|
||||
{
|
||||
float EdgeTessFactor[3] : SV_TessFactor;
|
||||
float InsideTessFactor : SV_InsideTessFactor;
|
||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
||||
float3 B210 : POSITION4;
|
||||
float3 B120 : POSITION5;
|
||||
float3 B021 : POSITION6;
|
||||
float3 B012 : POSITION7;
|
||||
float3 B102 : POSITION8;
|
||||
float3 B201 : POSITION9;
|
||||
float3 B111 : CENTER;
|
||||
#endif
|
||||
};
|
||||
|
||||
TessalationPatch HS_PatchConstant(InputPatch<VertexOutput, 3> input)
|
||||
{
|
||||
TessalationPatch output;
|
||||
|
||||
// Average tess factors along edges, and pick an edge tess factor for the interior tessellation
|
||||
float4 TessellationMultipliers;
|
||||
TessellationMultipliers.x = 0.5f * (input[1].TessellationMultiplier + input[2].TessellationMultiplier);
|
||||
TessellationMultipliers.y = 0.5f * (input[2].TessellationMultiplier + input[0].TessellationMultiplier);
|
||||
TessellationMultipliers.z = 0.5f * (input[0].TessellationMultiplier + input[1].TessellationMultiplier);
|
||||
TessellationMultipliers.w = 0.333f * (input[0].TessellationMultiplier + input[1].TessellationMultiplier + input[2].TessellationMultiplier);
|
||||
|
||||
TessellationMultipliers = clamp(TessellationMultipliers, 1, MAX_TESSELLATION_FACTOR);
|
||||
|
||||
output.EdgeTessFactor[0] = TessellationMultipliers.x; // 1->2 edge
|
||||
output.EdgeTessFactor[1] = TessellationMultipliers.y; // 2->0 edge
|
||||
output.EdgeTessFactor[2] = TessellationMultipliers.z; // 0->1 edge
|
||||
output.InsideTessFactor = TessellationMultipliers.w;
|
||||
|
||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
||||
// Calculate PN-Triangle coefficients
|
||||
// Refer to Vlachos 2001 for the original formula
|
||||
float3 p1 = input[0].WorldPosition;
|
||||
float3 p2 = input[1].WorldPosition;
|
||||
float3 p3 = input[2].WorldPosition;
|
||||
float3 n1 = input[0].WorldNormal;
|
||||
float3 n2 = input[1].WorldNormal;
|
||||
float3 n3 = input[2].WorldNormal;
|
||||
|
||||
// Calculate control points
|
||||
output.B210 = (2.0f * p1 + p2 - dot((p2 - p1), n1) * n1) / 3.0f;
|
||||
output.B120 = (2.0f * p2 + p1 - dot((p1 - p2), n2) * n2) / 3.0f;
|
||||
output.B021 = (2.0f * p2 + p3 - dot((p3 - p2), n2) * n2) / 3.0f;
|
||||
output.B012 = (2.0f * p3 + p2 - dot((p2 - p3), n3) * n3) / 3.0f;
|
||||
output.B102 = (2.0f * p3 + p1 - dot((p1 - p3), n3) * n3) / 3.0f;
|
||||
output.B201 = (2.0f * p1 + p3 - dot((p3 - p1), n1) * n1) / 3.0f;
|
||||
float3 e = (output.B210 + output.B120 + output.B021 +
|
||||
output.B012 + output.B102 + output.B201) / 6.0f;
|
||||
float3 v = (p1 + p2 + p3) / 3.0f;
|
||||
output.B111 = e + ((e - v) / 2.0f);
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
META_HS(USE_TESSELLATION, FEATURE_LEVEL_SM5)
|
||||
META_HS_PATCH(TESSELLATION_IN_CONTROL_POINTS)
|
||||
[domain("tri")]
|
||||
[partitioning("fractional_odd")]
|
||||
[outputtopology("triangle_cw")]
|
||||
[maxtessfactor(MAX_TESSELLATION_FACTOR)]
|
||||
[outputcontrolpoints(3)]
|
||||
[patchconstantfunc("HS_PatchConstant")]
|
||||
TessalationHSToDS HS(InputPatch<VertexOutput, TESSELLATION_IN_CONTROL_POINTS> input, uint ControlPointID : SV_OutputControlPointID)
|
||||
{
|
||||
TessalationHSToDS output;
|
||||
|
||||
// Pass through shader
|
||||
#define COPY(thing) output.thing = input[ControlPointID].thing;
|
||||
COPY(Position);
|
||||
COPY(WorldPosition);
|
||||
COPY(TexCoord);
|
||||
COPY(LightmapUV);
|
||||
COPY(WorldNormal);
|
||||
COPY(HolesMask);
|
||||
COPY(TessellationMultiplier);
|
||||
#if USE_TERRAIN_LAYERS
|
||||
COPY(Layers);
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
COPY(CustomVSToPS);
|
||||
#endif
|
||||
#undef COPY
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PHONG
|
||||
|
||||
// Orthogonal projection on to plane
|
||||
float3 ProjectOntoPlane(float3 planeNormal, float3 planePoint, float3 pointToProject)
|
||||
{
|
||||
return pointToProject - dot(pointToProject-planePoint, planeNormal) * planeNormal;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
META_DS(USE_TESSELLATION, FEATURE_LEVEL_SM5)
|
||||
[domain("tri")]
|
||||
TessalationDSToPS DS(TessalationPatch constantData, float3 barycentricCoords : SV_DomainLocation, const OutputPatch<TessalationHSToDS, 3> input)
|
||||
{
|
||||
TessalationDSToPS output;
|
||||
|
||||
// Get the barycentric coords
|
||||
float U = barycentricCoords.x;
|
||||
float V = barycentricCoords.y;
|
||||
float W = barycentricCoords.z;
|
||||
|
||||
// Interpolate patch attributes to generated vertices
|
||||
#define INTERPOLATE(thing) output.thing = U * input[0].thing + V * input[1].thing + W * input[2].thing
|
||||
#define COPY(thing) output.thing = input[0].thing
|
||||
INTERPOLATE(Position);
|
||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
||||
// Precompute squares and squares * 3
|
||||
float UU = U * U;
|
||||
float VV = V * V;
|
||||
float WW = W * W;
|
||||
float UU3 = UU * 3.0f;
|
||||
float VV3 = VV * 3.0f;
|
||||
float WW3 = WW * 3.0f;
|
||||
|
||||
// Interpolate using barycentric coordinates and PN Triangle control points
|
||||
output.WorldPosition =
|
||||
input[0].WorldPosition * UU * U +
|
||||
input[1].WorldPosition * VV * V +
|
||||
input[2].WorldPosition * WW * W +
|
||||
constantData.B210 * UU3 * V +
|
||||
constantData.B120 * VV3 * U +
|
||||
constantData.B021 * VV3 * W +
|
||||
constantData.B012 * WW3 * V +
|
||||
constantData.B102 * WW3 * U +
|
||||
constantData.B201 * UU3 * W +
|
||||
constantData.B111 * 6.0f * W * U * V;
|
||||
#else
|
||||
INTERPOLATE(WorldPosition);
|
||||
#endif
|
||||
INTERPOLATE(TexCoord);
|
||||
INTERPOLATE(LightmapUV);
|
||||
INTERPOLATE(WorldNormal);
|
||||
INTERPOLATE(HolesMask);
|
||||
#if USE_TERRAIN_LAYERS
|
||||
UNROLL
|
||||
for (int i = 0; i < TERRAIN_LAYERS_DATA_SIZE; i++)
|
||||
{
|
||||
INTERPOLATE(Layers[i]);
|
||||
}
|
||||
#endif
|
||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||
UNROLL
|
||||
for (int i = 0; i < CUSTOM_VERTEX_INTERPOLATORS_COUNT; i++)
|
||||
{
|
||||
INTERPOLATE(CustomVSToPS[i]);
|
||||
}
|
||||
#endif
|
||||
#undef INTERPOLATE
|
||||
#undef COPY
|
||||
|
||||
// Interpolating normal can unnormalize it, so normalize it
|
||||
output.WorldNormal = normalize(output.WorldNormal);
|
||||
|
||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PHONG
|
||||
// Orthogonal projection in the tangent planes
|
||||
float3 posProjectedU = ProjectOntoPlane(input[0].WorldNormal, input[0].WorldPosition, output.WorldPosition);
|
||||
float3 posProjectedV = ProjectOntoPlane(input[1].WorldNormal, input[1].WorldPosition, output.WorldPosition);
|
||||
float3 posProjectedW = ProjectOntoPlane(input[2].WorldNormal, input[2].WorldPosition, output.WorldPosition);
|
||||
|
||||
// Interpolate the projected points
|
||||
output.WorldPosition = U * posProjectedU + V * posProjectedV + W * posProjectedW;
|
||||
#endif
|
||||
|
||||
// Perform displacement mapping
|
||||
#if USE_DISPLACEMENT
|
||||
MaterialInput materialInput = GetMaterialInput(output);
|
||||
Material material = GetMaterialDS(materialInput);
|
||||
output.WorldPosition += material.WorldDisplacement;
|
||||
#endif
|
||||
|
||||
// Recalculate the clip space position
|
||||
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_LIGHTMAP
|
||||
|
||||
float3 SampleLightmap(Material material, MaterialInput materialInput)
|
||||
{
|
||||
// Sample lightmaps
|
||||
float4 lightmap0 = Lightmap0.Sample(SamplerLinearClamp, materialInput.LightmapUV);
|
||||
float4 lightmap1 = Lightmap1.Sample(SamplerLinearClamp, materialInput.LightmapUV);
|
||||
float4 lightmap2 = Lightmap2.Sample(SamplerLinearClamp, materialInput.LightmapUV);
|
||||
|
||||
// Unpack H-basis
|
||||
float3 h0 = float3(lightmap0.x, lightmap1.x, lightmap2.x);
|
||||
float3 h1 = float3(lightmap0.y, lightmap1.y, lightmap2.y);
|
||||
float3 h2 = float3(lightmap0.z, lightmap1.z, lightmap2.z);
|
||||
float3 h3 = float3(lightmap0.w, lightmap1.w, lightmap2.w);
|
||||
|
||||
// Sample baked diffuse irradiance from the H-basis coefficients
|
||||
float3 normal = material.TangentNormal;
|
||||
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
|
||||
normal *= material.TangentNormal;
|
||||
#endif
|
||||
return GetHBasisIrradiance(normal, h0, h1, h2, h3) / PI;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Pixel Shader function for GBuffer Pass
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
META_PERMUTATION_1(USE_LIGHTMAP=0)
|
||||
META_PERMUTATION_1(USE_LIGHTMAP=1)
|
||||
void PS_GBuffer(
|
||||
in PixelInput input
|
||||
,out float4 Light : SV_Target0
|
||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||
,out float4 RT0 : SV_Target1
|
||||
,out float4 RT1 : SV_Target2
|
||||
,out float4 RT2 : SV_Target3
|
||||
#if USE_GBUFFER_CUSTOM_DATA
|
||||
,out float4 RT3 : SV_Target4
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Light = 0;
|
||||
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
#if USE_LIGHTMAP
|
||||
|
||||
float3 diffuseColor = GetDiffuseColor(material.Color, material.Metalness);
|
||||
float3 specularColor = GetSpecularColor(material.Color, material.Specular, material.Metalness);
|
||||
|
||||
// Sample lightmap
|
||||
float3 diffuseIndirectLighting = SampleLightmap(material, materialInput);
|
||||
|
||||
// Apply static indirect light
|
||||
Light.rgb = diffuseColor * diffuseIndirectLighting * AOMultiBounce(material.AO, diffuseColor);
|
||||
|
||||
#endif
|
||||
|
||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||
|
||||
// Pack material properties to GBuffer
|
||||
RT0 = float4(material.Color, material.AO);
|
||||
RT1 = float4(material.WorldNormal * 0.5 + 0.5, MATERIAL_SHADING_MODEL * (1.0 / 3.0));
|
||||
RT2 = float4(material.Roughness, material.Metalness, material.Specular, 0);
|
||||
|
||||
// Custom data
|
||||
#if USE_GBUFFER_CUSTOM_DATA
|
||||
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
|
||||
RT3 = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
|
||||
RT3 = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#else
|
||||
RT3 = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Add light emission
|
||||
#if USE_EMISSIVE
|
||||
Light.rgb += material.Emissive;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// Handle blending as faked forward pass (use Light buffer and skip GBuffer modification)
|
||||
Light = float4(material.Emissive, material.Opacity);
|
||||
|
||||
#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 MATERIAL_MASKED
|
||||
// Perform per pixel clipping if material requries it
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
#if GLSL
|
||||
OutColor = 0;
|
||||
#endif
|
||||
}
|
||||
BIN
Content/Editor/Particles/Constant Burst.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Constant Burst.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Particle Material Preview.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Particle Material Preview.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Periodic Burst.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Periodic Burst.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Ribbon Spiral.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Ribbon Spiral.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Atlas Normal.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Smoke Atlas Normal.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Atlas.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Smoke Atlas.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Smoke.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Smoke.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Particles/Sparks.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Particles/Sparks.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Primitives/Capsule.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Primitives/Capsule.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Primitives/Cone.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Primitives/Cone.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Primitives/Cube.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Primitives/Cube.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Primitives/Cylinder.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Primitives/Cylinder.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Primitives/Plane.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Primitives/Plane.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Primitives/Sphere.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Primitives/Sphere.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
24
Content/Editor/Scripting/ScriptTemplate.cpp
Normal file
24
Content/Editor/Scripting/ScriptTemplate.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
%copyright%
|
||||
#include "%filename%.h"
|
||||
|
||||
%class%::%class%(const SpawnParams& params)
|
||||
: Script(params)
|
||||
{
|
||||
// Enable ticking OnUpdate function
|
||||
_tickUpdate = true;
|
||||
}
|
||||
|
||||
void %class%::OnEnable()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is enabled (eg. register for events)
|
||||
}
|
||||
|
||||
void %class%::OnDisable()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is disabled (eg. unregister from events)
|
||||
}
|
||||
|
||||
void %class%::OnUpdate()
|
||||
{
|
||||
// Here you can add code that needs to be called every frame
|
||||
}
|
||||
29
Content/Editor/Scripting/ScriptTemplate.cs
Normal file
29
Content/Editor/Scripting/ScriptTemplate.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
%copyright%using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace %namespace%
|
||||
{
|
||||
public class %class% : Script
|
||||
{
|
||||
public override void OnStart()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is created, just before the first game update
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is enabled (eg. register for events)
|
||||
}
|
||||
|
||||
public override void OnDisable()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is disabled (eg. unregister from events)
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
// Here you can add code that needs to be called every frame
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Content/Editor/Scripting/ScriptTemplate.h
Normal file
14
Content/Editor/Scripting/ScriptTemplate.h
Normal file
@@ -0,0 +1,14 @@
|
||||
%copyright%
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/Script.h"
|
||||
|
||||
API_CLASS() class %module%%class% : public Script
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE(%class%);
|
||||
|
||||
// [Script]
|
||||
void OnEnable() override;
|
||||
void OnDisable() override;
|
||||
void OnUpdate() override;
|
||||
};
|
||||
12
Content/Editor/Scripting/ShaderTemplate.shader
Normal file
12
Content/Editor/Scripting/ShaderTemplate.shader
Normal file
@@ -0,0 +1,12 @@
|
||||
%copyright%#include "./Flax/Common.hlsl"
|
||||
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4 Color;
|
||||
META_CB_END
|
||||
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Fullscreen(Quad_VS2PS input) : SV_Target
|
||||
{
|
||||
// Solid color fill from the constant buffer passed from code
|
||||
return Color;
|
||||
}
|
||||
BIN
Content/Editor/SimplySky.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/SimplySky.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/VisjectSurface.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/VisjectSurface.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Normal file
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
Reference in New Issue
Block a user