Jelajahi Sumber

Spot light shadows functional

BearishSun 8 tahun lalu
induk
melakukan
f3033d55de

+ 2 - 1
Data/Raw/Engine/Shaders/ShadowDepthNormal.bsl

@@ -6,7 +6,8 @@ mixin ShadowDepth
 	{
 	{
 		float4 fsmain(ShadowVStoFS input, out float outDepth : SV_Depth) : SV_Target0
 		float4 fsmain(ShadowVStoFS input, out float outDepth : SV_Depth) : SV_Target0
 		{
 		{
-			outDepth = saturate(-input.shadowPos * gInvDepthRange + gDepthBias);
+			// Shadow position in clip space, plus bias, scaled to [0, 1] range
+			outDepth = saturate(input.shadowPos * gInvDepthRange + gDepthBias);
 			return 0;
 			return 0;
 		}
 		}
 	};
 	};

+ 4 - 1
Source/RenderBeast/Source/BsLightRendering.cpp

@@ -85,7 +85,10 @@ namespace bs { namespace ct
 
 
 		gPerLightParamDef.gLightGeometry.set(buffer, lightGeometry);
 		gPerLightParamDef.gLightGeometry.set(buffer, lightGeometry);
 
 
-		Matrix4 transform = Matrix4::TRS(internal->getPosition(), internal->getRotation(), Vector3::ONE);
+		Quaternion lightRotation(BsIdentity);
+		lightRotation.lookRotation(internal->getRotation().zAxis());
+
+		Matrix4 transform = Matrix4::TRS(internal->getPosition(), lightRotation, Vector3::ONE);
 		gPerLightParamDef.gMatConeTransform.set(buffer, transform);
 		gPerLightParamDef.gMatConeTransform.set(buffer, transform);
 	}
 	}
 
 

+ 22 - 16
Source/RenderBeast/Source/BsShadowRendering.cpp

@@ -111,7 +111,7 @@ namespace bs { namespace ct
 	template<bool Directional, bool ZFailStencil>
 	template<bool Directional, bool ZFailStencil>
 	void ShadowProjectStencilMat<Directional, ZFailStencil>::bind(const SPtr<GpuParamBlockBuffer>& perCamera)
 	void ShadowProjectStencilMat<Directional, ZFailStencil>::bind(const SPtr<GpuParamBlockBuffer>& perCamera)
 	{
 	{
-		Vector4 lightPosAndScale(0, 0, 0, 0); // Not used
+		Vector4 lightPosAndScale(0, 0, 0, 1);
 		gShadowProjectVertParamsDef.gPositionAndScale.set(mVertParams, lightPosAndScale);
 		gShadowProjectVertParamsDef.gPositionAndScale.set(mVertParams, lightPosAndScale);
 
 
 		mParamsSet->setParamBlockBuffer("PerCamera", perCamera);
 		mParamsSet->setParamBlockBuffer("PerCamera", perCamera);
@@ -220,8 +220,8 @@ namespace bs { namespace ct
 
 
 		Matrix4 shadowMapTfrm
 		Matrix4 shadowMapTfrm
 		(
 		(
-			shadowMapArea.width * 0.5f, 0, 0, shadowMapArea.x + 0.5f,
-			0, flipY * shadowMapArea.height * 0.5f, 0, shadowMapArea.y + 0.5f,
+			shadowMapArea.width * 0.5f, 0, 0, shadowMapArea.x + 0.5f * shadowMapArea.width,
+			0, flipY * shadowMapArea.height * 0.5f, 0, shadowMapArea.y + 0.5f * shadowMapArea.height,
 			0, 0, 1.0f / depthRange, 0,
 			0, 0, 1.0f / depthRange, 0,
 			0, 0, 0, 1
 			0, 0, 0, 1
 		);
 		);
@@ -232,7 +232,7 @@ namespace bs { namespace ct
 	template <int ShadowQuality, bool Directional, bool MSAA>
 	template <int ShadowQuality, bool Directional, bool MSAA>
 	void ShadowProjectMat<ShadowQuality, Directional, MSAA>::bind(const ShadowProjectParams& params)
 	void ShadowProjectMat<ShadowQuality, Directional, MSAA>::bind(const ShadowProjectParams& params)
 	{
 	{
-		Vector4 lightPosAndScale(params.light.getPosition(), params.light.getAttenuationRadius());
+		Vector4 lightPosAndScale(Vector3(0.0f, 0.0f, 0.0f), 1.0f);
 		gShadowProjectVertParamsDef.gPositionAndScale.set(mVertParams, lightPosAndScale);
 		gShadowProjectVertParamsDef.gPositionAndScale.set(mVertParams, lightPosAndScale);
 
 
 		TextureSurface surface;
 		TextureSurface surface;
@@ -387,7 +387,7 @@ namespace bs { namespace ct
 	}
 	}
 
 
 	ShadowMapAtlas::ShadowMapAtlas(UINT32 size)
 	ShadowMapAtlas::ShadowMapAtlas(UINT32 size)
-		:mLastUsedCounter(0)
+		: mLayout(0, 0, size, size, true), mLastUsedCounter(0)
 	{
 	{
 		mAtlas = GpuResourcePool::instance().get(
 		mAtlas = GpuResourcePool::instance().get(
 			POOLED_RENDER_TEXTURE_DESC::create2D(SHADOW_MAP_FORMAT, size, size, TU_DEPTHSTENCIL));
 			POOLED_RENDER_TEXTURE_DESC::create2D(SHADOW_MAP_FORMAT, size, size, TU_DEPTHSTENCIL));
@@ -1072,8 +1072,13 @@ namespace bs { namespace ct
 		mapInfo.depthRange = mapInfo.depthFar - mapInfo.depthNear;
 		mapInfo.depthRange = mapInfo.depthFar - mapInfo.depthNear;
 		mapInfo.depthBias = getDepthBias(*light, mapInfo.depthRange, options.mapSize);
 		mapInfo.depthBias = getDepthBias(*light, mapInfo.depthRange, options.mapSize);
 
 
-		Matrix4 view = Matrix4::view(light->getPosition(), light->getRotation());
+		Quaternion lightRotation(BsIdentity);
+		lightRotation.lookRotation(light->getRotation().zAxis());
+
+		Matrix4 view = Matrix4::view(light->getPosition(), lightRotation);
 		Matrix4 proj = Matrix4::projectionPerspective(light->getSpotAngle(), 1.0f, 0.05f, light->getAttenuationRadius());
 		Matrix4 proj = Matrix4::projectionPerspective(light->getSpotAngle(), 1.0f, 0.05f, light->getAttenuationRadius());
+
+		ConvexVolume localFrustum = ConvexVolume(proj);
 		RenderAPI::instance().convertProjectionMatrix(proj, proj);
 		RenderAPI::instance().convertProjectionMatrix(proj, proj);
 
 
 		mapInfo.shadowVPTransform = proj * view;
 		mapInfo.shadowVPTransform = proj * view;
@@ -1085,8 +1090,6 @@ namespace bs { namespace ct
 
 
 		mDepthNormalMat.bind(shadowParamsBuffer);
 		mDepthNormalMat.bind(shadowParamsBuffer);
 
 
-		ConvexVolume localFrustum = ConvexVolume(proj);
-
 		const Vector<Plane>& frustumPlanes = localFrustum.getPlanes();
 		const Vector<Plane>& frustumPlanes = localFrustum.getPlanes();
 		Matrix4 worldMatrix = view.transpose();
 		Matrix4 worldMatrix = view.transpose();
 
 
@@ -1584,9 +1587,9 @@ namespace bs { namespace ct
 
 
 	float ShadowRendering::getDepthBias(const Light& light, float depthRange, UINT32 mapSize)
 	float ShadowRendering::getDepthBias(const Light& light, float depthRange, UINT32 mapSize)
 	{
 	{
-		const static float RADIAL_LIGHT_BIAS = 0.05f;
-		const static float SPOT_DEPTH_BIAS = 1.0f;
-		const static float DIR_DEPTH_BIAS = 5.0f;
+		const static float RADIAL_LIGHT_BIAS = 0.005f;
+		const static float SPOT_DEPTH_BIAS = 0.1f;
+		const static float DIR_DEPTH_BIAS = 0.5f;
 		const static float DEFAULT_RESOLUTION = 512.0f;
 		const static float DEFAULT_RESOLUTION = 512.0f;
 		
 		
 		// Increase bias if map size smaller than some resolution
 		// Increase bias if map size smaller than some resolution
@@ -1597,8 +1600,12 @@ namespace bs { namespace ct
 		else
 		else
 			resolutionScale = DEFAULT_RESOLUTION / (float)mapSize;
 			resolutionScale = DEFAULT_RESOLUTION / (float)mapSize;
 
 
-		// Decrease bias with larger depth range
-		float rangeScale = 1.0f / depthRange;
+		// Adjust range because in shader we compare vs. clip space depth
+		float rangeScale;
+		if (light.getType() == LightType::Radial)
+			rangeScale = 1.0f;
+		else
+			rangeScale = 1.0f / depthRange;
 		
 		
 		float defaultBias = 1.0f;
 		float defaultBias = 1.0f;
 		switch(light.getType())
 		switch(light.getType())
@@ -1619,8 +1626,8 @@ namespace bs { namespace ct
 
 
 	float ShadowRendering::getFadeTransition(const Light& light, float depthRange, UINT32 mapSize)
 	float ShadowRendering::getFadeTransition(const Light& light, float depthRange, UINT32 mapSize)
 	{
 	{
-		const static float SPOT_LIGHT_SCALE = 1.0f / 50.0f;
-		const static float DIR_LIGHT_SCALE = 20.0f;
+		const static float SPOT_LIGHT_SCALE = 1000.0f;
+		const static float DIR_LIGHT_SCALE = 1000.0f;
 
 
 		// Note: Currently fade transitions are only used in spot & directional (non omni-directional) lights, so no need
 		// Note: Currently fade transitions are only used in spot & directional (non omni-directional) lights, so no need
 		// to account for radial light type.
 		// to account for radial light type.
@@ -1640,5 +1647,4 @@ namespace bs { namespace ct
 		else
 		else
 			return light.getShadowBias() * SPOT_LIGHT_SCALE;
 			return light.getShadowBias() * SPOT_LIGHT_SCALE;
 	}
 	}
-
 }}
 }}