Browse Source

Convert MotionVectors to HLSL

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
c5ee1d8057

+ 51 - 49
AnKi/Shaders/MotionVectors.glsl → AnKi/Shaders/MotionVectors.hlsl

@@ -5,17 +5,19 @@
 
 
 // Calculates the motion vectors that will be used to sample from the previous frame
 // Calculates the motion vectors that will be used to sample from the previous frame
 
 
-#include <AnKi/Shaders/Functions.glsl>
+#pragma anki hlsl
+
+#include <AnKi/Shaders/Functions.hlsl>
 
 
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(kFramebufferSize, 0u);
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(kFramebufferSize, 0u);
-const F32 kMaxRejectionDistance = 0.1; // In meters
-const F32 kMaxHistoryLength = 16.0;
+constexpr F32 kMaxRejectionDistance = 0.1; // In meters
+constexpr F32 kMaxHistoryLength = 16.0;
 
 
-layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
-layout(set = 0, binding = 1) uniform texture2D u_currentDepthTex;
-layout(set = 0, binding = 2) uniform texture2D u_historyDepthTex;
-layout(set = 0, binding = 3) uniform texture2D u_velocityTex;
-layout(set = 0, binding = 4) uniform texture2D u_historyLengthTex;
+[[vk::binding(0)]] SamplerState g_linearAnyClampSampler;
+[[vk::binding(1)]] Texture2D g_currentDepthTex;
+[[vk::binding(2)]] Texture2D g_historyDepthTex;
+[[vk::binding(3)]] Texture2D g_velocityTex;
+[[vk::binding(4)]] Texture2D g_historyLengthTex;
 
 
 struct Uniforms
 struct Uniforms
 {
 {
@@ -24,49 +26,39 @@ struct Uniforms
 	Mat4 m_prevViewProjectionInvMat;
 	Mat4 m_prevViewProjectionInvMat;
 };
 };
 
 
-layout(set = 0, binding = 5, std140, row_major) uniform b_unis
-{
-	Uniforms u_unis;
-};
+[[vk::binding(5)]] ConstantBuffer<Uniforms> g_unis;
 
 
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
-layout(set = 0, binding = 6) uniform writeonly image2D u_motionVectorsImage;
-layout(set = 0, binding = 7) uniform writeonly image2D u_historyLengthImage;
-
-const UVec2 kWorkgroupSize = UVec2(8, 8);
-layout(local_size_x = kWorkgroupSize.x, local_size_y = kWorkgroupSize.y, local_size_z = 1) in;
-#else
-layout(location = 0) in Vec2 in_uv;
-layout(location = 0) out Vec2 out_motionVectors;
-layout(location = 1) out F32 out_historyLength;
+[[vk::binding(6)]] RWTexture2D<Vec2> g_motionVectorsUav;
+[[vk::binding(7)]] RWTexture2D<F32> g_historyLengthUav;
 #endif
 #endif
 
 
 Vec3 clipToWorld(Vec4 clip, Mat4 clipToWorldMat)
 Vec3 clipToWorld(Vec4 clip, Mat4 clipToWorldMat)
 {
 {
-	const Vec4 v4 = clipToWorldMat * clip;
+	const Vec4 v4 = mul(clipToWorldMat, clip);
 	return v4.xyz / v4.w;
 	return v4.xyz / v4.w;
 }
 }
 
 
 /// Average the some depth values and unproject.
 /// Average the some depth values and unproject.
-Vec3 getAverageWorldPosition(texture2D tex, Vec2 uv, Mat4 clipToWorldMat)
+Vec3 getAverageWorldPosition(Texture2D tex, Vec2 uv, Mat4 clipToWorldMat)
 {
 {
 	const Vec2 halfTexel = (1.0 / Vec2(kFramebufferSize)) / 2.0;
 	const Vec2 halfTexel = (1.0 / Vec2(kFramebufferSize)) / 2.0;
 
 
-	Vec4 depths = textureGather(sampler2D(tex, u_linearAnyClampSampler), uv + halfTexel, 0);
-	depths += textureGather(sampler2D(tex, u_linearAnyClampSampler), uv - halfTexel, 0);
+	Vec4 depths = tex.GatherRed(g_linearAnyClampSampler, uv + halfTexel);
+	depths += tex.GatherRed(g_linearAnyClampSampler, uv - halfTexel);
 
 
 	const F32 avgDepth = (depths.x + depths.y + depths.z + depths.w) / 8.0;
 	const F32 avgDepth = (depths.x + depths.y + depths.z + depths.w) / 8.0;
 
 
-	return clipToWorld(Vec4(UV_TO_NDC(uv), avgDepth, 1.0), clipToWorldMat);
+	return clipToWorld(Vec4(uvToNdc(uv), avgDepth, 1.0), clipToWorldMat);
 }
 }
 
 
 /// Get the depths of some neighbour texels, unproject and find the AABB in world space that encloses them.
 /// Get the depths of some neighbour texels, unproject and find the AABB in world space that encloses them.
-void getMinMaxWorldPositions(texture2D tex, Vec2 uv, Mat4 clipToWorldMat, out Vec3 aabbMin, out Vec3 aabbMax)
+void getMinMaxWorldPositions(Texture2D tex, Vec2 uv, Mat4 clipToWorldMat, out Vec3 aabbMin, out Vec3 aabbMax)
 {
 {
 	const Vec2 halfTexel = (1.0 / Vec2(kFramebufferSize)) / 2.0;
 	const Vec2 halfTexel = (1.0 / Vec2(kFramebufferSize)) / 2.0;
 
 
-	const Vec4 depths1 = textureGather(sampler2D(tex, u_linearAnyClampSampler), uv + halfTexel, 0);
-	const Vec4 depths2 = textureGather(sampler2D(tex, u_linearAnyClampSampler), uv - halfTexel, 0);
+	const Vec4 depths1 = tex.GatherRed(g_linearAnyClampSampler, uv + halfTexel);
+	const Vec4 depths2 = tex.GatherRed(g_linearAnyClampSampler, uv - halfTexel);
 
 
 	const Vec4 minDepths4 = min(depths1, depths2);
 	const Vec4 minDepths4 = min(depths1, depths2);
 	const Vec4 maxDepths4 = max(depths1, depths2);
 	const Vec4 maxDepths4 = max(depths1, depths2);
@@ -77,8 +69,8 @@ void getMinMaxWorldPositions(texture2D tex, Vec2 uv, Mat4 clipToWorldMat, out Ve
 	const F32 minDepth = min(minDepths2.x, minDepths2.y);
 	const F32 minDepth = min(minDepths2.x, minDepths2.y);
 	const F32 maxDepth = max(maxDepths2.x, maxDepths2.y);
 	const F32 maxDepth = max(maxDepths2.x, maxDepths2.y);
 
 
-	const Vec3 a = clipToWorld(Vec4(UV_TO_NDC(uv), minDepth, 1.0), clipToWorldMat);
-	const Vec3 b = clipToWorld(Vec4(UV_TO_NDC(uv), maxDepth, 1.0), clipToWorldMat);
+	const Vec3 a = clipToWorld(Vec4(uvToNdc(uv), minDepth, 1.0), clipToWorldMat);
+	const Vec3 b = clipToWorld(Vec4(uvToNdc(uv), maxDepth, 1.0), clipToWorldMat);
 
 
 	aabbMin = min(a, b);
 	aabbMin = min(a, b);
 	aabbMax = max(a, b);
 	aabbMax = max(a, b);
@@ -88,15 +80,15 @@ F32 computeRejectionFactor(Vec2 uv, Vec2 historyUv)
 {
 {
 	Vec3 boxMin;
 	Vec3 boxMin;
 	Vec3 boxMax;
 	Vec3 boxMax;
-	getMinMaxWorldPositions(u_currentDepthTex, uv, u_unis.m_viewProjectionInvMat, boxMin, boxMax);
+	getMinMaxWorldPositions(g_currentDepthTex, uv, g_unis.m_viewProjectionInvMat, boxMin, boxMax);
 
 
 #if 0
 #if 0
-	const F32 historyDepth = textureLod(u_historyDepthTex, u_linearAnyClampSampler, historyUv, 0.0).r;
-	const Vec3 historyWorldPos = clipToWorld(Vec4(UV_TO_NDC(historyUv), historyDepth, 1.0), u_unis.m_prevViewProjectionInvMat);
+	const F32 historyDepth = g_historyDepthTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0).r;
+	const Vec3 historyWorldPos = clipToWorld(Vec4(uvToNdc(historyUv), historyDepth, 1.0), g_unis.m_prevViewProjectionInvMat);
 #else
 #else
 	// Average gives more rejection so less ghosting
 	// Average gives more rejection so less ghosting
 	const Vec3 historyWorldPos =
 	const Vec3 historyWorldPos =
-		getAverageWorldPosition(u_historyDepthTex, historyUv, u_unis.m_prevViewProjectionInvMat);
+		getAverageWorldPosition(g_historyDepthTex, historyUv, g_unis.m_prevViewProjectionInvMat);
 #endif
 #endif
 	const Vec3 clampedHistoryWorldPos = clamp(historyWorldPos, boxMin, boxMax);
 	const Vec3 clampedHistoryWorldPos = clamp(historyWorldPos, boxMin, boxMax);
 
 
@@ -117,21 +109,29 @@ F32 computeRejectionFactor(Vec2 uv, Vec2 historyUv)
 	return rejection;
 	return rejection;
 }
 }
 
 
-void main()
+#if defined(ANKI_COMPUTE_SHADER)
+[numthreads(8, 8, 1)] void main(UVec3 svDispatchThreadId : SV_DISPATCHTHREADID)
+#else
+struct FragOut
+{
+	Vec2 m_motionVectors : SV_TARGET0;
+	F32 m_historyLength : SV_TARGET1;
+};
+
+FragOut main(Vec2 uv : TEXCOORD)
+#endif
 {
 {
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
-	if(skipOutOfBoundsInvocations(kWorkgroupSize, kFramebufferSize))
+	if(skipOutOfBoundsInvocations(UVec2(8, 8), kFramebufferSize, svDispatchThreadId.xy))
 	{
 	{
 		return;
 		return;
 	}
 	}
 
 
-	const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(kFramebufferSize);
-#else
-	const Vec2 uv = in_uv;
+	const Vec2 uv = (Vec2(svDispatchThreadId.xy) + 0.5) / Vec2(kFramebufferSize);
 #endif
 #endif
-	const F32 depth = textureLod(u_currentDepthTex, u_linearAnyClampSampler, uv, 0.0).r;
+	const F32 depth = g_currentDepthTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).r;
 
 
-	const Vec2 velocity = textureLod(u_velocityTex, u_linearAnyClampSampler, uv, 0.0).rg;
+	const Vec2 velocity = g_velocityTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).rg;
 
 
 	Vec2 historyUv;
 	Vec2 historyUv;
 	if(velocity.x != 1.0)
 	if(velocity.x != 1.0)
@@ -140,8 +140,8 @@ void main()
 	}
 	}
 	else
 	else
 	{
 	{
-		const Vec4 v4 = u_unis.m_reprojectionMat * Vec4(UV_TO_NDC(uv), depth, 1.0);
-		historyUv = NDC_TO_UV(v4.xy / v4.w);
+		const Vec4 v4 = mul(g_unis.m_reprojectionMat, Vec4(uvToNdc(uv), depth, 1.0));
+		historyUv = ndcToUv(v4.xy / v4.w);
 	}
 	}
 
 
 	const F32 rejection = computeRejectionFactor(uv, historyUv);
 	const F32 rejection = computeRejectionFactor(uv, historyUv);
@@ -155,16 +155,18 @@ void main()
 	}
 	}
 	else
 	else
 	{
 	{
-		historyLength = textureLod(u_historyLengthTex, u_linearAnyClampSampler, historyUv, 0.0).r;
+		historyLength = g_historyLengthTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0).r;
 		historyLength += 1.0 / kMaxHistoryLength;
 		historyLength += 1.0 / kMaxHistoryLength;
 	}
 	}
 
 
 	// Write out
 	// Write out
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
-	imageStore(u_motionVectorsImage, IVec2(gl_GlobalInvocationID.xy), Vec4(historyUv - uv, 0.0, 0.0));
-	imageStore(u_historyLengthImage, IVec2(gl_GlobalInvocationID.xy), Vec4(historyLength, 0.0, 0.0, 0.0));
+	g_motionVectorsUav[svDispatchThreadId.xy] = historyUv - uv;
+	g_historyLengthUav[svDispatchThreadId.xy] = historyLength;
 #else
 #else
-	out_motionVectors = historyUv - uv;
-	out_historyLength = historyLength;
+	FragOut output;
+	output.m_motionVectors = historyUv - uv;
+	output.m_historyLength = historyLength;
+	return output;
 #endif
 #endif
 }
 }

+ 2 - 2
AnKi/Shaders/MotionVectorsCompute.ankiprog

@@ -4,5 +4,5 @@
 // http://www.anki3d.org/LICENSE
 // http://www.anki3d.org/LICENSE
 
 
 #pragma anki start comp
 #pragma anki start comp
-#include <AnKi/Shaders/MotionVectors.glsl>
-#pragma anki end
+#include <AnKi/Shaders/MotionVectors.hlsl>
+#pragma anki end

+ 3 - 3
AnKi/Shaders/MotionVectorsRaster.ankiprog

@@ -4,9 +4,9 @@
 // http://www.anki3d.org/LICENSE
 // http://www.anki3d.org/LICENSE
 
 
 #pragma anki start vert
 #pragma anki start vert
-#include <AnKi/Shaders/QuadVert.glsl>
+#include <AnKi/Shaders/QuadVert.hlsl>
 #pragma anki end
 #pragma anki end
 
 
 #pragma anki start frag
 #pragma anki start frag
-#include <AnKi/Shaders/MotionVectors.glsl>
-#pragma anki end
+#include <AnKi/Shaders/MotionVectors.hlsl>
+#pragma anki end