소스 검색

Some rafactoring

Panagiotis Christopoulos Charitos 3 년 전
부모
커밋
e567a65b28

+ 1 - 1
AnKi/Renderer/Renderer.cpp

@@ -691,7 +691,7 @@ void Renderer::gpuSceneCopy(RenderingContext& ctx)
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("GPU scene patching");
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("GPU scene patching");
 	rpass.newBufferDependency(m_runCtx.m_gpuSceneHandle, BufferUsageBit::kStorageComputeWrite);
 	rpass.newBufferDependency(m_runCtx.m_gpuSceneHandle, BufferUsageBit::kStorageComputeWrite);
 
 
-	rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
+	rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 		m_subsystems.m_gpuSceneMicroPatcher->patchGpuScene(*m_subsystems.m_rebarStagingPool,
 		m_subsystems.m_gpuSceneMicroPatcher->patchGpuScene(*m_subsystems.m_rebarStagingPool,
 														   *rgraphCtx.m_commandBuffer.get(),
 														   *rgraphCtx.m_commandBuffer.get(),
 														   m_subsystems.m_gpuScenePool->getBuffer());
 														   m_subsystems.m_gpuScenePool->getBuffer());

+ 2 - 3
AnKi/Scene/Components/RenderComponent.cpp

@@ -46,9 +46,8 @@ void RenderComponent::allocateAndSetupUniforms(const MaterialResourcePtr& mtl, c
 
 
 		for(U32 i = 0; i < transforms.getSize(); ++i)
 		for(U32 i = 0; i < transforms.getSize(); ++i)
 		{
 		{
-			memcpy(&renderableGpuViews->m_worldTransform, &transforms[i], sizeof(renderableGpuViews->m_worldTransform));
-			memcpy(&renderableGpuViews->m_previousWorldTransform, &prevTransforms[i],
-				   sizeof(renderableGpuViews->m_previousWorldTransform));
+			renderableGpuViews->m_worldTransform = transforms[i];
+			renderableGpuViews->m_previousWorldTransform = prevTransforms[i];
 			renderableGpuViews->m_positionScaleF32AndTranslationVec3 = positionScaleAndTranslation;
 			renderableGpuViews->m_positionScaleF32AndTranslationVec3 = positionScaleAndTranslation;
 
 
 			++renderableGpuViews;
 			++renderableGpuViews;

+ 3 - 62
AnKi/ShaderCompiler/Glslang.cpp

@@ -197,65 +197,6 @@ static EShLanguage ankiToGlslangShaderType(ShaderType shaderType)
 	return gslangShader;
 	return gslangShader;
 }
 }
 
 
-/// Parse Glslang's error message for the line of the error.
-static Error parseErrorLine(CString error, BaseMemoryPool& pool, U32& lineNumber)
-{
-	lineNumber = kMaxU32;
-
-	StringListRaii lines(&pool);
-	lines.splitString(error, '\n');
-	for(String& line : lines)
-	{
-		if(line.find("ERROR: ") == 0)
-		{
-			StringListRaii tokens(&pool);
-			tokens.splitString(line, ':');
-
-			if(tokens.getSize() < 3 || (tokens.getBegin() + 2)->toNumber(lineNumber) != Error::kNone)
-			{
-
-				ANKI_SHADER_COMPILER_LOGE("Failed to parse the GLSlang error message: %s", error.cstr());
-				return Error::kFunctionFailed;
-			}
-			else
-			{
-				break;
-			}
-		}
-	}
-
-	return Error::kNone;
-}
-
-static void createErrorLog(CString glslangError, CString source, BaseMemoryPool& pool, StringRaii& outError)
-{
-	U32 errorLineNumberu = 0;
-	const Error err = parseErrorLine(glslangError, pool, errorLineNumberu);
-
-	const I32 errorLineNumber = (!err) ? I32(errorLineNumberu) : -1;
-
-	constexpr I32 lineCountAroundError = 4;
-
-	StringRaii prettySrc(&pool);
-	StringListRaii lines(&pool);
-
-	lines.splitString(source, '\n', true);
-
-	I32 lineno = 0;
-	for(auto it = lines.getBegin(); it != lines.getEnd(); ++it)
-	{
-		++lineno;
-
-		if(lineno >= errorLineNumber - lineCountAroundError && lineno <= errorLineNumber + lineCountAroundError)
-		{
-			prettySrc.append(StringRaii(&pool).sprintf("%s%s\n", (lineno == errorLineNumber) ? ">>  " : "    ",
-													   (it->isEmpty()) ? " " : (*it).cstr()));
-		}
-	}
-
-	outError.sprintf("%sIn:\n%s\n", glslangError.cstr(), prettySrc.cstr());
-}
-
 Error preprocessGlsl(CString in, StringRaii& out)
 Error preprocessGlsl(CString in, StringRaii& out)
 {
 {
 	glslang::TShader shader(EShLangVertex);
 	glslang::TShader shader(EShLangVertex);
@@ -276,8 +217,8 @@ Error preprocessGlsl(CString in, StringRaii& out)
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
-Error compileGlslToSpirv(CString src, ShaderType shaderType, BaseMemoryPool& tmpPool, DynamicArrayRaii<U8>& spirv,
-						 StringRaii& errorMessage)
+Error compileGlslToSpirv(CString src, ShaderType shaderType, [[maybe_unused]] BaseMemoryPool& tmpPool,
+						 DynamicArrayRaii<U8>& spirv, StringRaii& errorMessage)
 {
 {
 #if ANKI_GLSLANG_DUMP
 #if ANKI_GLSLANG_DUMP
 	// Dump it
 	// Dump it
@@ -308,7 +249,7 @@ Error compileGlslToSpirv(CString src, ShaderType shaderType, BaseMemoryPool& tmp
 	if(!shader.parse(&GLSLANG_LIMITS, 100, false, messages))
 	if(!shader.parse(&GLSLANG_LIMITS, 100, false, messages))
 	{
 	{
 		// printf("%s\n", src.cstr());
 		// printf("%s\n", src.cstr());
-		createErrorLog(shader.getInfoLog(), src, tmpPool, errorMessage);
+		errorMessage = shader.getInfoLog();
 		return Error::kUserData;
 		return Error::kUserData;
 	}
 	}
 
 

+ 2 - 2
AnKi/Shaders/ForwardShadingFog.ankiprog

@@ -37,11 +37,11 @@ layout(location = 0) out F32 out_zVSpace;
 void main()
 void main()
 {
 {
 	const RenderableGpuView renderable = u_renderableGpuViews[0];
 	const RenderableGpuView renderable = u_renderableGpuViews[0];
-	const Vec3 worldPos = transform(renderable.m_worldTransform, Vec4(in_position, 1.0));
+	const Vec3 worldPos = renderable.m_worldTransform * Vec4(in_position, 1.0);
 
 
 	gl_Position = u_global.m_viewProjectionMatrix * Vec4(worldPos, 1.0);
 	gl_Position = u_global.m_viewProjectionMatrix * Vec4(worldPos, 1.0);
 
 
-	const Vec3 viewPos = transform(u_global.m_viewTransform, Vec4(worldPos, 1.0));
+	const Vec3 viewPos = u_global.m_viewTransform * Vec4(worldPos, 1.0);
 	out_zVSpace = viewPos.z;
 	out_zVSpace = viewPos.z;
 }
 }
 
 

+ 1 - 1
AnKi/Shaders/ForwardShadingGenericTransparent.ankiprog

@@ -48,7 +48,7 @@ layout(location = 1) out Vec3 out_worldPosition;
 
 
 void main()
 void main()
 {
 {
-	out_worldPosition = transform(u_renderableGpuViews[gl_InstanceIndex].m_worldTransform, Vec4(in_position, 1.0));
+	out_worldPosition = u_renderableGpuViews[gl_InstanceIndex].m_worldTransform * Vec4(in_position, 1.0);
 
 
 	gl_Position = u_globalUniforms.m_viewProjectionMatrix * Vec4(out_worldPosition, 1.0);
 	gl_Position = u_globalUniforms.m_viewProjectionMatrix * Vec4(out_worldPosition, 1.0);
 
 

+ 3 - 3
AnKi/Shaders/ForwardShadingParticles.ankiprog

@@ -50,10 +50,10 @@ VertOut main(VertIn input)
 
 
 	output.m_uv = Vec2(input.m_vertexId & 1, input.m_vertexId >> 1);
 	output.m_uv = Vec2(input.m_vertexId & 1, input.m_vertexId >> 1);
 
 
-	output.m_worldPos = transform(g_ankiGlobals.m_cameraTransform, Vec4((output.m_uv - 0.5) * input.m_scale, 0.0, 0.0))
-						+ input.m_position;
+	output.m_worldPos =
+		mul(g_ankiGlobals.m_cameraTransform, Vec4((output.m_uv - 0.5) * input.m_scale, 0.0, 0.0)) + input.m_position;
 
 
-	output.m_svPosition = Vec4(transform(g_renderableGpuViews[0].m_worldTransform, Vec4(output.m_worldPos, 1.0)), 1.0);
+	output.m_svPosition = Vec4(mul(g_renderableGpuViews[0].m_worldTransform, Vec4(output.m_worldPos, 1.0)), 1.0);
 	output.m_svPosition = mul(g_ankiGlobals.m_viewProjectionMatrix, output.m_svPosition);
 	output.m_svPosition = mul(g_ankiGlobals.m_viewProjectionMatrix, output.m_svPosition);
 
 
 	output.m_alpha = input.m_alpha;
 	output.m_alpha = input.m_alpha;

+ 2 - 29
AnKi/Shaders/Functions.hlsl

@@ -438,7 +438,6 @@ Mat3 rotationFromDirection(Vec3 zAxis)
 	Vec3 x = (alignsWithXBasis) ? Vec3(0.0, 0.0, 1.0) : Vec3(1.0, 0.0, 0.0);
 	Vec3 x = (alignsWithXBasis) ? Vec3(0.0, 0.0, 1.0) : Vec3(1.0, 0.0, 0.0);
 	const Vec3 y = normalize(cross(x, z));
 	const Vec3 y = normalize(cross(x, z));
 	x = normalize(cross(z, y));
 	x = normalize(cross(z, y));
-	return Mat3(x, y, z);
 #else
 #else
 	// http://jcgt.org/published/0006/01/01/
 	// http://jcgt.org/published/0006/01/01/
 	const Vec3 z = zAxis;
 	const Vec3 z = zAxis;
@@ -448,9 +447,9 @@ Mat3 rotationFromDirection(Vec3 zAxis)
 
 
 	const Vec3 x = Vec3(1.0 + sign * a * pow(z.x, 2.0), sign * b, -sign * z.x);
 	const Vec3 x = Vec3(1.0 + sign * a * pow(z.x, 2.0), sign * b, -sign * z.x);
 	const Vec3 y = Vec3(b, sign + a * pow(z.y, 2.0), -z.y);
 	const Vec3 y = Vec3(b, sign + a * pow(z.y, 2.0), -z.y);
-
-	return Mat3(x, y, z);
 #endif
 #endif
+
+	return constructMatrixColumns(x, y, z);
 }
 }
 
 
 #if defined(ANKI_COMPUTE_SHADER) && ANKI_GLSL
 #if defined(ANKI_COMPUTE_SHADER) && ANKI_GLSL
@@ -688,29 +687,3 @@ F32 fastCos(F32 x)
 {
 {
 	return fastSin(x + kPi / 2.0);
 	return fastSin(x + kPi / 2.0);
 }
 }
-
-/// Transform using a 3x4 matrix. mat is row major.
-Vec3 transform(Vec4 mat[3u], Vec4 v)
-{
-	const F32 a = dot(mat[0], v);
-	const F32 b = dot(mat[1], v);
-	const F32 c = dot(mat[2], v);
-	return Vec3(a, b, c);
-}
-
-/// Rotate using a 3x3 matrix. mat is row major.
-Vec3 rotate(Vec3 mat[3u], Vec3 v)
-{
-	const F32 a = dot(mat[0], v);
-	const F32 b = dot(mat[1], v);
-	const F32 c = dot(mat[2], v);
-	return Vec3(a, b, c);
-}
-
-RVec3 rotate(RVec3 mat[3u], RVec3 v)
-{
-	const RF32 a = dot(mat[0], v);
-	const RF32 b = dot(mat[1], v);
-	const RF32 c = dot(mat[2], v);
-	return RVec3(a, b, c);
-}

+ 10 - 13
AnKi/Shaders/GBufferGeneric.ankiprog

@@ -137,8 +137,8 @@ void skinning(VertIn input, inout Vec3 pos, inout Vec3 prevPos, inout RVec3 norm
 	Mat4 prevSkinMat = g_prevFrameBoneTransforms[input.m_boneIndices[0]] * input.m_boneWeights[0];
 	Mat4 prevSkinMat = g_prevFrameBoneTransforms[input.m_boneIndices[0]] * input.m_boneWeights[0];
 	[[unroll]] for(U32 i = 1u; i < 4u; ++i)
 	[[unroll]] for(U32 i = 1u; i < 4u; ++i)
 	{
 	{
-		skinMat += g_boneTransforms[input.m_boneIndices[i]] * input.m_boneWeights[i];
-		prevSkinMat += g_prevFrameBoneTransforms[input.m_boneIndices[i]] * input.m_boneWeights[i];
+		skinMat = skinMat + g_boneTransforms[input.m_boneIndices[i]] * input.m_boneWeights[i];
+		prevSkinMat = prevSkinMat + g_prevFrameBoneTransforms[input.m_boneIndices[i]] * input.m_boneWeights[i];
 	}
 	}
 
 
 #	if ANKI_TECHNIQUE == ANKI_RENDERING_TECHNIQUE_GBUFFER
 #	if ANKI_TECHNIQUE == ANKI_RENDERING_TECHNIQUE_GBUFFER
@@ -159,13 +159,13 @@ void velocity(RenderableGpuView view, Vec3 prevLocalPos, inout VertOut output)
 {
 {
 #	if ANKI_VELOCITY
 #	if ANKI_VELOCITY
 	// Object is also moving
 	// Object is also moving
-	const Vec4 trf[3] = view.m_previousWorldTransform;
+	const Mat3x4 trf = view.m_previousWorldTransform;
 #	else
 #	else
 	// Object is a skin that is not moving
 	// Object is a skin that is not moving
-	const Vec4 trf[3] = view.m_worldTransform;
+	const Mat3x4 trf = view.m_worldTransform;
 #	endif
 #	endif
 
 
-	Vec4 v4 = Vec4(transform(trf, Vec4(prevLocalPos, 1.0)), 1.0);
+	Vec4 v4 = Vec4(mul(trf, Vec4(prevLocalPos, 1.0)), 1.0);
 	v4 = mul(g_globalUniforms.m_previousViewProjectionMatrix, v4);
 	v4 = mul(g_globalUniforms.m_previousViewProjectionMatrix, v4);
 
 
 	output.m_prevClipXyw = v4.xyw;
 	output.m_prevClipXyw = v4.xyw;
@@ -208,12 +208,12 @@ VertOut main(VertIn input)
 	skinning(input, pos, prevPos, normal, tangent);
 	skinning(input, pos, prevPos, normal, tangent);
 #endif
 #endif
 
 
-	output.m_position = Vec4(transform(view.m_worldTransform, Vec4(pos, 1.0)), 1.0);
+	output.m_position = Vec4(mul(view.m_worldTransform, Vec4(pos, 1.0)), 1.0);
 	output.m_position = mul(g_globalUniforms.m_viewProjectionMatrix, output.m_position);
 	output.m_position = mul(g_globalUniforms.m_viewProjectionMatrix, output.m_position);
 
 
 #if ANKI_TECHNIQUE == ANKI_RENDERING_TECHNIQUE_GBUFFER
 #if ANKI_TECHNIQUE == ANKI_RENDERING_TECHNIQUE_GBUFFER
-	output.m_normal = transform(view.m_worldTransform, Vec4(normal, 0.0));
-	output.m_tangent = transform(view.m_worldTransform, Vec4(tangent.xyz, 0.0));
+	output.m_normal = mul(view.m_worldTransform, Vec4(normal, 0.0));
+	output.m_tangent = mul(view.m_worldTransform, Vec4(tangent.xyz, 0.0));
 	output.m_bitangent = cross(output.m_normal, output.m_tangent) * tangent.w;
 	output.m_bitangent = cross(output.m_normal, output.m_tangent) * tangent.w;
 #endif
 #endif
 
 
@@ -268,12 +268,9 @@ RVec3 readNormalFromTexture(VertOut input, Texture2D<RVec4> map, SamplerState sa
 	const RVec3 t = normalize(input.m_tangent);
 	const RVec3 t = normalize(input.m_tangent);
 	const RVec3 b = normalize(input.m_bitangent);
 	const RVec3 b = normalize(input.m_bitangent);
 
 
-	RVec3 tbnMat[3u];
-	tbnMat[0] = RVec3(t.x, b.x, n.x);
-	tbnMat[1] = RVec3(t.y, b.y, n.y);
-	tbnMat[2] = RVec3(t.z, b.z, n.z);
+	const RMat3 tbnMat = constructMatrixColumns(t, b, n);
 
 
-	return rotate(tbnMat, nAtTangentspace);
+	return mul(tbnMat, nAtTangentspace);
 }
 }
 
 
 FragOut main(VertOut input)
 FragOut main(VertOut input)

+ 5 - 6
AnKi/Shaders/GBufferGpuParticles.ankiprog

@@ -57,12 +57,10 @@ VertOut main(VertIn input)
 	VertOut output;
 	VertOut output;
 	const GpuParticle part = u_particles[input.m_svVertexId / 2];
 	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);
+	Vec4 crntClipPos = Vec4(mul(u_renderableGpuViews[0].m_worldTransform, Vec4(part.m_newWorldPosition, 1.0)), 1.0);
 	crntClipPos = mul(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);
+	Vec4 prevClipPos = Vec4(mul(u_renderableGpuViews[0].m_worldTransform, Vec4(part.m_oldWorldPosition, 1.0)), 1.0);
 	prevClipPos = mul(u_globalUniforms.m_viewProjectionMatrix, prevClipPos);
 	prevClipPos = mul(u_globalUniforms.m_viewProjectionMatrix, prevClipPos);
 
 
 	output.m_svPosition = ((input.m_svVertexId & 1) == 0) ? crntClipPos : prevClipPos;
 	output.m_svPosition = ((input.m_svVertexId & 1) == 0) ? crntClipPos : prevClipPos;
@@ -75,8 +73,9 @@ VertOut main(VertIn input)
 
 
 	output.m_lifeFactor = saturate(1.0 - (part.m_life / part.m_startingLife));
 	output.m_lifeFactor = saturate(1.0 - (part.m_life / part.m_startingLife));
 
 
-	output.m_normal = normalize(Vec3(u_globalUniforms.m_cameraTransform[0][2], u_globalUniforms.m_cameraTransform[1][2],
-									 u_globalUniforms.m_cameraTransform[1][2]));
+	output.m_normal =
+		normalize(Vec3(u_globalUniforms.m_cameraTransform.m_row0[2], u_globalUniforms.m_cameraTransform.m_row1[2],
+					   u_globalUniforms.m_cameraTransform.m_row2[2]));
 
 
 	return output;
 	return output;
 }
 }

+ 1 - 6
AnKi/Shaders/Include/ClusteredShadingTypes.h

@@ -7,7 +7,7 @@
 
 
 #include <AnKi/Shaders/Include/Common.h>
 #include <AnKi/Shaders/Include/Common.h>
 
 
-#define ANKI_CLUSTERED_SHADING_USE_64BIT !ANKI_PLATFORM_MOBILE
+#define ANKI_CLUSTERED_SHADING_USE_64BIT ANKI_SUPPORTS_64BIT_TYPES
 
 
 ANKI_BEGIN_NAMESPACE
 ANKI_BEGIN_NAMESPACE
 
 
@@ -190,13 +190,8 @@ ANKI_SHADER_STATIC_ASSERT(sizeof(GlobalIlluminationProbe) == kSizeof_GlobalIllum
 /// Common matrices.
 /// Common matrices.
 struct CommonMatrices
 struct CommonMatrices
 {
 {
-#if ANKI_CPP
 	Mat3x4 m_cameraTransform;
 	Mat3x4 m_cameraTransform;
 	Mat3x4 m_view;
 	Mat3x4 m_view;
-#else
-	Vec4 m_cameraTransform[3];
-	Vec4 m_view[3];
-#endif
 	Mat4 m_projection;
 	Mat4 m_projection;
 	Mat4 m_viewProjection;
 	Mat4 m_viewProjection;
 
 

+ 156 - 7
AnKi/Shaders/Include/Common.h

@@ -5,6 +5,8 @@
 
 
 #pragma once
 #pragma once
 
 
+#define ANKI_SUPPORTS_64BIT_TYPES !ANKI_PLATFORM_MOBILE
+
 //! == C++ =============================================================================================================
 //! == C++ =============================================================================================================
 #if defined(__cplusplus)
 #if defined(__cplusplus)
 
 
@@ -51,7 +53,6 @@ ANKI_END_NAMESPACE
 #	define constexpr static const
 #	define constexpr static const
 
 
 #	define ANKI_SUPPORTS_16BIT_TYPES 0
 #	define ANKI_SUPPORTS_16BIT_TYPES 0
-#	define ANKI_SUPPORTS_64BIT_TYPES !ANKI_PLATFORM_MOBILE
 
 
 template<typename T>
 template<typename T>
 void maybeUnused(T a)
 void maybeUnused(T a)
@@ -189,26 +190,174 @@ typedef int64_t4 I64Vec4;
 constexpr uint kSizeof_I64Vec4 = 32u;
 constexpr uint kSizeof_I64Vec4 = 32u;
 #	endif
 #	endif
 
 
-typedef float3x3 Mat3;
-typedef float4x4 Mat4;
-typedef float3x4 Mat3x4;
-
 typedef bool Bool;
 typedef bool Bool;
 
 
+#	define _ANKI_DEFINE_OPERATOR_F32_ROWS3(mat, fl, op) \
+		mat operator op(fl f) \
+		{ \
+			mat o; \
+			o.m_row0 = m_row0 op f; \
+			o.m_row1 = m_row1 op f; \
+			o.m_row2 = m_row2 op f; \
+			return o; \
+		}
+
+#	define _ANKI_DEFINE_OPERATOR_F32_ROWS4(mat, fl, op) \
+		mat operator op(fl f) \
+		{ \
+			mat o; \
+			o.m_row0 = m_row0 op f; \
+			o.m_row1 = m_row1 op f; \
+			o.m_row2 = m_row2 op f; \
+			o.m_row3 = m_row3 op f; \
+			return o; \
+		}
+
+#	define _ANKI_DEFINE_OPERATOR_SELF_ROWS3(mat, op) \
+		mat operator op(mat b) \
+		{ \
+			mat o; \
+			o.m_row0 = m_row0 op b.m_row0; \
+			o.m_row1 = m_row1 op b.m_row1; \
+			o.m_row2 = m_row2 op b.m_row2; \
+			return o; \
+		}
+
+#	define _ANKI_DEFINE_OPERATOR_SELF_ROWS4(mat, op) \
+		mat operator op(mat b) \
+		{ \
+			mat o; \
+			o.m_row0 = m_row0 op b.m_row0; \
+			o.m_row1 = m_row1 op b.m_row1; \
+			o.m_row2 = m_row2 op b.m_row2; \
+			o.m_row3 = m_row3 op b.m_row3; \
+			return o; \
+		}
+
+#	define _ANKI_DEFINE_ALL_OPERATORS_ROWS3(mat, fl) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS3(mat, fl, +) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS3(mat, fl, -) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS3(mat, fl, *) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS3(mat, fl, /) \
+		_ANKI_DEFINE_OPERATOR_SELF_ROWS3(mat, +) \
+		_ANKI_DEFINE_OPERATOR_SELF_ROWS3(mat, -)
+
+#	define _ANKI_DEFINE_ALL_OPERATORS_ROWS4(mat, fl) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS4(mat, fl, +) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS4(mat, fl, -) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS4(mat, fl, *) \
+		_ANKI_DEFINE_OPERATOR_F32_ROWS4(mat, fl, /) \
+		_ANKI_DEFINE_OPERATOR_SELF_ROWS4(mat, +) \
+		_ANKI_DEFINE_OPERATOR_SELF_ROWS4(mat, -)
+
+struct Mat3
+{
+	Vec3 m_row0;
+	Vec3 m_row1;
+	Vec3 m_row2;
+
+	_ANKI_DEFINE_ALL_OPERATORS_ROWS3(Mat3, F32)
+};
+
+struct Mat4
+{
+	Vec4 m_row0;
+	Vec4 m_row1;
+	Vec4 m_row2;
+	Vec4 m_row3;
+
+	_ANKI_DEFINE_ALL_OPERATORS_ROWS4(Mat4, F32)
+};
+
+struct Mat3x4
+{
+	Vec4 m_row0;
+	Vec4 m_row1;
+	Vec4 m_row2;
+
+	_ANKI_DEFINE_ALL_OPERATORS_ROWS3(Mat3x4, F32)
+};
+
 #	if ANKI_FORCE_FULL_FP_PRECISION
 #	if ANKI_FORCE_FULL_FP_PRECISION
 typedef float RF32;
 typedef float RF32;
 typedef float2 RVec2;
 typedef float2 RVec2;
 typedef float3 RVec3;
 typedef float3 RVec3;
 typedef float4 RVec4;
 typedef float4 RVec4;
-typedef float3x3 RMat3;
+typedef Mat3 RMat3;
 #	else
 #	else
 typedef min16float RF32;
 typedef min16float RF32;
 typedef min16float2 RVec2;
 typedef min16float2 RVec2;
 typedef min16float3 RVec3;
 typedef min16float3 RVec3;
 typedef min16float4 RVec4;
 typedef min16float4 RVec4;
-typedef min16float3x3 RMat3;
+
+struct RMat3
+{
+	RVec3 m_row0;
+	RVec3 m_row1;
+	RVec3 m_row2;
+
+	_ANKI_DEFINE_ALL_OPERATORS_ROWS3(RMat3, RF32)
+};
 #	endif
 #	endif
 
 
+// Matrix functions
+Mat3 constructMatrixColumns(Vec3 c0, Vec3 c1, Vec3 c2)
+{
+	Mat3 m;
+	m.m_row0 = Vec3(c0.x, c1.x, c2.x);
+	m.m_row1 = Vec3(c0.y, c1.y, c2.y);
+	m.m_row2 = Vec3(c0.z, c1.z, c2.z);
+	return m;
+}
+
+RMat3 constructMatrixColumns(RVec3 c0, RVec3 c1, RVec3 c2)
+{
+	RMat3 m;
+	m.m_row0 = RVec3(c0.x, c1.x, c2.x);
+	m.m_row1 = RVec3(c0.y, c1.y, c2.y);
+	m.m_row2 = RVec3(c0.z, c1.z, c2.z);
+	return m;
+}
+
+Vec3 mul(Mat3 m, Vec3 v)
+{
+	const F32 a = dot(m.m_row0, v);
+	const F32 b = dot(m.m_row1, v);
+	const F32 c = dot(m.m_row2, v);
+	return Vec3(a, b, c);
+}
+
+RVec3 mul(RMat3 m, RVec3 v)
+{
+	const RF32 a = dot(m.m_row0, v);
+	const RF32 b = dot(m.m_row1, v);
+	const RF32 c = dot(m.m_row2, v);
+	return RVec3(a, b, c);
+}
+
+Vec4 mul(Mat4 m, Vec4 v)
+{
+	const F32 a = dot(m.m_row0, v);
+	const F32 b = dot(m.m_row1, v);
+	const F32 c = dot(m.m_row2, v);
+	const F32 d = dot(m.m_row3, v);
+	return Vec4(a, b, c, d);
+}
+
+Vec3 mul(Mat3x4 m, Vec4 v)
+{
+	const F32 a = dot(m.m_row0, v);
+	const F32 b = dot(m.m_row1, v);
+	const F32 c = dot(m.m_row2, v);
+	return Vec3(a, b, c);
+}
+
+Mat3 transpose(Mat3 m)
+{
+	return constructMatrixColumns(m.m_row0, m.m_row1, m.m_row2);
+}
+
+// Common constants
 constexpr F32 kEpsilonF32 = 0.000001f;
 constexpr F32 kEpsilonF32 = 0.000001f;
 #	if ANKI_SUPPORTS_16BIT_TYPES
 #	if ANKI_SUPPORTS_16BIT_TYPES
 constexpr F16 kEpsilonhF16 = (F16)0.0001f; // Divisions by this should be OK according to http://weitz.de/ieee
 constexpr F16 kEpsilonhF16 = (F16)0.0001f; // Divisions by this should be OK according to http://weitz.de/ieee

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

@@ -43,8 +43,8 @@ struct MeshGpuView
 
 
 struct RenderableGpuView
 struct RenderableGpuView
 {
 {
-	Vec4 m_worldTransform[3u];
-	Vec4 m_previousWorldTransform[3u];
+	Mat3x4 m_worldTransform;
+	Mat3x4 m_previousWorldTransform;
 	Vec4 m_positionScaleF32AndTranslationVec3; ///< The scale and translation that uncompress positions.
 	Vec4 m_positionScaleF32AndTranslationVec3; ///< The scale and translation that uncompress positions.
 };
 };
 
 

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

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

+ 1 - 1
AnKi/Shaders/IndirectDiffuse.glsl

@@ -73,7 +73,7 @@ void main()
 
 
 	// Get normal
 	// Get normal
 	const Vec3 worldNormal = unpackNormalFromGBuffer(textureLod(u_gbufferRt2, u_linearAnyClampSampler, uv, 0.0));
 	const Vec3 worldNormal = unpackNormalFromGBuffer(textureLod(u_gbufferRt2, u_linearAnyClampSampler, uv, 0.0));
-	const Vec3 viewNormal = transform(u_clusteredShading.m_matrices.m_view, Vec4(worldNormal, 0.0)).xyz;
+	const Vec3 viewNormal = (u_clusteredShading.m_matrices.m_view * Vec4(worldNormal, 0.0)).xyz;
 
 
 	// Get origin
 	// Get origin
 	const F32 depth = textureLod(u_depthRt, u_linearAnyClampSampler, uv, 0.0).r;
 	const F32 depth = textureLod(u_depthRt, u_linearAnyClampSampler, uv, 0.0).r;

+ 1 - 2
AnKi/Shaders/VolumetricLightingAccumulation.ankiprog

@@ -73,8 +73,7 @@ Vec3 worldPosInsideClusterAndZViewSpace(Vec3 relativePos, out F32 negativeZViewS
 	const Vec2 xyViewSpace = UV_TO_NDC(uv) * u_clusteredShading.m_matrices.m_unprojectionParameters.xy * zViewSpace;
 	const Vec2 xyViewSpace = UV_TO_NDC(uv) * u_clusteredShading.m_matrices.m_unprojectionParameters.xy * zViewSpace;
 
 
 	// Get the final world pos
 	// Get the final world pos
-	const Vec3 worldPos =
-		transform(u_clusteredShading.m_matrices.m_cameraTransform, Vec4(xyViewSpace, zViewSpace, 1.0));
+	const Vec3 worldPos = u_clusteredShading.m_matrices.m_cameraTransform * Vec4(xyViewSpace, zViewSpace, 1.0);
 
 
 	return worldPos;
 	return worldPos;
 }
 }