浏览代码

Moving some forward shading shaders to HLSL

Panagiotis Christopoulos Charitos 3 年之前
父节点
当前提交
126b12fc36

+ 6 - 4
AnKi/Math/Mat.h

@@ -1393,8 +1393,9 @@ public:
 	}
 
 	/// Create a new transform matrix position at eye and looking at refPoint.
-	template<U VEC_DIMS, ANKI_ENABLE(kTRowCount == 3 && kTColumnCount == 4 && VEC_DIMS >= 3)>
-	static TMat lookAt(const TVec<T, VEC_DIMS>& eye, const TVec<T, VEC_DIMS>& refPoint, const TVec<T, VEC_DIMS>& up)
+	template<U kVecDimensions, ANKI_ENABLE(kTRowCount == 3 && kTColumnCount == 4 && kVecDimensions >= 3)>
+	static TMat lookAt(const TVec<T, kVecDimensions>& eye, const TVec<T, kVecDimensions>& refPoint,
+					   const TVec<T, kVecDimensions>& up)
 	{
 		const TVec<T, 3> vdir = (refPoint.xyz() - eye.xyz()).getNormalized();
 		const TVec<T, 3> vup = (up.xyz() - vdir * up.xyz().dot(vdir)).getNormalized();
@@ -1405,8 +1406,9 @@ public:
 	}
 
 	/// Create a new transform matrix position at eye and looking at refPoint.
-	template<U VEC_DIMS, ANKI_ENABLE(kTRowCount == 4 && kTColumnCount == 4 && VEC_DIMS >= 3)>
-	static TMat lookAt(const TVec<T, VEC_DIMS>& eye, const TVec<T, VEC_DIMS>& refPoint, const TVec<T, VEC_DIMS>& up)
+	template<U kVecDimensions, ANKI_ENABLE(kTRowCount == 4 && kTColumnCount == 4 && kVecDimensions >= 3)>
+	static TMat lookAt(const TVec<T, kVecDimensions>& eye, const TVec<T, kVecDimensions>& refPoint,
+					   const TVec<T, kVecDimensions>& up)
 	{
 		const TVec<T, 4> vdir = (refPoint.xyz0() - eye.xyz0()).getNormalized();
 		const TVec<T, 4> vup = (up.xyz0() - vdir * up.xyz0().dot(vdir)).getNormalized();

+ 4 - 2
AnKi/Renderer/Drawer.cpp

@@ -54,8 +54,10 @@ void RenderableDrawer::drawRange(RenderingTechnique technique, const RenderableD
 
 		globalUniforms->m_viewProjectionMatrix = args.m_viewProjectionMatrix;
 		globalUniforms->m_previousViewProjectionMatrix = args.m_previousViewProjectionMatrix;
-		globalUniforms->m_viewMatrix = args.m_viewMatrix;
-		globalUniforms->m_cameraTransform = args.m_cameraTransform;
+		static_assert(sizeof(globalUniforms->m_viewTransform) == sizeof(args.m_viewMatrix));
+		memcpy(&globalUniforms->m_viewTransform, &args.m_viewMatrix, sizeof(args.m_viewMatrix));
+		static_assert(sizeof(globalUniforms->m_cameraTransform) == sizeof(args.m_cameraTransform));
+		memcpy(&globalUniforms->m_cameraTransform, &args.m_cameraTransform, sizeof(args.m_cameraTransform));
 
 		cmdb->bindUniformBuffer(kMaterialSetGlobal, kMaterialBindingGlobalUniforms,
 								m_r->getExternalSubsystems().m_rebarStagingPool->getBuffer(),

+ 4 - 4
AnKi/ShaderCompiler/ShaderProgramParser.cpp

@@ -615,19 +615,19 @@ Error ShaderProgramParser::parsePragmaMember(const StringRaii* begin, const Stri
 
 	const CString typeStr = *begin;
 	member.m_type = ShaderVariableDataType::kNone;
-	if(typeStr == "F32")
+	if(typeStr == "F32" || typeStr == "RF32")
 	{
 		member.m_type = ShaderVariableDataType::kF32;
 	}
-	else if(typeStr == "Vec2")
+	else if(typeStr == "Vec2" || typeStr == "RVec2")
 	{
 		member.m_type = ShaderVariableDataType::kVec2;
 	}
-	else if(typeStr == "Vec3")
+	else if(typeStr == "Vec3" || typeStr == "RVec3")
 	{
 		member.m_type = ShaderVariableDataType::kVec3;
 	}
-	else if(typeStr == "Vec4")
+	else if(typeStr == "Vec4" || typeStr == "Vec4")
 	{
 		member.m_type = ShaderVariableDataType::kVec4;
 	}

+ 8 - 6
AnKi/Shaders/ForwardShadingCommon.hlsl

@@ -29,7 +29,7 @@ ANKI_BINDLESS_SET(kMaterialSetBindless)
 
 struct FragOut
 {
-	RVec4 m_color;
+	RVec4 m_color : SV_TARGET0;
 };
 
 void packGBuffer(Vec4 color, out FragOut output)
@@ -60,7 +60,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos, Vec4 svPosition)
 	// Point lights
 	[[loop]] while(cluster.m_pointLightsMask != (ExtendedClusterObjectMask)0)
 	{
-		const I32 idx = findLSB2(cluster.m_pointLightsMask);
+		const I32 idx = firstbitlow2(cluster.m_pointLightsMask);
 		cluster.m_pointLightsMask &= ~((ExtendedClusterObjectMask)1 << (ExtendedClusterObjectMask)idx);
 		const PointLight light = u_pointLights2[idx];
 
@@ -69,7 +69,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos, Vec4 svPosition)
 		const Vec3 frag2Light = light.m_position - worldPos;
 		const F32 att = computeAttenuationFactor(light.m_squareRadiusOverOne, frag2Light);
 
-#	if LOD > 1
+#	if defined(ANKI_LOD) && ANKI_LOD > 1
 		const F32 shadow = 1.0;
 #	else
 		F32 shadow = 1.0;
@@ -85,7 +85,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos, Vec4 svPosition)
 	// Spot lights
 	[[loop]] while(cluster.m_spotLightsMask != (ExtendedClusterObjectMask)0)
 	{
-		const I32 idx = findLSB2(cluster.m_spotLightsMask);
+		const I32 idx = firstbitlow2(cluster.m_spotLightsMask);
 		cluster.m_spotLightsMask &= ~((ExtendedClusterObjectMask)1 << (ExtendedClusterObjectMask)idx);
 		const SpotLight light = u_spotLights[idx];
 
@@ -98,7 +98,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos, Vec4 svPosition)
 
 		const F32 spot = computeSpotFactor(l, light.m_outerCos, light.m_innerCos, light.m_direction);
 
-#	if LOD > 1
+#	if defined(ANKI_LOD) && ANKI_LOD > 1
 		const F32 shadow = 1.0;
 #	else
 		F32 shadow = 1.0;
@@ -117,6 +117,8 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos, Vec4 svPosition)
 // Just read the light color from the vol texture
 RVec3 computeLightColorLow(RVec3 diffCol, RVec3 worldPos, Vec4 svPosition)
 {
+	ANKI_MAYBE_UNUSED(worldPos);
+
 	const Vec2 uv = svPosition.xy / u_clusteredShading.m_renderingSize;
 	const F32 linearDepth = linearizeDepth(svPosition.z, u_clusteredShading.m_near, u_clusteredShading.m_far);
 	const F32 w =
@@ -142,7 +144,7 @@ void fog(RVec3 color, RF32 fogAlphaScale, RF32 fogDistanceOfMaxThikness, F32 zVS
 	F32 zFeatherFactor;
 
 	const Vec4 fragPosVspace4 =
-		u_clusteredShading.m_matrices.m_invertedProjectionJitter * Vec4(Vec3(UV_TO_NDC(texCoords), depth), 1.0);
+		mul(u_clusteredShading.m_matrices.m_invertedProjectionJitter, Vec4(Vec3(uvToNdc(texCoords), depth), 1.0));
 	const F32 sceneZVspace = fragPosVspace4.z / fragPosVspace4.w;
 
 	const F32 diff = max(0.0, zVSpace - sceneZVspace);

+ 1 - 1
AnKi/Shaders/ForwardShadingFog.ankiprog

@@ -41,7 +41,7 @@ void main()
 
 	gl_Position = u_global.m_viewProjectionMatrix * Vec4(worldPos, 1.0);
 
-	const Vec3 viewPos = u_global.m_viewMatrix * Vec4(worldPos, 1.0);
+	const Vec3 viewPos = transform(u_global.m_viewTransform, Vec4(worldPos, 1.0));
 	out_zVSpace = viewPos.z;
 }
 

+ 48 - 44
AnKi/Shaders/ForwardShadingParticles.ankiprog

@@ -3,83 +3,87 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
+#pragma anki hlsl
+
 #pragma anki mutator ANKI_TECHNIQUE 3
 #pragma anki mutator ANIMATED_TEXTURE 0 1
 #pragma anki mutator LIGHT 0 1
 
-#include <AnKi/Shaders/ForwardShadingCommon.glsl>
-
-#pragma anki reflect AnKiLocalUniforms
-#pragma anki struct AnKiLocalUniforms
-#pragma anki member F32 m_animationPeriod if ANIMATED_TEXTURE is 1
-#pragma anki member ANKI_RP Vec4 m_colorScale
-#pragma anki member ANKI_RP Vec4 m_colorBias
-#pragma anki member U32 m_diffuseMap
-#pragma anki struct end
+#include <AnKi/Shaders/ForwardShadingCommon.hlsl>
 
-layout(set = kMaterialSetGlobal, binding = kMaterialBindingGlobalUniforms) uniform b_ankiGlobalUniforms
+struct VertIn
 {
-	MaterialGlobalUniforms u_ankiGlobals;
+	[[vk::location(VertexStreamId::kParticlePosition)]] Vec3 m_position : POSITION;
+	[[vk::location(VertexStreamId::kParticleScale)]] RF32 m_scale : SCALE;
+	[[vk::location(VertexStreamId::kParticleAlpha)]] RF32 m_alpha : ALPHA;
+	U32 m_vertexId : SV_VERTEXID;
 };
 
-layout(set = kMaterialSetGlobal, binding = kMaterialBindingTrilinearRepeatSampler) uniform sampler u_globalSampler;
-
-layout(set = kMaterialSetLocal, binding = kMaterialBindingLocalUniforms, std430) buffer b_localUniforms
+struct VertOut
 {
-	U32 u_localUniforms[];
+	nointerpolation RF32 m_alpha : ALPHA;
+	Vec2 m_uv : TEXCOORD;
+	Vec3 m_worldPos : WORLD_POS;
+	Vec4 m_svPosition : SV_POSITION;
 };
 
-layout(set = kMaterialSetLocal, binding = kMaterialBindingRenderableGpuView) uniform b_renderableGpuViews
-{
-	RenderableGpuView u_renderableGpuViews[1];
-};
+#pragma anki reflect AnKiLocalUniforms
+#pragma anki struct AnKiLocalUniforms
+#pragma anki member F32 m_animationPeriod if ANIMATED_TEXTURE is 1
+#pragma anki member Vec4 m_colorScale
+#pragma anki member Vec4 m_colorBias
+#pragma anki member U32 m_diffuseMap
+#pragma anki struct end
+
+[[vk::binding(kMaterialBindingGlobalUniforms, kMaterialSetGlobal)]] ConstantBuffer<MaterialGlobalUniforms>
+	u_ankiGlobals;
+[[vk::binding(kMaterialBindingTrilinearRepeatSampler, kMaterialSetGlobal)]] SamplerState u_globalSampler;
+[[vk::binding(kMaterialBindingLocalUniforms, kMaterialSetLocal)]] StructuredBuffer<U32> u_localUniforms;
+[[vk::binding(kMaterialBindingRenderableGpuView, kMaterialSetLocal)]] StructuredBuffer<RenderableGpuView>
+	u_renderableGpuViews;
 
 #pragma anki start vert
 
-layout(location = kVertexStreamIdParticleScale) in F32 in_scale;
-layout(location = kVertexStreamIdParticleAlpha) in F32 in_alpha;
+VertOut main(VertIn input)
+{
+	VertOut output;
 
-layout(location = 0) flat out ANKI_RP F32 out_alpha;
-layout(location = 1) out Vec2 out_uv;
-layout(location = 2) out Vec3 out_worldPos;
+	output.m_uv = Vec2(input.m_vertexId & 1, input.m_vertexId >> 1);
 
-void main()
-{
-	out_uv = Vec2(gl_VertexIndex & 1, gl_VertexIndex >> 1);
+	output.m_worldPos = transform(u_ankiGlobals.m_cameraTransform, Vec4((output.m_uv - 0.5) * input.m_scale, 0.0, 0.0))
+						+ input.m_position;
 
-	out_worldPos = u_ankiGlobals.m_cameraTransform * Vec4((out_uv - 0.5) * in_scale, 0.0, 0.0) + in_position;
+	output.m_svPosition = Vec4(transform(u_renderableGpuViews[0].m_worldTransform, Vec4(output.m_worldPos, 1.0)), 1.0);
+	output.m_svPosition = mul(u_ankiGlobals.m_viewProjectionMatrix, output.m_svPosition);
 
-	gl_Position = Vec4(transform(u_renderableGpuViews[0].m_worldTransform, Vec4(out_worldPos, 1.0)), 1.0);
-	gl_Position = u_ankiGlobals.m_viewProjectionMatrix * gl_Position;
+	output.m_alpha = input.m_alpha;
 
-	out_alpha = in_alpha;
+	return output;
 }
 #pragma anki end
 
 #pragma anki start frag
 
-layout(location = 0) flat in ANKI_RP F32 in_alpha;
-layout(location = 1) in Vec2 in_uv;
-layout(location = 2) in Vec3 in_worldPos;
-
-void main()
+FragOut main(VertOut input)
 {
+	FragOut output = (FragOut)0;
 	const AnKiLocalUniforms localUniforms = loadAnKiLocalUniforms(u_localUniforms, 0u);
 
 #if ANIMATED_TEXTURE == 1
-	ANKI_RP Vec4 texCol =
-		readAnimatedTextureRgba(u_bindlessTextures2dArrayF32[localUniforms.m_diffuseMap], u_globalSampler,
-								localUniforms.m_animationPeriod, in_uv, u_clusteredShading.m_time);
+	RVec4 texCol = readAnimatedTextureRgba(u_bindlessTextures2dArrayF32[localUniforms.m_diffuseMap], u_globalSampler,
+										   localUniforms.m_animationPeriod, input.m_uv, u_clusteredShading.m_time);
 #else
-	ANKI_RP Vec4 texCol = texture(u_bindlessTextures2dF32[localUniforms.m_diffuseMap], u_globalSampler, in_uv);
+	RVec4 texCol = u_bindlessTextures2dF32[localUniforms.m_diffuseMap].Sample(u_globalSampler, input.m_uv);
 #endif
 
 #if LIGHT
-	texCol.rgb = computeLightColorLow(texCol.rgb, in_worldPos);
+	texCol.rgb = computeLightColorLow(texCol.rgb, input.m_worldPos, input.m_svPosition);
 #endif
 
-	ANKI_RP Vec4 colScale = localUniforms.m_colorScale;
-	colScale.a *= in_alpha;
-	particleAlpha(texCol, colScale, localUniforms.m_colorBias);
+	RVec4 colScale = localUniforms.m_colorScale;
+	colScale.a *= input.m_alpha;
+	particleAlpha(texCol, colScale, localUniforms.m_colorBias, output);
+
+	return output;
 }
 #pragma anki end

+ 0 - 89
AnKi/Shaders/ForwardShadingParticles2.ankiprog

@@ -1,89 +0,0 @@
-// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma anki hlsl
-
-#pragma anki mutator ANKI_TECHNIQUE 3
-#pragma anki mutator ANIMATED_TEXTURE 0 1
-#pragma anki mutator LIGHT 0 1
-
-#include <AnKi/Shaders/ForwardShadingCommon.hlsl>
-
-struct VertIn
-{
-	[[vk::location(VertexStreamId::kParticlePosition)]] Vec3 m_position : POSITION;
-	[[vk::location(VertexStreamId::kParticleScale)]] RF32 m_scale : SCALE;
-	[[vk::location(VertexStreamId::kParticleAlpha)]] RF32 m_alpha : ALPHA;
-	U32 m_vertexId : SV_VERTEXID;
-};
-
-struct VertOut
-{
-	nointerpolation RF32 m_alpha : ALPHA;
-	Vec2 m_uv : TEXCOORD;
-	Vec3 m_worldPos : WORLD_POS;
-	Vec4 m_svPosition : SV_POSITION;
-};
-
-#pragma anki reflect AnKiLocalUniforms
-#pragma anki struct AnKiLocalUniforms
-#pragma anki member F32 m_animationPeriod if ANIMATED_TEXTURE is 1
-#pragma anki member Vec4 m_colorScale
-#pragma anki member Vec4 m_colorBias
-#pragma anki member U32 m_diffuseMap
-#pragma anki struct end
-
-[[vk::binding(kMaterialBindingGlobalUniforms, kMaterialSetGlobal)]] ConstantBuffer<MaterialGlobalUniforms>
-	u_ankiGlobals;
-[[vk::binding(kMaterialBindingTrilinearRepeatSampler, kMaterialSetGlobal)]] SamplerState u_globalSampler;
-[[vk::binding(kMaterialBindingLocalUniforms, kMaterialSetLocal)]] StructuredBuffer<U32> u_localUniforms;
-[[vk::binding(kMaterialBindingRenderableGpuView, kMaterialSetLocal)]] StructuredBuffer<RenderableGpuView>
-	u_renderableGpuViews;
-
-#pragma anki start vert
-
-VertOut main(VertIn input)
-{
-	VertOut output;
-
-	output.m_uv = Vec2(input.m_vertexId & 1, input.m_vertexId >> 1);
-
-	output.m_worldPos =
-		mul(u_ankiGlobals.m_cameraTransform, Vec4((output.m_uv - 0.5) * input.m_scale, 0.0, 0.0)) + input.m_position;
-
-	output.m_svPosition = Vec4(transform(u_renderableGpuViews[0].m_worldTransform, Vec4(output.m_worldPos, 1.0)), 1.0);
-	output.m_svPosition = mul(u_ankiGlobals.m_viewProjectionMatrix, output.m_svPosition);
-
-	output.m_alpha = input.m_alpha;
-
-	return output;
-}
-#pragma anki end
-
-#pragma anki start frag
-
-FragOut main(VerIn input)
-{
-	FragOut output;
-	const AnKiLocalUniforms localUniforms = loadAnKiLocalUniforms(u_localUniforms, 0u);
-
-#if ANIMATED_TEXTURE == 1
-	RVec4 texCol = readAnimatedTextureRgba(u_bindlessTextures2dArrayF32[localUniforms.m_diffuseMap], u_globalSampler,
-										   localUniforms.m_animationPeriod, input.m_uv, u_clusteredShading.m_time);
-#else
-	RVec4 texCol = u_bindlessTextures2dF32[localUniforms.m_diffuseMap].Sample(u_globalSampler, input.m_uv);
-#endif
-
-#if LIGHT
-	texCol.rgb = computeLightColorLow(texCol.rgb, input.m_worldPos, input.m_svPosition);
-#endif
-
-	RVec4 colScale = localUniforms.m_colorScale;
-	colScale.a *= in_alpha;
-	particleAlpha(texCol, colScale, localUniforms.m_colorBias, output);
-
-	return output;
-}
-#pragma anki end

+ 9 - 11
AnKi/Shaders/Functions.hlsl

@@ -572,24 +572,22 @@ F32 computeMipLevel(Vec2 normalizedUvs)
 }
 #endif
 
-#if ANKI_GLSL
-#	if ANKI_SUPPORTS_64BIT_TYPES
-/// The regular findLSB in glslang has some issues since it invokes a builtin that is only supposed to be used with
+#if ANKI_SUPPORTS_64BIT_TYPES
+/// The regular firstbitlow in DXC has some issues since it invokes a builtin that is only supposed to be used with
 /// 32bit input. This is an alternative implementation but it expects that the input is not zero.
-I32 findLSB2(U64 v)
+I32 firstbitlow2(U64 v)
 {
-	const I32 lsb1 = findLSB(U32(v));
-	const I32 lsb2 = findLSB(U32(v >> 32ul));
+	const I32 lsb1 = firstbitlow((U32)v);
+	const I32 lsb2 = firstbitlow((U32)(v >> 32ul));
 	return (lsb1 >= 0) ? lsb1 : lsb2 + 32;
 }
-#	endif
+#endif
 
-/// Define an alternative findLSB to go in pair with the 64bit version.
-I32 findLSB2(U32 v)
+/// Define an alternative firstbitlow to go in pair with the 64bit version.
+I32 firstbitlow2(U32 v)
 {
-	return findLSB(v);
+	return firstbitlow(v);
 }
-#endif
 
 /// Encode the shading rate to be stored in an SRI. The rates should be power of two, can't be zero and can't exceed 4.
 /// So the possible values are 1,2,4

+ 47 - 45
AnKi/Shaders/GBufferGpuParticles.ankiprog

@@ -3,101 +3,103 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
+#pragma anki hlsl
+
 #pragma anki mutator ANKI_TECHNIQUE 0 1
 
 #include <AnKi/Shaders/Include/ParticleTypes.h>
 #include <AnKi/Shaders/Include/MaterialTypes.h>
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
-#include <AnKi/Shaders/Functions.glsl>
+#include <AnKi/Shaders/Functions.hlsl>
 
 #pragma anki reflect AnKiLocalUniforms
 #pragma anki struct AnKiLocalUniforms
-#pragma anki member ANKI_RP Vec3 m_diffColor
-#pragma anki member ANKI_RP F32 m_roughness
-#pragma anki member ANKI_RP Vec3 m_specColor
-#pragma anki member ANKI_RP F32 m_metallic
-#pragma anki member ANKI_RP Vec3 m_initialEmission
-#pragma anki member ANKI_RP Vec3 m_finalEmission
+#pragma anki member RVec3 m_diffColor
+#pragma anki member RF32 m_roughness
+#pragma anki member RVec3 m_specColor
+#pragma anki member RF32 m_metallic
+#pragma anki member RVec3 m_initialEmission
+#pragma anki member RVec3 m_finalEmission
 #pragma anki struct end
 
-layout(set = kMaterialSetLocal, binding = kMaterialBindingLocalUniforms, std430) buffer b_localUniforms
-{
-	U32 u_localUniforms[];
-};
+[[vk::binding(kMaterialBindingLocalUniforms, kMaterialSetLocal)]] StructuredBuffer<U32> u_localUniforms;
+[[vk::binding(kMaterialBindingRenderableGpuView, kMaterialSetLocal)]] StructuredBuffer<RenderableGpuView>
+	u_renderableGpuViews;
+[[vk::binding(kMaterialBindingGlobalUniforms, kMaterialSetGlobal)]] ConstantBuffer<MaterialGlobalUniforms>
+	u_globalUniforms;
+[[vk::binding(kMaterialBindingFirstNonStandardLocal, kMaterialSetLocal)]] StructuredBuffer<GpuParticle> u_particles;
 
-layout(set = kMaterialSetLocal, binding = kMaterialBindingRenderableGpuView) uniform b_renderableGpuView
+struct VertIn
 {
-	RenderableGpuView u_renderableGpuViews[1];
+	U32 m_svVertexId : SV_VERTEXID;
 };
 
-layout(set = kMaterialSetGlobal, binding = kMaterialBindingGlobalUniforms) uniform b_globalUniforms
+struct VertOut
 {
-	MaterialGlobalUniforms u_globalUniforms;
+	Vec2 m_velocity : VELOCITY;
+	nointerpolation RF32 m_lifeFactor : LIFE;
+	nointerpolation RVec3 m_normal : NORMAL;
+	Vec4 m_svPosition : SV_POSITION;
 };
 
-layout(set = kMaterialSetLocal, binding = kMaterialBindingFirstNonStandardLocal) buffer b_particles
+struct FragOut
 {
-	GpuParticle u_particles[];
+	Vec4 m_color0 : SV_TARGET0;
+	Vec4 m_color1 : SV_TARGET1;
+	Vec4 m_color2 : SV_TARGET2;
+	Vec2 m_color3 : SV_TARGET3;
 };
 
 #pragma anki start vert
 
-layout(location = 0) out Vec2 out_velocity;
-layout(location = 1) flat out ANKI_RP F32 out_lifeFactor;
-layout(location = 2) out flat ANKI_RP Vec3 out_normal;
-
-void main()
+VertOut main(VertIn input)
 {
-	const GpuParticle part = u_particles[gl_VertexIndex / 2];
+	VertOut output;
+	const GpuParticle part = u_particles[input.m_svVertexId / 2];
 
 	Vec4 crntClipPos =
 		Vec4(transform(u_renderableGpuViews[0].m_worldTransform, Vec4(part.m_newWorldPosition, 1.0)), 1.0);
-	crntClipPos = u_globalUniforms.m_viewProjectionMatrix * crntClipPos;
+	crntClipPos = mul(u_globalUniforms.m_viewProjectionMatrix, crntClipPos);
 
 	Vec4 prevClipPos =
 		Vec4(transform(u_renderableGpuViews[0].m_worldTransform, Vec4(part.m_oldWorldPosition, 1.0)), 1.0);
-	prevClipPos = u_globalUniforms.m_viewProjectionMatrix * prevClipPos;
+	prevClipPos = mul(u_globalUniforms.m_viewProjectionMatrix, prevClipPos);
 
-	gl_Position = ((gl_VertexIndex & 1) == 0) ? crntClipPos : prevClipPos;
+	output.m_svPosition = ((input.m_svVertexId & 1) == 0) ? crntClipPos : prevClipPos;
 
 	const Vec2 crntNdc = crntClipPos.xy / crntClipPos.w;
 	const Vec2 prevNdc = prevClipPos.xy / prevClipPos.w;
 
 	// It's NDC_TO_UV(prevNdc) - NDC_TO_UV(crntNdc) or:
-	out_velocity = ((gl_VertexIndex & 1) == 0) ? Vec2(0.0) : (prevNdc - crntNdc) * 0.5;
+	output.m_velocity = ((input.m_svVertexId & 1) == 0) ? Vec2(0.0, 0.0) : (prevNdc - crntNdc) * 0.5;
 
-	out_lifeFactor = saturate(1.0 - (part.m_life / part.m_startingLife));
+	output.m_lifeFactor = saturate(1.0 - (part.m_life / part.m_startingLife));
 
-	out_normal = normalize(u_globalUniforms.m_cameraTransform[3]);
+	output.m_normal = normalize(Vec3(u_globalUniforms.m_cameraTransform[0][2], u_globalUniforms.m_cameraTransform[1][2],
+									 u_globalUniforms.m_cameraTransform[1][2]));
+
+	return output;
 }
 #pragma anki end
 
 #pragma anki start frag
-#define MAX_EMISSION 1024.0
-#include <AnKi/Shaders/PackFunctions.glsl>
-
-layout(location = 0) out Vec4 out_gbuffer0;
-layout(location = 1) out Vec4 out_gbuffer1;
-layout(location = 2) out Vec4 out_gbuffer2;
-layout(location = 3) out Vec2 out_gbuffer3;
-
-layout(location = 0) in Vec2 in_velocity;
-layout(location = 1) flat in ANKI_RP F32 in_lifeFactor;
-layout(location = 2) in flat ANKI_RP Vec3 in_normal;
+#include <AnKi/Shaders/PackFunctions.hlsl>
 
-void main()
+FragOut main(VertOut input)
 {
+	FragOut output;
 	const AnKiLocalUniforms localUniforms = loadAnKiLocalUniforms(u_localUniforms, 0u);
 
 	GbufferInfo g;
 	g.m_diffuse = localUniforms.m_diffColor;
-	g.m_normal = in_normal;
+	g.m_normal = input.m_normal;
 	g.m_f0 = localUniforms.m_specColor;
 	g.m_roughness = localUniforms.m_roughness;
 	g.m_subsurface = 0.0;
-	g.m_emission = mix(localUniforms.m_initialEmission, localUniforms.m_finalEmission, in_lifeFactor);
+	g.m_emission = lerp(localUniforms.m_initialEmission, localUniforms.m_finalEmission, input.m_lifeFactor);
 	g.m_metallic = localUniforms.m_metallic;
-	g.m_velocity = in_velocity;
-	packGBuffer(g, out_gbuffer0, out_gbuffer1, out_gbuffer2, out_gbuffer3);
+	g.m_velocity = input.m_velocity;
+	packGBuffer(g, output.m_color0, output.m_color1, output.m_color2, output.m_color3);
+	return output;
 }
 #pragma anki end

+ 2 - 2
AnKi/Shaders/Include/MaterialTypes.h

@@ -14,8 +14,8 @@ struct MaterialGlobalUniforms
 {
 	Mat4 m_viewProjectionMatrix;
 	Mat4 m_previousViewProjectionMatrix;
-	Mat3x4 m_viewMatrix;
-	Mat3x4 m_cameraTransform;
+	Vec4 m_viewTransform[3];
+	Vec4 m_cameraTransform[3];
 };
 ANKI_SHADER_STATIC_ASSERT(sizeof(MaterialGlobalUniforms) == 14 * sizeof(Vec4));