Răsfoiți Sursa

Merge pull request #32 from godlikepanos/pbr_experiments

Correct PBR
Panagiotis Christopoulos Charitos 7 ani în urmă
părinte
comite
2814b6af92
34 a modificat fișierele cu 367 adăugiri și 571 ștergeri
  1. 13 17
      programs/DeferredShading.ankiprog
  2. 5 0
      programs/GBufferPost.ankiprog
  3. 3 1
      programs/Irradiance.ankiprog
  4. 13 30
      programs/LightShading.ankiprog
  5. 11 24
      programs/Reflections.ankiprog
  6. 39 52
      programs/Ssao.ankiprog
  7. 7 7
      programs/VolumetricFog.ankiprog
  8. BIN
      samples/simple_scene/assets/column.ankimesh
  9. BIN
      samples/simple_scene/assets/room.ankimesh
  10. 1 2
      samples/simple_scene/assets/scene.lua
  11. BIN
      samples/simple_scene/assets/sector.ankimesh
  12. BIN
      samples/simple_scene/assets/simple_scene.blend
  13. 1 1
      samples/sponza/assets/arch-material.ankimtl
  14. 1 1
      samples/sponza/assets/floor-material.ankimtl
  15. 101 106
      samples/sponza/assets/scene.lua
  16. BIN
      samples/sponza/assets/sponza_381.ankimesh
  17. BIN
      samples/sponza/assets/sponza_69.ankimesh
  18. 34 34
      samples/sponza/assets/unnamed_0.ankianim
  19. 6 7
      shaders/ClusterLightCommon.glsl
  20. 7 11
      shaders/ForwardShadingCommonFrag.glsl
  21. 54 52
      shaders/LightFunctions.glsl
  22. 17 19
      shaders/Pack.glsl
  23. 0 3
      src/anki/event/LightEvent.cpp
  24. 0 7
      src/anki/event/LightEvent.h
  25. 12 3
      src/anki/input/InputSdl.cpp
  26. 2 7
      src/anki/renderer/Indirect.cpp
  27. 5 9
      src/anki/renderer/LightBin.cpp
  28. 0 2
      src/anki/renderer/RenderQueue.h
  29. 30 50
      src/anki/renderer/Ssao.cpp
  30. 5 2
      src/anki/renderer/Ssao.h
  31. 0 13
      src/anki/scene/components/LightComponent.h
  32. 0 95
      src/anki/script/Scene.cpp
  33. 0 8
      src/anki/script/Scene.xml
  34. 0 8
      tools/scene/Exporter.cpp

+ 13 - 17
programs/DeferredShading.ankiprog

@@ -55,7 +55,6 @@ struct PointLight
 {
 {
 	vec4 posRadius; // xyz: Light pos in world space. w: The -1/radius
 	vec4 posRadius; // xyz: Light pos in world space. w: The -1/radius
 	vec4 diffuseColorPad1; // xyz: diff color
 	vec4 diffuseColorPad1; // xyz: diff color
-	vec4 specularColorPad1; // xyz: spec color
 };
 };
 
 
 // Spot light
 // Spot light
@@ -63,8 +62,7 @@ struct SpotLight
 {
 {
 	vec4 posRadius; // xyz: Light pos in world space. w: The -1/radius
 	vec4 posRadius; // xyz: Light pos in world space. w: The -1/radius
 	vec4 diffuseColorOuterCos; // xyz: diff color, w: outer cosine of spot
 	vec4 diffuseColorOuterCos; // xyz: diff color, w: outer cosine of spot
-	vec4 specularColorInnerCos; // xyz: spec color, w: inner cosine of spot
-	vec4 lightDirPad1;
+	vec4 lightDirInnerCos; // xyz: light dir, w: inner cosine of spot
 };
 };
 
 
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_msRt0;
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_msRt0;
@@ -82,16 +80,18 @@ layout(ANKI_UBO_BINDING(0, 1), row_major) uniform u1_
 #elif LIGHT_TYPE == SPOT_LIGHT_TYPE
 #elif LIGHT_TYPE == SPOT_LIGHT_TYPE
 	SpotLight u_light;
 	SpotLight u_light;
 #else
 #else
-#error See file
+#	error See file
 #endif
 #endif
 };
 };
 
 
 #if LIGHT_TYPE == POINT_LIGHT_TYPE
 #if LIGHT_TYPE == POINT_LIGHT_TYPE
-#define u_ldiff u_light.diffuseColorPad1.xyz
-#define u_lspec u_light.specularColorPad1.xyz
+#	define u_ldiff u_light.diffuseColorPad1.xyz
 #else
 #else
-#define u_ldiff u_light.diffuseColorOuterCos.xyz
-#define u_lspec u_light.specularColorInnerCos.xyz
+#	define u_ldiff u_light.diffuseColorOuterCos.xyz
+#	define u_lightDir u_light.lightDirInnerCos.xyz
+#	define u_outerCos u_light.diffuseColorOuterCos.w
+#	define u_innerCos u_light.lightDirInnerCos.w
+#	define u_lightDir u_light.lightDirInnerCos.xyz
 #endif
 #endif
 
 
 #define u_camPos u_camPosPad1.xyz
 #define u_camPos u_camPosPad1.xyz
@@ -112,7 +112,6 @@ void main()
 	// Decode and process gbuffer
 	// Decode and process gbuffer
 	GbufferInfo gbuffer;
 	GbufferInfo gbuffer;
 	readGBuffer(u_msRt0, u_msRt1, u_msRt2, uvToRead, 0.0, gbuffer);
 	readGBuffer(u_msRt0, u_msRt1, u_msRt2, uvToRead, 0.0, gbuffer);
-	float a2 = pow(gbuffer.roughness, 2.0);
 
 
 	vec4 worldPos4 = u_invViewProjMat * vec4(UV_TO_NDC(uv), depth, 1.0);
 	vec4 worldPos4 = u_invViewProjMat * vec4(UV_TO_NDC(uv), depth, 1.0);
 	vec3 worldPos = worldPos4.xyz / worldPos4.w;
 	vec3 worldPos = worldPos4.xyz / worldPos4.w;
@@ -123,20 +122,17 @@ void main()
 	vec3 l = normalize(frag2Light);
 	vec3 l = normalize(frag2Light);
 	float nol = max(0.0, dot(gbuffer.normal, l));
 	float nol = max(0.0, dot(gbuffer.normal, l));
 
 
-	vec3 specC = computeSpecularColorBrdf(viewDir, l, gbuffer.normal, gbuffer.specular, u_lspec, a2, nol);
-
-	vec3 diffC = computeDiffuseColor(gbuffer.diffuse, u_ldiff);
+	vec3 specC = computeSpecularColorBrdf(gbuffer, viewDir, l);
+	vec3 diffC = diffuseLambert(gbuffer.diffuse);
 
 
 	float att = computeAttenuationFactor(u_light.posRadius.w, frag2Light);
 	float att = computeAttenuationFactor(u_light.posRadius.w, frag2Light);
 	float lambert = nol;
 	float lambert = nol;
 
 
 #if LIGHT_TYPE == POINT_LIGHT_TYPE
 #if LIGHT_TYPE == POINT_LIGHT_TYPE
-	out_color = (specC + diffC) * (att * max(lambert, gbuffer.subsurface));
+	out_color = (specC + diffC) * u_ldiff * (att * max(lambert, gbuffer.subsurface));
 #else
 #else
-	float spot =
-		computeSpotFactor(l, u_light.diffuseColorOuterCos.w, u_light.specularColorInnerCos.w, u_light.lightDirPad1.xyz);
-
-	out_color = (diffC + specC) * (att * spot * max(lambert, gbuffer.subsurface));
+	float spot = computeSpotFactor(l, u_outerCos, u_innerCos, u_lightDir);
+	out_color = (diffC + specC) * u_ldiff * (att * spot * max(lambert, gbuffer.subsurface));
 #endif
 #endif
 }
 }
 			]]></source>
 			]]></source>

+ 5 - 0
programs/GBufferPost.ankiprog

@@ -92,6 +92,11 @@ void main()
 
 
 	// Process decals
 	// Process decals
 	uint count = u_lightIndices[idxOffset++];
 	uint count = u_lightIndices[idxOffset++];
+	if(count == 0 && ssao >= (1.0 - EPSILON))
+	{
+		discard;
+	}
+
 	while(count-- != 0)
 	while(count-- != 0)
 	{
 	{
 		Decal decal = u_decals[u_lightIndices[idxOffset++]];
 		Decal decal = u_decals[u_lightIndices[idxOffset++]];

+ 3 - 1
programs/Irradiance.ankiprog

@@ -20,6 +20,8 @@ http://www.anki3d.org/LICENSE
 
 
 			<source><![CDATA[
 			<source><![CDATA[
 // Compute the irradiance given an environment map
 // Compute the irradiance given an environment map
+// It's almost the same as http://www.codinglabs.net/article_physically_based_rendering.aspx
+// It's more bright though
 
 
 #include "shaders/Functions.glsl"
 #include "shaders/Functions.glsl"
 
 
@@ -69,7 +71,7 @@ void main()
 		}
 		}
 	}
 	}
 
 
-	out_color = outCol / weight * (2.0 * PI);
+	out_color = outCol / weight * PI;
 }
 }
 			]]></source>
 			]]></source>
 		</shader>
 		</shader>

+ 13 - 30
programs/LightShading.ankiprog

@@ -68,11 +68,10 @@ const float SUBSURFACE_MIN = 0.05;
 #define LIGHTING_COMMON_BRDF() \
 #define LIGHTING_COMMON_BRDF() \
 	vec3 frag2Light = light.posRadius.xyz - worldPos; \
 	vec3 frag2Light = light.posRadius.xyz - worldPos; \
 	vec3 l = normalize(frag2Light); \
 	vec3 l = normalize(frag2Light); \
-	float nol = max(0.0, dot(normal, l)); \
-	vec3 specC = computeSpecularColorBrdf(viewDir, l, normal, specCol, light.specularColorRadius.rgb, a2, nol); \
-	vec3 diffC = computeDiffuseColor(diffCol, light.diffuseColorShadowmapId.rgb); \
+	vec3 specC = computeSpecularColorBrdf(gbuffer, viewDir, l); \
+	vec3 diffC = diffuseLambert(gbuffer.diffuse); \
 	float att = computeAttenuationFactor(light.posRadius.w, frag2Light); \
 	float att = computeAttenuationFactor(light.posRadius.w, frag2Light); \
-	float lambert = nol;
+	float lambert = max(0.0, dot(gbuffer.normal, l));
 
 
 void main()
 void main()
 {
 {
@@ -84,23 +83,9 @@ void main()
 	vec3 worldPos = worldPos4.xyz / worldPos4.w;
 	vec3 worldPos = worldPos4.xyz / worldPos4.w;
 
 
 	// Decode GBuffer
 	// Decode GBuffer
-	vec3 normal;
-	vec3 diffCol;
-	vec3 specCol;
-	float roughness;
-	float subsurface;
-	float emission;
-	float metallic;
-
 	GbufferInfo gbuffer;
 	GbufferInfo gbuffer;
 	readGBuffer(u_msRt0, u_msRt1, u_msRt2, in_uv, 0.0, gbuffer);
 	readGBuffer(u_msRt0, u_msRt1, u_msRt2, in_uv, 0.0, gbuffer);
-	diffCol = gbuffer.diffuse;
-	specCol = gbuffer.specular;
-	normal = gbuffer.normal;
-	roughness = gbuffer.roughness;
-	metallic = gbuffer.metallic;
-	subsurface = max(gbuffer.subsurface, SUBSURFACE_MIN);
-	emission = gbuffer.emission;
+	gbuffer.subsurface = max(gbuffer.subsurface, SUBSURFACE_MIN);
 
 
 	// Get first light index
 	// Get first light index
 	uint idxOffset;
 	uint idxOffset;
@@ -117,10 +102,7 @@ void main()
 	idxOffset += count;
 	idxOffset += count;
 
 
 	// Ambient and emissive color
 	// Ambient and emissive color
-	vec3 outC = diffCol * emission;
-
-	// Don't allow zero a2 because we may end up with division with zero
-	float a2 = computeRoughnesSquared(roughness);
+	vec3 outC = gbuffer.diffuse * gbuffer.emission;
 
 
 	// Point lights
 	// Point lights
 	vec3 viewDir = normalize(u_cameraPos - worldPos);
 	vec3 viewDir = normalize(u_cameraPos - worldPos);
@@ -131,17 +113,17 @@ void main()
 
 
 		LIGHTING_COMMON_BRDF();
 		LIGHTING_COMMON_BRDF();
 
 
-		if(light.diffuseColorShadowmapId.w >= 0.0)
+		if(light.diffuseColorTileSize.w >= 0.0)
 		{
 		{
 			float shadow = computeShadowFactorOmni(frag2Light, 
 			float shadow = computeShadowFactorOmni(frag2Light, 
-				light.specularColorRadius.w, 
+				light.radiusPad3.x, 
 				light.atlasTilesPad2.xy, 
 				light.atlasTilesPad2.xy, 
-				light.diffuseColorShadowmapId.w,
+				light.diffuseColorTileSize.w,
 				u_shadowTex);
 				u_shadowTex);
 			lambert *= shadow;
 			lambert *= shadow;
 		}
 		}
 
 
-		outC += (diffC + specC) * (att * max(subsurface, lambert));
+		outC += (diffC + specC) * light.diffuseColorTileSize.rgb * (att * max(gbuffer.subsurface, lambert));
 	}
 	}
 
 
 	// Spot lights
 	// Spot lights
@@ -152,17 +134,18 @@ void main()
 
 
 		LIGHTING_COMMON_BRDF();
 		LIGHTING_COMMON_BRDF();
 
 
-		float spot = computeSpotFactor(l, light.outerCosInnerCos.x, light.outerCosInnerCos.y, light.lightDir.xyz);
+		float spot = computeSpotFactor(
+			l, light.outerCosInnerCos.x, light.outerCosInnerCos.y, light.lightDirRadius.xyz);
 
 
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(shadowmapLayerIdx >= 0.0)
 		if(shadowmapLayerIdx >= 0.0)
 		{
 		{
 			float shadow = computeShadowFactorSpot(
 			float shadow = computeShadowFactorSpot(
-				light.texProjectionMat, worldPos, light.specularColorRadius.w, u_shadowTex);
+				light.texProjectionMat, worldPos, light.lightDirRadius.w, u_shadowTex);
 			lambert *= shadow;
 			lambert *= shadow;
 		}
 		}
 
 
-		outC += (diffC + specC) * (att * spot * max(subsurface, lambert));
+		outC += (diffC + specC) * light.diffuseColorShadowmapId.rgb * (att * spot * max(gbuffer.subsurface, lambert));
 	}
 	}
 
 
 	// Indirect
 	// Indirect

+ 11 - 24
programs/Reflections.ankiprog

@@ -207,17 +207,6 @@ void readReflectionsAndIrradianceFromProbes(
 	}
 	}
 }
 }
 
 
-vec3 computeSpecIndirectFactor(vec3 worldPos, vec3 normal, float roughness, vec3 specColor)
-{
-	vec3 viewDir = normalize(u_cameraPos - worldPos);
-	float ndotv = dot(normal, viewDir);
-
-	vec2 envBRDF = texture(u_integrationLut, vec2(roughness, ndotv)).xy;
-	vec3 specIndirectTerm = specColor * envBRDF.x + envBRDF.y;
-
-	return specIndirectTerm;
-}
-
 void main()
 void main()
 {
 {
 	// Compute a global invocation ID that takes the checkerboard pattern into account
 	// Compute a global invocation ID that takes the checkerboard pattern into account
@@ -249,16 +238,18 @@ void main()
 	vec4 worldPos4 = u_invViewProjMat * vec4(ndc, depth, 1.0);
 	vec4 worldPos4 = u_invViewProjMat * vec4(ndc, depth, 1.0);
 	vec3 worldPos = worldPos4.xyz / worldPos4.w;
 	vec3 worldPos = worldPos4.xyz / worldPos4.w;
 
 
-	// Compute how much reflections we need
-	float a2 = computeRoughnesSquared(gbuffer.roughness);
-	vec3 specIndirectTerm = computeSpecIndirectFactor(worldPos, gbuffer.normal, a2, gbuffer.specular);
-	bool runSslr = 
-		max(max(specIndirectTerm.x, specIndirectTerm.y), specIndirectTerm.z) > 0.05;
+	// Compute env BRDF
+	vec3 env;
+	{
+		vec3 viewDir = normalize(u_cameraPos - worldPos);
+		float NoV = max(EPSILON, dot(gbuffer.normal, viewDir));
+		env = envBRDF(gbuffer.specular, gbuffer.roughness, u_integrationLut, NoV);
+	}
 
 
 	// Try SSR
 	// Try SSR
 	float sslrFactor = 0.0;
 	float sslrFactor = 0.0;
 	vec3 sslrCol = vec3(0.0);
 	vec3 sslrCol = vec3(0.0);
-	if(runSslr)
+	if(env.g > 0.05)
 	{
 	{
 		// Get view pos
 		// Get view pos
 		vec4 viewPos4 = u_invProjMat * vec4(UV_TO_NDC(uv), depth, 1.0);
 		vec4 viewPos4 = u_invProjMat * vec4(UV_TO_NDC(uv), depth, 1.0);
@@ -300,15 +291,11 @@ void main()
 			idxOffset, worldPos, gbuffer.normal, gbuffer.roughness, probeCol, indirectCol);
 			idxOffset, worldPos, gbuffer.normal, gbuffer.roughness, probeCol, indirectCol);
 	}
 	}
 
 
-	vec3 outColor = indirectCol * gbuffer.diffuse;
-
 	// Combine the SSR and probe reflections and write the result
 	// Combine the SSR and probe reflections and write the result
-	{
-		vec3 finalRefl = mix(probeCol, sslrCol, sslrFactor);
-		finalRefl = specIndirectTerm * finalRefl;
+	vec3 finalRefl = mix(probeCol, sslrCol, sslrFactor);
 
 
-		outColor += finalRefl;
-	}
+	// Compute the final color
+	vec3 outColor = indirectCol * gbuffer.diffuse + finalRefl * env;
 
 
 	// Store the color for the resolve
 	// Store the color for the resolve
 	s_pixels[gl_LocalInvocationID.y][gl_LocalInvocationID.x] = outColor;
 	s_pixels[gl_LocalInvocationID.y][gl_LocalInvocationID.x] = outColor;

+ 39 - 52
programs/Ssao.ankiprog

@@ -5,6 +5,10 @@ Code licensed under the BSD License.
 http://www.anki3d.org/LICENSE
 http://www.anki3d.org/LICENSE
 -->
 -->
 <shaderProgram>
 <shaderProgram>
+	<mutators>
+		<mutator name="USE_NORMAL" values="0 1"/>
+	</mutators>
+
 	<shaders>
 	<shaders>
 		<shader type="vert">
 		<shader type="vert">
 			<source><![CDATA[
 			<source><![CDATA[
@@ -19,7 +23,7 @@ http://www.anki3d.org/LICENSE
 				<input name="RADIUS" type="float" const="1"/>
 				<input name="RADIUS" type="float" const="1"/>
 				<input name="BIAS" type="float" const="1"/>
 				<input name="BIAS" type="float" const="1"/>
 				<input name="STRENGTH" type="float" const="1"/>
 				<input name="STRENGTH" type="float" const="1"/>
-				<input name="HISTORY_FEEDBACK" type="float" const="1"/>
+				<input name="SAMPLE_COUNT" type="uint" const="1"/>
 			</inputs>
 			</inputs>
 
 
 			<source><![CDATA[
 			<source><![CDATA[
@@ -35,18 +39,16 @@ layout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform _blk
 {
 {
 	vec4 u_unprojectionParams;
 	vec4 u_unprojectionParams;
 	vec4 u_projectionMat;
 	vec4 u_projectionMat;
-	vec4 u_noiseLayerPad3;
-	mat4 u_prevViewProjMatMulInvViewProjMat;
 	mat3 u_viewRotMat;
 	mat3 u_viewRotMat;
 };
 };
 
 
-#define u_noiseLayer u_noiseLayerPad3.x
-
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_mMsDepthRt;
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_mMsDepthRt;
-layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_msRt;
-layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2DArray u_noiseMap;
-layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2D u_prevSsaoRt;
+layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2DArray u_noiseMap;
+#if USE_NORMAL
+layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_msRt;
+#endif
 
 
+#if USE_NORMAL
 // Get normal
 // Get normal
 vec3 readNormal(in vec2 uv)
 vec3 readNormal(in vec2 uv)
 {
 {
@@ -55,19 +57,20 @@ vec3 readNormal(in vec2 uv)
 	normal = u_viewRotMat * normal;
 	normal = u_viewRotMat * normal;
 	return normal;
 	return normal;
 }
 }
+#endif
 
 
 // Read the noise tex
 // Read the noise tex
-vec3 readRandom(in vec2 uv)
+vec3 readRandom(vec2 uv, float layer)
 {
 {
 	const vec2 tmp = vec2(float(FB_SIZE.x) / float(NOISE_MAP_SIZE), float(FB_SIZE.y) / float(NOISE_MAP_SIZE));
 	const vec2 tmp = vec2(float(FB_SIZE.x) / float(NOISE_MAP_SIZE), float(FB_SIZE.y) / float(NOISE_MAP_SIZE));
-	vec3 r = texture(u_noiseMap, vec3(tmp * uv, u_noiseLayer)).rgb;
+	vec3 r = texture(u_noiseMap, vec3(tmp * uv, layer)).rgb;
 	return r;
 	return r;
 }
 }
 
 
 // Returns the Z of the position in view space
 // Returns the Z of the position in view space
 float readZ(in vec2 uv)
 float readZ(in vec2 uv)
 {
 {
-	float depth = texture(u_mMsDepthRt, uv).r;
+	float depth = textureLod(u_mMsDepthRt, uv, 0.0).r;
 	float z = u_unprojectionParams.z / (u_unprojectionParams.w + depth);
 	float z = u_unprojectionParams.z / (u_unprojectionParams.w + depth);
 	return z;
 	return z;
 }
 }
@@ -77,8 +80,7 @@ vec3 readPosition(in vec2 uv)
 {
 {
 	vec3 fragPosVspace;
 	vec3 fragPosVspace;
 	fragPosVspace.z = readZ(uv);
 	fragPosVspace.z = readZ(uv);
-
-	fragPosVspace.xy = (2.0 * uv - 1.0) * u_unprojectionParams.xy * fragPosVspace.z;
+	fragPosVspace.xy = UV_TO_NDC(uv) * u_unprojectionParams.xy * fragPosVspace.z;
 
 
 	return fragPosVspace;
 	return fragPosVspace;
 }
 }
@@ -90,33 +92,16 @@ vec4 project(vec4 point)
 
 
 void main(void)
 void main(void)
 {
 {
-	vec2 ndc = in_uv * 2.0 - 1.0;
-	float depth = texture(u_mMsDepthRt, in_uv).r;
+	vec2 ndc = UV_TO_NDC(in_uv);
 
 
-	vec3 origin;
-	origin.z = u_unprojectionParams.z / (u_unprojectionParams.w + depth);
-	origin.xy = ndc * u_unprojectionParams.xy * origin.z;
+	// Compute origin
+	vec3 origin = readPosition(in_uv);
 
 
+	// Get normal
+#if USE_NORMAL
 	vec3 normal = readNormal(in_uv);
 	vec3 normal = readNormal(in_uv);
-
-	// Get rand factors
-	vec3 randFactors = readRandom(in_uv);
-
-	// Get prev SSAO
-	vec4 clip = u_prevViewProjMatMulInvViewProjMat * vec4(vec3(ndc, depth), 1.0);
-	clip.xy /= clip.w;
-	vec2 oldUv = NDC_TO_UV(clip.xy);
-	float prevSsao = textureLod(u_prevSsaoRt, oldUv, 0.0).r;
-
-	// Compute the history blend. If clip falls outside NDC then it's 1.0 (use only current SSAO term) and if it's
-	// inside NDC then use the HISTORY_FEEDBACK value
-#if 0
-	vec2 posNdc = abs(clip.xy);
-	float historyFeedback = max(posNdc.x, posNdc.y);
-	historyFeedback = min(floor(historyFeedback), 1.0 - HISTORY_FEEDBACK);
-	historyFeedback += HISTORY_FEEDBACK;
 #else
 #else
-	const float historyFeedback = HISTORY_FEEDBACK;
+	vec3 normal = normalize(cross(dFdx(origin), dFdy(origin)));
 #endif
 #endif
 
 
 	// Find the projected radius
 	// Find the projected radius
@@ -125,23 +110,25 @@ void main(void)
 	vec2 projSphereLimit2 = projSphereLimit.xy / projSphereLimit.w;
 	vec2 projSphereLimit2 = projSphereLimit.xy / projSphereLimit.w;
 	float projRadius = length(projSphereLimit2 - ndc);
 	float projRadius = length(projSphereLimit2 - ndc);
 
 
-	// Find a random point around the current NDC. Make sure that the sides fall inside the screen.
-#if 0
-	vec2 startXY = -in_uv; // range [0,-1]
-	startXY += randFactors.xy; // for the left side it's [0,1] for the center [0,0], right [-1,0]
-	vec2 finalDiskPoint = ndc + startXY * projRadius;
-#else
-	vec2 finalDiskPoint = ndc + (randFactors.xy - 0.5) * projRadius;
-#endif
-
-	// Compute factor
-	vec3 s = readPosition(NDC_TO_UV(finalDiskPoint));
-	vec3 u = s - origin;
-	float ssao = max(dot(normal, u) + BIAS, 0.0) / max(dot(u, u), EPSILON);
+	// Loop to compute
+	float ssao = 0.0;
+	for(uint i = 0; i < SAMPLE_COUNT; ++i)
+	{
+		// Compute disk
+		vec3 randFactors = readRandom(in_uv, float(i));
+		vec2 dir = normalize(randFactors.xy * 2.0 - 1.0);
+		float radius = projRadius * (randFactors.z * 0.85 + 0.15);
+		vec2 finalDiskPoint = ndc + dir * radius;
+
+		// Compute factor
+		vec3 s = readPosition(NDC_TO_UV(finalDiskPoint));
+		vec3 u = s - origin;
+		ssao += max(dot(normal, u) + BIAS, EPSILON) / max(dot(u, u), EPSILON);
+	}
+
+	ssao *= (1.0 / float(SAMPLE_COUNT));
 	ssao = 1.0 - ssao * STRENGTH;
 	ssao = 1.0 - ssao * STRENGTH;
-
-	// Blend
-	out_color = mix(prevSsao, ssao, historyFeedback);
+	out_color = ssao;
 }
 }
 			]]></source>
 			]]></source>
 		</shader>
 		</shader>

+ 7 - 7
programs/VolumetricFog.ankiprog

@@ -73,17 +73,17 @@ vec3 computeLightColor(vec3 fragPos, uint plightCount, uint plightIdx, uint slig
 		float factor = computeAttenuationFactor(light.posRadius.w, frag2Light);
 		float factor = computeAttenuationFactor(light.posRadius.w, frag2Light);
 
 
 #if ENABLE_SHADOWS
 #if ENABLE_SHADOWS
-		if(light.diffuseColorShadowmapId.w >= 0.0)
+		if(light.diffuseColorTileSize.w >= 0.0)
 		{
 		{
 			factor *= computeShadowFactorOmni(frag2Light, 
 			factor *= computeShadowFactorOmni(frag2Light, 
-				-1.0 / light.posRadius.w, 
+				light.radiusPad3.x, 
 				light.atlasTilesPad2.xy,
 				light.atlasTilesPad2.xy,
-				light.diffuseColorShadowmapId.w,
+				light.diffuseColorTileSize.w,
 				u_shadowTex);
 				u_shadowTex);
 		}
 		}
 #endif
 #endif
 
 
-		outColor += light.diffuseColorShadowmapId.rgb * factor;
+		outColor += light.diffuseColorTileSize.rgb * factor;
 	}
 	}
 
 
 	// Spot lights
 	// Spot lights
@@ -95,14 +95,14 @@ vec3 computeLightColor(vec3 fragPos, uint plightCount, uint plightIdx, uint slig
 
 
 		vec3 l = normalize(frag2Light);
 		vec3 l = normalize(frag2Light);
 
 
-		factor *= computeSpotFactor(l, light.outerCosInnerCos.x, light.outerCosInnerCos.y, light.lightDir.xyz);
+		factor *= computeSpotFactor(l, light.outerCosInnerCos.x, light.outerCosInnerCos.y, light.lightDirRadius.xyz);
 
 
 #if ENABLE_SHADOWS
 #if ENABLE_SHADOWS
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(shadowmapLayerIdx >= 0.0)
 		if(shadowmapLayerIdx >= 0.0)
 		{
 		{
 			factor *= computeShadowFactorSpot(
 			factor *= computeShadowFactorSpot(
-				light.texProjectionMat, fragPos, light.specularColorRadius.w, u_shadowTex);
+				light.texProjectionMat, fragPos, light.lightDirRadius.w, u_shadowTex);
 		}
 		}
 #endif
 #endif
 
 
@@ -200,7 +200,7 @@ void main()
 		kNear = kFar;
 		kNear = kFar;
 	}
 	}
 
 
-	newCol *= u_fogParticleColor;
+	newCol *= diffuseLambert(u_fogParticleColor);
 
 
 	// Read history
 	// Read history
 	float historyFeedback;
 	float historyFeedback;

BIN
samples/simple_scene/assets/column.ankimesh


BIN
samples/simple_scene/assets/room.ankimesh


+ 1 - 2
samples/simple_scene/assets/scene.lua

@@ -61,8 +61,7 @@ node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 
 
 node = scene:newPointLightNode("Point")
 node = scene:newPointLightNode("Point")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp = node:getSceneNodeBase():getLightComponent()
-lcomp:setDiffuseColor(Vec4.new(2, 2, 2, 1))
-lcomp:setSpecularColor(Vec4.new(2, 2, 2, 1))
+lcomp:setDiffuseColor(Vec4.new(10, 10, 10, 1))
 lcomp:setRadius(12.77)
 lcomp:setRadius(12.77)
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(0.0680842, 9.57987, 0.0302386, 0))
 trf:setOrigin(Vec4.new(0.0680842, 9.57987, 0.0302386, 0))

BIN
samples/simple_scene/assets/sector.ankimesh


BIN
samples/simple_scene/assets/simple_scene.blend


+ 1 - 1
samples/sponza/assets/arch-material.ankimtl

@@ -20,7 +20,7 @@
 		<input shaderInput="diffTex" value="assets/Sponza_Arch_diffuse.ankitex"/>
 		<input shaderInput="diffTex" value="assets/Sponza_Arch_diffuse.ankitex"/>
 		<input shaderInput="specColor" value="0.040000 0.040000 0.040000"/>
 		<input shaderInput="specColor" value="0.040000 0.040000 0.040000"/>
 		<input shaderInput="roughnessTex" value="assets/Sponza_Arch_roughness.ankitex"/>
 		<input shaderInput="roughnessTex" value="assets/Sponza_Arch_roughness.ankitex"/>
-		<input shaderInput="metallic" value="0.000000"/>
+		<input shaderInput="metallic" value="0.500000"/>
 		<input shaderInput="normalTex" value="assets/Sponza_Arch_normal.ankitex"/>
 		<input shaderInput="normalTex" value="assets/Sponza_Arch_normal.ankitex"/>
 		<input shaderInput="emission" value="0.000000 0.000000 0.000000"/>
 		<input shaderInput="emission" value="0.000000 0.000000 0.000000"/>
 		<input shaderInput="subsurface" value="0.000000"/>
 		<input shaderInput="subsurface" value="0.000000"/>

+ 1 - 1
samples/sponza/assets/floor-material.ankimtl

@@ -20,7 +20,7 @@
 		<input shaderInput="diffTex" value="assets/Sponza_Floor_diffuse.ankitex"/>
 		<input shaderInput="diffTex" value="assets/Sponza_Floor_diffuse.ankitex"/>
 		<input shaderInput="specColor" value="0.040000 0.040000 0.040000"/>
 		<input shaderInput="specColor" value="0.040000 0.040000 0.040000"/>
 		<input shaderInput="roughnessTex" value="assets/Sponza_Column_b_roughness.ankitex"/>
 		<input shaderInput="roughnessTex" value="assets/Sponza_Column_b_roughness.ankitex"/>
-		<input shaderInput="metallic" value="0.000000"/>
+		<input shaderInput="metallic" value="0.500000"/>
 		<input shaderInput="normalTex" value="assets/Sponza_Floor_normal.ankitex"/>
 		<input shaderInput="normalTex" value="assets/Sponza_Floor_normal.ankitex"/>
 		<input shaderInput="emission" value="0.000000 0.000000 0.000000"/>
 		<input shaderInput="emission" value="0.000000 0.000000 0.000000"/>
 		<input shaderInput="subsurface" value="0.000000"/>
 		<input shaderInput="subsurface" value="0.000000"/>

+ 101 - 106
samples/sponza/assets/scene.lua

@@ -396,7 +396,7 @@ node = scene:newModelNode("vase_hangervase_hanging-materialnone6", "assets/vase_
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7985, 3.70822, -4.00556, 0))
 trf:setOrigin(Vec4.new(-10.7985, 3.70822, -4.00556, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -405,7 +405,7 @@ node = scene:newModelNode("lionlion-materialnone7", "assets/lionlion-material.an
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.2633, 3.0115, -0.615574, 0))
 trf:setOrigin(Vec4.new(-24.2633, 3.0115, -0.615574, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -441,7 +441,7 @@ node = scene:newModelNode("column_b_topcolumn_b-materialnone11", "assets/column_
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(11.8637, 11.8549, 3.63655, 0))
 trf:setOrigin(Vec4.new(11.8637, 11.8549, 3.63655, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -450,7 +450,7 @@ node = scene:newModelNode("column_bcolumn_b-materialnone12", "assets/column_bcol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(11.8665, 10.433, 3.63917, 0))
 trf:setOrigin(Vec4.new(11.8665, 10.433, 3.63917, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -459,7 +459,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone13", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.664, 11.8453, -4.64486, 0))
 trf:setOrigin(Vec4.new(22.664, 11.8453, -4.64486, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -468,7 +468,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone14", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.664, 11.8453, 3.43241, 0))
 trf:setOrigin(Vec4.new(22.664, 11.8453, 3.43241, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -486,7 +486,7 @@ node = scene:newModelNode("column_bcolumn_b-materialnone16", "assets/column_bcol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(5.37345, 10.433, 3.63917, 0))
 trf:setOrigin(Vec4.new(5.37345, 10.433, 3.63917, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -495,7 +495,7 @@ node = scene:newModelNode("arch_support_tinycolumn_c-materialnone17", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.6831, 11.8453, -11.1357, 0))
 trf:setOrigin(Vec4.new(22.6831, 11.8453, -11.1357, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-4.37114e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, -4.37114e-08, 0)
+rot:setAll(7.54979e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, 7.54979e-08, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -504,7 +504,7 @@ node = scene:newModelNode("arch_support_tinycolumn_c-materialnone18", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.6831, 11.8453, 9.92013, 0))
 trf:setOrigin(Vec4.new(22.6831, 11.8453, 9.92013, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -558,7 +558,7 @@ node = scene:newModelNode("door_bdetails-materialnone24", "assets/door_bdetails-
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-1.08744, 2.60525, -11.2204, 0))
 trf:setOrigin(Vec4.new(-1.08744, 2.60525, -11.2204, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -612,7 +612,7 @@ node = scene:newModelNode("column_b_topcolumn_b-materialnone30", "assets/column_
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(5.37061, 11.8549, 3.63655, 0))
 trf:setOrigin(Vec4.new(5.37061, 11.8549, 3.63655, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -621,7 +621,7 @@ node = scene:newModelNode("column_b_topcolumn_b-materialnone31", "assets/column_
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-1.10079, 11.8549, 3.63655, 0))
 trf:setOrigin(Vec4.new(-1.10079, 11.8549, 3.63655, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -630,7 +630,7 @@ node = scene:newModelNode("column_bcolumn_b-materialnone32", "assets/column_bcol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-1.09794, 10.433, 3.63917, 0))
 trf:setOrigin(Vec4.new(-1.09794, 10.433, 3.63917, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -639,7 +639,7 @@ node = scene:newModelNode("column_bcolumn_b-materialnone33", "assets/column_bcol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-7.55905, 10.433, 3.63917, 0))
 trf:setOrigin(Vec4.new(-7.55905, 10.433, 3.63917, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -648,7 +648,7 @@ node = scene:newModelNode("column_b_topcolumn_b-materialnone34", "assets/column_
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-7.56189, 11.8549, 3.63655, 0))
 trf:setOrigin(Vec4.new(-7.56189, 11.8549, 3.63655, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -657,7 +657,7 @@ node = scene:newModelNode("column_b_topcolumn_b-materialnone35", "assets/column_
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-14.0421, 11.8549, 3.63655, 0))
 trf:setOrigin(Vec4.new(-14.0421, 11.8549, 3.63655, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -666,7 +666,7 @@ node = scene:newModelNode("column_bcolumn_b-materialnone36", "assets/column_bcol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-14.0392, 10.433, 3.63917, 0))
 trf:setOrigin(Vec4.new(-14.0392, 10.433, 3.63917, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -711,7 +711,7 @@ node = scene:newModelNode("lion_framelion_stand-materialnone41", "assets/lion_fr
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.6691, 10.9358, -0.678738, 0))
 trf:setOrigin(Vec4.new(-24.6691, 10.9358, -0.678738, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -774,7 +774,7 @@ node = scene:newModelNode("vase_hangervase_hanging-materialnone48", "assets/vase
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.54339, 3.70822, -4.00556, 0))
 trf:setOrigin(Vec4.new(8.54339, 3.70822, -4.00556, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -783,7 +783,7 @@ node = scene:newModelNode("small_window_outterarch-materialnone49", "assets/smal
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.4903, 21.7776, -0.611125, 0))
 trf:setOrigin(Vec4.new(-17.4903, 21.7776, -0.611125, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -801,7 +801,7 @@ node = scene:newModelNode("small_window_outterarch-materialnone51", "assets/smal
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.88968, 21.7509, 3.13994, 0))
 trf:setOrigin(Vec4.new(8.88968, 21.7509, 3.13994, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -810,7 +810,7 @@ node = scene:newModelNode("small_window_innerceiling-materialnone52", "assets/sm
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.6709, 21.7775, -0.611127, 0))
 trf:setOrigin(Vec4.new(-17.6709, 21.7775, -0.611127, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -855,7 +855,7 @@ node = scene:newModelNode("small_window_outterarch-materialnone57", "assets/smal
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.42175, 21.7509, 3.13994, 0))
 trf:setOrigin(Vec4.new(2.42175, 21.7509, 3.13994, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -864,7 +864,7 @@ node = scene:newModelNode("small_window_innerceiling-materialnone58", "assets/sm
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.88967, 21.7509, 3.32057, 0))
 trf:setOrigin(Vec4.new(8.88967, 21.7509, 3.32057, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -873,7 +873,7 @@ node = scene:newModelNode("column_acolumn_a-materialnone59", "assets/column_acol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.4942, 1.90945, 3.35488, 0))
 trf:setOrigin(Vec4.new(-17.4942, 1.90945, 3.35488, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -882,7 +882,7 @@ node = scene:newModelNode("column_acolumn_a-materialnone60", "assets/column_acol
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.4942, 1.90945, -4.58257, 0))
 trf:setOrigin(Vec4.new(-17.4942, 1.90945, -4.58257, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0871556, 0, 0.996195, 0, 0, 1, 0, 0, -0.996195, 0, 0.0871556, 0)
+rot:setAll(0.0871557, 0, 0.996195, 0, 0, 1, 0, 0, -0.996195, 0, 0.0871557, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -900,7 +900,7 @@ node = scene:newModelNode("arch_support_tinycolumn_c-materialnone62", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.8514, 3.49729, 9.92013, 0))
 trf:setOrigin(Vec4.new(-24.8514, 3.49729, 9.92013, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-4.37114e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, -4.37114e-08, 0)
+rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -927,7 +927,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone65", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.64133, 3.49729, -11.1693, 0))
 trf:setOrigin(Vec4.new(8.64133, 3.49729, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -936,7 +936,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone66", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(15.3946, 3.49729, -11.1693, 0))
 trf:setOrigin(Vec4.new(15.3946, 3.49729, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -945,7 +945,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone67", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.8321, 3.49729, -4.64486, 0))
 trf:setOrigin(Vec4.new(-24.8321, 3.49729, -4.64486, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, -1, 0, 0, 1, 0, 0, 1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -954,7 +954,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone68", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.8321, 3.49729, 3.43241, 0))
 trf:setOrigin(Vec4.new(-24.8321, 3.49729, 3.43241, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, -1, 0, 0, 1, 0, 0, 1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -963,7 +963,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone69", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.16756, 3.49729, -11.1693, 0))
 trf:setOrigin(Vec4.new(2.16756, 3.49729, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -972,7 +972,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone70", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.31302, 3.49729, -11.1693, 0))
 trf:setOrigin(Vec4.new(-4.31302, 3.49729, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1017,7 +1017,7 @@ node = scene:newModelNode("lion_framelion_stand-materialnone75", "assets/lion_fr
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.7335, 3.03315, -0.627679, 0))
 trf:setOrigin(Vec4.new(-24.7335, 3.03315, -0.627679, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1089,7 +1089,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone83", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.5521, 11.8453, -11.1693, 0))
 trf:setOrigin(Vec4.new(-17.5521, 11.8453, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1098,7 +1098,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone84", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7975, 11.8453, -11.1693, 0))
 trf:setOrigin(Vec4.new(-10.7975, 11.8453, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1107,7 +1107,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone85", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.16756, 11.8453, -11.1693, 0))
 trf:setOrigin(Vec4.new(2.16756, 11.8453, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1116,7 +1116,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone86", "assets/arc
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.31302, 11.8453, -11.1693, 0))
 trf:setOrigin(Vec4.new(-4.31302, 11.8453, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1260,7 +1260,7 @@ node = scene:newModelNode("carpetfabric_a-materialnone102", "assets/carpetfabric
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.13556, 7.51453, 3.57755, 0))
 trf:setOrigin(Vec4.new(2.13556, 7.51453, 3.57755, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1269,7 +1269,7 @@ node = scene:newModelNode("carpetfabric_e-materialnone103", "assets/carpetfabric
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.6647, 7.51453, 3.57755, 0))
 trf:setOrigin(Vec4.new(8.6647, 7.51453, 3.57755, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1323,7 +1323,7 @@ node = scene:newModelNode("round_windowarch-materialnone109", "assets/round_wind
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-7.55586, 16.9667, 3.25126, 0))
 trf:setOrigin(Vec4.new(-7.55586, 16.9667, 3.25126, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1332,7 +1332,7 @@ node = scene:newModelNode("round_windowarch-materialnone110", "assets/round_wind
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-1.05196, 16.9667, 3.25126, 0))
 trf:setOrigin(Vec4.new(-1.05196, 16.9667, 3.25126, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1341,7 +1341,7 @@ node = scene:newModelNode("small_window_innerceiling-materialnone111", "assets/s
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-11.0676, 21.7509, 3.32057, 0))
 trf:setOrigin(Vec4.new(-11.0676, 21.7509, 3.32057, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1350,7 +1350,7 @@ node = scene:newModelNode("round_windowarch-materialnone112", "assets/round_wind
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-14.0395, 16.9667, 3.25127, 0))
 trf:setOrigin(Vec4.new(-14.0395, 16.9667, 3.25127, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1359,7 +1359,7 @@ node = scene:newModelNode("small_window_innerceiling-materialnone113", "assets/s
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.59793, 21.7509, 3.32057, 0))
 trf:setOrigin(Vec4.new(-4.59793, 21.7509, 3.32057, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1368,7 +1368,7 @@ node = scene:newModelNode("small_window_outterarch-materialnone114", "assets/sma
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-11.0676, 21.7509, 3.13994, 0))
 trf:setOrigin(Vec4.new(-11.0676, 21.7509, 3.13994, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1377,7 +1377,7 @@ node = scene:newModelNode("small_window_innerceiling-materialnone115", "assets/s
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.42175, 21.7509, 3.32057, 0))
 trf:setOrigin(Vec4.new(2.42175, 21.7509, 3.32057, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1386,7 +1386,7 @@ node = scene:newModelNode("small_window_outterarch-materialnone116", "assets/sma
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.59793, 21.7509, 3.13994, 0))
 trf:setOrigin(Vec4.new(-4.59793, 21.7509, 3.13994, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1395,7 +1395,7 @@ node = scene:newModelNode("round_windowarch-materialnone117", "assets/round_wind
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(5.36936, 16.9667, 3.25126, 0))
 trf:setOrigin(Vec4.new(5.36936, 16.9667, 3.25126, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1404,7 +1404,7 @@ node = scene:newModelNode("round_windowarch-materialnone118", "assets/round_wind
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(11.8504, 16.9667, 3.25126, 0))
 trf:setOrigin(Vec4.new(11.8504, 16.9667, 3.25126, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1458,7 +1458,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone124", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.5521, 3.49729, -11.1693, 0))
 trf:setOrigin(Vec4.new(-17.5521, 3.49729, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1467,7 +1467,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone125", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7975, 3.49729, -11.1693, 0))
 trf:setOrigin(Vec4.new(-10.7975, 3.49729, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1503,7 +1503,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone129", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.64045, 14.6639, -4.50225, 0))
 trf:setOrigin(Vec4.new(8.64045, 14.6639, -4.50225, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0064406, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398853, 0)
+rot:setAll(0.00644071, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398842, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1521,7 +1521,7 @@ node = scene:newModelNode("flag_poleflagpole-materialnone131", "assets/flag_pole
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.64262, 15.0091, 1.8103, 0))
 trf:setOrigin(Vec4.new(8.64262, 15.0091, 1.8103, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1566,7 +1566,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone136", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-3.53477, 4.97226, 3.47375, 0))
 trf:setOrigin(Vec4.new(-3.53477, 4.97226, 3.47375, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -3.89414e-07, 0, 0, 1, 0, 0, 3.89414e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1575,7 +1575,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone137", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-16.4889, 4.97226, 3.47375, 0))
 trf:setOrigin(Vec4.new(-16.4889, 4.97226, 3.47375, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1593,7 +1593,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone139", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.92955, 4.97226, 3.47375, 0))
 trf:setOrigin(Vec4.new(2.92955, 4.97226, 3.47375, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1638,7 +1638,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone144", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(9.35847, 4.97226, 3.47375, 0))
 trf:setOrigin(Vec4.new(9.35847, 4.97226, 3.47375, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1665,7 +1665,7 @@ node = scene:newModelNode("arch_support_medcolumn_c-materialnone147", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.64133, 11.8453, -11.1693, 0))
 trf:setOrigin(Vec4.new(8.64133, 11.8453, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1674,7 +1674,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone148", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(15.3946, 11.8453, -11.1693, 0))
 trf:setOrigin(Vec4.new(15.3946, 11.8453, -11.1693, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1683,7 +1683,7 @@ node = scene:newModelNode("arch_support_tinycolumn_c-materialnone149", "assets/a
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.6831, 3.49729, -11.1357, 0))
 trf:setOrigin(Vec4.new(22.6831, 3.49729, -11.1357, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-4.37114e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, -4.37114e-08, 0)
+rot:setAll(7.54979e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, 7.54979e-08, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1692,7 +1692,7 @@ node = scene:newModelNode("arch_support_tinycolumn_c-materialnone150", "assets/a
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.6831, 3.49729, 9.92013, 0))
 trf:setOrigin(Vec4.new(22.6831, 3.49729, 9.92013, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1710,7 +1710,7 @@ node = scene:newModelNode("arch_support_tinycolumn_c-materialnone152", "assets/a
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-24.8514, 11.8453, 9.92013, 0))
 trf:setOrigin(Vec4.new(-24.8514, 11.8453, 9.92013, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-4.37114e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, -4.37114e-08, 0)
+rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1719,7 +1719,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone153", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.664, 3.49729, -4.64486, 0))
 trf:setOrigin(Vec4.new(22.664, 3.49729, -4.64486, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1728,7 +1728,7 @@ node = scene:newModelNode("arch_support_bigcolumn_c-materialnone154", "assets/ar
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(22.664, 3.49729, 3.43241, 0))
 trf:setOrigin(Vec4.new(22.664, 3.49729, 3.43241, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1782,7 +1782,7 @@ node = scene:newModelNode("column_c_squarecolumn_c-materialnone160", "assets/col
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.4, 10.5065, -4.65448, 0))
 trf:setOrigin(Vec4.new(-17.4, 10.5065, -4.65448, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1791,7 +1791,7 @@ node = scene:newModelNode("column_c_squarecolumn_c-materialnone161", "assets/col
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(15.2013, 10.5065, 3.39458, 0))
 trf:setOrigin(Vec4.new(15.2013, 10.5065, 3.39458, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, -1, 0, 0, 1, 0, 0, 1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1836,7 +1836,7 @@ node = scene:newModelNode("column_c_squarecolumn_c-materialnone166", "assets/col
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.4, 10.5065, 3.39458, 0))
 trf:setOrigin(Vec4.new(-17.4, 10.5065, 3.39458, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1845,7 +1845,7 @@ node = scene:newModelNode("arc_2arch-materialnone167", "assets/arc_2arch-materia
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(15.3796, 13.2449, -0.608689, 0))
 trf:setOrigin(Vec4.new(15.3796, 13.2449, -0.608689, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 3.89414e-07, 0, 0, 1, 0, 0, -3.89414e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1899,7 +1899,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone173", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-3.53477, 4.97226, -4.88203, 0))
 trf:setOrigin(Vec4.new(-3.53477, 4.97226, -4.88203, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1926,7 +1926,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone176", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.0265, 4.97226, -4.88203, 0))
 trf:setOrigin(Vec4.new(-10.0265, 4.97226, -4.88203, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -1980,7 +1980,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone182", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.92955, 4.97226, -4.88203, 0))
 trf:setOrigin(Vec4.new(2.92955, 4.97226, -4.88203, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2034,7 +2034,7 @@ node = scene:newModelNode("round_windowarch-materialnone188", "assets/round_wind
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-17.6818, 16.8682, -0.597432, 0))
 trf:setOrigin(Vec4.new(-17.6818, 16.8682, -0.597432, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, 1, 0, 0, 1, 0, 0, -1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2079,7 +2079,7 @@ node = scene:newModelNode("carpetfabric_e-materialnone193", "assets/carpetfabric
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7337, 7.51453, 3.57755, 0))
 trf:setOrigin(Vec4.new(-10.7337, 7.51453, 3.57755, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2088,7 +2088,7 @@ node = scene:newModelNode("carpetfabric_d-materialnone194", "assets/carpetfabric
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.23854, 7.51453, 3.57755, 0))
 trf:setOrigin(Vec4.new(-4.23854, 7.51453, 3.57755, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2097,7 +2097,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone195", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.30311, 14.6698, 3.2215, 0))
 trf:setOrigin(Vec4.new(-4.30311, 14.6698, 3.2215, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0121797, -0.0154098, -0.999807, 0, -0.414472, 0.909862, -0.0190726, 0, 0.909981, 0.414624, 0.00469499, 0)
+rot:setAll(0.0121798, -0.0154097, -0.999807, 0, -0.414472, 0.909862, -0.0190726, 0, 0.909981, 0.414624, 0.00469499, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2106,7 +2106,7 @@ node = scene:newModelNode("flag_poleflagpole-materialnone196", "assets/flag_pole
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.15796, 15.0091, 1.8103, 0))
 trf:setOrigin(Vec4.new(2.15796, 15.0091, 1.8103, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2115,7 +2115,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone197", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7721, 14.6639, 3.21873, 0))
 trf:setOrigin(Vec4.new(-10.7721, 14.6639, 3.21873, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-0.180823, 0.386751, -0.904283, 0, -0.379577, 0.820762, 0.426932, 0, 0.907317, 0.420443, -0.00161065, 0)
+rot:setAll(-0.180823, 0.386751, -0.904283, 0, -0.379577, 0.820762, 0.426932, 0, 0.907317, 0.420443, -0.00161085, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2124,7 +2124,7 @@ node = scene:newModelNode("flag_poleflagpole-materialnone198", "assets/flag_pole
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.30374, 15.0091, 1.8103, 0))
 trf:setOrigin(Vec4.new(-4.30374, 15.0091, 1.8103, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2142,7 +2142,7 @@ node = scene:newModelNode("flag_poleflagpole-materialnone200", "assets/flag_pole
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7754, 15.0091, 1.8103, 0))
 trf:setOrigin(Vec4.new(-10.7754, 15.0091, 1.8103, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2169,7 +2169,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone203", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(9.35847, 4.97226, -4.88203, 0))
 trf:setOrigin(Vec4.new(9.35847, 4.97226, -4.88203, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2214,7 +2214,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone208", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-16.4889, 4.97226, -4.88203, 0))
 trf:setOrigin(Vec4.new(-16.4889, 4.97226, -4.88203, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2223,7 +2223,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone209", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.0265, 4.97226, 3.47375, 0))
 trf:setOrigin(Vec4.new(-10.0265, 4.97226, 3.47375, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, 8.74228e-08, 0, 0, 1, 0, 0, -8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, -1.50996e-07, 0, 0, 1, 0, 0, 1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2367,7 +2367,7 @@ node = scene:newModelNode("column_acolumn_a-materialnone225", "assets/column_aco
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(15.2461, 1.90945, 3.35488, 0))
 trf:setOrigin(Vec4.new(15.2461, 1.90945, 3.35488, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(7.54979e-08, 0, -1, 0, 0, 1, 0, 0, 1, 0, 7.54979e-08, 0)
+rot:setAll(1.94707e-07, 0, -1, 0, 0, 1, 0, 0, 1, 0, 1.94707e-07, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2385,7 +2385,7 @@ node = scene:newModelNode("arch_aarch-materialnone227", "assets/arch_aarch-mater
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-1.09247, 13.2308, -4.78049, 0))
 trf:setOrigin(Vec4.new(-1.09247, 13.2308, -4.78049, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-1, 0, -8.74228e-08, 0, 0, 1, 0, 0, 8.74228e-08, 0, -1, 0)
+rot:setAll(-1, 0, 1.50996e-07, 0, 0, 1, 0, 0, -1.50996e-07, 0, -1, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2502,7 +2502,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone240", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.15731, 14.6698, 3.2215, 0))
 trf:setOrigin(Vec4.new(2.15731, 14.6698, 3.2215, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0121797, -0.0154098, -0.999807, 0, -0.414472, 0.909862, -0.0190726, 0, 0.909981, 0.414624, 0.00469499, 0)
+rot:setAll(0.0121798, -0.0154097, -0.999807, 0, -0.414472, 0.909862, -0.0190726, 0, 0.909981, 0.414624, 0.00469499, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2511,7 +2511,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone241", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.64287, 14.6698, 3.2215, 0))
 trf:setOrigin(Vec4.new(8.64287, 14.6698, 3.2215, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0121797, -0.0154098, -0.999807, 0, -0.414472, 0.909862, -0.0190726, 0, 0.909981, 0.414624, 0.00469499, 0)
+rot:setAll(0.0121798, -0.0154097, -0.999807, 0, -0.414472, 0.909862, -0.0190726, 0, 0.909981, 0.414624, 0.00469499, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2520,7 +2520,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone242", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(2.15573, 14.6639, -4.50225, 0))
 trf:setOrigin(Vec4.new(2.15573, 14.6639, -4.50225, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0064406, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398853, 0)
+rot:setAll(0.00644071, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398842, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2529,7 +2529,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone243", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-4.30505, 14.6639, -4.50225, 0))
 trf:setOrigin(Vec4.new(-4.30505, 14.6639, -4.50225, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0064406, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398853, 0)
+rot:setAll(0.00644071, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398842, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2538,7 +2538,7 @@ node = scene:newModelNode("rod_endflagpole-materialnone244", "assets/rod_endflag
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7768, 14.6639, -4.50225, 0))
 trf:setOrigin(Vec4.new(-10.7768, 14.6639, -4.50225, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(0.0064406, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398853, 0)
+rot:setAll(0.00644071, -0.0232627, 0.999709, 0, -0.422331, 0.906129, 0.023806, 0, -0.906419, -0.422361, -0.00398842, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2689,15 +2689,14 @@ node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 
 
 node = scene:newSpotLightNode("Lamp")
 node = scene:newSpotLightNode("Lamp")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp = node:getSceneNodeBase():getLightComponent()
-lcomp:setDiffuseColor(Vec4.new(0.951211, 1.37843, 2.00171, 1))
-lcomp:setSpecularColor(Vec4.new(0.951211, 1.37843, 2.00171, 1))
+lcomp:setDiffuseColor(Vec4.new(15, 15, 15, 1))
 lcomp:setInnerAngle(0.737402)
 lcomp:setInnerAngle(0.737402)
 lcomp:setOuterAngle(1.4748)
 lcomp:setOuterAngle(1.4748)
-lcomp:setDistance(79.5799)
+lcomp:setDistance(89.9999)
 trf = Transform.new()
 trf = Transform.new()
-trf:setOrigin(Vec4.new(9.66932, 40.2052, -0.372856, 0))
+trf:setOrigin(Vec4.new(9.66932, 40.2052, -9.96416, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-0.175433, -0.931124, 0.319735, 0, 0.0818194, 0.309859, 0.947256, 0, -0.981086, 0.19234, 0.0218246, 0)
+rot:setAll(-0.175432, -0.931125, 0.319735, 0, -0.392148, 0.363986, 0.844828, 0, -0.903019, 0.0228264, -0.428994, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
@@ -2705,8 +2704,7 @@ lcomp:setShadowEnabled(1)
 
 
 node = scene:newPointLightNode("Point")
 node = scene:newPointLightNode("Point")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp = node:getSceneNodeBase():getLightComponent()
-lcomp:setDiffuseColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
-lcomp:setSpecularColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
+lcomp:setDiffuseColor(Vec4.new(10.0038, 4.10403, 2.70507, 1))
 lcomp:setRadius(4)
 lcomp:setRadius(4)
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.54617, 2.49423, -3.8305, 0))
 trf:setOrigin(Vec4.new(8.54617, 2.49423, -3.8305, 0))
@@ -2722,8 +2720,7 @@ event:setFrequency(2, 0.02)
 
 
 node = scene:newPointLightNode("Point_001")
 node = scene:newPointLightNode("Point_001")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp = node:getSceneNodeBase():getLightComponent()
-lcomp:setDiffuseColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
-lcomp:setSpecularColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
+lcomp:setDiffuseColor(Vec4.new(10.0038, 4.10403, 2.70507, 1))
 lcomp:setRadius(4)
 lcomp:setRadius(4)
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(8.54617, 2.49423, 2.5181, 0))
 trf:setOrigin(Vec4.new(8.54617, 2.49423, 2.5181, 0))
@@ -2739,8 +2736,7 @@ event:setFrequency(2, 0.02)
 
 
 node = scene:newPointLightNode("Point_002")
 node = scene:newPointLightNode("Point_002")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp = node:getSceneNodeBase():getLightComponent()
-lcomp:setDiffuseColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
-lcomp:setSpecularColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
+lcomp:setDiffuseColor(Vec4.new(10.0038, 4.10403, 2.70507, 1))
 lcomp:setRadius(4)
 lcomp:setRadius(4)
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7834, 2.49423, 2.5181, 0))
 trf:setOrigin(Vec4.new(-10.7834, 2.49423, 2.5181, 0))
@@ -2756,8 +2752,7 @@ event:setFrequency(2, 0.02)
 
 
 node = scene:newPointLightNode("Point_003")
 node = scene:newPointLightNode("Point_003")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp = node:getSceneNodeBase():getLightComponent()
-lcomp:setDiffuseColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
-lcomp:setSpecularColor(Vec4.new(5.00188, 2.05202, 1.35254, 1))
+lcomp:setDiffuseColor(Vec4.new(10.0038, 4.10403, 2.70507, 1))
 lcomp:setRadius(4)
 lcomp:setRadius(4)
 trf = Transform.new()
 trf = Transform.new()
 trf:setOrigin(Vec4.new(-10.7834, 2.49423, -3.84153, 0))
 trf:setOrigin(Vec4.new(-10.7834, 2.49423, -3.84153, 0))
@@ -2771,13 +2766,13 @@ event = events:newLightEvent(0.0, -1.0, node:getSceneNodeBase())
 event:setIntensityMultiplier(Vec4.new(1.2, 1.3, 1.3, 0))
 event:setIntensityMultiplier(Vec4.new(1.2, 1.3, 1.3, 0))
 event:setFrequency(2, 0.02)
 event:setFrequency(2, 0.02)
 
 
-node = scene:newPerspectiveCameraNode("Camera")
+node = scene:newPerspectiveCameraNode("Camera_001")
 scene:setActiveCameraNode(node:getSceneNodeBase())
 scene:setActiveCameraNode(node:getSceneNodeBase())
 node:setAll(1.5708, 1.0 / getMainRenderer():getAspectRatio() * 1.5708, 0.1, 100)
 node:setAll(1.5708, 1.0 / getMainRenderer():getAspectRatio() * 1.5708, 0.1, 100)
 trf = Transform.new()
 trf = Transform.new()
-trf:setOrigin(Vec4.new(-19.4002, 11.2388, -4.00858, 0))
+trf:setOrigin(Vec4.new(20.556, 11.265, 2.45598, 0))
 rot = Mat3x4.new()
 rot = Mat3x4.new()
-rot:setAll(-0.198709, 0.33985, -0.919248, 0, 0.00976452, 0.938592, 0.344891, 0, 0.98001, 0.0595568, -0.189825, 0)
+rot:setAll(0.213344, -0.118711, 0.969738, 0, 0.0213826, 0.99292, 0.116845, 0, -0.976743, -0.00419256, 0.214372, 0)
 trf:setRotation(rot)
 trf:setRotation(rot)
 trf:setScale(1)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)

BIN
samples/sponza/assets/sponza_381.ankimesh


BIN
samples/sponza/assets/sponza_69.ankimesh


+ 34 - 34
samples/sponza/assets/unnamed_0.ankianim

@@ -14,24 +14,24 @@
 				<key><time>14.9583</time><value>12.6504 3.39613 1.59767</value></key>
 				<key><time>14.9583</time><value>12.6504 3.39613 1.59767</value></key>
 				<key><time>15.4167</time><value>13.5823 3.28238 1.48543</value></key>
 				<key><time>15.4167</time><value>13.5823 3.28238 1.48543</value></key>
 				<key><time>18.125</time><value>19.0891 2.61022 0.822178</value></key>
 				<key><time>18.125</time><value>19.0891 2.61022 0.822178</value></key>
-				<key><time>18.5833</time><value>19.2686 2.71714 -0.392216</value></key>
+				<key><time>18.5833</time><value>19.2686 2.71714 -0.392224</value></key>
 				<key><time>22.125</time><value>20.6558 3.54337 -9.77624</value></key>
 				<key><time>22.125</time><value>20.6558 3.54337 -9.77624</value></key>
 				<key><time>22.5833</time><value>19.0757 3.47306 -9.80221</value></key>
 				<key><time>22.5833</time><value>19.0757 3.47306 -9.80221</value></key>
 				<key><time>28.2083</time><value>-0.317 2.61022 -10.1209</value></key>
 				<key><time>28.2083</time><value>-0.317 2.61022 -10.1209</value></key>
-				<key><time>28.6667</time><value>-2.1778 2.61022 -10.1456</value></key>
+				<key><time>28.6667</time><value>-2.17778 2.61022 -10.1456</value></key>
 				<key><time>33.75</time><value>-22.8155 2.61022 -10.4201</value></key>
 				<key><time>33.75</time><value>-22.8155 2.61022 -10.4201</value></key>
 				<key><time>34.2083</time><value>-22.8155 2.61022 -9.43611</value></key>
 				<key><time>34.2083</time><value>-22.8155 2.61022 -9.43611</value></key>
 				<key><time>37.875</time><value>-22.8155 2.61022 -1.56428</value></key>
 				<key><time>37.875</time><value>-22.8155 2.61022 -1.56428</value></key>
 				<key><time>38.3333</time><value>-21.2008 2.61022 -1.48552</value></key>
 				<key><time>38.3333</time><value>-21.2008 2.61022 -1.48552</value></key>
-				<key><time>41.8333</time><value>-8.86985 2.61022 -0.884087</value></key>
+				<key><time>41.8333</time><value>-8.86983 2.61022 -0.884086</value></key>
 				<key><time>42.75</time><value>-5.6403 2.61022 -0.726567</value></key>
 				<key><time>42.75</time><value>-5.6403 2.61022 -0.726567</value></key>
 				<key><time>45.5833</time><value>-2.41902 2.61022 -3.09393</value></key>
 				<key><time>45.5833</time><value>-2.41902 2.61022 -3.09393</value></key>
 				<key><time>46.0833</time><value>-1.85056 2.61022 -3.5117</value></key>
 				<key><time>46.0833</time><value>-1.85056 2.61022 -3.5117</value></key>
-				<key><time>48.6667</time><value>0.513312 3.07061 -0.178203</value></key>
+				<key><time>48.6667</time><value>0.513307 3.07061 -0.178211</value></key>
 				<key><time>49.25</time><value>1.04708 3.17457 0.574512</value></key>
 				<key><time>49.25</time><value>1.04708 3.17457 0.574512</value></key>
 				<key><time>51.5833</time><value>-1.64297 3.63755 3.66435</value></key>
 				<key><time>51.5833</time><value>-1.64297 3.63755 3.66435</value></key>
-				<key><time>52.25</time><value>-2.52192 4.12086 3.00342</value></key>
-				<key><time>55.2083</time><value>-6.42225 6.26554 0.0705996</value></key>
+				<key><time>52.25</time><value>-2.52192 4.12086 3.00343</value></key>
+				<key><time>55.2083</time><value>-6.42225 6.26554 0.0705997</value></key>
 				<key><time>57.9583</time><value>-11.7427 8.8453 -1.1153</value></key>
 				<key><time>57.9583</time><value>-11.7427 8.8453 -1.1153</value></key>
 				<key><time>61.3333</time><value>-18.9233 11.2388 -2.79078</value></key>
 				<key><time>61.3333</time><value>-18.9233 11.2388 -2.79078</value></key>
 				<key><time>63.625</time><value>-20.4662 11.2388 -6.73073</value></key>
 				<key><time>63.625</time><value>-20.4662 11.2388 -6.73073</value></key>
@@ -39,39 +39,39 @@
 				<key><time>76</time><value>2.21567 8.81405 -8.82866</value></key>
 				<key><time>76</time><value>2.21567 8.81405 -8.82866</value></key>
 			</positionKeys>
 			</positionKeys>
 			<rotationKeys>
 			<rotationKeys>
-				<key><time>0.0416666</time><value>0.00658256 0.990661 0.131021 0.0371709</value></key>
+				<key><time>0.0416666</time><value>0.00658252 0.990661 0.131021 0.0371713</value></key>
 				<key><time>6.79167</time><value>-0.0629116 0.92831 0.111865 0.348955</value></key>
 				<key><time>6.79167</time><value>-0.0629116 0.92831 0.111865 0.348955</value></key>
-				<key><time>7.83333</time><value>-0.0725333 0.909795 0.106124 0.394651</value></key>
-				<key><time>9.79167</time><value>-0.0738086 0.778106 0.0773262 0.61897</value></key>
-				<key><time>10.875</time><value>-0.0706586 0.681249 0.0642267 0.725798</value></key>
-				<key><time>11.5833</time><value>-0.0588006 0.692572 0.0587403 0.716544</value></key>
-				<key><time>13.25</time><value>-0.0315795 0.718456 0.0444854 0.69343</value></key>
-				<key><time>14.9583</time><value>-0.0314005 0.773922 0.0563244 0.629989</value></key>
-				<key><time>15.4167</time><value>-0.0310474 0.78785 0.0595463 0.612195</value></key>
-				<key><time>18.125</time><value>0.00826454 0.757009 0.0205183 0.65303</value></key>
+				<key><time>7.83333</time><value>-0.0725334 0.909795 0.106124 0.394651</value></key>
+				<key><time>9.79167</time><value>-0.0738087 0.778106 0.0773262 0.61897</value></key>
+				<key><time>10.875</time><value>-0.0706587 0.681249 0.0642268 0.725798</value></key>
+				<key><time>11.5833</time><value>-0.0588005 0.692572 0.0587403 0.716544</value></key>
+				<key><time>13.25</time><value>-0.0315796 0.718456 0.0444854 0.69343</value></key>
+				<key><time>14.9583</time><value>-0.0314006 0.773922 0.0563245 0.629989</value></key>
+				<key><time>15.4167</time><value>-0.0310475 0.78785 0.0595464 0.612195</value></key>
+				<key><time>18.125</time><value>0.00826449 0.757009 0.0205184 0.65303</value></key>
 				<key><time>18.5833</time><value>0.0153087 0.751397 0.0143268 0.659518</value></key>
 				<key><time>18.5833</time><value>0.0153087 0.751397 0.0143268 0.659518</value></key>
-				<key><time>22.125</time><value>0.0011288 0.858185 0.0108005 0.513226</value></key>
-				<key><time>22.5833</time><value>-0.000756213 0.870004 0.0107529 0.492926</value></key>
-				<key><time>28.2083</time><value>0.00369008 0.998339 0.0174987 0.0547757</value></key>
-				<key><time>28.6667</time><value>0.00433361 0.99968 0.0179625 0.0172714</value></key>
-				<key><time>33.75</time><value>0.00938432 0.96125 0.0159174 -0.275059</value></key>
-				<key><time>34.2083</time><value>0.00980572 0.953568 0.0156614 -0.30061</value></key>
-				<key><time>37.875</time><value>-0.0148589 -0.777295 -0.0109838 0.628865</value></key>
-				<key><time>38.3333</time><value>-0.0153571 -0.746987 -0.0102757 0.664582</value></key>
-				<key><time>41.8333</time><value>-0.0158938 -0.709685 -0.00942415 0.704277</value></key>
-				<key><time>42.75</time><value>-0.0137285 -0.834403 -0.0123676 0.550845</value></key>
-				<key><time>45.5833</time><value>0.00412683 0.999416 0.0180111 0.0287622</value></key>
-				<key><time>46.0833</time><value>0.00160613 0.988104 0.0200395 0.15247</value></key>
-				<key><time>48.6667</time><value>-0.0169 0.69967 0.0230664 0.713893</value></key>
-				<key><time>49.25</time><value>-0.0271612 0.603149 0.0263888 0.796729</value></key>
-				<key><time>51.5833</time><value>-0.0736537 0.137743 0.0149732 0.987612</value></key>
-				<key><time>52.25</time><value>-0.0857242 -0.00694491 0.0040622 0.996286</value></key>
-				<key><time>55.2083</time><value>-0.227278 -0.731621 -0.275592 0.580624</value></key>
+				<key><time>22.125</time><value>0.00112877 0.858185 0.0108006 0.513226</value></key>
+				<key><time>22.5833</time><value>-0.000756239 0.870004 0.0107529 0.492926</value></key>
+				<key><time>28.2083</time><value>0.00369008 0.998339 0.0174989 0.0547752</value></key>
+				<key><time>28.6667</time><value>0.00433361 0.99968 0.0179626 0.0172713</value></key>
+				<key><time>33.75</time><value>0.00938436 0.96125 0.0159175 -0.275059</value></key>
+				<key><time>34.2083</time><value>0.00980576 0.953568 0.0156615 -0.30061</value></key>
+				<key><time>37.875</time><value>-0.0148589 -0.777295 -0.0109839 0.628865</value></key>
+				<key><time>38.3333</time><value>-0.0153571 -0.746987 -0.0102758 0.664582</value></key>
+				<key><time>41.8333</time><value>-0.0158939 -0.709685 -0.00942424 0.704277</value></key>
+				<key><time>42.75</time><value>-0.0137286 -0.834403 -0.0123677 0.550845</value></key>
+				<key><time>45.5833</time><value>0.00412683 0.999416 0.0180111 0.028762</value></key>
+				<key><time>46.0833</time><value>0.00160611 0.988104 0.0200396 0.152471</value></key>
+				<key><time>48.6667</time><value>-0.0169002 0.69967 0.0230664 0.713893</value></key>
+				<key><time>49.25</time><value>-0.0271614 0.603148 0.0263889 0.79673</value></key>
+				<key><time>51.5833</time><value>-0.0736538 0.137741 0.0149731 0.987612</value></key>
+				<key><time>52.25</time><value>-0.0857243 -0.00694491 0.0040622 0.996286</value></key>
+				<key><time>55.2083</time><value>-0.227278 -0.731622 -0.275592 0.580624</value></key>
 				<key><time>57.9583</time><value>-0.216984 -0.749851 -0.255673 0.570327</value></key>
 				<key><time>57.9583</time><value>-0.216984 -0.749851 -0.255673 0.570327</value></key>
 				<key><time>61.3333</time><value>-0.122639 -0.722497 -0.125187 0.668794</value></key>
 				<key><time>61.3333</time><value>-0.122639 -0.722497 -0.125187 0.668794</value></key>
 				<key><time>63.625</time><value>-0.0950878 -0.841784 -0.147208 0.510576</value></key>
 				<key><time>63.625</time><value>-0.0950878 -0.841784 -0.147208 0.510576</value></key>
-				<key><time>65.0417</time><value>0.0684444 0.91685 0.16133 -0.358712</value></key>
-				<key><time>76</time><value>0.00658256 0.990661 0.131021 0.0371709</value></key>
+				<key><time>65.0417</time><value>0.0684445 0.91685 0.16133 -0.358712</value></key>
+				<key><time>76</time><value>0.00658252 0.990661 0.131021 0.0371713</value></key>
 			</rotationKeys>
 			</rotationKeys>
 			<scalingKeys>
 			<scalingKeys>
 				<key><time>0.0416666</time><value>1</value></key>
 				<key><time>0.0416666</time><value>1</value></key>

+ 6 - 7
shaders/ClusterLightCommon.glsl

@@ -30,9 +30,9 @@ struct LightingUniforms
 // Point light
 // Point light
 struct PointLight
 struct PointLight
 {
 {
-	vec4 posRadius; // xyz: Light pos in view space. w: The -1/(radius^2)
-	vec4 diffuseColorShadowmapId; // xyz: diff color, w: tile size in the shadow atlas
-	vec4 specularColorRadius; // xyz: spec color, w: radius
+	vec4 posRadius; // xyz: Light pos in world space. w: The 1/(radius^2)
+	vec4 diffuseColorTileSize; // xyz: diff color, w: tile size in the shadow atlas
+	vec4 radiusPad3; // x: radius
 	uvec4 atlasTilesPad2; // x: encodes 6 uints with atlas tile indices in the x dir. y: same for y dir.
 	uvec4 atlasTilesPad2; // x: encodes 6 uints with atlas tile indices in the x dir. y: same for y dir.
 };
 };
 const uint POINT_LIGHT_SIZEOF = (4 * 4) * 4;
 const uint POINT_LIGHT_SIZEOF = (4 * 4) * 4;
@@ -40,14 +40,13 @@ const uint POINT_LIGHT_SIZEOF = (4 * 4) * 4;
 // Spot light
 // Spot light
 struct SpotLight
 struct SpotLight
 {
 {
-	vec4 posRadius; // xyz: Light pos in view space. w: The -1/(radius^2)
+	vec4 posRadius; // xyz: Light pos in world space. w: The 1/(radius^2)
 	vec4 diffuseColorShadowmapId; // xyz: diff color, w: shadowmap tex ID
 	vec4 diffuseColorShadowmapId; // xyz: diff color, w: shadowmap tex ID
-	vec4 specularColorRadius; // xyz: spec color, w: radius
-	vec4 lightDir;
+	vec4 lightDirRadius; // xyz: light direction, w: radius
 	vec4 outerCosInnerCos;
 	vec4 outerCosInnerCos;
 	mat4 texProjectionMat;
 	mat4 texProjectionMat;
 };
 };
-const uint SPOT_LIGHT_SIZEOF = (5 * 4 + 16) * 4;
+const uint SPOT_LIGHT_SIZEOF = (4 * 4 + 16) * 4;
 
 
 // Representation of a reflection probe
 // Representation of a reflection probe
 struct ReflectionProbe
 struct ReflectionProbe

+ 7 - 11
shaders/ForwardShadingCommonFrag.glsl

@@ -58,7 +58,7 @@ vec3 computeLightColor(vec3 diffCol, vec3 worldPos)
 	{
 	{
 		PointLight light = u_pointLights[u_lightIndices[idxOffset++]];
 		PointLight light = u_pointLights[u_lightIndices[idxOffset++]];
 
 
-		vec3 diffC = computeDiffuseColor(diffCol, light.diffuseColorShadowmapId.rgb);
+		vec3 diffC = diffuseLambert(diffCol) * light.diffuseColorTileSize.rgb;
 
 
 		vec3 frag2Light = light.posRadius.xyz - worldPos;
 		vec3 frag2Light = light.posRadius.xyz - worldPos;
 		float att = computeAttenuationFactor(light.posRadius.w, frag2Light);
 		float att = computeAttenuationFactor(light.posRadius.w, frag2Light);
@@ -67,13 +67,10 @@ vec3 computeLightColor(vec3 diffCol, vec3 worldPos)
 		const float shadow = 1.0;
 		const float shadow = 1.0;
 #else
 #else
 		float shadow = 1.0;
 		float shadow = 1.0;
-		if(light.diffuseColorShadowmapId.w >= 0.0)
+		if(light.diffuseColorTileSize.w >= 0.0)
 		{
 		{
-			shadow = computeShadowFactorOmni(frag2Light,
-				light.specularColorRadius.w,
-				light.atlasTilesPad2.xy,
-				light.diffuseColorShadowmapId.w,
-				u_shadowTex);
+			shadow = computeShadowFactorOmni(
+				frag2Light, light.radiusPad3.x, light.atlasTilesPad2.xy, light.diffuseColorTileSize.w, u_shadowTex);
 		}
 		}
 #endif
 #endif
 
 
@@ -86,14 +83,14 @@ vec3 computeLightColor(vec3 diffCol, vec3 worldPos)
 	{
 	{
 		SpotLight light = u_spotLights[u_lightIndices[idxOffset++]];
 		SpotLight light = u_spotLights[u_lightIndices[idxOffset++]];
 
 
-		vec3 diffC = computeDiffuseColor(diffCol, light.diffuseColorShadowmapId.rgb);
+		vec3 diffC = diffuseLambert(diffCol) * light.diffuseColorShadowmapId.rgb;
 
 
 		vec3 frag2Light = light.posRadius.xyz - worldPos;
 		vec3 frag2Light = light.posRadius.xyz - worldPos;
 		float att = computeAttenuationFactor(light.posRadius.w, frag2Light);
 		float att = computeAttenuationFactor(light.posRadius.w, frag2Light);
 
 
 		vec3 l = normalize(frag2Light);
 		vec3 l = normalize(frag2Light);
 
 
-		float spot = computeSpotFactor(l, light.outerCosInnerCos.x, light.outerCosInnerCos.y, light.lightDir.xyz);
+		float spot = computeSpotFactor(l, light.outerCosInnerCos.x, light.outerCosInnerCos.y, light.lightDirRadius.xyz);
 
 
 #if LOD > 1
 #if LOD > 1
 		const float shadow = 1.0;
 		const float shadow = 1.0;
@@ -102,8 +99,7 @@ vec3 computeLightColor(vec3 diffCol, vec3 worldPos)
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(shadowmapLayerIdx >= 0.0)
 		if(shadowmapLayerIdx >= 0.0)
 		{
 		{
-			shadow =
-				computeShadowFactorSpot(light.texProjectionMat, worldPos, light.specularColorRadius.w, u_shadowTex);
+			shadow = computeShadowFactorSpot(light.texProjectionMat, worldPos, light.lightDirRadius.w, u_shadowTex);
 		}
 		}
 #endif
 #endif
 
 

+ 54 - 52
shaders/LightFunctions.glsl

@@ -9,66 +9,65 @@
 #define ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
 #define ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
 
 
 #include "shaders/Functions.glsl"
 #include "shaders/Functions.glsl"
+#include "shaders/Pack.glsl"
 
 
 const float LIGHT_FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
 const float LIGHT_FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
 const uint SHADOW_SAMPLE_COUNT = 16;
 const uint SHADOW_SAMPLE_COUNT = 16;
 const float ESM_CONSTANT = 40.0;
 const float ESM_CONSTANT = 40.0;
 
 
-float computeAttenuationFactor(float lightRadius, vec3 frag2Light)
+// Fresnel term unreal
+vec3 F_Unreal(vec3 specular, float VoH)
 {
 {
-	float fragLightDist = dot(frag2Light, frag2Light);
-	float att = 1.0 - fragLightDist * lightRadius;
-	att = max(0.0, att);
-	return att * att;
+	return specular + (1.0 - specular) * pow(2.0, (-5.55473 * VoH - 6.98316) * VoH);
 }
 }
 
 
-// Performs BRDF specular lighting
-vec3 computeSpecularColorBrdf(vec3 v, // view dir
-	vec3 l, // light dir
-	vec3 n, // normal
-	vec3 specCol,
-	vec3 lightSpecCol,
-	float a2, // rougness^2
-	float nol) // N dot L
+// D(n,h) aka NDF: GGX Trowbridge-Reitz
+float D_GGX(float roughness, float NoH)
 {
 {
-	vec3 h = normalize(l + v);
-
-	// Fresnel
-	float voh = dot(v, h);
-#if 0
-	// Schlick
-	vec3 F = specCol + (1.0 - specCol) * pow((1.0 + EPSILON - loh), 5.0);
-#else
-	// Unreal
-	vec3 F = specCol + (1.0 - specCol) * pow(2.0, (-5.55473 * voh - 6.98316) * voh);
-#endif
+	float a = roughness * roughness;
+	float a2 = a * a;
 
 
-	// D(n,h) aka NDF: GGX Trowbridge-Reitz
-	float noh = dot(n, h);
-	float D = noh * noh * (a2 - 1.0) + 1.0;
-	D = a2 / (PI * D * D);
-
-// G(l,v,h)/(4*dot(n,h)*dot(n,v)) aka Visibility term: Geometric shadowing divided by BRDF denominator
-#if 0
-	float nov = max(EPSILON, dot(n, v));
-	float V_v = nov + sqrt((nov - nov * a2) * nov + a2);
-	float V_l = nol + sqrt((nol - nol * a2) * nol + a2);
-	float V = 1.0 / (V_l * V_v);
-#else
-	float k = (a2 + 1.0);
-	k = k * k / 8.0;
-	float nov = max(EPSILON, dot(n, v));
-	float V_v = nov * (1.0 - k) + k;
-	float V_l = nol * (1.0 - k) + k;
-	float V = 1.0 / (4.0 * V_l * V_v);
-#endif
+	float D = (NoH * a2 - NoH) * NoH + 1.0;
+	return a2 / (PI * D * D);
+}
+
+// Visibility term: Geometric shadowing divided by BRDF denominator
+float V_Schlick(float roughness, float NoV, float NoL)
+{
+	float k = (roughness * roughness) * 0.5;
+	float Vis_SchlickV = NoV * (1.0 - k) + k;
+	float Vis_SchlickL = NoL * (1.0 - k) + k;
+	return 0.25 / (Vis_SchlickV * Vis_SchlickL);
+}
+
+vec3 envBRDF(vec3 specular, float roughness, sampler2D integrationLut, float NoV)
+{
+	float a = roughness * roughness;
+	float a2 = a * a;
+	vec2 envBRDF = textureLod(integrationLut, vec2(a2, NoV), 0.0).xy;
+	return specular * envBRDF.x + min(1.0, 50.0 * specular.g) * envBRDF.y;
+}
 
 
-	return F * (V * D) * lightSpecCol;
+vec3 diffuseLambert(vec3 diffuse)
+{
+	return diffuse * (1.0 / PI);
 }
 }
 
 
-vec3 computeDiffuseColor(vec3 diffCol, vec3 lightDiffCol)
+// Performs BRDF specular lighting
+vec3 computeSpecularColorBrdf(GbufferInfo gbuffer, vec3 viewDir, vec3 frag2Light)
 {
 {
-	return diffCol * lightDiffCol;
+	vec3 H = normalize(frag2Light + viewDir);
+
+	float NoL = max(EPSILON, dot(gbuffer.normal, frag2Light));
+	float VoH = max(EPSILON, dot(viewDir, H));
+	float NoH = max(EPSILON, dot(gbuffer.normal, H));
+	float NoV = max(EPSILON, dot(gbuffer.normal, viewDir));
+
+	vec3 F = F_Unreal(gbuffer.specular, VoH);
+	float D = D_GGX(gbuffer.roughness, NoH);
+	float V = V_Schlick(gbuffer.roughness, NoV, NoL);
+
+	return F * (V * D);
 }
 }
 
 
 float computeSpotFactor(vec3 l, float outerCos, float innerCos, vec3 spotDir)
 float computeSpotFactor(vec3 l, float outerCos, float innerCos, vec3 spotDir)
@@ -100,7 +99,9 @@ float computeShadowFactorSpot(mat4 lightProjectionMat, vec3 worldPos, float dist
 
 
 	float linearDepth = linearizeDepth(texCoords3.z, near, far);
 	float linearDepth = linearizeDepth(texCoords3.z, near, far);
 
 
-	return clamp(exp(ESM_CONSTANT * (textureLod(spotMapArr, texCoords3.xy, 0.0).r - linearDepth)), 0.0, 1.0);
+	float shadowFactor = textureLod(spotMapArr, texCoords3.xy, 0.0).r;
+
+	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
 }
 }
 
 
 float computeShadowFactorOmni(vec3 frag2Light, float radius, uvec2 atlasTiles, float tileSize, sampler2D shadowMap)
 float computeShadowFactorOmni(vec3 frag2Light, float radius, uvec2 atlasTiles, float tileSize, sampler2D shadowMap)
@@ -132,7 +133,7 @@ float computeShadowFactorOmni(vec3 frag2Light, float radius, uvec2 atlasTiles, f
 		shadowFactor = textureLod(shadowMap, uv, 0.0).r;
 		shadowFactor = textureLod(shadowMap, uv, 0.0).r;
 	}
 	}
 
 
-	return clamp(exp(ESM_CONSTANT * (shadowFactor - linearDepth)), 0.0, 1.0);
+	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
 }
 }
 
 
 // Compute the cubemap texture lookup vector given the reflection vector (r) the radius squared of the probe (R2) and
 // Compute the cubemap texture lookup vector given the reflection vector (r) the radius squared of the probe (R2) and
@@ -163,11 +164,12 @@ vec3 computeCubemapVecCheap(in vec3 r, in float R2, in vec3 f)
 	return r;
 	return r;
 }
 }
 
 
-float computeRoughnesSquared(float roughness)
+float computeAttenuationFactor(float lightRadius, vec3 frag2Light)
 {
 {
-	float a2 = roughness * 0.95 + 0.05;
-	a2 *= a2 * a2;
-	return a2;
+	float fragLightDist = dot(frag2Light, frag2Light);
+	float att = 1.0 - fragLightDist * lightRadius;
+	att = max(0.0, att);
+	return att * att;
 }
 }
 
 
 #endif
 #endif

+ 17 - 19
shaders/Pack.glsl

@@ -145,9 +145,8 @@ struct GbufferInfo
 // Populate the G buffer
 // Populate the G buffer
 void writeGBuffer(in GbufferInfo g, out vec4 rt0, out vec4 rt1, out vec4 rt2)
 void writeGBuffer(in GbufferInfo g, out vec4 rt0, out vec4 rt1, out vec4 rt2)
 {
 {
-	float comp = packUnorm2ToUnorm1(vec2(g.subsurface, g.metallic));
-	rt0 = vec4(g.diffuse, comp);
-	rt1 = vec4(g.specular, g.roughness);
+	rt0 = vec4(g.diffuse, g.subsurface);
+	rt1 = vec4(g.roughness, g.metallic, g.specular.x, 0.0);
 
 
 	vec3 encNorm = signedOctEncode(g.normal);
 	vec3 encNorm = signedOctEncode(g.normal);
 	rt2 = vec4(encNorm.xy, g.emission / MAX_EMISSION, encNorm.z);
 	rt2 = vec4(encNorm.xy, g.emission / MAX_EMISSION, encNorm.z);
@@ -159,32 +158,31 @@ void readNormalFromGBuffer(in sampler2D rt2, in vec2 uv, out vec3 normal)
 	normal = signedOctDecode(texture(rt2, uv).rga);
 	normal = signedOctDecode(texture(rt2, uv).rga);
 }
 }
 
 
-// Read the roughness from the G-buffer
-void readRoughnessSpecularFromGBuffer(in sampler2D rt1, in vec2 uv, out float roughness, out vec3 specular)
-{
-	vec4 comp = textureLod(rt1, uv, 0.0);
-	specular = comp.xyz;
-	roughness = comp.w;
-}
-
 // Read from the G buffer
 // Read from the G buffer
 void readGBuffer(in sampler2D rt0, in sampler2D rt1, in sampler2D rt2, in vec2 uv, in float lod, out GbufferInfo g)
 void readGBuffer(in sampler2D rt0, in sampler2D rt1, in sampler2D rt2, in vec2 uv, in float lod, out GbufferInfo g)
 {
 {
-	vec4 comp = textureLod(rt0, uv, lod);
+	vec4 comp = textureLod(rt0, uv, 0.0);
 	g.diffuse = comp.xyz;
 	g.diffuse = comp.xyz;
-	vec2 comp2 = unpackUnorm1ToUnorm2(comp.w);
-	g.subsurface = comp2.x;
-	g.metallic = comp2.y;
+	g.subsurface = comp.w;
 
 
-	readRoughnessSpecularFromGBuffer(rt1, uv, g.roughness, g.specular);
+	comp = textureLod(rt1, uv, 0.0);
+	g.roughness = comp.x;
+	g.metallic = comp.y;
+	g.specular = vec3(comp.z);
 
 
-	comp = textureLod(rt2, uv, lod);
+	comp = textureLod(rt2, uv, 0.0);
 	g.normal = signedOctDecode(comp.xyw);
 	g.normal = signedOctDecode(comp.xyw);
 	g.emission = comp.z * MAX_EMISSION;
 	g.emission = comp.z * MAX_EMISSION;
 
 
-	// Fix values
+	// Fix roughness
+	const float MIN_ROUGHNESS = 0.05;
+	g.roughness = g.roughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS;
+
+	// Compute reflectance
 	g.specular = mix(g.specular, g.diffuse, g.metallic);
 	g.specular = mix(g.specular, g.diffuse, g.metallic);
-	g.diffuse *= (1.0 - g.metallic);
+
+	// Compute diffuse
+	g.diffuse = g.diffuse - g.diffuse * g.metallic;
 }
 }
 
 
 #endif
 #endif

+ 0 - 3
src/anki/event/LightEvent.cpp

@@ -32,7 +32,6 @@ Error LightEvent::init(F32 startTime, F32 duration, SceneNode* light)
 	}
 	}
 
 
 	m_originalDiffColor = lightc.getDiffuseColor();
 	m_originalDiffColor = lightc.getDiffuseColor();
-	m_originalSpecColor = lightc.getSpecularColor();
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
@@ -76,8 +75,6 @@ Error LightEvent::update(F32 prevUpdateTime, F32 crntTime)
 		lightc.setDiffuseColor(outCol);
 		lightc.setDiffuseColor(outCol);
 	}
 	}
 
 
-	lightc.setSpecularColor(m_originalSpecColor + factor * m_specularIntensityMultiplier);
-
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 

+ 0 - 7
src/anki/event/LightEvent.h

@@ -42,11 +42,6 @@ public:
 		m_intensityMultiplier = v;
 		m_intensityMultiplier = v;
 	}
 	}
 
 
-	void setSpecularIntensityMultiplier(const Vec4& v)
-	{
-		m_specularIntensityMultiplier = v;
-	}
-
 	/// Set the frequency of changes.
 	/// Set the frequency of changes.
 	/// @param freq The higher it is the faster things happen.
 	/// @param freq The higher it is the faster things happen.
 	/// @param deviation Add a randomization to the frequency.
 	/// @param deviation Add a randomization to the frequency.
@@ -63,11 +58,9 @@ private:
 	F32 m_freqDeviation = 0.0;
 	F32 m_freqDeviation = 0.0;
 	F32 m_radiusMultiplier = 0.0;
 	F32 m_radiusMultiplier = 0.0;
 	Vec4 m_intensityMultiplier = Vec4(0.0);
 	Vec4 m_intensityMultiplier = Vec4(0.0);
-	Vec4 m_specularIntensityMultiplier = Vec4(0.0);
 
 
 	F32 m_originalRadius;
 	F32 m_originalRadius;
 	Vec4 m_originalDiffColor;
 	Vec4 m_originalDiffColor;
-	Vec4 m_originalSpecColor;
 };
 };
 /// @}
 /// @}
 
 

+ 12 - 3
src/anki/input/InputSdl.cpp

@@ -377,9 +377,18 @@ void Input::moveCursor(const Vec2& pos)
 {
 {
 	if(pos != m_mousePosNdc)
 	if(pos != m_mousePosNdc)
 	{
 	{
-		SDL_WarpMouseInWindow(m_nativeWindow->getNative().m_window,
-			m_nativeWindow->getWidth() * (pos.x() * 0.5 + 0.5),
-			m_nativeWindow->getHeight() * (pos.y() * 0.5 + 0.5));
+		const int x = m_nativeWindow->getWidth() * (pos.x() * 0.5f + 0.5f);
+		const int y = m_nativeWindow->getHeight() * (-pos.y() * 0.5f + 0.5f);
+
+		SDL_WarpMouseInWindow(m_nativeWindow->getNative().m_window, x, y);
+
+		// SDL doesn't generate a SDL_MOUSEMOTION event if the cursor is outside the window. Push that event
+		SDL_Event event;
+		event.type = SDL_MOUSEMOTION;
+		event.button.x = x;
+		event.button.y = y;
+
+		SDL_PushEvent(&event);
 	}
 	}
 }
 }
 
 

+ 2 - 7
src/anki/renderer/Indirect.cpp

@@ -27,7 +27,6 @@ struct Indirect::LightPassPointLightUniforms
 	Vec4 m_camPosPad1;
 	Vec4 m_camPosPad1;
 	Vec4 m_posRadius;
 	Vec4 m_posRadius;
 	Vec4 m_diffuseColorPad1;
 	Vec4 m_diffuseColorPad1;
-	Vec4 m_specularColorPad1;
 };
 };
 
 
 struct Indirect::LightPassSpotLightUniforms
 struct Indirect::LightPassSpotLightUniforms
@@ -37,8 +36,7 @@ struct Indirect::LightPassSpotLightUniforms
 	Vec4 m_camPosPad1;
 	Vec4 m_camPosPad1;
 	Vec4 m_posRadius;
 	Vec4 m_posRadius;
 	Vec4 m_diffuseColorOuterCos;
 	Vec4 m_diffuseColorOuterCos;
-	Vec4 m_specularColorInnerCos;
-	Vec4 m_lightDirPad1;
+	Vec4 m_lightDirInnerCos;
 };
 };
 
 
 Indirect::Indirect(Renderer* r)
 Indirect::Indirect(Renderer* r)
@@ -462,7 +460,6 @@ void Indirect::runLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx)
 			light->m_posRadius =
 			light->m_posRadius =
 				Vec4(plightEl->m_worldPosition.xyz(), 1.0f / (plightEl->m_radius * plightEl->m_radius));
 				Vec4(plightEl->m_worldPosition.xyz(), 1.0f / (plightEl->m_radius * plightEl->m_radius));
 			light->m_diffuseColorPad1 = plightEl->m_diffuseColor.xyz0();
 			light->m_diffuseColorPad1 = plightEl->m_diffuseColor.xyz0();
-			light->m_specularColorPad1 = plightEl->m_specularColor.xyz0();
 
 
 			// Draw
 			// Draw
 			cmdb->drawElements(PrimitiveTopology::TRIANGLES, indexCount);
 			cmdb->drawElements(PrimitiveTopology::TRIANGLES, indexCount);
@@ -509,10 +506,8 @@ void Indirect::runLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx)
 
 
 			light->m_diffuseColorOuterCos = Vec4(splightEl->m_diffuseColor, cos(splightEl->m_outerAngle / 2.0f));
 			light->m_diffuseColorOuterCos = Vec4(splightEl->m_diffuseColor, cos(splightEl->m_outerAngle / 2.0f));
 
 
-			light->m_specularColorInnerCos = Vec4(splightEl->m_specularColor, cos(splightEl->m_innerAngle / 2.0f));
-
 			Vec3 lightDir = -splightEl->m_worldTransform.getZAxis().xyz();
 			Vec3 lightDir = -splightEl->m_worldTransform.getZAxis().xyz();
-			light->m_lightDirPad1 = lightDir.xyz0();
+			light->m_lightDirInnerCos = Vec4(lightDir, cos(splightEl->m_innerAngle / 2.0f));
 
 
 			// Draw
 			// Draw
 			cmdb->drawElements(PrimitiveTopology::TRIANGLES, indexCount);
 			cmdb->drawElements(PrimitiveTopology::TRIANGLES, indexCount);

+ 5 - 9
src/anki/renderer/LightBin.cpp

@@ -30,7 +30,7 @@ class ShaderPointLight
 public:
 public:
 	Vec4 m_posRadius;
 	Vec4 m_posRadius;
 	Vec4 m_diffuseColorTileSize;
 	Vec4 m_diffuseColorTileSize;
-	Vec4 m_specularColorRadius;
+	Vec4 m_radiusPad3;
 	UVec4 m_atlasTilesPad2;
 	UVec4 m_atlasTilesPad2;
 };
 };
 
 
@@ -39,8 +39,7 @@ class ShaderSpotLight
 public:
 public:
 	Vec4 m_posRadius;
 	Vec4 m_posRadius;
 	Vec4 m_diffuseColorShadowmapId;
 	Vec4 m_diffuseColorShadowmapId;
-	Vec4 m_specularColorRadius;
-	Vec4 m_lightDir;
+	Vec4 m_lightDirRadius;
 	Vec4 m_outerCosInnerCos;
 	Vec4 m_outerCosInnerCos;
 	Mat4 m_texProjectionMat; ///< Texture projection matrix
 	Mat4 m_texProjectionMat; ///< Texture projection matrix
 };
 };
@@ -669,7 +668,7 @@ void LightBin::writeAndBinPointLight(
 		slight.m_atlasTilesPad2 = UVec4(lightEl.m_atlasTiles.x(), lightEl.m_atlasTiles.y(), 0, 0);
 		slight.m_atlasTilesPad2 = UVec4(lightEl.m_atlasTiles.x(), lightEl.m_atlasTiles.y(), 0, 0);
 	}
 	}
 
 
-	slight.m_specularColorRadius = Vec4(lightEl.m_specularColor, lightEl.m_radius);
+	slight.m_radiusPad3 = Vec4(lightEl.m_radius);
 
 
 	// Now bin it
 	// Now bin it
 	Sphere sphere(lightEl.m_worldPosition.xyz0(), lightEl.m_radius);
 	Sphere sphere(lightEl.m_worldPosition.xyz0(), lightEl.m_radius);
@@ -717,12 +716,9 @@ void LightBin::writeAndBinSpotLight(
 	// Diff color and shadowmap ID now
 	// Diff color and shadowmap ID now
 	light.m_diffuseColorShadowmapId = Vec4(lightEl.m_diffuseColor, shadowmapIndex);
 	light.m_diffuseColorShadowmapId = Vec4(lightEl.m_diffuseColor, shadowmapIndex);
 
 
-	// Spec color
-	light.m_specularColorRadius = Vec4(lightEl.m_specularColor, lightEl.m_distance);
-
-	// Light dir
+	// Light dir & radius
 	Vec3 lightDir = -lightEl.m_worldTransform.getRotationPart().getZAxis();
 	Vec3 lightDir = -lightEl.m_worldTransform.getRotationPart().getZAxis();
-	light.m_lightDir = Vec4(lightDir, 0.0f);
+	light.m_lightDirRadius = Vec4(lightDir, lightEl.m_distance);
 
 
 	// Angles
 	// Angles
 	light.m_outerCosInnerCos = Vec4(cos(lightEl.m_outerAngle / 2.0f), cos(lightEl.m_innerAngle / 2.0f), 1.0f, 1.0f);
 	light.m_outerCosInnerCos = Vec4(cos(lightEl.m_outerAngle / 2.0f), cos(lightEl.m_innerAngle / 2.0f), 1.0f, 1.0f);

+ 0 - 2
src/anki/renderer/RenderQueue.h

@@ -67,7 +67,6 @@ public:
 	Vec3 m_worldPosition;
 	Vec3 m_worldPosition;
 	F32 m_radius;
 	F32 m_radius;
 	Vec3 m_diffuseColor;
 	Vec3 m_diffuseColor;
-	Vec3 m_specularColor;
 	Array<RenderQueue*, 6> m_shadowRenderQueues;
 	Array<RenderQueue*, 6> m_shadowRenderQueues;
 	const void* m_userData;
 	const void* m_userData;
 	RenderQueueDrawCallback m_drawCallback;
 	RenderQueueDrawCallback m_drawCallback;
@@ -95,7 +94,6 @@ public:
 	F32 m_outerAngle;
 	F32 m_outerAngle;
 	F32 m_innerAngle;
 	F32 m_innerAngle;
 	Vec3 m_diffuseColor;
 	Vec3 m_diffuseColor;
-	Vec3 m_specularColor;
 	RenderQueue* m_shadowRenderQueue;
 	RenderQueue* m_shadowRenderQueue;
 	const void* m_userData;
 	const void* m_userData;
 	RenderQueueDrawCallback m_drawCallback;
 	RenderQueueDrawCallback m_drawCallback;

+ 30 - 50
src/anki/renderer/Ssao.cpp

@@ -26,15 +26,18 @@ Error Ssao::initMain(const ConfigSet& config)
 	// Shader
 	// Shader
 	ANKI_CHECK(getResourceManager().loadResource("programs/Ssao.ankiprog", m_main.m_prog));
 	ANKI_CHECK(getResourceManager().loadResource("programs/Ssao.ankiprog", m_main.m_prog));
 
 
+	ShaderProgramResourceMutationInitList<1> mutators(m_main.m_prog);
+	mutators.add("USE_NORMAL", 0u);
+
 	ShaderProgramResourceConstantValueInitList<6> consts(m_main.m_prog);
 	ShaderProgramResourceConstantValueInitList<6> consts(m_main.m_prog);
 	consts.add("NOISE_MAP_SIZE", U32(m_main.m_noiseTex->getWidth()))
 	consts.add("NOISE_MAP_SIZE", U32(m_main.m_noiseTex->getWidth()))
 		.add("FB_SIZE", UVec2(m_width, m_height))
 		.add("FB_SIZE", UVec2(m_width, m_height))
-		.add("RADIUS", 3.0f)
+		.add("RADIUS", 2.5f)
 		.add("BIAS", 0.0f)
 		.add("BIAS", 0.0f)
-		.add("STRENGTH", 2.0f)
-		.add("HISTORY_FEEDBACK", 1.0f / 4.0f);
+		.add("STRENGTH", 2.5f)
+		.add("SAMPLE_COUNT", 4u);
 	const ShaderProgramResourceVariant* variant;
 	const ShaderProgramResourceVariant* variant;
-	m_main.m_prog->getOrCreateVariant(consts.get(), variant);
+	m_main.m_prog->getOrCreateVariant(mutators.get(), consts.get(), variant);
 	m_main.m_grProg = variant->getProgram();
 	m_main.m_grProg = variant->getProgram();
 
 
 	return Error::NONE;
 	return Error::NONE;
@@ -83,19 +86,13 @@ Error Ssao::init(const ConfigSet& config)
 
 
 	ANKI_R_LOGI("Initializing SSAO. Size %ux%u", m_width, m_height);
 	ANKI_R_LOGI("Initializing SSAO. Size %ux%u", m_width, m_height);
 
 
-	static const Array<const char*, 2> RT_NAMES = {{"SsaoMain #1", "SsaoMain #2"}};
-	for(U i = 0; i < 2; ++i)
-	{
-		// RT
-		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(m_width,
-			m_height,
-			Ssao::RT_PIXEL_FORMAT,
-			TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE | TextureUsageBit::CLEAR,
-			&RT_NAMES[i][0]);
-		texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
-
-		m_rtTextures[i] = m_r->createAndClearRenderTarget(texinit);
-	}
+	// RT
+	m_rtDescr = m_r->create2DRenderTargetDescription(m_width,
+		m_height,
+		Ssao::RT_PIXEL_FORMAT,
+		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE | TextureUsageBit::CLEAR,
+		"SSAO");
+	m_rtDescr.bake();
 
 
 	// FB descr
 	// FB descr
 	m_fbDescr.m_colorAttachmentCount = 1;
 	m_fbDescr.m_colorAttachmentCount = 1;
@@ -131,20 +128,16 @@ void Ssao::runMain(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 
 
 	rgraphCtx.bindTextureAndSampler(
 	rgraphCtx.bindTextureAndSampler(
 		0, 0, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
 		0, 0, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getGBuffer().getColorRt(2), m_r->getLinearSampler());
 	cmdb->bindTextureAndSampler(0,
 	cmdb->bindTextureAndSampler(0,
-		2,
+		1,
 		m_main.m_noiseTex->getGrTextureView(),
 		m_main.m_noiseTex->getGrTextureView(),
 		m_r->getTrilinearRepeatSampler(),
 		m_r->getTrilinearRepeatSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
-	rgraphCtx.bindColorTextureAndSampler(0, 3, m_runCtx.m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 
 
 	struct Unis
 	struct Unis
 	{
 	{
 		Vec4 m_unprojectionParams;
 		Vec4 m_unprojectionParams;
 		Vec4 m_projectionMat;
 		Vec4 m_projectionMat;
-		Vec4 m_noiseLayerPad3;
-		Mat4 m_prevViewProjMatMulInvViewProjMat;
 		Mat3x4 m_viewRotMat;
 		Mat3x4 m_viewRotMat;
 	};
 	};
 
 
@@ -152,9 +145,6 @@ void Ssao::runMain(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 	const Mat4& pmat = ctx.m_renderQueue->m_projectionMatrix;
 	const Mat4& pmat = ctx.m_renderQueue->m_projectionMatrix;
 	unis->m_unprojectionParams = ctx.m_unprojParams;
 	unis->m_unprojectionParams = ctx.m_unprojParams;
 	unis->m_projectionMat = Vec4(pmat(0, 0), pmat(1, 1), pmat(2, 2), pmat(2, 3));
 	unis->m_projectionMat = Vec4(pmat(0, 0), pmat(1, 1), pmat(2, 2), pmat(2, 3));
-	unis->m_noiseLayerPad3 = Vec4(m_r->getFrameCount() % m_main.m_noiseTex->getLayerCount(), 0.0, 0.0, 0.0);
-	unis->m_prevViewProjMatMulInvViewProjMat =
-		ctx.m_prevViewProjMat * ctx.m_renderQueue->m_viewProjectionMatrix.getInverse();
 	unis->m_viewRotMat = Mat3x4(ctx.m_renderQueue->m_viewMatrix.getRotationPart());
 	unis->m_viewRotMat = Mat3x4(ctx.m_renderQueue->m_viewMatrix.getRotationPart());
 
 
 	drawQuad(cmdb);
 	drawQuad(cmdb);
@@ -166,7 +156,7 @@ void Ssao::runHBlur(RenderPassWorkContext& rgraphCtx)
 
 
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->bindShaderProgram(m_hblur.m_grProg);
 	cmdb->bindShaderProgram(m_hblur.m_grProg);
-	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_rts[m_r->getFrameCount() & 1], m_r->getLinearSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_rts[0], m_r->getLinearSampler());
 	rgraphCtx.bindTextureAndSampler(
 	rgraphCtx.bindTextureAndSampler(
 		0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
 		0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
 	drawQuad(cmdb);
 	drawQuad(cmdb);
@@ -178,7 +168,7 @@ void Ssao::runVBlur(RenderPassWorkContext& rgraphCtx)
 
 
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->bindShaderProgram(m_vblur.m_grProg);
 	cmdb->bindShaderProgram(m_vblur.m_grProg);
-	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_rts[1], m_r->getLinearSampler());
 	rgraphCtx.bindTextureAndSampler(
 	rgraphCtx.bindTextureAndSampler(
 		0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
 		0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getLinearSampler());
 	drawQuad(cmdb);
 	drawQuad(cmdb);
@@ -190,25 +180,20 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
 	// Create RTs
 	// Create RTs
-	const U rtToRenderIdx = m_r->getFrameCount() & 1;
-	m_runCtx.m_rts[rtToRenderIdx] =
-		rgraph.importRenderTarget("SSAO #1", m_rtTextures[rtToRenderIdx], TextureUsageBit::NONE);
-	const U rtToReadIdx = !rtToRenderIdx;
-	m_runCtx.m_rts[rtToReadIdx] =
-		rgraph.importRenderTarget("SSAO #2", m_rtTextures[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT);
+	m_runCtx.m_rts[0] = rgraph.newRenderTarget(m_rtDescr);
+	m_runCtx.m_rts[1] = rgraph.newRenderTarget(m_rtDescr);
 
 
 	// Create main render pass
 	// Create main render pass
 	{
 	{
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO main");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO main");
 
 
 		pass.setWork(runMainCallback, this, 0);
 		pass.setWork(runMainCallback, this, 0);
-		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[rtToRenderIdx]}}, {});
+		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[0]}}, {});
 
 
 		pass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
 		pass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT});
 		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
 		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
-		pass.newProducer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newProducer({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 	}
 
 
 	// Create HBlur pass
 	// Create HBlur pass
@@ -216,12 +201,12 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO hblur");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO hblur");
 
 
 		pass.setWork(runHBlurCallback, this, 0);
 		pass.setWork(runHBlurCallback, this, 0);
-		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[rtToReadIdx]}}, {});
+		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[1]}}, {});
 
 
-		pass.newConsumer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_FRAGMENT});
 		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
 		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
-		pass.newProducer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 	}
 
 
 	// Create VBlur pass
 	// Create VBlur pass
@@ -229,18 +214,13 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO vblur");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO vblur");
 
 
 		pass.setWork(runVBlurCallback, this, 0);
 		pass.setWork(runVBlurCallback, this, 0);
-		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[rtToRenderIdx]}}, {});
+		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[0]}}, {});
 
 
-		pass.newConsumer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::SAMPLED_FRAGMENT});
 		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
 		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
-		pass.newProducer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newProducer({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 	}
 }
 }
 
 
-RenderTargetHandle Ssao::getRt() const
-{
-	return m_runCtx.m_rts[m_r->getFrameCount() & 1];
-}
-
 } // end namespace anki
 } // end namespace anki

+ 5 - 2
src/anki/renderer/Ssao.h

@@ -33,7 +33,10 @@ anki_internal:
 	/// Populate the rendergraph.
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);
 
 
-	RenderTargetHandle getRt() const;
+	RenderTargetHandle getRt() const
+	{
+		return m_runCtx.m_rts[0];
+	}
 
 
 private:
 private:
 	U32 m_width, m_height;
 	U32 m_width, m_height;
@@ -67,7 +70,7 @@ private:
 		const RenderingContext* m_ctx = nullptr;
 		const RenderingContext* m_ctx = nullptr;
 	} m_runCtx; ///< Runtime context.
 	} m_runCtx; ///< Runtime context.
 
 
-	Array<TexturePtr, 2> m_rtTextures;
+	RenderTargetDescription m_rtDescr;
 	FramebufferDescription m_fbDescr;
 	FramebufferDescription m_fbDescr;
 
 
 	ANKI_USE_RESULT Error initMain(const ConfigSet& set);
 	ANKI_USE_RESULT Error initMain(const ConfigSet& set);

+ 0 - 13
src/anki/scene/components/LightComponent.h

@@ -55,16 +55,6 @@ public:
 		m_diffColor = x;
 		m_diffColor = x;
 	}
 	}
 
 
-	const Vec4& getSpecularColor() const
-	{
-		return m_specColor;
-	}
-
-	void setSpecularColor(const Vec4& x)
-	{
-		m_specColor = x;
-	}
-
 	void setRadius(F32 x)
 	void setRadius(F32 x)
 	{
 	{
 		m_radius = x;
 		m_radius = x;
@@ -140,7 +130,6 @@ public:
 		el.m_worldPosition = m_trf.getOrigin().xyz();
 		el.m_worldPosition = m_trf.getOrigin().xyz();
 		el.m_radius = m_radius;
 		el.m_radius = m_radius;
 		el.m_diffuseColor = m_diffColor.xyz();
 		el.m_diffuseColor = m_diffColor.xyz();
-		el.m_specularColor = m_specColor.xyz();
 		el.m_userData = this;
 		el.m_userData = this;
 		el.m_drawCallback = pointLightDebugDrawCallback;
 		el.m_drawCallback = pointLightDebugDrawCallback;
 	}
 	}
@@ -155,7 +144,6 @@ public:
 		el.m_outerAngle = m_outerAngle;
 		el.m_outerAngle = m_outerAngle;
 		el.m_innerAngle = m_innerAngle;
 		el.m_innerAngle = m_innerAngle;
 		el.m_diffuseColor = m_diffColor.xyz();
 		el.m_diffuseColor = m_diffColor.xyz();
-		el.m_specularColor = m_specColor.xyz();
 		el.m_userData = this;
 		el.m_userData = this;
 		el.m_drawCallback = spotLightDebugDrawCallback;
 		el.m_drawCallback = spotLightDebugDrawCallback;
 	}
 	}
@@ -163,7 +151,6 @@ public:
 private:
 private:
 	LightComponentType m_type;
 	LightComponentType m_type;
 	Vec4 m_diffColor = Vec4(0.5f);
 	Vec4 m_diffColor = Vec4(0.5f);
-	Vec4 m_specColor = Vec4(0.5f);
 	union
 	union
 	{
 	{
 		F32 m_radius;
 		F32 m_radius;

+ 0 - 95
src/anki/script/Scene.cpp

@@ -541,99 +541,6 @@ static int wrapLightComponentgetDiffuseColor(lua_State* l)
 	return 0;
 	return 0;
 }
 }
 
 
-/// Pre-wrap method LightComponent::setSpecularColor.
-static inline int pwrapLightComponentsetSpecularColor(lua_State* l)
-{
-	LuaUserData* ud;
-	(void)ud;
-	void* voidp;
-	(void)voidp;
-	PtrSize size;
-	(void)size;
-
-	LuaBinder::checkArgsCount(l, 2);
-
-	// Get "this" as "self"
-	if(LuaBinder::checkUserData(l, 1, classnameLightComponent, 7940823622056993903, ud))
-	{
-		return -1;
-	}
-
-	LightComponent* self = ud->getData<LightComponent>();
-
-	// Pop arguments
-	if(LuaBinder::checkUserData(l, 2, "Vec4", 6804478823655046386, ud))
-	{
-		return -1;
-	}
-
-	Vec4* iarg0 = ud->getData<Vec4>();
-	const Vec4& arg0(*iarg0);
-
-	// Call the method
-	self->setSpecularColor(arg0);
-
-	return 0;
-}
-
-/// Wrap method LightComponent::setSpecularColor.
-static int wrapLightComponentsetSpecularColor(lua_State* l)
-{
-	int res = pwrapLightComponentsetSpecularColor(l);
-	if(res >= 0)
-	{
-		return res;
-	}
-
-	lua_error(l);
-	return 0;
-}
-
-/// Pre-wrap method LightComponent::getSpecularColor.
-static inline int pwrapLightComponentgetSpecularColor(lua_State* l)
-{
-	LuaUserData* ud;
-	(void)ud;
-	void* voidp;
-	(void)voidp;
-	PtrSize size;
-	(void)size;
-
-	LuaBinder::checkArgsCount(l, 1);
-
-	// Get "this" as "self"
-	if(LuaBinder::checkUserData(l, 1, classnameLightComponent, 7940823622056993903, ud))
-	{
-		return -1;
-	}
-
-	LightComponent* self = ud->getData<LightComponent>();
-
-	// Call the method
-	const Vec4& ret = self->getSpecularColor();
-
-	// Push return value
-	voidp = lua_newuserdata(l, sizeof(LuaUserData));
-	ud = static_cast<LuaUserData*>(voidp);
-	luaL_setmetatable(l, "Vec4");
-	ud->initPointed(6804478823655046386, const_cast<Vec4*>(&ret));
-
-	return 1;
-}
-
-/// Wrap method LightComponent::getSpecularColor.
-static int wrapLightComponentgetSpecularColor(lua_State* l)
-{
-	int res = pwrapLightComponentgetSpecularColor(l);
-	if(res >= 0)
-	{
-		return res;
-	}
-
-	lua_error(l);
-	return 0;
-}
-
 /// Pre-wrap method LightComponent::setRadius.
 /// Pre-wrap method LightComponent::setRadius.
 static inline int pwrapLightComponentsetRadius(lua_State* l)
 static inline int pwrapLightComponentsetRadius(lua_State* l)
 {
 {
@@ -1080,8 +987,6 @@ static inline void wrapLightComponent(lua_State* l)
 	LuaBinder::createClass(l, classnameLightComponent);
 	LuaBinder::createClass(l, classnameLightComponent);
 	LuaBinder::pushLuaCFuncMethod(l, "setDiffuseColor", wrapLightComponentsetDiffuseColor);
 	LuaBinder::pushLuaCFuncMethod(l, "setDiffuseColor", wrapLightComponentsetDiffuseColor);
 	LuaBinder::pushLuaCFuncMethod(l, "getDiffuseColor", wrapLightComponentgetDiffuseColor);
 	LuaBinder::pushLuaCFuncMethod(l, "getDiffuseColor", wrapLightComponentgetDiffuseColor);
-	LuaBinder::pushLuaCFuncMethod(l, "setSpecularColor", wrapLightComponentsetSpecularColor);
-	LuaBinder::pushLuaCFuncMethod(l, "getSpecularColor", wrapLightComponentgetSpecularColor);
 	LuaBinder::pushLuaCFuncMethod(l, "setRadius", wrapLightComponentsetRadius);
 	LuaBinder::pushLuaCFuncMethod(l, "setRadius", wrapLightComponentsetRadius);
 	LuaBinder::pushLuaCFuncMethod(l, "getRadius", wrapLightComponentgetRadius);
 	LuaBinder::pushLuaCFuncMethod(l, "getRadius", wrapLightComponentgetRadius);
 	LuaBinder::pushLuaCFuncMethod(l, "setDistance", wrapLightComponentsetDistance);
 	LuaBinder::pushLuaCFuncMethod(l, "setDistance", wrapLightComponentsetDistance);

+ 0 - 8
src/anki/script/Scene.xml

@@ -87,14 +87,6 @@ static SceneGraph* getSceneGraph(lua_State* l)
 				<method name="getDiffuseColor">
 				<method name="getDiffuseColor">
 					<return>const Vec4&amp;</return>
 					<return>const Vec4&amp;</return>
 				</method>
 				</method>
-				<method name="setSpecularColor">
-					<args>
-						<arg>const Vec4&amp;</arg>
-					</args>
-				</method>
-				<method name="getSpecularColor">
-					<return>const Vec4&amp;</return>
-				</method>
 				<method name="setRadius">
 				<method name="setRadius">
 					<args>
 					<args>
 						<arg>F32</arg>
 						<arg>F32</arg>

+ 0 - 8
tools/scene/Exporter.cpp

@@ -473,14 +473,6 @@ void Exporter::exportLight(const aiLight& light)
 	aiVector3D linear(light.mColorDiffuse[0], light.mColorDiffuse[1], light.mColorDiffuse[2]);
 	aiVector3D linear(light.mColorDiffuse[0], light.mColorDiffuse[1], light.mColorDiffuse[2]);
 	file << "lcomp:setDiffuseColor(Vec4.new(" << linear[0] << ", " << linear[1] << ", " << linear[2] << ", 1))\n";
 	file << "lcomp:setDiffuseColor(Vec4.new(" << linear[0] << ", " << linear[1] << ", " << linear[2] << ", 1))\n";
 
 
-	// linear = computeLightColor(light.mColorSpecular);
-	if(light.mProperties.find("specular_color") != light.mProperties.end())
-	{
-		stringToFloatArray<3>(light.mProperties.at("specular_color"), linear);
-	}
-
-	file << "lcomp:setSpecularColor(Vec4.new(" << linear[0] << ", " << linear[1] << ", " << linear[2] << ", 1))\n";
-
 	// Geometry
 	// Geometry
 	aiVector3D direction(0.0, 0.0, 1.0);
 	aiVector3D direction(0.0, 0.0, 1.0);