|
|
@@ -3,34 +3,37 @@
|
|
|
// Code licensed under the BSD License.
|
|
|
// http://www.anki3d.org/LICENSE
|
|
|
|
|
|
+#pragma anki hlsl
|
|
|
+
|
|
|
#pragma anki start vert
|
|
|
-#include <AnKi/Shaders/QuadVert.glsl>
|
|
|
+#include <AnKi/Shaders/QuadVert.hlsl>
|
|
|
#pragma anki end
|
|
|
|
|
|
#pragma anki start frag
|
|
|
-#include <AnKi/Shaders/PackFunctions.glsl>
|
|
|
-#include <AnKi/Shaders/Functions.glsl>
|
|
|
+#include <AnKi/Shaders/PackFunctions.hlsl>
|
|
|
+#include <AnKi/Shaders/Functions.hlsl>
|
|
|
|
|
|
ANKI_SPECIALIZATION_CONSTANT_UVEC2(kTileCount, 0u);
|
|
|
ANKI_SPECIALIZATION_CONSTANT_U32(kZSplitCount, 2u);
|
|
|
ANKI_SPECIALIZATION_CONSTANT_U32(kTileSize, 3u);
|
|
|
|
|
|
-layout(set = 0, binding = 0) uniform sampler u_nearestAnyClampSampler;
|
|
|
-layout(set = 0, binding = 1) uniform texture2D u_depthTex;
|
|
|
-layout(set = 0, binding = 2) uniform sampler u_trilinearRepeatSampler;
|
|
|
+[[vk::binding(0)]] SamplerState g_nearestAnyClampSampler;
|
|
|
+[[vk::binding(1)]] Texture2D g_depthTex;
|
|
|
+[[vk::binding(2)]] SamplerState g_trilinearRepeatSampler;
|
|
|
|
|
|
#define CLUSTERED_SHADING_SET 0u
|
|
|
#define CLUSTERED_SHADING_UNIFORMS_BINDING 3u
|
|
|
#define CLUSTERED_SHADING_DECALS_BINDING 4u
|
|
|
#define CLUSTERED_SHADING_CLUSTERS_BINDING 7u
|
|
|
-#include <AnKi/Shaders/ClusteredShadingCommon.glsl>
|
|
|
-
|
|
|
-layout(location = 0) in Vec2 in_uv;
|
|
|
+#include <AnKi/Shaders/ClusteredShadingCommon.hlsl>
|
|
|
|
|
|
-layout(location = 0) out ANKI_RP Vec4 out_diffuse;
|
|
|
-layout(location = 1) out ANKI_RP Vec4 out_roughnessMetallicF0;
|
|
|
+struct FragOut
|
|
|
+{
|
|
|
+ RVec4 m_diffuse : SV_TARGET0;
|
|
|
+ RVec4 m_roughnessMetallicF0 : SV_TARGET1;
|
|
|
+};
|
|
|
|
|
|
-void main()
|
|
|
+FragOut main([[vk::location(0)]] Vec2 uv : TEXCOORD, Vec4 svPosition : SV_POSITION)
|
|
|
{
|
|
|
// This code blends the diffuse and the specular+rougness of the decals with GBuffer render targets.
|
|
|
// Normaly the blending is being done ('D' is the decal diffuse and 'f' is decal blend factor):
|
|
|
@@ -39,33 +42,33 @@ void main()
|
|
|
// 2nd decal: d''=d'*(1-f')+D'*f' <=> d''=d*(1-f)*(1-f')+D*f*(1-f')+D'*f'
|
|
|
// By looking at the trend we will have to multiply the gbuffer.diff with: (1-f)*(1-f') ... (1-f'''')
|
|
|
|
|
|
- ANKI_RP Vec4 diffuse = Vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
- ANKI_RP Vec4 roughnessMetallicF0 = Vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
+ RVec4 diffuse = Vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
+ RVec4 roughnessMetallicF0 = Vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
|
|
|
// Get worldPos
|
|
|
- const F32 depth = textureLod(u_depthTex, u_nearestAnyClampSampler, in_uv, 0.0).r;
|
|
|
- const Vec2 ndc = UV_TO_NDC(in_uv);
|
|
|
- const Vec4 worldPos4 = u_clusteredShading.m_matrices.m_invertedViewProjectionJitter * Vec4(ndc, depth, 1.0);
|
|
|
+ const F32 depth = g_depthTex.SampleLevel(g_nearestAnyClampSampler, uv, 0.0).r;
|
|
|
+ const Vec2 ndc = uvToNdc(uv);
|
|
|
+ const Vec4 worldPos4 = mul(g_clusteredShading.m_matrices.m_invertedViewProjectionJitter, Vec4(ndc, depth, 1.0));
|
|
|
const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
|
|
|
|
|
|
// Get the cluster
|
|
|
- Cluster cluster = getClusterFragCoord(Vec3(gl_FragCoord.xy, depth), kTileSize, kTileCount, kZSplitCount,
|
|
|
- u_clusteredShading.m_zSplitMagic.x, u_clusteredShading.m_zSplitMagic.y);
|
|
|
+ Cluster cluster = getClusterFragCoord(Vec3(svPosition.xy, depth), kTileSize, kTileCount, kZSplitCount,
|
|
|
+ g_clusteredShading.m_zSplitMagic.x, g_clusteredShading.m_zSplitMagic.y);
|
|
|
|
|
|
// Process decals
|
|
|
- if(cluster.m_decalsMask == ExtendedClusterObjectMask(0))
|
|
|
+ if(cluster.m_decalsMask == 0)
|
|
|
{
|
|
|
discard;
|
|
|
}
|
|
|
|
|
|
- [[dont_unroll]] while(cluster.m_decalsMask != ExtendedClusterObjectMask(0))
|
|
|
+ [[loop]] while(cluster.m_decalsMask != 0)
|
|
|
{
|
|
|
- const I32 idx = findLSB2(cluster.m_decalsMask);
|
|
|
- cluster.m_decalsMask &= ~(ExtendedClusterObjectMask(1) << ExtendedClusterObjectMask(idx));
|
|
|
- const Decal decal = u_decals2[idx];
|
|
|
+ const I32 idx = firstbitlow2(cluster.m_decalsMask);
|
|
|
+ cluster.m_decalsMask &= ~((ExtendedClusterObjectMask)1 << (ExtendedClusterObjectMask)idx);
|
|
|
+ const Decal decal = g_decals[idx];
|
|
|
|
|
|
// Project pos to decal space
|
|
|
- const Vec4 texCoords4 = decal.m_textureMatrix * Vec4(worldPos, 1.0);
|
|
|
+ const Vec4 texCoords4 = mul(decal.m_textureMatrix, Vec4(worldPos, 1.0));
|
|
|
if(texCoords4.w <= 0.7)
|
|
|
{
|
|
|
// Behind the decal, skip
|
|
|
@@ -79,14 +82,14 @@ void main()
|
|
|
|
|
|
// Read diffuse
|
|
|
const Vec2 diffUv = mad(texCoords2, decal.m_diffuseUv.zw, decal.m_diffuseUv.xy);
|
|
|
- const ANKI_RP Vec4 decalDiff = texture(u_diffuseDecalTex, u_trilinearRepeatSampler, diffUv);
|
|
|
+ const RVec4 decalDiff = g_diffuseDecalTex.Sample(g_trilinearRepeatSampler, diffUv);
|
|
|
|
|
|
// Read roughness
|
|
|
const Vec2 specUv = mad(texCoords2, decal.m_normRoughnessUv.zw, decal.m_normRoughnessUv.xy);
|
|
|
- const ANKI_RP Vec3 spec = texture(u_specularRoughnessDecalTex, u_trilinearRepeatSampler, specUv).rgb;
|
|
|
+ const RVec3 spec = g_specularRoughnessDecalTex.Sample(g_trilinearRepeatSampler, specUv).rgb;
|
|
|
|
|
|
// Update diffuse
|
|
|
- ANKI_RP F32 f = decalDiff.a * decal.m_blendFactors[0];
|
|
|
+ RF32 f = decalDiff.a * decal.m_blendFactors[0];
|
|
|
diffuse.rgb = diffuse.rgb * (1.0 - f) + decalDiff.rgb * f;
|
|
|
diffuse.a *= (1.0 - f);
|
|
|
|
|
|
@@ -96,7 +99,10 @@ void main()
|
|
|
roughnessMetallicF0.a *= (1.0 - f);
|
|
|
}
|
|
|
|
|
|
- out_diffuse = diffuse;
|
|
|
- out_roughnessMetallicF0 = roughnessMetallicF0;
|
|
|
+ FragOut output;
|
|
|
+ output.m_diffuse = diffuse;
|
|
|
+ output.m_roughnessMetallicF0 = roughnessMetallicF0;
|
|
|
+
|
|
|
+ return output;
|
|
|
}
|
|
|
#pragma anki end
|