Prechádzať zdrojové kódy

WIP: Reflection probes

BearishSun 8 rokov pred
rodič
commit
c84917e7e1

+ 1 - 1
Data/Raw/Engine/Includes/ImageBasedLighting.bslinc

@@ -94,7 +94,7 @@ mixin ImageBasedLighting
 		
 		float3 getLookupForBoxProxy(float3 originWS, float3 dirWS, float3 centerWS, float3 extents, float4x4 invBoxTransform, float transitionDistance, out float contribution)
 		{
-			// Transform origin and direction into box local space, where it is united sized and axis aligned
+			// Transform origin and direction into box local space, where it is unit sized and axis aligned
 			float3 originLS = mul(invBoxTransform, float4(originWS, 1)).xyz;
 			float3 dirLS = mul(invBoxTransform, float4(dirWS, 0)).xyz;
 			

+ 10 - 11
Data/Raw/Engine/Shaders/TiledDeferredImageBasedLighting.bsl

@@ -80,15 +80,15 @@ technique TiledDeferredImageBasedLighting
 			
 			GroupMemoryBarrierWithGroupSync();
 			
-			minTileZ = asfloat(sTileMinZ);
-			maxTileZ = asfloat(sTileMaxZ);
+			minTileZ = -asfloat(sTileMinZ);
+			maxTileZ = -asfloat(sTileMaxZ);
 		}
 		
 		void calcTileAABB(uint2 tileId, float viewZMin, float viewZMax, out float3 center, out float3 extent)
 		{
 			uint2 pixelPos = tileId * TILE_SIZE;
 		
-			// Convert threat XY coordinates to NDC coordinates
+			// Convert thread XY coordinates to NDC coordinates
 			float2 uvTopLeft = (pixelPos + 0.5f) / gFramebufferSize;
 			float2 uvBottomRight = (pixelPos + uint2(TILE_SIZE, TILE_SIZE) - 0.5f) / gFramebufferSize;
 		
@@ -104,9 +104,8 @@ technique TiledDeferredImageBasedLighting
 			ndcMin.y *= flipY;
 			ndcMax.y *= flipY;
 		
-			// Camera is looking along negative z, therefore min in view space is max in NDC
-			ndcMin.z = convertToNDCZ(viewZMax);
-			ndcMax.z = convertToNDCZ(viewZMin);
+			ndcMin.z = convertToNDCZ(viewZMin);
+			ndcMax.z = convertToNDCZ(viewZMax);
 		
 			float4 corner[5];
 			// Far
@@ -165,7 +164,7 @@ technique TiledDeferredImageBasedLighting
 			#endif				
 			
 			float ao = gAmbientOcclusionTex.Load(int3(pixelPos.xy, 0));
-			float4 ssr = gSSRTex.Load(int3(pixelPos.xy, 0));
+			float4 ssr = 0;//gSSRTex.Load(int3(pixelPos.xy, 0));
 			float3 imageBasedSpecular = getImageBasedSpecular(worldPosition, V, specR, surfaceData, ao, ssr, probeOffset, numProbes);
 
 			float4 totalLighting = existingColor;
@@ -210,7 +209,7 @@ technique TiledDeferredImageBasedLighting
 			calcTileAABB(groupId.xy, minTileZ, maxTileZ, center, extent);
 							
 			// Find probes overlapping the tile
-			for (uint i = 0; i < gNumProbes && i < MAX_LIGHTS; i += TILE_SIZE)
+			for (uint i = threadIndex; i < gNumProbes && i < MAX_LIGHTS; i += TILE_SIZE)
 			{
 				float4 probePosition = mul(gMatView, float4(gReflectionProbes[i].position, 1.0f));
 				float probeRadius = gReflectionProbes[i].radius;
@@ -254,7 +253,7 @@ technique TiledDeferredImageBasedLighting
 			if (all(dispatchThreadId.xy < viewportMax))
 			{
 				#if MSAA_COUNT > 1
-				float4 lighting = getLighting(pixelPos, 0, clipSpacePos.xy, surfaceData[0], 0, gNumProbes);
+				float4 lighting = getLighting(pixelPos, 0, clipSpacePos.xy, surfaceData[0], 0, sNumProbes);
 				writeBufferSample(pixelPos, 0, lighting);
 
 				bool doPerSampleShading = needsPerSampleShading(surfaceData);
@@ -263,7 +262,7 @@ technique TiledDeferredImageBasedLighting
 					[unroll]
 					for(uint i = 1; i < MSAA_COUNT; ++i)
 					{
-						lighting = getLighting(pixelPos, i, clipSpacePos.xy, surfaceData[i], 0, gNumProbes);
+						lighting = getLighting(pixelPos, i, clipSpacePos.xy, surfaceData[i], 0, sNumProbes);
 						writeBufferSample(pixelPos, i, lighting);
 					}
 				}
@@ -275,7 +274,7 @@ technique TiledDeferredImageBasedLighting
 				}
 				
 				#else
-				float4 lighting = getLighting(pixelPos, 0, clipSpacePos.xy, surfaceData[0], 0, gNumProbes);
+				float4 lighting = getLighting(pixelPos, 0, clipSpacePos.xy, surfaceData[0], 0, sNumProbes);
 				gOutput[pixelPos] = lighting;
 				#endif
 			}

+ 8 - 7
Source/BansheeUtility/Math/BsMatrix4.cpp

@@ -339,7 +339,7 @@ namespace bs
 		return Matrix4(mat);
 	}
 
-	Matrix4 Matrix4::projectionPerspective(const Degree& horzFOV, float aspect, float near, float far)
+	Matrix4 Matrix4::projectionPerspective(const Degree& horzFOV, float aspect, float near, float far, bool positiveZ)
 	{
 		// Note: Duplicate code in Camera, bring it all here eventually
 		static constexpr float INFINITE_FAR_PLANE_ADJUST = 0.00001f;
@@ -365,6 +365,7 @@ namespace bs
 		float C = (right + left) * inv_w;
 		float D = (top + bottom) * inv_h;
 		float q, qn;
+		float sign = positiveZ ? 1.0f : -1.0f;
 
 		if (far == 0)
 		{
@@ -374,15 +375,15 @@ namespace bs
 		}
 		else
 		{
-			q = -(far + near) * inv_d;
-			qn = -2 * (far * near) * inv_d;
+			q = sign * (far + near) * inv_d;
+			qn = -2.0f * (far * near) * inv_d;
 		}
 
 		Matrix4 mat;
-		mat[0][0] = A;		mat[0][1] = 0.0f;	mat[0][2] = C;	mat[0][3] = 0.0f;
-		mat[1][0] = 0.0f;	mat[1][1] = B;		mat[1][2] = D;	mat[1][3] = 0.0f;
-		mat[2][0] = 0.0f;	mat[2][1] = 0.0f;	mat[2][2] = q;	mat[2][3] = qn;
-		mat[3][0] = 0.0f;	mat[3][1] = 0.0f;	mat[3][2] = -1;	mat[3][3] = 0.0f;
+		mat[0][0] = A;		mat[0][1] = 0.0f;	mat[0][2] = C;		mat[0][3] = 0.0f;
+		mat[1][0] = 0.0f;	mat[1][1] = B;		mat[1][2] = D;		mat[1][3] = 0.0f;
+		mat[2][0] = 0.0f;	mat[2][1] = 0.0f;	mat[2][2] = q;		mat[2][3] = qn;
+		mat[3][0] = 0.0f;	mat[3][1] = 0.0f;	mat[3][2] = sign;	mat[3][3] = 0.0f;
 
 		return mat;
 	}

+ 12 - 2
Source/BansheeUtility/Math/BsMatrix4.h

@@ -458,8 +458,18 @@ namespace bs
 		/** Creates a 4x4 transformation matrix that performs rotation. */
 		static Matrix4 rotation(const Quaternion& rotation);
 
-		/** Creates a 4x4 perspective projection matrix. */
-		static Matrix4 projectionPerspective(const Degree& horzFOV, float aspect, float near, float far);
+		/** 
+		 * Creates a 4x4 perspective projection matrix. 
+		 * 
+		 * @param[in]	horzFOV		Horizontal field of view.
+		 * @param[in]	aspect		Aspect ratio. Determines the vertical field of view.
+		 * @param[in]	near		Distance to the near plane.
+		 * @param[in]	far			Distance to the far plane.
+		 * @param[in]	positiveZ	If true the matrix will project geometry as if its looking along the positive Z axis.
+		 *							Otherwise it projects along the negative Z axis (default).
+		 */
+		static Matrix4 projectionPerspective(const Degree& horzFOV, float aspect, float near, float far, 
+			bool positiveZ = false);
 
 		/** @copydoc makeProjectionOrtho() */
 		static Matrix4 projectionOrthographic(float left, float right, float top, float bottom, float near, float far);

+ 14 - 9
Source/RenderBeast/BsRenderBeast.cpp

@@ -572,7 +572,7 @@ namespace bs { namespace ct
 		viewDesc.visibleLayers = 0xFFFFFFFFFFFFFFFF;
 		viewDesc.nearPlane = 0.5f;
 		viewDesc.farPlane = 1000.0f;
-		viewDesc.flipView = RenderAPI::instance().getAPIInfo().isFlagSet(RenderAPIFeatureFlag::UVYAxisUp);
+		viewDesc.flipView = !RenderAPI::instance().getAPIInfo().isFlagSet(RenderAPIFeatureFlag::UVYAxisUp);
 
 		viewDesc.viewOrigin = position;
 		viewDesc.projTransform = projTransform;
@@ -590,22 +590,25 @@ namespace bs { namespace ct
 
 		Matrix4 viewOffsetMat = Matrix4::translation(-position);
 
+		// Note: We render upside down, then flip the image vertically, which results in a horizontal flip. The horizontal
+		// flip is required due to the fact how cubemap faces are defined. Another option would be to change the view
+		// orientation matrix, but that also requires a culling mode flip which is inconvenient to do globally.
 		RendererView views[6];
 		for(UINT32 i = 0; i < 6; i++)
 		{
 			// Calculate view matrix
-			Matrix3 viewRotationMat;
 			Vector3 forward;
-
 			Vector3 up = Vector3::UNIT_Y;
 
 			switch (i)
 			{
 			case CF_PositiveX:
-				forward = Vector3::UNIT_X;
+				forward = -Vector3::UNIT_X;
+				up = -Vector3::UNIT_Y;
 				break;
 			case CF_NegativeX:
-				forward = -Vector3::UNIT_X;
+				forward = Vector3::UNIT_X;
+				up = -Vector3::UNIT_Y;
 				break;
 			case CF_PositiveY:
 				forward = Vector3::UNIT_Y;
@@ -616,17 +619,19 @@ namespace bs { namespace ct
 				up = Vector3::UNIT_Z;
 				break;
 			case CF_PositiveZ:
-				forward = Vector3::UNIT_Z;
+				forward = -Vector3::UNIT_Z;
+				up = -Vector3::UNIT_Y;
 				break;
 			case CF_NegativeZ:
-				forward = -Vector3::UNIT_Z;
+				forward = Vector3::UNIT_Z;
+				up = -Vector3::UNIT_Y;
 				break;
 			}
 
 			Vector3 right = Vector3::cross(up, forward);
-			viewRotationMat = Matrix3(right, up, forward);
+			Matrix3 viewRotationMat = Matrix3(right, up, forward);
 
-			viewDesc.viewDirection = forward;
+			viewDesc.viewDirection = -forward;
 			viewDesc.viewTransform = Matrix4(viewRotationMat) * viewOffsetMat;
 
 			// Calculate world frustum for culling

+ 2 - 2
Source/RenderBeast/BsRendererScene.cpp

@@ -457,8 +457,8 @@ namespace bs {	namespace ct
 		}
 
 		// Last element is the one we want to erase
-		mInfo.radialLights.erase(mInfo.radialLights.end() - 1);
-		mInfo.radialLightWorldBounds.erase(mInfo.radialLightWorldBounds.end() - 1);
+		mInfo.reflProbes.erase(mInfo.reflProbes.end() - 1);
+		mInfo.reflProbeWorldBounds.erase(mInfo.reflProbeWorldBounds.end() - 1);
 	}
 
 	void RendererScene::setReflectionProbeArrayIndex(UINT32 probeIdx, UINT32 arrayIdx, bool markAsClean)

+ 1 - 1
Source/RenderBeast/BsRendererView.cpp

@@ -51,7 +51,7 @@ namespace bs { namespace ct
 
 	void SkyboxMat::setParams(const SPtr<Texture>& texture, const Color& solidColor)
 	{
-		mSkyTextureParam.set(texture, TextureSurface(1, 1, 0, 0));
+		mSkyTextureParam.set(texture, TextureSurface(0, 1, 0, 0));
 
 		gSkyboxParamDef.gClearColor.set(mParamBuffer, solidColor);
 		mParamBuffer->flushToGPU();