diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index fb95afb92..b068849f0 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -116,7 +116,7 @@ ReflectionProbe::ReflectionProbe() mRadius = 10; mUseCubemap = false; - mUseHDRCaptures = false; + mUseHDRCaptures = true; mStaticCubemap = NULL; mReflectionPath = ""; @@ -584,19 +584,17 @@ bool ReflectionProbe::createClientResources() mIrridianceMap->createMap(); } - if (!mUseHDRCaptures) - { - String irrPath = getIrradianceMapPath(); - if (Platform::isFile(irrPath)) - { - mIrridianceMap->setCubemapFile(FileName(irrPath)); - mIrridianceMap->updateFaces(); - } - if (mIrridianceMap->mCubemap.isNull()) - Con::errorf("ReflectionProbe::createClientResources() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str()); + String irrPath = getIrradianceMapPath(); + if (Platform::isFile(irrPath)) + { + mIrridianceMap->setCubemapFile(FileName(irrPath)); + mIrridianceMap->updateFaces(); } + if (mIrridianceMap->mCubemap.isNull()) + Con::errorf("ReflectionProbe::createClientResources() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str()); + // if (!mPrefilterMap) { @@ -606,19 +604,16 @@ bool ReflectionProbe::createClientResources() mPrefilterMap->createMap(); } - if (!mUseHDRCaptures) + String prefilPath = getPrefilterMapPath(); + if (Platform::isFile(prefilPath)) { - String prefilPath = getPrefilterMapPath(); - if (Platform::isFile(prefilPath)) - { - mPrefilterMap->setCubemapFile(FileName(prefilPath)); - mPrefilterMap->updateFaces(); - } - - if (mPrefilterMap->mCubemap.isNull()) - Con::errorf("ReflectionProbe::createClientResources() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str()); + mPrefilterMap->setCubemapFile(FileName(prefilPath)); + mPrefilterMap->updateFaces(); } + if (mPrefilterMap->mCubemap.isNull()) + Con::errorf("ReflectionProbe::createClientResources() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str()); + //brdf lookup texture String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/pbr/brdfTexture.dds"); mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile); @@ -776,11 +771,11 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri, const MatrixF worldToObjectXfm = getTransform(); Box3F cube(-Point3F(mRadius, mRadius, mRadius),Point3F(mRadius, mRadius, mRadius)); - Box3F wb = getWorldBox(); + Box3F wb = getWorldBox(); cube.setCenter(getPosition()+mProbePosOffset); - wb.setCenter(getPosition() + mProbePosOffset); + wb.setCenter(getPosition() + mProbePosOffset); draw->drawCube(desc, cube, color, &worldToObjectXfm); - draw->drawCube(desc, wb, color, &worldToObjectXfm); + draw->drawCube(desc, wb, color, &worldToObjectXfm); } } @@ -874,7 +869,7 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro mDynamicCubemap = GFX->createCubemap(); if(mUseHDRCaptures) - mDynamicCubemap->initDynamic(resolution, GFXFormatR16G16B16A16); + mDynamicCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); else mDynamicCubemap->initDynamic(resolution, GFXFormatB8G8R8A8); @@ -922,7 +917,7 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro for (U32 i = 0; i < 6; ++i) { GFXTexHandle blendTex; - blendTex.set(resolution, resolution, GFXFormatR16G16B16A16, &GFXRenderTargetProfile, ""); + blendTex.set(resolution, resolution, GFXFormatR16G16B16A16F, &GFXRenderTargetProfile, ""); GFXTextureTargetRef baseTarget = GFX->allocRenderToTextureTarget(); @@ -980,10 +975,11 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro MathUtils::makeFrustum(&left, &right, &top, &bottom, M_HALFPI_F, 1.0f, nearPlane); Frustum frustum(false, left, right, top, bottom, nearPlane, farDist); - F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust; - TSShapeInstance::smDetailAdjust *= getNextPow2(resolution); + F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust; + TSShapeInstance::smDetailAdjust *= getNextPow2(resolution); renderFrame(&baseTarget, matView, frustum, mCaptureMask & EDITOR_RENDER_TYPEMASK, gCanvasClearColor); - TSShapeInstance::smDetailAdjust = detailAdjustBackup; + TSShapeInstance::smDetailAdjust = detailAdjustBackup; + baseTarget->resolve(); } @@ -1009,8 +1005,8 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro //Prep it with whatever resolution we've dictated for our bake if (mUseHDRCaptures) { - mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16); - mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16); + mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); + mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); } else { @@ -1026,12 +1022,8 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro IBLUtilities::GenerateIrradianceMap(renderTarget, sceneCaptureCubemap, mIrridianceMap->mCubemap); IBLUtilities::GeneratePrefilterMap(renderTarget, sceneCaptureCubemap, mPrefilterMipLevels, mPrefilterMap->mCubemap); - //We can't save HDR captures at the moment - if (!mUseHDRCaptures) - { - IBLUtilities::SaveCubeMap(getIrradianceMapPath(), mIrridianceMap->mCubemap); - IBLUtilities::SaveCubeMap(getPrefilterMapPath(), mPrefilterMap->mCubemap); - } + IBLUtilities::SaveCubeMap(getIrradianceMapPath(), mIrridianceMap->mCubemap); + IBLUtilities::SaveCubeMap(getPrefilterMapPath(), mPrefilterMap->mCubemap); } else { diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp b/Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp index f44c57081..e2508eb40 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp @@ -177,8 +177,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp) // check format limitations // at the moment we only support RGBA for the source (other 4 byte formats should // be easy to add though) - AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format"); - if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB) + AssertFatal(mFormat == GFXFormatR16G16B16A16F || mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format"); + if (mFormat != GFXFormatR16G16B16A16F && mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB) return false; PROFILE_START(GFXD3D11TextureObject_copyToBmp); @@ -190,11 +190,18 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp) bmp->setHasTransparency(mHasTransparency); // set some constants - const U32 sourceBytesPerPixel = 4; + U32 sourceBytesPerPixel = 4; U32 destBytesPerPixel = 0; const GFXFormat fmt = bmp->getFormat(); - if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatR8G8B8A8_SRGB) + bool fp16 = false;//is rgba16f format? + if (fmt == GFXFormatR16G16B16A16F) + { + destBytesPerPixel = 8; + sourceBytesPerPixel = 8; + fp16 = true; + } + else if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatR8G8B8A8_SRGB) destBytesPerPixel = 4; else if(bmp->getFormat() == GFXFormatR8G8B8) destBytesPerPixel = 3; @@ -249,11 +256,19 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp) { for (U32 col = 0; col < width; ++col) { - destPtr[0] = srcPtr[2]; // red - destPtr[1] = srcPtr[1]; // green - destPtr[2] = srcPtr[0]; // blue - if (destBytesPerPixel == 4) - destPtr[3] = srcPtr[3]; // alpha + //we can just copy data straight in with RGBA16F format + if (fp16) + { + dMemcpy(destPtr, srcPtr, sizeof(U16) * 4); + } + else + { + destPtr[0] = srcPtr[2]; // red + destPtr[1] = srcPtr[1]; // green + destPtr[2] = srcPtr[0]; // blue + if (destBytesPerPixel == 4) + destPtr[3] = srcPtr[3]; // alpha + } // go to next pixel in src srcPtr += sourceBytesPerPixel; diff --git a/Engine/source/gfx/bitmap/cubemapSaver.cpp b/Engine/source/gfx/bitmap/cubemapSaver.cpp index ae9d09b56..a27dd323f 100644 --- a/Engine/source/gfx/bitmap/cubemapSaver.cpp +++ b/Engine/source/gfx/bitmap/cubemapSaver.cpp @@ -52,6 +52,7 @@ namespace CubemapSaver GFXFormat targetFmt = pCubemap->getFormat(); //setup render targets GFXTexHandle pTextures[CubeFaces]; + for (U32 face = 0; face < CubeFaces; face++) { pTextures[face].set(faceSize, faceSize, targetFmt, @@ -75,9 +76,6 @@ namespace CubemapSaver Con::errorf("CubemapSaver: cubemap number %u failed to copy", i); error = true; } - //gen mip maps if there are none - if(!hasMips) - pBitmaps[i]->extrudeMipLevels(); } if (!error) @@ -85,8 +83,8 @@ namespace CubemapSaver DDSFile *pDds = DDSFile::createDDSCubemapFileFromGBitmaps(pBitmaps); if (pDds) { - // non compressed format needs swizzling - if (!compressedFormat) + // compressed and floating point don't need swizzling + if (!compressedFormat && targetFmt != GFXFormatR16G16B16A16F) ImageUtil::swizzleDDS(pDds, Swizzles::bgra); if(compressedFormat) diff --git a/Engine/source/gfx/bitmap/ddsData.h b/Engine/source/gfx/bitmap/ddsData.h index fa322a472..ac49e4392 100644 --- a/Engine/source/gfx/bitmap/ddsData.h +++ b/Engine/source/gfx/bitmap/ddsData.h @@ -742,6 +742,132 @@ namespace dds } } + const U32 getBitsPerPixel(DXGI_FORMAT fmt) + { + switch (fmt) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 128; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 96; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 64; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return 32; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return 16; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 8; + + case DXGI_FORMAT_R1_UNORM: + return 1; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 4; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 8; + + default: + return 0; + } + } + const bool validateHeader(const DDS_HEADER &header) { if (header.size != DDS_HEADER_SIZE) diff --git a/Engine/source/gfx/bitmap/ddsFile.cpp b/Engine/source/gfx/bitmap/ddsFile.cpp index 8c11fe5c6..3d9c33685 100644 --- a/Engine/source/gfx/bitmap/ddsFile.cpp +++ b/Engine/source/gfx/bitmap/ddsFile.cpp @@ -272,7 +272,7 @@ bool DDSFile::readHeader(Stream &s) mFlags.set(CompressedData); else { - mBytesPerPixel = header.ddspf.bpp / 8; + mBytesPerPixel = dds::getBitsPerPixel(dx10header.dxgiFormat) / 8; mFlags.set(RGBData); } @@ -397,8 +397,8 @@ bool DDSFile::read(Stream &s, U32 dropMipCount) } // Load all the mips. - for(S32 l=0; lreadNextMip(this, s, mHeight, mWidth, l, l < dropMipCount ); + for(S32 mip=0; mipreadNextMip(this, s, mHeight, mWidth, mip, mip < dropMipCount ); } } @@ -483,6 +483,8 @@ bool DDSFile::writeHeader( Stream &s ) { surfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP; cubemapFlags |= DDS_CUBEMAP_ALLFACES; + if (hasDx10Header) + dx10header.miscFlag = dds::D3D10_RESOURCE_MISC_TEXTURECUBE; } //volume texture @@ -739,9 +741,10 @@ DDSFile *DDSFile::createDDSCubemapFileFromGBitmaps(GBitmap **gbmps) //all cubemaps have the same dimensions and formats GBitmap *pBitmap = gbmps[0]; - if (pBitmap->getFormat() != GFXFormatR8G8B8A8) + GFXFormat fmt = pBitmap->getFormat(); + if (fmt != GFXFormatR8G8B8A8 && fmt != GFXFormatR16G16B16A16F) { - Con::errorf("createDDSCubemapFileFromGBitmaps: Only GFXFormatR8G8B8A8 supported for now"); + Con::errorf("createDDSCubemapFileFromGBitmaps: unsupported format"); return NULL; } diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index 6fba97e09..effc5f258 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -379,6 +379,9 @@ void GBitmap::allocateBitmapWithMips(const U32 in_width, const U32 in_height, co case GFXFormatR5G6B5: case GFXFormatR5G5B5A1: mBytesPerPixel = 2; break; + case GFXFormatR16G16B16A16F: + case GFXFormatR16G16B16A16: mBytesPerPixel = 8; + break; default: AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier"); break; @@ -452,6 +455,13 @@ void GBitmap::extrudeMipLevels(bool clearBorders) bitmapExtrudeRGBA(getBits(i - 1), getWritableBits(i), getHeight(i-1), getWidth(i-1)); break; } + + case GFXFormatR16G16B16A16F: + { + for (U32 i = 1; i < mNumMipLevels; i++) + bitmapExtrudeFPRGBA(getBits(i - 1), getWritableBits(i), getHeight(i - 1), getWidth(i - 1)); + break; + } default: break;