Jelajahi Sumber

When importing cubemaps for reflections, keep their original size

BearishSun 8 tahun lalu
induk
melakukan
1cdeda5dd2

+ 1 - 1
Source/BansheeCore/Include/BsTextureImportOptions.h

@@ -83,7 +83,7 @@ namespace bs
 
 		/**
 		 * Marks the cubemap as a reflection cubemap and perform special filtering on the cubemap mip-maps. Only relevant
-		 * when texture is imported as a cubemap. This will override texture size and mip levels to match the requirements
+		 * when texture is imported as a cubemap. This will override texture mip levels to match the requirements
 		 * needed for reflection cubemaps.
 		 */
 		void setCubemapIsReflection(bool reflection) { mCubemapIsReflection = reflection; }

+ 0 - 9
Source/BansheeFreeImgImporter/Source/BsFreeImgImporter.cpp

@@ -148,15 +148,6 @@ namespace bs
 		{
 			texType = TEX_TYPE_CUBE_MAP;
 
-			if(textureImportOptions->getCubemapIsReflection())
-			{
-				SPtr<PixelData> scaledImgData = PixelData::create(ct::ReflectionProbes::REFLECTION_CUBEMAP_SIZE, 
-					ct::ReflectionProbes::REFLECTION_CUBEMAP_SIZE, 0, imgData->getFormat());
-
-				PixelUtil::scale(*imgData, *scaledImgData);
-				imgData = scaledImgData;
-			}
-
 			std::array<SPtr<PixelData>, 6> cubemapFaces;
 			if (generateCubemap(imgData, textureImportOptions->getCubemapSourceType(), cubemapFaces))
 			{

+ 2 - 2
Source/MBansheeEditor/Windows/Library/ImportOptions.cs

@@ -126,8 +126,8 @@ namespace BansheeEditor
 
         /// <summary>
         /// If true makrs the cubemap as a reflection cubemap and perform special filtering on the cubemap mip-maps. Only
-        /// relevant when texture is imported as a cubemap.This will override texture size and mip levels to match the
-        /// requirements needed for reflection cubemaps.
+        /// relevant when texture is imported as a cubemap. This will override texture mip levels to match the requirements
+        /// needed for reflection cubemaps.
         /// </summary>
         public bool IsCubemapReflection
         {

+ 2 - 2
Source/RenderBeast/Source/BsReflectionProbeSampling.cpp

@@ -52,8 +52,8 @@ namespace bs { namespace ct
 		:probe(probe)
 	{
 		arrayIdx = -1;
-		texture = probe->getCustomTexture();
-		customTexture = texture != nullptr;
+		texture = nullptr;
+		customTexture = probe->getCustomTexture() != nullptr;
 		textureDirty = ReflectionCubemapCache::instance().isDirty(probe->getUUID());
 		arrayDirty = true;
 		errorFlagged = false;

+ 32 - 14
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -502,11 +502,8 @@ namespace bs { namespace ct
 		RendererReflectionProbe& probeInfo = mReflProbes[probeId];
 		probeInfo.arrayDirty = true;
 
-		if (!probeInfo.customTexture)
-		{
-			ReflectionCubemapCache::instance().notifyDirty(probe->getUUID());
-			probeInfo.textureDirty = true;
-		}
+		ReflectionCubemapCache::instance().notifyDirty(probe->getUUID());
+		probeInfo.textureDirty = true;
 	}
 
 	void RenderBeast::notifyReflectionProbeRemoved(ReflectionProbe* probe)
@@ -1230,22 +1227,43 @@ namespace bs { namespace ct
 			for (UINT32 i = 0; i < numProbes; i++)
 			{
 				RendererReflectionProbe& probeInfo = mReflProbes[i];
-				if (!probeInfo.customTexture)
+				if (probeInfo.probe->getType() != ReflectionProbeType::Plane)
 				{
-					if (probeInfo.probe->getType() != ReflectionProbeType::Plane)
+					if (probeInfo.texture == nullptr)
+						probeInfo.texture = ReflectionCubemapCache::instance().getCachedTexture(probeInfo.probe->getUUID());
+
+					if (probeInfo.texture == nullptr || probeInfo.textureDirty)
 					{
-						if (probeInfo.texture == nullptr)
-							probeInfo.texture = ReflectionCubemapCache::instance().getCachedTexture(probeInfo.probe->getUUID());
+						probeInfo.texture = Texture::create(cubemapDesc);
 
-						if (probeInfo.texture == nullptr || probeInfo.textureDirty)
+						if (!probeInfo.customTexture)
 						{
-							probeInfo.texture = Texture::create(cubemapDesc);
-
 							captureSceneCubeMap(probeInfo.texture, probeInfo.probe->getPosition(), true, frameInfo);
-							ReflectionProbes::filterCubemapForSpecular(probeInfo.texture, scratchCubemap);
+						}
+						else
+						{
+							SPtr<Texture> customTexture = probeInfo.probe->getCustomTexture();
+
+							// Note: If the Texture class supported scale on copy we could avoid using CPU reads & buffers
+							auto& texProps = probeInfo.texture->getProperties();
+							SPtr<PixelData> scaledFaceData = texProps.allocBuffer(0, 0);
 
-							ReflectionCubemapCache::instance().setCachedTexture(probeInfo.probe->getUUID(), probeInfo.texture);
+							auto& customTexProps = customTexture->getProperties();
+							SPtr<PixelData> originalFaceData = customTexProps.allocBuffer(0, 0);
+							for (UINT32 j = 0; j < 6; j++)
+							{
+								if (j < customTexProps.getNumFaces())
+									customTexture->readData(*originalFaceData, 0, j);
+
+								PixelUtil::scale(*originalFaceData, *scaledFaceData);
+
+								probeInfo.texture->writeData(*scaledFaceData, 0, j);
+
+							}
 						}
+
+						ReflectionProbes::filterCubemapForSpecular(probeInfo.texture, scratchCubemap);
+						ReflectionCubemapCache::instance().setCachedTexture(probeInfo.probe->getUUID(), probeInfo.texture);
 					}
 				}