Explorar o código

Fixing cylindrical/spherical environment map import

BearishSun %!s(int64=9) %!d(string=hai) anos
pai
achega
ddf6204f9e

+ 1 - 1
Source/BansheeCore/Source/BsPixelData.cpp

@@ -114,7 +114,7 @@ namespace bs
 			INT32 x1 = Math::clamp(x + 1, 0U, (UINT32)maxExtentX);
 			INT32 x1 = Math::clamp(x + 1, 0U, (UINT32)maxExtentX);
 			INT32 y1 = Math::clamp(y + 1, 0U, (UINT32)maxExtentY);
 			INT32 y1 = Math::clamp(y + 1, 0U, (UINT32)maxExtentY);
 
 
-			Color color;
+			Color color = Color::ZERO;
 			color += (1.0f - fracX) * (1.0f - fracY) * getColorAt(x, y);
 			color += (1.0f - fracX) * (1.0f - fracY) * getColorAt(x, y);
 			color += fracX * (1.0f - fracY) * getColorAt(x1, y);
 			color += fracX * (1.0f - fracY) * getColorAt(x1, y);
 			color += (1.0f - fracX) * fracY * getColorAt(x, y1);
 			color += (1.0f - fracX) * fracY * getColorAt(x, y1);

+ 34 - 21
Source/BansheeFreeImgImporter/Source/BsFreeImgImporter.cpp

@@ -463,27 +463,28 @@ namespace bs
 	/** Method that maps a direction to a point on a plane in range [0, 1] using spherical mapping. */
 	/** Method that maps a direction to a point on a plane in range [0, 1] using spherical mapping. */
 	Vector2 mapCubemapDirToSpherical(const Vector3& dir)
 	Vector2 mapCubemapDirToSpherical(const Vector3& dir)
 	{
 	{
+		// Using the OpenGL spherical mapping formula
 		Vector3 nrmDir = Vector3::normalize(dir);
 		Vector3 nrmDir = Vector3::normalize(dir);
+		nrmDir.z += 1.0f;
 
 
-		float u = acos(Math::abs(nrmDir.z)) / Math::PI;
-		if (nrmDir.x > 0.0f)
-			u = 1.0f - u;
+		float m = 2 * nrmDir.length();
 
 
-		float v = 1.0f - acos(nrmDir.y) / Math::PI;
+		float u = nrmDir.x / m + 0.5f;
+		float v = nrmDir.y / m + 0.5f;
 
 
 		return Vector2(u, v);
 		return Vector2(u, v);
 	}
 	}
 
 
-	/** Method that maps a direction to a point on a plane in range [0, 1] using cylindrical mapping. */
+	/** 
+	 * Method that maps a direction to a point on a plane in range [0, 1] using cylindrical mapping. This mapping is also
+	 * know as longitude-latitude mapping, Blinn/Newell mapping or equirectangular cylindrical mapping. 
+	 */
 	Vector2 mapCubemapDirToCylindrical(const Vector3& dir)
 	Vector2 mapCubemapDirToCylindrical(const Vector3& dir)
 	{
 	{
 		Vector3 nrmDir = Vector3::normalize(dir);
 		Vector3 nrmDir = Vector3::normalize(dir);
 
 
-		float u = 0.75f - atan2(nrmDir.z, nrmDir.x) / Math::HALF_PI;
-		if (u > 1.0f)
-			u -= 1.0f;
-
-		float v = 1.0f - acos(nrmDir.y) / Math::PI;
+		float u = (atan2(nrmDir.z, nrmDir.x) + Math::PI) / Math::TWO_PI;
+		float v = acos(nrmDir.y) / Math::PI;
 
 
 		return Vector2(u, v);
 		return Vector2(u, v);
 	}
 	}
@@ -521,8 +522,8 @@ namespace bs
 		{
 		{
 			{ 2, 1, 0, {  1.0f, -1.0f,  1.0f }}, // X+
 			{ 2, 1, 0, {  1.0f, -1.0f,  1.0f }}, // X+
 			{ 2, 1, 0, { -1.0f, -1.0f, -1.0f }}, // X-
 			{ 2, 1, 0, { -1.0f, -1.0f, -1.0f }}, // X-
-			{ 0, 2, 1, { -1.0f,  1.0f, -1.0f }}, // Y+
-			{ 0, 2, 1, { -1.0f, -1.0f,  1.0f }}, // Y-
+			{ 0, 2, 1, {  1.0f, -1.0f,  1.0f }}, // Y+
+			{ 0, 2, 1, {  1.0f,  1.0f, -1.0f }}, // Y-
 			{ 0, 1, 2, {  1.0f, -1.0f, -1.0f }}, // Z+
 			{ 0, 1, 2, {  1.0f, -1.0f, -1.0f }}, // Z+
 			{ 0, 1, 2, { -1.0f, -1.0f,  1.0f }}  // Z-
 			{ 0, 1, 2, { -1.0f, -1.0f,  1.0f }}  // Z-
 		};
 		};
@@ -541,14 +542,14 @@ namespace bs
 					Vector2 sourceCoord = (Vector2((float)x, (float)y) * invSize) * 2.0f - Vector2(1.0f, 1.0f);
 					Vector2 sourceCoord = (Vector2((float)x, (float)y) * invSize) * 2.0f - Vector2(1.0f, 1.0f);
 					Vector3 direction = Vector3(sourceCoord.x, sourceCoord.y, 1.0f);
 					Vector3 direction = Vector3(sourceCoord.x, sourceCoord.y, 1.0f);
 
 
+					direction *= remapInfo.sign;
+
 					// Rotate towards current face
 					// Rotate towards current face
 					Vector3 rotatedDir;
 					Vector3 rotatedDir;
 					rotatedDir[remapInfo.idx[0]] = direction.x;
 					rotatedDir[remapInfo.idx[0]] = direction.x;
 					rotatedDir[remapInfo.idx[1]] = direction.y;
 					rotatedDir[remapInfo.idx[1]] = direction.y;
 					rotatedDir[remapInfo.idx[2]] = direction.z;
 					rotatedDir[remapInfo.idx[2]] = direction.z;
 
 
-					rotatedDir *= remapInfo.sign;
-
 					// Find location in the source to sample from
 					// Find location in the source to sample from
 					Vector2 sourceUV = remap(rotatedDir);
 					Vector2 sourceUV = remap(rotatedDir);
 					Color color = source->sampleColorAt(sourceUV);
 					Color color = source->sampleColorAt(sourceUV);
@@ -563,6 +564,9 @@ namespace bs
 	bool FreeImgImporter::generateCubemap(const SPtr<PixelData>& source, CubemapSourceType sourceType,
 	bool FreeImgImporter::generateCubemap(const SPtr<PixelData>& source, CubemapSourceType sourceType,
 						 std::array<SPtr<PixelData>, 6>& output)
 						 std::array<SPtr<PixelData>, 6>& output)
 	{
 	{
+		// Note: Expose this as a parameter if needed:
+		UINT32 cubemapSupersampling = 1; // Set to amount of samples
+
 		Vector2I faceSize;
 		Vector2I faceSize;
 		bool cross = false;
 		bool cross = false;
 		bool vertical = false;
 		bool vertical = false;
@@ -613,9 +617,6 @@ namespace bs
 			// Don't allow sizes larger than 4096
 			// Don't allow sizes larger than 4096
 			faceSize.x = std::min(faceSize.x, 4096);
 			faceSize.x = std::min(faceSize.x, 4096);
 
 
-			// We also do 4x super-sampling, so increase size accordingly
-			faceSize.x *= 4;
-
 			faceSize.y = faceSize.x;
 			faceSize.y = faceSize.x;
 
 
 			break;
 			break;
@@ -649,16 +650,28 @@ namespace bs
 		break;
 		break;
 		case CubemapSourceType::Cylindrical:
 		case CubemapSourceType::Cylindrical:
 		{			
 		{			
+			UINT32 superSampledFaceSize = faceSize.x * cubemapSupersampling;
+
 			std::array<SPtr<PixelData>, 6> superSampledOutput;
 			std::array<SPtr<PixelData>, 6> superSampledOutput;
-			readCubemapUVRemap(source, superSampledOutput, faceSize.x, &mapCubemapDirToCylindrical);
-			downsampleCubemap(superSampledOutput, output, faceSize.x / 4);
+			readCubemapUVRemap(source, superSampledOutput, superSampledFaceSize, &mapCubemapDirToCylindrical);
+
+			if (faceSize.x != superSampledFaceSize)
+				downsampleCubemap(superSampledOutput, output, faceSize.x);
+			else
+				output = superSampledOutput;
 		}
 		}
 		break;
 		break;
 		case CubemapSourceType::Spherical:
 		case CubemapSourceType::Spherical:
 		{
 		{
+			UINT32 superSampledFaceSize = faceSize.x * cubemapSupersampling;
+
 			std::array<SPtr<PixelData>, 6> superSampledOutput;
 			std::array<SPtr<PixelData>, 6> superSampledOutput;
-			readCubemapUVRemap(source, superSampledOutput, faceSize.x, &mapCubemapDirToSpherical);
-			downsampleCubemap(superSampledOutput, output, faceSize.x / 4);
+			readCubemapUVRemap(source, superSampledOutput, superSampledFaceSize, &mapCubemapDirToSpherical);
+
+			if (faceSize.x != superSampledFaceSize)
+				downsampleCubemap(superSampledOutput, output, faceSize.x);
+			else
+				output = superSampledOutput;
 		}
 		}
 		break;
 		break;
 		default: // Single-image
 		default: // Single-image

+ 4 - 4
Source/BansheeUtility/Source/BsTimer.cpp

@@ -22,17 +22,17 @@ namespace bs
 	UINT64 Timer::getMilliseconds() const
 	UINT64 Timer::getMilliseconds() const
 	{
 	{
 		auto newTime = mHRClock.now();
 		auto newTime = mHRClock.now();
-		nanoseconds newTimeNs = newTime.time_since_epoch();
+		duration<double> dur = newTime - mStartTime;
 
 
-		return duration_cast<milliseconds>(newTimeNs).count();
+		return duration_cast<milliseconds>(dur).count();
 	}
 	}
 
 
 	UINT64 Timer::getMicroseconds() const
 	UINT64 Timer::getMicroseconds() const
 	{
 	{
 		auto newTime = mHRClock.now();
 		auto newTime = mHRClock.now();
-		nanoseconds newTimeNs = newTime.time_since_epoch();
+		duration<double> dur = newTime - mStartTime;
 
 
-		return duration_cast<microseconds>(newTimeNs).count();
+		return duration_cast<microseconds>(dur).count();
 	}
 	}
 
 
 	UINT64 Timer::getStartMs() const
 	UINT64 Timer::getStartMs() const

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

@@ -609,7 +609,10 @@ namespace bs
 
 
 		// Present render targets with back buffers
 		// Present render targets with back buffers
 		for (auto& rtInfo : mRenderTargets)
 		for (auto& rtInfo : mRenderTargets)
-			RenderAPICore::instance().swapBuffers(rtInfo.target);
+		{
+			if(rtInfo.target->getProperties().isWindow())
+				RenderAPICore::instance().swapBuffers(rtInfo.target);
+		}
 
 
 		gProfilerCPU().endSample("renderAllCore");
 		gProfilerCPU().endSample("renderAllCore");
 	}
 	}