Browse Source

Separate unlit particle shaders & techniques for optional soft particle support. Soft particles versions of renderpaths. Soft particle shaders adapted from work by 1vanK & MonkeyFirst (https://github.com/1vanK/Urho3DSoftParticles). Fix Shadow shader failing for billboards. Fix ForwardHWDepth renderpath unnecessarily rendering depth in a separate pass. Closes #1623.

Lasse Öörni 9 years ago
parent
commit
861a85fb1f

+ 2 - 0
Docs/Reference.dox

@@ -1589,6 +1589,8 @@ The render path starts by allocating a readable depth-stencil texture the same s
 
 The ForwardDepth.xml render path does the same, but using a linear depth rendertarget instead of a hardware depth texture. The advantage is better compatibility (guaranteed to work without checking \ref Graphics::GetReadableDepthSupport "GetReadableDepthSupport()") but it has worse performance as it will perform an additional full scene rendering pass.
 
+Renderpaths whose name ends with "SP" implement soft particles by comparing the scene depth to particles' depth.
+
 \section RenderPaths_ForwardLighting Forward lighting special considerations
 
 Otherwise fully customized scene render passes can be specified, but there are a few things to remember related to forward lighting:

+ 8 - 0
bin/CoreData/RenderPaths/DeferredHWDepthSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/DeferredHWDepth.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" depthstencil="depth" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES HWDEPTH" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 8 - 0
bin/CoreData/RenderPaths/DeferredSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/Deferred.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 8 - 0
bin/CoreData/RenderPaths/ForwardDepthSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/ForwardDepth.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 1 - 3
bin/CoreData/RenderPaths/ForwardHWDepth.xml

@@ -1,8 +1,6 @@
 <renderpath>
     <rendertarget name="depth" sizedivisor="1 1" format="readabledepth" />
-    <command type="clear" depth="1.0" output="depth" />
-    <command type="scenepass" pass="shadow" output="depth" />
-    <command type="clear" color="fog" depthstencil="depth" />
+    <command type="clear" color="fog" depth="1.0" stencil="0" depthstencil="depth" />
     <command type="scenepass" pass="base" vertexlights="true" metadata="base" depthstencil="depth" />
     <command type="forwardlights" pass="light" depthstencil="depth" />
     <command type="scenepass" pass="postopaque" depthstencil="depth" />

+ 8 - 0
bin/CoreData/RenderPaths/ForwardHWDepthSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/ForwardHWDepth.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" depthstencil="depth" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES HWDEPTH" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 8 - 0
bin/CoreData/RenderPaths/PBRDeferredHWDepthSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/PBRDeferredHWDepth.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" depthstencil="depth" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES HWDEPTH" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 8 - 0
bin/CoreData/RenderPaths/PBRDeferredSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/PBRDeferred.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 8 - 0
bin/CoreData/RenderPaths/PrepassHWDepthSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/PrepassHWDepth.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" depthstencil="depth" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES HWDEPTH" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 8 - 0
bin/CoreData/RenderPaths/PrepassSP.xml

@@ -0,0 +1,8 @@
+<renderpath inherit="RenderPaths/Prepass.xml">
+    <replace sel="/renderpath/command[@type='scenepass' and @pass='alpha']">
+        <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" vsdefines="SOFTPARTICLES" psdefines="SOFTPARTICLES" >
+            <parameter name="SoftParticleFadeScale" value="1" />
+            <texture unit="depth" name="depth" />
+        </command>
+    </replace>
+</renderpath>

+ 22 - 0
bin/CoreData/Shaders/GLSL/LitParticle.glsl

@@ -1,6 +1,7 @@
 #include "Uniforms.glsl"
 #include "Samplers.glsl"
 #include "Transform.glsl"
+#include "ScreenPos.glsl"
 #include "Lighting.glsl"
 #include "Fog.glsl"
 
@@ -9,6 +10,10 @@ varying vec4 vWorldPos;
 #ifdef VERTEXCOLOR
     varying vec4 vColor;
 #endif
+#ifdef SOFTPARTICLES
+    varying vec4 vScreenPos;
+    uniform float cSoftParticleFadeScale;
+#endif
 #ifdef PERPIXEL
     #ifdef SHADOW
         #ifndef GL_ES
@@ -35,6 +40,10 @@ void VS()
     vTexCoord = GetTexCoord(iTexCoord);
     vWorldPos = vec4(worldPos, GetDepth(gl_Position));
 
+    #ifdef SOFTPARTICLES
+        vScreenPos = GetScreenPos(gl_Position);
+    #endif
+
     #ifdef VERTEXCOLOR
         vColor = iColor;
     #endif
@@ -93,6 +102,19 @@ void PS()
         float fogFactor = GetFogFactor(vWorldPos.w);
     #endif
 
+    // Soft particle fade
+    #ifdef SOFTPARTICLES
+        float particleDepth = vWorldPos.w;
+        #ifdef HWDEPTH
+            float depth = ReconstructDepth(texture2DProj(sDepthBuffer, vScreenPos).r);
+        #else
+            float depth = DecodeDepth(texture2DProj(sDepthBuffer, vScreenPos).rgb);
+        #endif
+        float diffZ = abs(depth - particleDepth) * (cFarClipPS - cNearClipPS);
+        float fade = clamp(1.0 - diffZ * cSoftParticleFadeScale, 0.0, 1.0);
+        diffColor.a -= fade;
+    #endif
+
     #ifdef PERPIXEL
         // Per-pixel forward lighting
         vec3 lightColor;

+ 77 - 0
bin/CoreData/Shaders/GLSL/UnlitParticle.glsl

@@ -0,0 +1,77 @@
+#include "Uniforms.glsl"
+#include "Samplers.glsl"
+#include "Transform.glsl"
+#include "ScreenPos.glsl"
+#include "Fog.glsl"
+
+varying vec2 vTexCoord;
+varying vec4 vWorldPos;
+#ifdef VERTEXCOLOR
+    varying vec4 vColor;
+#endif
+#ifdef SOFTPARTICLES
+    varying vec4 vScreenPos;
+    uniform float cSoftParticleFadeScale;
+#endif
+
+void VS()
+{
+    mat4 modelMatrix = iModelMatrix;
+    vec3 worldPos = GetWorldPos(modelMatrix);
+    gl_Position = GetClipPos(worldPos);
+    vTexCoord = GetTexCoord(iTexCoord);
+    vWorldPos = vec4(worldPos, GetDepth(gl_Position));
+
+    #ifdef SOFTPARTICLES
+        vScreenPos = GetScreenPos(gl_Position);
+    #endif
+
+    #ifdef VERTEXCOLOR
+        vColor = iColor;
+    #endif
+
+}
+
+void PS()
+{
+    // Get material diffuse albedo
+    #ifdef DIFFMAP
+        vec4 diffColor = cMatDiffColor * texture2D(sDiffMap, vTexCoord);
+        #ifdef ALPHAMASK
+            if (diffColor.a < 0.5)
+                discard;
+        #endif
+    #else
+        vec4 diffColor = cMatDiffColor;
+    #endif
+
+    #ifdef VERTEXCOLOR
+        diffColor *= vColor;
+    #endif
+
+    // Get fog factor
+    #ifdef HEIGHTFOG
+        float fogFactor = GetHeightFogFactor(vWorldPos.w, vWorldPos.y);
+    #else
+        float fogFactor = GetFogFactor(vWorldPos.w);
+    #endif
+
+    // Soft particle fade
+    #ifdef SOFTPARTICLES
+        float particleDepth = vWorldPos.w;
+        #ifdef HWDEPTH
+            float depth = ReconstructDepth(texture2DProj(sDepthBuffer, vScreenPos).r);
+        #else
+            float depth = DecodeDepth(texture2DProj(sDepthBuffer, vScreenPos).rgb);
+        #endif
+        float diffZ = abs(depth - particleDepth) * (cFarClipPS - cNearClipPS);
+        float fade = clamp(1.0 - diffZ * cSoftParticleFadeScale, 0.0, 1.0);
+        #ifndef ADDITIVE
+            diffColor.a -= fade;
+        #else
+            diffColor.rgb -= fade;
+        #endif
+    #endif
+
+    gl_FragColor = vec4(GetFog(diffColor.rgb, fogFactor), diffColor.a);
+}

+ 36 - 0
bin/CoreData/Shaders/HLSL/LitParticle.hlsl

@@ -2,8 +2,22 @@
 #include "Samplers.hlsl"
 #include "Transform.hlsl"
 #include "Lighting.hlsl"
+#include "ScreenPos.hlsl"
 #include "Fog.hlsl"
 
+#if defined(COMPILEPS) && defined(SOFTPARTICLES)
+#ifndef D3D11
+// D3D9 uniform
+uniform float cSoftParticleFadeScale;
+#else
+// D3D11 constant buffer
+cbuffer CustomPS : register(b6)
+{
+    float cSoftParticleFadeScale;
+}
+#endif
+#endif
+
 void VS(float4 iPos : POSITION,
     #if !defined(BILLBOARD) && !defined(TRAILFACECAM)
         float3 iNormal : NORMAL,
@@ -28,6 +42,9 @@ void VS(float4 iPos : POSITION,
         float4 iTangent : TANGENT,
     #endif
     out float2 oTexCoord : TEXCOORD0,
+    #ifdef SOFTPARTICLES
+        out float4 oScreenPos : TEXCOORD1,
+    #endif
     out float4 oWorldPos : TEXCOORD3,
     #if PERPIXEL
         #ifdef SHADOW
@@ -65,6 +82,10 @@ void VS(float4 iPos : POSITION,
         oClip = dot(oPos, cClipPlane);
     #endif
 
+    #ifdef SOFTPARTICLES
+        oScreenPos = GetScreenPos(oPos);
+    #endif
+
     #ifdef VERTEXCOLOR
         oColor = iColor;
     #endif
@@ -98,6 +119,9 @@ void VS(float4 iPos : POSITION,
 }
 
 void PS(float2 iTexCoord : TEXCOORD0,
+    #ifdef SOFTPARTICLES
+        float4 iScreenPos: TEXCOORD1,
+    #endif
     float4 iWorldPos : TEXCOORD3,
     #ifdef PERPIXEL
         #ifdef SHADOW
@@ -143,6 +167,18 @@ void PS(float2 iTexCoord : TEXCOORD0,
         float fogFactor = GetFogFactor(iWorldPos.w);
     #endif
 
+    // Soft particle fade
+    #ifdef SOFTPARTICLES
+        float particleDepth = iWorldPos.w;
+        float depth = Sample2DProj(DepthBuffer, iScreenPos).r;
+        #ifdef HWDEPTH
+            depth = ReconstructDepth(depth);
+        #endif
+        float diffZ = abs(depth - particleDepth) * (cFarClipPS - cNearClipPS);
+        float fade = saturate(1.0 - diffZ * cSoftParticleFadeScale);
+        diffColor.a -= fade;
+    #endif
+
     #ifdef PERPIXEL
         // Per-pixel forward lighting
         float3 lightColor;

+ 5 - 2
bin/CoreData/Shaders/HLSL/Shadow.hlsl

@@ -3,6 +3,9 @@
 #include "Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
+    #ifndef NOUV
+        float2 iTexCoord : TEXCOORD0,
+    #endif
     #ifdef SKINNED
         float4 iBlendWeights : BLENDWEIGHT,
         int4 iBlendIndices : BLENDINDICES,
@@ -10,8 +13,8 @@ void VS(float4 iPos : POSITION,
     #ifdef INSTANCED
         float4x3 iModelInstance : TEXCOORD4,
     #endif
-    #ifndef NOUV
-        float2 iTexCoord : TEXCOORD0,
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
+        float2 iSize : TEXCOORD1,
     #endif
     #ifdef VSM_SHADOW
         out float3 oTexCoord : TEXCOORD0,

+ 132 - 0
bin/CoreData/Shaders/HLSL/UnlitParticle.hlsl

@@ -0,0 +1,132 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+#include "Fog.hlsl"
+
+#if defined(COMPILEPS) && defined(SOFTPARTICLES)
+#ifndef D3D11
+// D3D9 uniform
+uniform float cSoftParticleFadeScale;
+#else
+// D3D11 constant buffer
+cbuffer CustomPS : register(b6)
+{
+    float cSoftParticleFadeScale;
+}
+#endif
+#endif
+
+void VS(float4 iPos : POSITION,
+    #ifndef NOUV
+        float2 iTexCoord : TEXCOORD0,
+    #endif
+    #ifdef VERTEXCOLOR
+        float4 iColor : COLOR0,
+    #endif
+    #ifdef SKINNED
+        float4 iBlendWeights : BLENDWEIGHT,
+        int4 iBlendIndices : BLENDINDICES,
+    #endif
+    #ifdef INSTANCED
+        float4x3 iModelInstance : TEXCOORD4,
+    #endif
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
+        float2 iSize : TEXCOORD1,
+    #endif
+    #if defined(DIRBILLBOARD) || defined(TRAILBONE)
+        float3 iNormal : NORMAL,
+    #endif
+    #if defined(TRAILFACECAM) || defined(TRAILBONE)
+        float4 iTangent : TANGENT,
+    #endif
+    out float2 oTexCoord : TEXCOORD0,
+    #ifdef SOFTPARTICLES
+        out float4 oScreenPos : TEXCOORD1,
+    #endif
+    out float4 oWorldPos : TEXCOORD2,
+    #ifdef VERTEXCOLOR
+        out float4 oColor : COLOR0,
+    #endif
+    #if defined(D3D11) && defined(CLIPPLANE)
+        out float oClip : SV_CLIPDISTANCE0,
+    #endif
+    out float4 oPos : OUTPOSITION)
+{
+    // Define a 0,0 UV coord if not expected from the vertex data
+    #ifdef NOUV
+    float2 iTexCoord = float2(0.0, 0.0);
+    #endif
+
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    oTexCoord = GetTexCoord(iTexCoord);
+    oWorldPos = float4(worldPos, GetDepth(oPos));
+
+    #if defined(D3D11) && defined(CLIPPLANE)
+        oClip = dot(oPos, cClipPlane);
+    #endif
+
+    #ifdef SOFTPARTICLES
+        oScreenPos = GetScreenPos(oPos);
+    #endif
+
+    #ifdef VERTEXCOLOR
+        oColor = iColor;
+    #endif
+}
+
+void PS(float2 iTexCoord : TEXCOORD0,
+    #ifdef SOFTPARTICLES
+        float4 iScreenPos: TEXCOORD1,
+    #endif
+    float4 iWorldPos: TEXCOORD2,
+    #ifdef VERTEXCOLOR
+        float4 iColor : COLOR0,
+    #endif
+    #if defined(D3D11) && defined(CLIPPLANE)
+        float iClip : SV_CLIPDISTANCE0,
+    #endif
+    out float4 oColor : OUTCOLOR0)
+{
+    // Get material diffuse albedo
+    #ifdef DIFFMAP
+        float4 diffColor = cMatDiffColor * Sample2D(DiffMap, iTexCoord);
+        #ifdef ALPHAMASK
+            if (diffColor.a < 0.5)
+                discard;
+        #endif
+    #else
+        float4 diffColor = cMatDiffColor;
+    #endif
+
+    #ifdef VERTEXCOLOR
+        diffColor *= iColor;
+    #endif
+
+    // Get fog factor
+    #ifdef HEIGHTFOG
+        float fogFactor = GetHeightFogFactor(iWorldPos.w, iWorldPos.y);
+    #else
+        float fogFactor = GetFogFactor(iWorldPos.w);
+    #endif
+    
+    // Soft particle fade
+    #ifdef SOFTPARTICLES
+        float particleDepth = iWorldPos.w;
+        float depth = Sample2DProj(DepthBuffer, iScreenPos).r;
+        #ifdef HWDEPTH
+            depth = ReconstructDepth(depth);
+        #endif
+        float diffZ = abs(depth - particleDepth) * (cFarClipPS - cNearClipPS);
+        float fade = saturate(1.0 - diffZ * cSoftParticleFadeScale);
+        #ifndef ADDITIVE
+            diffColor.a -= fade;
+        #else
+            diffColor.rgb -= fade;
+        #endif
+    #endif
+
+    oColor = float4(GetFog(diffColor.rgb, fogFactor), diffColor.a);
+}

+ 3 - 0
bin/CoreData/Techniques/DiffUnlitParticleAdd.xml

@@ -0,0 +1,3 @@
+<technique vs="UnlitParticle" ps="UnlitParticle" vsdefines="VERTEXCOLOR" psdefines="DIFFMAP VERTEXCOLOR ADDITIVE">
+    <pass name="alpha" depthwrite="false" blend="add" />
+</technique>

+ 3 - 0
bin/CoreData/Techniques/DiffUnlitParticleAlpha.xml

@@ -0,0 +1,3 @@
+<technique vs="UnlitParticle" ps="UnlitParticle" vsdefines="VERTEXCOLOR" psdefines="DIFFMAP VERTEXCOLOR">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+</technique>

+ 1 - 1
bin/Data/Materials/LitSmoke.xml

@@ -1,5 +1,5 @@
 <material>
     <technique name="Techniques/DiffLitParticleAlpha.xml" />
-    <parameter name="MatDiffColor" value="0.5 0.5 0.5 0.5" />    
+    <parameter name="MatDiffColor" value="0.5 0.5 0.5 0.5" />
     <texture unit="diffuse" name="Textures/Smoke.dds" />
 </material>

+ 1 - 1
bin/Data/Materials/Particle.xml

@@ -1,4 +1,4 @@
 <material>
-    <technique name="Techniques/DiffVColAdd.xml" />
+    <technique name="Techniques/DiffUnlitParticleAdd.xml" />
     <texture unit="diffuse" name="Textures/Flare.dds" />
 </material>

+ 1 - 1
bin/Data/Materials/Smoke.xml

@@ -1,4 +1,4 @@
 <material>
-    <technique name="Techniques/DiffVColUnlitAlpha.xml" />
+    <technique name="Techniques/DiffUnlitParticleAlpha.xml" />
     <texture unit="diffuse" name="Textures/Smoke.dds" />
 </material>

+ 2 - 1
bin/Data/NinjaSnowWarShaders.xml

@@ -6,7 +6,8 @@
 	<shader vs="Unlit" vsdefines="" ps="Unlit" psdefines="DIFFMAP" />
 	<shader vs="Basic" vsdefines="DIFFMAP VERTEXCOLOR" ps="Basic" psdefines="ALPHAMASK DIFFMAP VERTEXCOLOR" />
 	<shader vs="Basic" vsdefines="DIFFMAP VERTEXCOLOR" ps="Basic" psdefines="ALPHAMAP VERTEXCOLOR" />
-	<shader vs="Unlit" vsdefines="BILLBOARD VERTEXCOLOR" ps="Unlit" psdefines="DIFFMAP VERTEXCOLOR" />
+	<shader vs="UnlitParticle" vsdefines="BILLBOARD VERTEXCOLOR" ps="UnlitParticle" psdefines="ADDITIVE DIFFMAP VERTEXCOLOR" />
+	<shader vs="UnlitParticle" vsdefines="BILLBOARD VERTEXCOLOR" ps="UnlitParticle" psdefines="DIFFMAP VERTEXCOLOR" />
 	<shader vs="Shadow" vsdefines="" ps="Shadow" psdefines="" />
 	<shader vs="LitSolid" vsdefines="DIRLIGHT INSTANCED PERPIXEL SHADOW" ps="LitSolid" psdefines="AMBIENT DIFFMAP DIRLIGHT PCF_SHADOW PERPIXEL SHADOW" />
 	<shader vs="Shadow" vsdefines="INSTANCED" ps="Shadow" psdefines="" />