Explorar o código

Tweaking extrapolated light probe mesh

BearishSun %!s(int64=8) %!d(string=hai) anos
pai
achega
4eadbc51fb

+ 13 - 45
Data/Raw/Engine/Shaders/IrradianceEvaluate.bsl

@@ -226,56 +226,24 @@ technique IrradianceEvaluate
 						float3 factors = mul(volume.transform, float4(P, 1.0f));			
 						float3 factors = mul(volume.transform, float4(P, 1.0f));			
 						coords = float4(factors, 1.0f - factors.x - factors.y - factors.z);
 						coords = float4(factors, 1.0f - factors.x - factors.y - factors.z);
 					}
 					}
+
+					SHVector3RGB shCoeffs;
+					SHZero(shCoeffs);
 					
 					
 					for(uint i = 0; i < 4; ++i)
 					for(uint i = 0; i < 4; ++i)
 					{
 					{
-						if(coords[i] == 0.0f)
-							continue;
-					
-						if(volume.indices[i] == 0)
-							irradiance += float3(1.0f, 0, 0) * coords[i];
-					
-						if(volume.indices[i] == 1)
-							irradiance += float3(0.0f, 1.0f, 0) * coords[i];
-							
-						if(volume.indices[i] == 2)
-							irradiance += float3(1.0f, 1.0f, 1.0f) * coords[i];
-							
-						if(volume.indices[i] == 3)
-							irradiance += float3(1.0f, 1.0f, 1.0f) * coords[i];
-					
-						if(volume.indices[i] == 4)
-							irradiance += float3(0.0f, 1.0f, 1.0f) * coords[i];
-							
-						if(volume.indices[i] == 5)
-							irradiance += float3(1.0f, 1.0f, 0.0f) * coords[i];
-							
-						if(volume.indices[i] == 6)
-							irradiance += float3(1.0f, 1.0f, 1.0f) * coords[i];
-							
-						if(volume.indices[i] == 7)
-							irradiance += float3(1.0f, 1.0f, 1.0f) * coords[i];
-					}					
-					
-					//SHVector3RGB shCoeffs;
-					//SHZero(shCoeffs);
-					
-					//for(uint i = 0; i < 4; ++i)
-					//{
-					//	if(coords[i] > 0.0f)
-					//		SHMultiplyAdd(shCoeffs, gSHCoeffs[volume.indices[i]], coords[i]);
-					//}
-					
-					//SHVector3 shBasis = SHBasis3(surfaceData.worldNormal);
-					//SHMultiply(shCoeffs.R, shBasis);
-					//SHMultiply(shCoeffs.G, shBasis);
-					//SHMultiply(shCoeffs.B, shBasis);
+						if(coords[i] > 0.0f)
+							SHMultiplyAdd(shCoeffs, gSHCoeffs[volume.indices[i]], coords[i]);
+					}
 					
 					
-					//irradiance.r = evaluate(shCoeffs.R);
-					//irradiance.g = evaluate(shCoeffs.G);
-					//irradiance.b = evaluate(shCoeffs.B);
+					SHVector3 shBasis = SHBasis3(surfaceData.worldNormal);
+					SHMultiply(shCoeffs.R, shBasis);
+					SHMultiply(shCoeffs.G, shBasis);
+					SHMultiply(shCoeffs.B, shBasis);
 					
 					
-					//irradiance *= float3(10.0f, 0.0f, 0.0f);
+					irradiance.r = evaluateLambert(shCoeffs.R);
+					irradiance.g = evaluateLambert(shCoeffs.G);
+					irradiance.b = evaluateLambert(shCoeffs.B);
 				}
 				}
 			#endif // SKY_ONLY
 			#endif // SKY_ONLY
 			
 			

+ 123 - 28
Source/RenderBeast/Source/BsLightProbes.cpp

@@ -199,6 +199,19 @@ namespace bs { namespace ct
 		}
 		}
 	}
 	}
 
 
+	/** Hash value generator for std::pair<INT32, INT32>. */
+	struct pair_hash
+	{
+		size_t operator()(const std::pair<INT32, INT32>& key) const
+		{
+			size_t hash = 0;
+			bs::hash_combine(hash, key.first);
+			bs::hash_combine(hash, key.second);
+
+			return hash;
+		}
+	};
+
 	/** Information about a single tetrahedron, for use on the GPU. */
 	/** Information about a single tetrahedron, for use on the GPU. */
 	struct TetrahedronDataGPU
 	struct TetrahedronDataGPU
 	{
 	{
@@ -371,7 +384,6 @@ namespace bs { namespace ct
 
 
 		// Insert inner tetrahedron triangles
 		// Insert inner tetrahedron triangles
 		UINT32 tetIdx = 0;
 		UINT32 tetIdx = 0;
-		UINT32 triIdx = 0;
 		for (UINT32 i = 0; i < (UINT32)mTetrahedronInfos.size(); i++)
 		for (UINT32 i = 0; i < (UINT32)mTetrahedronInfos.size(); i++)
 		{
 		{
 			if (!validTets[i])
 			if (!validTets[i])
@@ -420,13 +432,55 @@ namespace bs { namespace ct
 				indices[2] = tetIdx * 4 * 3 + j * 3 + 2;
 				indices[2] = tetIdx * 4 * 3 + j * 3 + 2;
 
 
 				indices += 3;
 				indices += 3;
-				triIdx++;
 			}
 			}
 
 
 			tetIdx++;
 			tetIdx++;
 		}
 		}
 
 
-		// Generate triangles for extruded outer faces
+		// Generate an edge map for outer faces (required for step below)
+		struct Edge
+		{
+			UINT32 vertInner[2];
+			UINT32 vertOuter[2];
+			UINT32 face[2];
+		};
+
+		FrameUnorderedMap<std::pair<INT32, INT32>, Edge, pair_hash> edgeMap;
+		for(UINT32 i = 0; i < (UINT32)outerFaces.size(); i++)
+		{
+			if (!validTets[outerFaces[i].tetrahedron])
+				continue;
+
+			for (UINT32 j = 0; j < 3; ++j)
+			{
+				UINT32 v0 = outerFaces[i].innerVertices[j];
+				UINT32 v1 = outerFaces[i].innerVertices[(j + 1) % 3];
+
+				// Keep the same ordering so other faces can find the same edge
+				if (v0 > v1)
+					std::swap(v0, v1);
+
+				auto iterFind = edgeMap.find(std::make_pair((INT32)v0, (INT32)v1));
+				if (iterFind != edgeMap.end())
+				{
+					iterFind->second.face[1] = i;
+				}
+				else
+				{
+					Edge edge;
+					edge.vertInner[0] = outerFaces[i].innerVertices[j];
+					edge.vertInner[1] = outerFaces[i].innerVertices[(j + 1) % 3];
+					edge.vertOuter[0] = outerFaces[i].outerVertices[j];
+					edge.vertOuter[1] = outerFaces[i].outerVertices[(j + 1) % 3];
+					edge.face[0] = i;
+					edge.face[1] = -1;
+
+					edgeMap.insert(std::make_pair(std::make_pair((INT32)v0, (INT32)v1), edge));
+				}
+			}
+		}
+
+		// Generate front and back triangles for extruded outer faces
 		UINT32 faceIdx = 0;
 		UINT32 faceIdx = 0;
 		for(UINT32 i = 0; i < (UINT32)outerFaces.size(); i++)
 		for(UINT32 i = 0; i < (UINT32)outerFaces.size(); i++)
 		{
 		{
@@ -435,13 +489,7 @@ namespace bs { namespace ct
 
 
 			const TetrahedronFaceData& entry = outerFaces[i];
 			const TetrahedronFaceData& entry = outerFaces[i];
 
 
-			static const UINT32 Permutations[8][3] = 
-			{
-				{0, 1, 2 }, { 3, 4, 5},
-				{0, 1, 3 }, { 1, 3, 4},
-				{1, 2, 4 }, { 2, 4, 5},
-				{2, 0, 5 }, { 0, 5, 3}
-			};
+			static const UINT32 Permutations[2][3] = { {0, 1, 2 }, { 3, 4, 5} };
 
 
 			// Make sure the triangle is clockwise, facing away from the center
 			// Make sure the triangle is clockwise, facing away from the center
 			Vector3 center(BsZero);
 			Vector3 center(BsZero);
@@ -453,7 +501,7 @@ namespace bs { namespace ct
 
 
 			center /= 6.0f;
 			center /= 6.0f;
 
 
-			for(UINT32 j = 0; j < 8; ++j)
+			for(UINT32 j = 0; j < 2; ++j)
 			{
 			{
 				UINT32 idxA = Permutations[j][0];
 				UINT32 idxA = Permutations[j][0];
 				UINT32 idxB = Permutations[j][1];
 				UINT32 idxB = Permutations[j][1];
@@ -482,17 +530,77 @@ namespace bs { namespace ct
 				idIter.addValue(tetIdx + faceIdx);
 				idIter.addValue(tetIdx + faceIdx);
 				idIter.addValue(tetIdx + faceIdx);
 				idIter.addValue(tetIdx + faceIdx);
 
 
-				indices[0] = tetIdx * 4 * 3 + faceIdx * 8 * 3 + j * 3 + 0;
-				indices[1] = tetIdx * 4 * 3 + faceIdx * 8 * 3 + j * 3 + 1;
-				indices[2] = tetIdx * 4 * 3 + faceIdx * 8 * 3 + j * 3 + 2;
+				indices[0] = tetIdx * 4 * 3 + faceIdx * 2 * 3 + j * 3 + 0;
+				indices[1] = tetIdx * 4 * 3 + faceIdx * 2 * 3 + j * 3 + 1;
+				indices[2] = tetIdx * 4 * 3 + faceIdx * 2 * 3 + j * 3 + 2;
 
 
 				indices += 3;
 				indices += 3;
-				triIdx++;
 			}
 			}
 
 
 			faceIdx++;
 			faceIdx++;
 		}
 		}
 
 
+		// Generate sides for extruded outer faces
+		UINT32 sideIdx = 0;
+		for(auto& entry : edgeMap)
+		{
+			const Edge& edge = entry.second;
+
+			for (UINT32 i = 0; i < 2; i++)
+			{
+				const TetrahedronFaceData& face = outerFaces[edge.face[i]];
+
+				// Make sure the triangle is clockwise, facing away from the center
+				Vector3 center(BsZero);
+				for (UINT32 k = 0; k < 3; k++)
+				{
+					center += mTempTetrahedronPositions[face.innerVertices[k]];
+					center += mTempTetrahedronPositions[face.outerVertices[k]];
+				}
+
+				center /= 6.0f;
+
+				static const UINT32 Permutations[2][3] = { {0, 1, 2 }, { 1, 2, 3} };
+				for(UINT32 j = 0; j < 2; ++j)
+				{
+					UINT32 idxA = Permutations[j][0];
+					UINT32 idxB = Permutations[j][1];
+					UINT32 idxC = Permutations[j][2];
+
+					idxA = idxA > 1 ? edge.vertOuter[idxA - 2] : edge.vertInner[idxA];
+					idxB = idxB > 1 ? edge.vertOuter[idxB - 2] : edge.vertInner[idxB];
+					idxC = idxC > 1 ? edge.vertOuter[idxC - 2] : edge.vertInner[idxC];
+					
+					Vector3 A = mTempTetrahedronPositions[idxA];
+					Vector3 B = mTempTetrahedronPositions[idxB];
+					Vector3 C = mTempTetrahedronPositions[idxC];
+
+					Vector3 e0 = A - C;
+					Vector3 e1 = B - C;
+
+					Vector3 normal = e0.cross(e1);
+					if (normal.dot(A - center) > 0.0f)
+						std::swap(A, B);
+
+					posIter.addValue(A);
+					posIter.addValue(B);
+					posIter.addValue(C);
+
+					idIter.addValue(tetIdx + edge.face[i]);
+					idIter.addValue(tetIdx + edge.face[i]);
+					idIter.addValue(tetIdx + edge.face[i]);
+
+					indices[0] = tetIdx * 4 * 3 + faceIdx * 2 * 3 + sideIdx * 2 * 3 + j * 3 + 0;
+					indices[1] = tetIdx * 4 * 3 + faceIdx * 2 * 3 + sideIdx * 2 * 3 + j * 3 + 1;
+					indices[2] = tetIdx * 4 * 3 + faceIdx * 2 * 3 + sideIdx * 2 * 3 + j * 3 + 2;
+
+					indices += 3;
+				}
+
+				sideIdx++;
+			}
+		}
+
 		// Generate "caps" on the end of the extruded volume
 		// Generate "caps" on the end of the extruded volume
 		UINT32 capIdx = 0;
 		UINT32 capIdx = 0;
 		for(UINT32 i = 0; i < (UINT32)outerFaces.size(); i++)
 		for(UINT32 i = 0; i < (UINT32)outerFaces.size(); i++)
@@ -688,19 +796,6 @@ namespace bs { namespace ct
 		mMaxCoefficients = count;
 		mMaxCoefficients = count;
 	}
 	}
 
 
-	/** Hash value generator for std::pair<INT32, INT32>. */
-	struct pair_hash
-	{
-		size_t operator()(const std::pair<INT32, INT32>& key) const
-		{
-			size_t hash = 0;
-			bs::hash_combine(hash, key.first);
-			bs::hash_combine(hash, key.second);
-
-			return hash;
-		}
-	};
-
 	void LightProbes::generateTetrahedronData(Vector<Vector3>& positions, Vector<TetrahedronData>& tetrahedra,
 	void LightProbes::generateTetrahedronData(Vector<Vector3>& positions, Vector<TetrahedronData>& tetrahedra,
 		Vector<TetrahedronFaceData>& faces,	bool generateExtrapolationVolume)
 		Vector<TetrahedronFaceData>& faces,	bool generateExtrapolationVolume)
 	{
 	{