Browse Source

Fix the cascaded shadows a bit. Make the distance logarithmic

Panagiotis Christopoulos Charitos 5 years ago
parent
commit
7ea6e3ebd1

+ 16 - 5
shaders/ShadowmapsResolve.ankiprog

@@ -44,12 +44,23 @@ void main()
 	// Dir light
 	if(u_dirLight.m_active != 0u && u_dirLight.m_cascadeCount > 0)
 	{
-		const F32 linearDepth = linearizeDepth(depth, u_near, u_far);
-		const F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
-		const U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
+		const Vec4 viewPos4 = u_invProjMat * Vec4(ndc, depth, 1.0);
+		const F32 zViewSpace = viewPos4.z / viewPos4.w;
 
-		const F32 shadowFactor =
-			computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex, u_linearAnyClampSampler);
+		F32 shadowFactor;
+		if(-zViewSpace < u_dirLight.m_effectiveShadowDistance)
+		{
+			const U32 cascadeIdx =
+				computeShadowCascadeIndex(-zViewSpace, u_dirLight.m_shadowCascadesDistancePower,
+										  u_dirLight.m_effectiveShadowDistance, u_dirLight.m_cascadeCount);
+
+			shadowFactor =
+				computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex, u_linearAnyClampSampler);
+		}
+		else
+		{
+			shadowFactor = 1.0;
+		}
 
 		shadowFactors[0] = shadowFactor;
 		++shadowCasterCountPerFragment;

+ 7 - 6
shaders/VolumetricLightingAccumulation.ankiprog

@@ -94,7 +94,7 @@ F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
 	return saturate(a * b);
 }
 
-Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
+Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 negativeZViewSpace)
 {
 	Vec3 color = Vec3(0.0);
 	const Vec3 viewDir = normalize(u_cameraPos - worldPos);
@@ -108,10 +108,12 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
 		F32 factor = phaseFunction(viewDir, u_dirLight.m_dir, PHASE_FUNCTION_ANISOTROPY);
 
 #if ENABLE_SHADOWS
-		if(u_dirLight.m_cascadeCount > 0u)
+		if(u_dirLight.m_cascadeCount > 0u && negativeZViewSpace < u_dirLight.m_effectiveShadowDistance)
 		{
-			const F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
-			const U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
+			const U32 cascadeIdx =
+				computeShadowCascadeIndex(negativeZViewSpace, u_dirLight.m_shadowCascadesDistancePower,
+										  u_dirLight.m_effectiveShadowDistance, u_dirLight.m_cascadeCount);
+
 			factor *=
 				computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex, u_linearAnyClampSampler);
 		}
@@ -261,8 +263,7 @@ void main()
 	const Vec3 worldPos = worldPosInsideClusterAndZViewSpace(readRand(), negativeZViewSpace);
 
 	// Get lighting
-	const F32 linearDepth = negativeZViewSpace / (u_far - u_near);
-	Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos, linearDepth);
+	Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos, negativeZViewSpace);
 
 	// Read the prev result
 	{

+ 22 - 1
shaders/glsl_cpp_common/ClusteredShading.h

@@ -65,9 +65,12 @@ struct DirectionalLight
 	U32 m_cascadeCount; // If it's zero then it doesn't case shadow
 	Vec3 m_dir;
 	U32 m_active;
+	Vec2 m_padding;
+	F32 m_effectiveShadowDistance;
+	F32 m_shadowCascadesDistancePower;
 	Mat4 m_textureMatrices[MAX_SHADOW_CASCADES];
 };
-const U32 SIZEOF_DIR_LIGHT = 2 * SIZEOF_VEC4 + MAX_SHADOW_CASCADES * SIZEOF_MAT4;
+const U32 SIZEOF_DIR_LIGHT = 3 * SIZEOF_VEC4 + MAX_SHADOW_CASCADES * SIZEOF_MAT4;
 ANKI_SHADER_STATIC_ASSERT(sizeof(DirectionalLight) == SIZEOF_DIR_LIGHT)
 
 // Representation of a reflection probe
@@ -197,4 +200,22 @@ ANKI_SHADER_FUNC_INLINE Vec3 computeClustererVolumeTextureUvs(ClustererMagicValu
 	return Vec3(uv, k / F32(clusterCountZ));
 }
 
+// Compute the far plane of a shadow cascade. "p" is the power that defines the distance curve.
+// "effectiveShadowDistance" is the far plane of the last cascade.
+ANKI_SHADER_FUNC_INLINE F32 computeShadowCascadeDistance(U32 cascadeIdx, F32 p, F32 effectiveShadowDistance,
+														 U32 shadowCascadeCount)
+{
+	return pow((F32(cascadeIdx) + 1.0f) / F32(shadowCascadeCount), p) * effectiveShadowDistance;
+}
+
+// The reverse of computeShadowCascadeDistance().
+ANKI_SHADER_FUNC_INLINE U32 computeShadowCascadeIndex(F32 distance, F32 p, F32 effectiveShadowDistance,
+													  U32 shadowCascadeCount)
+{
+	const F32 shadowCascadeCountf = F32(shadowCascadeCount);
+	F32 idx = pow(distance / effectiveShadowDistance, 1.0f / p) * shadowCascadeCountf;
+	idx = min(idx, shadowCascadeCountf - 1.0f);
+	return U32(idx);
+}
+
 ANKI_END_NAMESPACE

+ 2 - 0
src/anki/importer/GltfImporter.cpp

@@ -1352,6 +1352,8 @@ Error GltfImporter::writeCamera(const cgltf_node& node, const HashMapAuto<CStrin
 
 	ANKI_CHECK(m_sceneFile.writeText("frustumc:setPerspective(%f, %f, getMainRenderer():getAspectRatio() * %f, %f)\n",
 									 cam.znear, cam.zfar, cam.yfov, cam.yfov));
+	ANKI_CHECK(m_sceneFile.writeText("frustumc:setShadowCascadesDistancePower(1.5)\n"));
+	ANKI_CHECK(m_sceneFile.writeText("frustumc:setEffectiveShadowDistance(%f)\n", min(cam.zfar, 100.0f)));
 
 	return Error::NONE;
 }

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

@@ -164,6 +164,8 @@ public:
 	U64 m_uuid; ///< Zero means that there is no dir light
 	Vec3 m_diffuseColor;
 	Vec3 m_direction;
+	F32 m_effectiveShadowDistance;
+	F32 m_shadowCascadesDistancePower;
 	U8 m_shadowCascadeCount; ///< Zero means that it doesn't case any shadows
 
 	DirectionalLightQueueElement()

+ 2 - 0
src/anki/renderer/Renderer.cpp

@@ -574,6 +574,8 @@ void Renderer::updateLightShadingUniforms(RenderingContext& ctx) const
 		out.m_cascadeCount = in.m_shadowCascadeCount;
 		out.m_dir = in.m_direction;
 		out.m_active = 1;
+		out.m_effectiveShadowDistance = in.m_effectiveShadowDistance;
+		out.m_shadowCascadesDistancePower = in.m_shadowCascadesDistancePower;
 
 		for(U cascade = 0; cascade < in.m_shadowCascadeCount; ++cascade)
 		{

+ 2 - 2
src/anki/scene/LightNode.cpp

@@ -97,7 +97,7 @@ void LightNode::frameUpdateCommon()
 	const LightComponent& lc = getComponent<LightComponent>();
 	const Bool castsShadow = lc.getShadowEnabled();
 
-	Error err = iterateComponentsOfType<FrustumComponent>([&](FrustumComponent& frc) -> Error {
+	const Error err = iterateComponentsOfType<FrustumComponent>([&](FrustumComponent& frc) -> Error {
 		if(castsShadow)
 		{
 			frc.setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::SHADOW_CASTERS);
@@ -136,7 +136,7 @@ Error LightNode::loadLensFlare(const CString& filename)
 
 	LensFlareComponent* flareComp = newComponent<LensFlareComponent>(this);
 
-	Error err = flareComp->init(filename);
+	const Error err = flareComp->init(filename);
 	if(err)
 	{
 		ANKI_ASSERT(!"TODO: Remove component");

+ 40 - 9
src/anki/scene/components/FrustumComponent.h

@@ -11,6 +11,7 @@
 #include <anki/collision/Obb.h>
 #include <anki/collision/ConvexHullShape.h>
 #include <anki/collision/Plane.h>
+#include <shaders/glsl_cpp_common/ClusteredShading.h>
 
 namespace anki
 {
@@ -238,17 +239,37 @@ public:
 		}
 	}
 
+	/// Set how far to render shadows for this frustum or set to negative if you want to use the m_frustun's far.
+	void setEffectiveShadowDistance(F32 distance)
+	{
+		m_effectiveShadowDistance = distance;
+	}
+
 	/// How far to render shadows for this frustum.
 	F32 getEffectiveShadowDistance() const
 	{
-		ANKI_ASSERT(m_frustumType != FrustumType::COUNT);
-		return (m_effectiveShadowDist < 0.0f) ? m_perspective.m_far : m_effectiveShadowDist;
+		const F32 distance = (m_effectiveShadowDistance <= 0.0f) ? m_common.m_far : m_effectiveShadowDistance;
+		ANKI_ASSERT(distance > m_common.m_near && distance <= m_common.m_far);
+		return distance;
 	}
 
-	/// Set how far to render shadows for this frustum or set to negative if you want to use the m_frustun's far.
-	void setEffectiveShadowDistance(F32 dist)
+	/// See computeShadowCascadeDistance()
+	void setShadowCascadesDistancePower(F32 power)
+	{
+		ANKI_ASSERT(power >= 1.0f);
+		m_shadowCascadesDistancePower = power;
+	}
+
+	/// See computeShadowCascadeDistance()
+	F32 getShadowCascadesDistancePower() const
 	{
-		m_effectiveShadowDist = dist;
+		return m_shadowCascadesDistancePower;
+	}
+
+	F32 computeShadowCascadeDistance(U32 cascadeIdx) const
+	{
+		return anki::computeShadowCascadeDistance(cascadeIdx, m_shadowCascadesDistancePower,
+												  getEffectiveShadowDistance(), getCascadeCount());
 	}
 
 	const ConvexHullShape& getPerspectiveBoundingShape() const
@@ -263,7 +284,7 @@ public:
 		return m_ortho.m_obbW;
 	}
 
-	const Array<Plane, U(FrustumPlaneType::COUNT)>& getViewPlanes() const
+	const Array<Plane, U32(FrustumPlaneType::COUNT)>& getViewPlanes() const
 	{
 		return m_viewPlanesW;
 	}
@@ -309,8 +330,8 @@ private:
 	};
 
 	// View planes
-	Array<Plane, U(FrustumPlaneType::COUNT)> m_viewPlanesL;
-	Array<Plane, U(FrustumPlaneType::COUNT)> m_viewPlanesW;
+	Array<Plane, U32(FrustumPlaneType::COUNT)> m_viewPlanesL;
+	Array<Plane, U32(FrustumPlaneType::COUNT)> m_viewPlanesW;
 
 	Transform m_trf = Transform::getIdentity();
 	Mat4 m_projMat = Mat4::getIdentity(); ///< Projection matrix
@@ -319,7 +340,10 @@ private:
 	Mat4 m_prevViewProjMat = Mat4::getIdentity();
 
 	/// How far to render shadows for this frustum. If negative it's the m_frustum's far.
-	F32 m_effectiveShadowDist = -1.0f;
+	F32 m_effectiveShadowDistance = -1.0f;
+
+	/// Defines the the rate of the cascade distances
+	F32 m_shadowCascadesDistancePower = 1.0f;
 
 	class
 	{
@@ -334,6 +358,13 @@ private:
 	Bool m_trfMarkedForUpdate = true;
 
 	Bool updateInternal();
+
+	U32 getCascadeCount() const
+	{
+		return !!(m_flags & FrustumComponentVisibilityTestFlag::DIRECTIONAL_LIGHT_SHADOWS_ALL_CASCADES)
+				   ? MAX_SHADOW_CASCADES
+				   : 1;
+	}
 };
 /// @}
 

+ 7 - 7
src/anki/scene/components/LightComponent.cpp

@@ -92,28 +92,27 @@ void LightComponent::setupDirectionalLightQueueElement(const FrustumComponent& f
 	el.m_uuid = m_uuid;
 	el.m_diffuseColor = m_diffColor.xyz();
 	el.m_direction = -m_trf.getRotation().getZAxis().xyz();
+	el.m_effectiveShadowDistance = frustumComp.getEffectiveShadowDistance();
+	el.m_shadowCascadesDistancePower = frustumComp.getShadowCascadesDistancePower();
 	el.m_shadowCascadeCount = U8(shadowCascadeCount);
 
-	// Compute the texture matrices
 	if(shadowCascadeCount == 0)
 	{
 		return;
 	}
 
+	// Compute the texture matrices
 	const Mat4 lightTrf(m_trf);
 	if(frustumComp.getFrustumType() == FrustumType::PERSPECTIVE)
 	{
 		// Get some stuff
 		const F32 fovX = frustumComp.getFovX();
 		const F32 fovY = frustumComp.getFovY();
-		const F32 far = frustumComp.getEffectiveShadowDistance();
 
 		// Compute a sphere per cascade
 		Array<Sphere, MAX_SHADOW_CASCADES> boundingSpheres;
-		for(U i = 0; i < shadowCascadeCount; ++i)
+		for(U32 i = 0; i < shadowCascadeCount; ++i)
 		{
-			const F32 cascadeFarNearDist = far / F32(shadowCascadeCount);
-
 			// Compute the center of the sphere
 			//           ^ z
 			//           |
@@ -130,8 +129,9 @@ void LightComponent::setupDirectionalLightQueueElement(const FrustumComponent& f
 			// --------------------------> x
 			//           |
 			// The square distance of A-C is equal to B-C. Solve the equation to find the z.
-			const F32 f = F32(i + 1) * cascadeFarNearDist; // Cascade far
-			const F32 n = max(frustumComp.getNear(), F32(i) * cascadeFarNearDist); // Cascade near
+			const F32 f = frustumComp.computeShadowCascadeDistance(i); // Cascade far
+			const F32 n =
+				(i == 0) ? frustumComp.getNear() : frustumComp.computeShadowCascadeDistance(i - 1); // Cascade near
 			const F32 a = f * tan(fovY / 2.0f) * fovX / fovY;
 			const F32 b = n * tan(fovY / 2.0f) * fovX / fovY;
 			const F32 z = (b * b + n * n - a * a - f * f) / (2.0f * (f - n));

+ 6 - 3
src/anki/scene/components/LightComponent.h

@@ -175,13 +175,15 @@ private:
 	RenderQueueDrawCallback m_drawCallback = nullptr;
 	const void* m_drawCallbackUserData = nullptr;
 
-	struct Point
+	class Point
 	{
+	public:
 		F32 m_radius;
 	};
 
-	struct Spot
+	class Spot
 	{
+	public:
 		Mat4 m_textureMat;
 		F32 m_distance;
 		F32 m_innerAngleCos;
@@ -190,8 +192,9 @@ private:
 		F32 m_innerAngle;
 	};
 
-	struct Dir
+	class Dir
 	{
+	public:
 		Vec3 m_sceneMin;
 		Vec3 m_sceneMax;
 	};

+ 129 - 28
src/anki/script/Scene.cpp

@@ -62,7 +62,7 @@ static EventManager* getEventManager(lua_State* l)
 using WeakArraySceneNodePtr = WeakArray<SceneNode*>;
 
 LuaUserDataTypeInfo luaUserDataTypeInfoWeakArraySceneNodePtr = {
-	4158963409681942864, "WeakArraySceneNodePtr", LuaUserData::computeSizeForGarbageCollected<WeakArraySceneNodePtr>(),
+	4809158641728402513, "WeakArraySceneNodePtr", LuaUserData::computeSizeForGarbageCollected<WeakArraySceneNodePtr>(),
 	nullptr, nullptr};
 
 template<>
@@ -187,7 +187,7 @@ static inline void wrapWeakArraySceneNodePtr(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoMoveComponent = {2038493110845313445, "MoveComponent",
+LuaUserDataTypeInfo luaUserDataTypeInfoMoveComponent = {-2944793417571201988, "MoveComponent",
 														LuaUserData::computeSizeForGarbageCollected<MoveComponent>(),
 														nullptr, nullptr};
 
@@ -609,7 +609,7 @@ static inline void wrapMoveComponent(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoLightComponent = {7940823622056993903, "LightComponent",
+LuaUserDataTypeInfo luaUserDataTypeInfoLightComponent = {-5929610182624634661, "LightComponent",
 														 LuaUserData::computeSizeForGarbageCollected<LightComponent>(),
 														 nullptr, nullptr};
 
@@ -1209,7 +1209,7 @@ static inline void wrapLightComponent(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoDecalComponent = {-1979693900066114370, "DecalComponent",
+LuaUserDataTypeInfo luaUserDataTypeInfoDecalComponent = {-4163588209729645620, "DecalComponent",
 														 LuaUserData::computeSizeForGarbageCollected<DecalComponent>(),
 														 nullptr, nullptr};
 
@@ -1431,7 +1431,7 @@ static inline void wrapDecalComponent(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoLensFlareComponent = {
-	-2019248835133422777, "LensFlareComponent", LuaUserData::computeSizeForGarbageCollected<LensFlareComponent>(),
+	3485175800586425724, "LensFlareComponent", LuaUserData::computeSizeForGarbageCollected<LensFlareComponent>(),
 	nullptr, nullptr};
 
 template<>
@@ -1554,7 +1554,7 @@ static inline void wrapLensFlareComponent(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoTriggerComponent = {
-	7180780522076545145, "TriggerComponent", LuaUserData::computeSizeForGarbageCollected<TriggerComponent>(), nullptr,
+	2349517582012766186, "TriggerComponent", LuaUserData::computeSizeForGarbageCollected<TriggerComponent>(), nullptr,
 	nullptr};
 
 template<>
@@ -1623,7 +1623,7 @@ static inline void wrapTriggerComponent(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoFogDensityComponent = {
-	3433641273323722630, "FogDensityComponent", LuaUserData::computeSizeForGarbageCollected<FogDensityComponent>(),
+	2494662987971482753, "FogDensityComponent", LuaUserData::computeSizeForGarbageCollected<FogDensityComponent>(),
 	nullptr, nullptr};
 
 template<>
@@ -1848,7 +1848,7 @@ static inline void wrapFogDensityComponent(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoFrustumComponent = {
-	3265476675265865783, "FrustumComponent", LuaUserData::computeSizeForGarbageCollected<FrustumComponent>(), nullptr,
+	-6751360472098617278, "FrustumComponent", LuaUserData::computeSizeForGarbageCollected<FrustumComponent>(), nullptr,
 	nullptr};
 
 template<>
@@ -1924,16 +1924,117 @@ static int wrapFrustumComponentsetPerspective(lua_State* l)
 	return 0;
 }
 
+/// Pre-wrap method FrustumComponent::setShadowCascadesDistancePower.
+static inline int pwrapFrustumComponentsetShadowCascadesDistancePower(lua_State* l)
+{
+	LuaUserData* ud;
+	(void)ud;
+	void* voidp;
+	(void)voidp;
+	PtrSize size;
+	(void)size;
+
+	if(ANKI_UNLIKELY(LuaBinder::checkArgsCount(l, 2)))
+	{
+		return -1;
+	}
+
+	// Get "this" as "self"
+	if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfoFrustumComponent, ud))
+	{
+		return -1;
+	}
+
+	FrustumComponent* self = ud->getData<FrustumComponent>();
+
+	// Pop arguments
+	F32 arg0;
+	if(ANKI_UNLIKELY(LuaBinder::checkNumber(l, 2, arg0)))
+	{
+		return -1;
+	}
+
+	// Call the method
+	self->setShadowCascadesDistancePower(arg0);
+
+	return 0;
+}
+
+/// Wrap method FrustumComponent::setShadowCascadesDistancePower.
+static int wrapFrustumComponentsetShadowCascadesDistancePower(lua_State* l)
+{
+	int res = pwrapFrustumComponentsetShadowCascadesDistancePower(l);
+	if(res >= 0)
+	{
+		return res;
+	}
+
+	lua_error(l);
+	return 0;
+}
+
+/// Pre-wrap method FrustumComponent::setEffectiveShadowDistance.
+static inline int pwrapFrustumComponentsetEffectiveShadowDistance(lua_State* l)
+{
+	LuaUserData* ud;
+	(void)ud;
+	void* voidp;
+	(void)voidp;
+	PtrSize size;
+	(void)size;
+
+	if(ANKI_UNLIKELY(LuaBinder::checkArgsCount(l, 2)))
+	{
+		return -1;
+	}
+
+	// Get "this" as "self"
+	if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfoFrustumComponent, ud))
+	{
+		return -1;
+	}
+
+	FrustumComponent* self = ud->getData<FrustumComponent>();
+
+	// Pop arguments
+	F32 arg0;
+	if(ANKI_UNLIKELY(LuaBinder::checkNumber(l, 2, arg0)))
+	{
+		return -1;
+	}
+
+	// Call the method
+	self->setEffectiveShadowDistance(arg0);
+
+	return 0;
+}
+
+/// Wrap method FrustumComponent::setEffectiveShadowDistance.
+static int wrapFrustumComponentsetEffectiveShadowDistance(lua_State* l)
+{
+	int res = pwrapFrustumComponentsetEffectiveShadowDistance(l);
+	if(res >= 0)
+	{
+		return res;
+	}
+
+	lua_error(l);
+	return 0;
+}
+
 /// Wrap class FrustumComponent.
 static inline void wrapFrustumComponent(lua_State* l)
 {
 	LuaBinder::createClass(l, &luaUserDataTypeInfoFrustumComponent);
 	LuaBinder::pushLuaCFuncMethod(l, "setPerspective", wrapFrustumComponentsetPerspective);
+	LuaBinder::pushLuaCFuncMethod(l, "setShadowCascadesDistancePower",
+								  wrapFrustumComponentsetShadowCascadesDistancePower);
+	LuaBinder::pushLuaCFuncMethod(l, "setEffectiveShadowDistance", wrapFrustumComponentsetEffectiveShadowDistance);
 	lua_settop(l, 0);
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoGlobalIlluminationProbeComponent = {
-	-8635406553972724905, "GlobalIlluminationProbeComponent",
+	8593813226099276965, "GlobalIlluminationProbeComponent",
 	LuaUserData::computeSizeForGarbageCollected<GlobalIlluminationProbeComponent>(), nullptr, nullptr};
 
 template<>
@@ -2310,7 +2411,7 @@ static inline void wrapGlobalIlluminationProbeComponent(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoSceneNode = {
-	-2220074417980276571, "SceneNode", LuaUserData::computeSizeForGarbageCollected<SceneNode>(), nullptr, nullptr};
+	7067551561970394862, "SceneNode", LuaUserData::computeSizeForGarbageCollected<SceneNode>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<SceneNode>()
@@ -2918,7 +3019,7 @@ static inline void wrapSceneNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoModelNode = {
-	-1856316251880904290, "ModelNode", LuaUserData::computeSizeForGarbageCollected<ModelNode>(), nullptr, nullptr};
+	-8349908074325239506, "ModelNode", LuaUserData::computeSizeForGarbageCollected<ModelNode>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<ModelNode>()
@@ -2984,7 +3085,7 @@ static inline void wrapModelNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoPerspectiveCameraNode = {
-	-7590637754681648962, "PerspectiveCameraNode", LuaUserData::computeSizeForGarbageCollected<PerspectiveCameraNode>(),
+	-4090904124533602581, "PerspectiveCameraNode", LuaUserData::computeSizeForGarbageCollected<PerspectiveCameraNode>(),
 	nullptr, nullptr};
 
 template<>
@@ -3050,7 +3151,7 @@ static inline void wrapPerspectiveCameraNode(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoPointLightNode = {8507789763949195644, "PointLightNode",
+LuaUserDataTypeInfo luaUserDataTypeInfoPointLightNode = {8707302266304136892, "PointLightNode",
 														 LuaUserData::computeSizeForGarbageCollected<PointLightNode>(),
 														 nullptr, nullptr};
 
@@ -3176,7 +3277,7 @@ static inline void wrapPointLightNode(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoSpotLightNode = {-9214759951813290587, "SpotLightNode",
+LuaUserDataTypeInfo luaUserDataTypeInfoSpotLightNode = {-7222077148830080090, "SpotLightNode",
 														LuaUserData::computeSizeForGarbageCollected<SpotLightNode>(),
 														nullptr, nullptr};
 
@@ -3244,7 +3345,7 @@ static inline void wrapSpotLightNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoDirectionalLightNode = {
-	3634924534632382552, "DirectionalLightNode", LuaUserData::computeSizeForGarbageCollected<DirectionalLightNode>(),
+	-6666005605485382239, "DirectionalLightNode", LuaUserData::computeSizeForGarbageCollected<DirectionalLightNode>(),
 	nullptr, nullptr};
 
 template<>
@@ -3311,7 +3412,7 @@ static inline void wrapDirectionalLightNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoStaticCollisionNode = {
-	-4376619865753613291, "StaticCollisionNode", LuaUserData::computeSizeForGarbageCollected<StaticCollisionNode>(),
+	-7978287687231391720, "StaticCollisionNode", LuaUserData::computeSizeForGarbageCollected<StaticCollisionNode>(),
 	nullptr, nullptr};
 
 template<>
@@ -3378,7 +3479,7 @@ static inline void wrapStaticCollisionNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoParticleEmitterNode = {
-	4851204309813771919, "ParticleEmitterNode", LuaUserData::computeSizeForGarbageCollected<ParticleEmitterNode>(),
+	-5784093545999626496, "ParticleEmitterNode", LuaUserData::computeSizeForGarbageCollected<ParticleEmitterNode>(),
 	nullptr, nullptr};
 
 template<>
@@ -3445,7 +3546,7 @@ static inline void wrapParticleEmitterNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoGpuParticleEmitterNode = {
-	-3652396348144519688, "GpuParticleEmitterNode",
+	6007656008303009875, "GpuParticleEmitterNode",
 	LuaUserData::computeSizeForGarbageCollected<GpuParticleEmitterNode>(), nullptr, nullptr};
 
 template<>
@@ -3512,7 +3613,7 @@ static inline void wrapGpuParticleEmitterNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoReflectionProbeNode = {
-	-801309373000950648, "ReflectionProbeNode", LuaUserData::computeSizeForGarbageCollected<ReflectionProbeNode>(),
+	5703642721641072194, "ReflectionProbeNode", LuaUserData::computeSizeForGarbageCollected<ReflectionProbeNode>(),
 	nullptr, nullptr};
 
 template<>
@@ -3578,7 +3679,7 @@ static inline void wrapReflectionProbeNode(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoOccluderNode = {-6885028590097645115, "OccluderNode",
+LuaUserDataTypeInfo luaUserDataTypeInfoOccluderNode = {-6187789785935092103, "OccluderNode",
 													   LuaUserData::computeSizeForGarbageCollected<OccluderNode>(),
 													   nullptr, nullptr};
 
@@ -3646,7 +3747,7 @@ static inline void wrapOccluderNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoDecalNode = {
-	1097508121406753350, "DecalNode", LuaUserData::computeSizeForGarbageCollected<DecalNode>(), nullptr, nullptr};
+	6982636593004043135, "DecalNode", LuaUserData::computeSizeForGarbageCollected<DecalNode>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<DecalNode>()
@@ -3712,7 +3813,7 @@ static inline void wrapDecalNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoTriggerNode = {
-	-3029786875306006141, "TriggerNode", LuaUserData::computeSizeForGarbageCollected<TriggerNode>(), nullptr, nullptr};
+	2512901559271188276, "TriggerNode", LuaUserData::computeSizeForGarbageCollected<TriggerNode>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<TriggerNode>()
@@ -3777,7 +3878,7 @@ static inline void wrapTriggerNode(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoFogDensityNode = {-2463430472135938886, "FogDensityNode",
+LuaUserDataTypeInfo luaUserDataTypeInfoFogDensityNode = {5130479292739784925, "FogDensityNode",
 														 LuaUserData::computeSizeForGarbageCollected<FogDensityNode>(),
 														 nullptr, nullptr};
 
@@ -3845,7 +3946,7 @@ static inline void wrapFogDensityNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoGlobalIlluminationProbeNode = {
-	7117765190519964845, "GlobalIlluminationProbeNode",
+	-8712129074094540189, "GlobalIlluminationProbeNode",
 	LuaUserData::computeSizeForGarbageCollected<GlobalIlluminationProbeNode>(), nullptr, nullptr};
 
 template<>
@@ -3912,7 +4013,7 @@ static inline void wrapGlobalIlluminationProbeNode(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoSceneGraph = {
-	-7754439619132389154, "SceneGraph", LuaUserData::computeSizeForGarbageCollected<SceneGraph>(), nullptr, nullptr};
+	8889763873203372334, "SceneGraph", LuaUserData::computeSizeForGarbageCollected<SceneGraph>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<SceneGraph>()
@@ -4862,7 +4963,7 @@ static inline void wrapSceneGraph(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoEvent = {1660689530604735101, "Event",
+LuaUserDataTypeInfo luaUserDataTypeInfoEvent = {2647322402732904700, "Event",
 												LuaUserData::computeSizeForGarbageCollected<Event>(), nullptr, nullptr};
 
 template<>
@@ -4931,7 +5032,7 @@ static inline void wrapEvent(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoLightEvent = {
-	840634010629725278, "LightEvent", LuaUserData::computeSizeForGarbageCollected<LightEvent>(), nullptr, nullptr};
+	2742841834679080733, "LightEvent", LuaUserData::computeSizeForGarbageCollected<LightEvent>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<LightEvent>()
@@ -5055,7 +5156,7 @@ static inline void wrapLightEvent(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoEventManager = {-6959305329499243407, "EventManager",
+LuaUserDataTypeInfo luaUserDataTypeInfoEventManager = {-3700681373112918438, "EventManager",
 													   LuaUserData::computeSizeForGarbageCollected<EventManager>(),
 													   nullptr, nullptr};
 

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

@@ -253,6 +253,16 @@ using WeakArraySceneNodePtr = WeakArray<SceneNode*>;
 						<arg>F32</arg>
 					</args>
 				</method>
+				<method name="setShadowCascadesDistancePower">
+					<args>
+						<arg>F32</arg>
+					</args>
+				</method>
+				<method name="setEffectiveShadowDistance">
+					<args>
+						<arg>F32</arg>
+					</args>
+				</method>
 			</methods>
 		</class>