diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index d3f20edcc5..4cf34801f6 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -813,7 +813,7 @@ String AssetImporter::getAssetTypeByFile(Torque::Path filePath) if (fileExt == String("dts") && fileName.endsWith("cached")) return ""; - if (fileExt == String("png") || fileExt == String("jpg") || fileExt == String("jpeg") || fileExt == String("dds")) + if (fileExt == String("png") || fileExt == String("jpg") || fileExt == String("jpeg") || fileExt == String("dds") || fileExt == String("bmp")) return "ImageAsset"; else if (fileExt == String("dae") || fileExt == String("fbx") || fileExt == String("blend") || fileExt == String("obj") || fileExt == String("dts") || fileExt == String("gltf") || fileExt == String("glb")) return "ShapeAsset"; diff --git a/Engine/source/gfx/bitmap/bitmapUtils.h b/Engine/source/gfx/bitmap/bitmapUtils.h index 10053fdf7c..91cd3efd0c 100644 --- a/Engine/source/gfx/bitmap/bitmapUtils.h +++ b/Engine/source/gfx/bitmap/bitmapUtils.h @@ -41,10 +41,8 @@ extern void (*bitmapExtrudeRGBA)(const void *srcMip, void *mip, U32 height, U32 extern void (*bitmapExtrude16BitRGBA)(const void *srcMip, void *mip, U32 height, U32 width, U32 bpp); extern void(*bitmapExtrudeFPRGBA)(const void *srcMip, void *mip, U32 height, U32 width, U32 bpp); extern void(*bitmapExtrudeF32RGBA)(const void *srcMip, void *mip, U32 height, U32 width, U32 bpp); - extern void(*bitmapResizeToOutput)(const void* src, U32 srcHeight, U32 srcWidth, void* out, U32 outHeight, U32 outWidth, U32 bpp, GFXFormat format); extern bool(*bitmapConvertToOutput)(U8** src, U32 pixels, GFXFormat srcFormat, GFXFormat dstFormat); - extern void (*bitmapConvertRGB_to_5551)(U8 *src, U32 pixels); extern void (*bitmapConvertRGB_to_1555)(U8 *src, U32 pixels); extern void (*bitmapConvertRGB_to_RGBX)( U8 **src, U32 pixels ); @@ -145,7 +143,6 @@ inline U16 convertFloatToHalf(F32 f) return (U16)(sign | (exp << 10) | (mant >> 13)); } } - // Convert a single 16-bit value (0..65535) to 8-bit (0..255) inline U8 convert16To8(U16 v16) { @@ -165,5 +162,4 @@ inline U8 floatTo8(F32 v) return U8(mClamp(v * 255.f, 0.f, 255.f)); } - #endif //_BITMAPUTILS_H_ diff --git a/Engine/source/gfx/bitmap/ddsData.h b/Engine/source/gfx/bitmap/ddsData.h index ac49e4392b..21b6bd5621 100644 --- a/Engine/source/gfx/bitmap/ddsData.h +++ b/Engine/source/gfx/bitmap/ddsData.h @@ -281,6 +281,7 @@ namespace dds #define DDS_MAGIC 0x20534444 // "DDS " #define DDS_FOURCC 0x00000004 // DDPF_FOURCC #define DDS_RGB 0x00000040 // DDPF_RGB + #define DDS_R32F 0x00000072 // R32F Fourcc #define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS #define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE #define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS @@ -517,6 +518,9 @@ namespace dds const DDS_PIXELFORMAT DDSPF_V16U16 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; + const DDS_PIXELFORMAT DDSPF_F32 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, DDS_R32F, 32, 0, 0, 0, 0 }; + // D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue // This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) @@ -547,6 +551,7 @@ namespace dds case GFXFormatB8G8R8A8: return DDSPF_A8B8G8R8; case GFXFormatR16G16B16A16F: case GFXFormatR32G32B32A32F: return DDSPF_DX10; + case GFXFormatR32F: return DDSPF_F32; //compressed case GFXFormatBC1: return DDSPF_DXT1; case GFXFormatBC2: return DDSPF_DXT3; @@ -712,6 +717,8 @@ namespace dds return GFXFormatR5G6B5; else if (format == DDSPF_A1R5G5B5) return GFXFormatR5G5B5A1; + else if (format == DDSPF_F32) + return GFXFormatR32F; else { Con::errorf("dds::getGFXFormat: unknown format"); @@ -734,6 +741,7 @@ namespace dds case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F; case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F; case D3DFMT_G16R16F: return GFXFormatR16G16F; + case D3DFMT_R32F: return GFXFormatR32F; default: { Con::errorf("dds::getGFXFormatFourcc: unknown format"); @@ -905,4 +913,4 @@ namespace dds } -#endif \ No newline at end of file +#endif diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 99c4e979e0..f703598eca 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -139,6 +139,7 @@ void ProbeShaderConstants::init(GFXShader* shader) mProbeCountSC = shader->getShaderConstHandle(ShaderGenVars::probeCount); mBRDFTextureMap = shader->getShaderConstHandle(ShaderGenVars::BRDFTextureMap); + mProbeAtlasMap = shader->getShaderConstHandle(ShaderGenVars::ProbeAtlasMap); mWetnessTextureMap = shader->getShaderConstHandle(ShaderGenVars::WetnessTextureMap); mSkylightCubemapIdxSC = shader->getShaderConstHandle(ShaderGenVars::skylightCubemapIdx); @@ -177,7 +178,8 @@ RenderProbeMgr::RenderProbeMgr() mSkylightCubemapIdx(-1), mSkylightDamp(true), mCubeMapCount(0), - mUseHDRCaptures(true) + mUseHDRCaptures(true), + mProbeAtlas(NULL) { mEffectiveProbeCount = 0; mMipCount = 0; @@ -803,6 +805,11 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData& sgData, if (mBRDFTexture.isValid() && probeShaderConsts->mBRDFTextureMap->getSamplerRegister() != -1) GFX->setTexture(probeShaderConsts->mBRDFTextureMap->getSamplerRegister(), mBRDFTexture); + + if (mBRDFTexture.isValid() && probeShaderConsts->mBRDFTextureMap->getSamplerRegister() != -1) + GFX->setTexture(probeShaderConsts->mBRDFTextureMap->getSamplerRegister(), mBRDFTexture); + + if (mWetnessTexture.isValid() && probeShaderConsts->mWetnessTextureMap->getSamplerRegister() != -1) GFX->setTexture(probeShaderConsts->mWetnessTextureMap->getSamplerRegister(), mWetnessTexture); @@ -881,6 +888,19 @@ void RenderProbeMgr::render( SceneRenderState *state ) mProbeArrayEffect->setTexture(4, mPrefilterArray); mProbeArrayEffect->setTexture(5, mIrradianceArray); mProbeArrayEffect->setTexture(6, mWetnessTexture); + + if (mProbeAtlas) + { + if (mProbeAtlasTexture.set(mProbeAtlas, &GFXTexturePersistentProfile, false, "atlasTexture")) + { + mProbeArrayEffect->setTexture(7, mProbeAtlasTexture); + //mProbeArrayEffect->setShaderConst("$numAtlasEntries", (S32)10); //make adaptive + } + } + else + { + mProbeArrayEffect->setTexture(7, GFXTexHandle(NULL)); + } //ssao mask if (AdvancedLightBinManager::smUseSSAOMask) { @@ -890,13 +910,11 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (pTexObj) { mProbeArrayEffect->setShaderMacro("USE_SSAO_MASK"); - mProbeArrayEffect->setTexture(7, pTexObj); + mProbeArrayEffect->setTexture(8, pTexObj); } } - else - { - mProbeArrayEffect->setTexture(7, GFXTexHandle(NULL)); - } + + mProbeArrayEffect->setShaderConst("$numProbes", (S32)mProbeData.effectiveProbeCount); mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)mProbeData.skyLightIdx); mProbeArrayEffect->setShaderConst(ShaderGenVars::skylightDamp, mProbeData.skyLightDamp); @@ -942,7 +960,104 @@ void RenderProbeMgr::render( SceneRenderState *state ) // Make sure the effect is gonna render. getProbeArrayEffect()->setSkip(false); } +#pragma pack(push, 4) +struct ProbeSerialize +{ + F32 ambientCol[4]{0,1.0,0,1.0}; + F32 xForm[4][4]; + F32 offset[3]{ 0.0,0.0,0.0 }; + F32 refScale[3]{ 0.0,0.0,0.0 }; + F32 type = 0;//(U8)(ProbeInfo::Box); + F32 radius = 5; + F32 scale = 10; + F32 attenuation = 0; + U32 flags = BIT(0); //[0]canDamp +}; +#pragma pack(pop) + +#define probeDataLength (U32)(sizeof(ProbeSerialize) / 4) +void RenderProbeMgr::serializeProbes() +{ + U32 count = 10; + U32 probeAllocSize = sizeof(ProbeSerialize) * count; + ProbeSerialize* saveBuffer = (ProbeSerialize*)dMalloc(probeAllocSize); + for (U32 i = 0; i < count; i++) + { + ProbeSerialize pSer; + MatrixF inmat = MatrixF(Point3F(0,0,0), Point3F(-5.0f + i * 10, 100.0f + i * 10, 0.0f)); + inmat.scale(10); + for (U32 x = 0; x < 4; x++) + { + for (U32 y = 0; y < 4; y++) + { + pSer.xForm[x][y] = inmat(x, y); + } + } + saveBuffer[i] = pSer; // ensures defaults are applied + + } + + F32* checkPack = (F32*)dMalloc(probeAllocSize); + memcpy(checkPack, saveBuffer, probeAllocSize); + for (U32 i = 0; i < probeDataLength; i++) + { + Con::warnf("packed[%i]: %f",i, checkPack[i]); + } + + DDSFile dataFile; + dataFile.mFormat = GFXFormatR32F; + dataFile.mBytesPerPixel = 4; + dataFile.mHeight = count; + dataFile.mWidth = probeDataLength; + dataFile.mMipMapCount = 1; + dataFile.mSurfaces.push_back(new DDSFile::SurfaceData); + dataFile.mSurfaces.last()->mMips.push_back(reinterpret_cast(checkPack)); + + FileStream* out = FileStream::createAndOpen(Con::getVariable("$Probes::AtlasTexture"), Torque::FS::File::Write); + dataFile.write(*out); + out->close(); + free(saveBuffer); + mProbeAtlas = dataFile.load(Con::getVariable("$Probes::AtlasTexture"), 0); +} + +void RenderProbeMgr::testProbeAtlas() +{ + U32 count = 10; + DDSFile dataFile; + mProbeAtlas = dataFile.load(Con::getVariable("$Probes::AtlasTexture"),0); + + U32 probeAllocSize = sizeof(F32) * probeDataLength * count; + ProbeSerialize* readBuffer = (ProbeSerialize*)dMalloc(probeAllocSize); + const void* dataStart = mProbeAtlas->mSurfaces[0]->mMips[0]; + memcpy(readBuffer, dataStart, probeAllocSize); + + MatrixF inmat; + for (U32 x = 0; x < 4; x++) + { + for (U32 y = 0; y < 4; y++) + { + inmat(x, y) = readBuffer[0].xForm[x][y]; + } + } + + Con::warnf(" ambient: %f %f %f %f", readBuffer[0].ambientCol[0], readBuffer[0].ambientCol[1], readBuffer[0].ambientCol[2], readBuffer[0].ambientCol[3]); + Con::warnf("worldPos: %f %f %f", inmat.getPosition().x, inmat.getPosition().y, inmat.getPosition().z); + Con::warnf("rotation: %f %f %f", inmat.getForwardVector().x, inmat.getForwardVector().y, inmat.getForwardVector().z); + Con::warnf(" type: %f", readBuffer[0].type); + Con::warnf(" radius: %f", readBuffer[0].radius); + Con::warnf(" scale: %f", readBuffer[0].scale); + Con::warnf(" atten: %f", readBuffer[0].attenuation); +} + +DefineEngineFunction(bakeProbeAtlas, void, (), ,"") +{ + PROBEMGR->serializeProbes(); +} +DefineEngineFunction(testProbeAtlas, void, (), , "") +{ + PROBEMGR->testProbeAtlas(); +} //============================================================================= // Console functions //============================================================================= diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 3f953d295a..6771a6d0d6 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -98,9 +98,10 @@ struct ProbeShaderConstants GFXShaderConstHandle *mProbeCountSC; GFXShaderConstHandle *mBRDFTextureMap; - GFXShaderConstHandle* mWetnessTextureMap; + GFXShaderConstHandle *mProbeAtlasMap; + GFXShaderConstHandle *mWetnessTextureMap; GFXShaderConstHandle *mSkylightCubemapIdxSC; - GFXShaderConstHandle* mSkylightDampSC; + GFXShaderConstHandle *mSkylightDampSC; GFXShaderConstHandle* mMaxProbeDrawDistanceSC; @@ -278,6 +279,7 @@ class RenderProbeMgr : public RenderBinManager /// The BRDF texture used in PBR math calculations /// GFXTexHandle mBRDFTexture; + GFXTexHandle mProbeAtlasTexture; GFXTexHandle mWetnessTexture; /// @@ -478,6 +480,10 @@ class RenderProbeMgr : public RenderBinManager void render(SceneRenderState * state) override; void clear() override { mActiveProbes.clear(); Parent::clear(); } + + Resource mProbeAtlas; + void serializeProbes(); + void testProbeAtlas(); }; RenderProbeMgr* RenderProbeMgr::getProbeManager() diff --git a/Engine/source/shaderGen/shaderGenVars.cpp b/Engine/source/shaderGen/shaderGenVars.cpp index e6a3348930..7493018e84 100644 --- a/Engine/source/shaderGen/shaderGenVars.cpp +++ b/Engine/source/shaderGen/shaderGenVars.cpp @@ -93,6 +93,7 @@ const String ShaderGenVars::irradianceCubemapAR("$IrradianceCubemapAR"); const String ShaderGenVars::probeCount("$inNumProbes"); const String ShaderGenVars::BRDFTextureMap("$BRDFTexture"); +const String ShaderGenVars::ProbeAtlasMap("$probeAtlas"); const String ShaderGenVars::WetnessTextureMap("$WetnessTexture"); const String ShaderGenVars::maxProbeDrawDistance("$maxProbeDrawDistance"); diff --git a/Engine/source/shaderGen/shaderGenVars.h b/Engine/source/shaderGen/shaderGenVars.h index 4acc97fa88..4e021c21f4 100644 --- a/Engine/source/shaderGen/shaderGenVars.h +++ b/Engine/source/shaderGen/shaderGenVars.h @@ -104,6 +104,7 @@ struct ShaderGenVars const static String probeCount; const static String BRDFTextureMap; + const static String ProbeAtlasMap; const static String WetnessTextureMap; const static String maxProbeDrawDistance; diff --git a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript index 1fcee60793..8352beaa08 100644 --- a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript +++ b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript @@ -291,6 +291,7 @@ singleton shaderData( PrefiterCubemapShader ) }; // + singleton ShaderData( PFX_ReflectionProbeArray ) { DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl"; @@ -306,7 +307,8 @@ singleton ShaderData( PFX_ReflectionProbeArray ) samplerNames[4] = "$specularCubemapAR"; samplerNames[5] = "$irradianceCubemapAR"; samplerNames[6] = "$WetnessTexture"; - samplerNames[7] = "$ssaoMask"; + samplerNames[7] = "$probeAtlas"; + samplerNames[8] = "$ssaoMask"; pixVersion = 2.0; }; @@ -336,5 +338,6 @@ singleton GFXStateBlockData( PFX_ReflectionProbeArrayStateBlock ) samplerStates[4] = SamplerClampLinear; samplerStates[5] = SamplerClampLinear; samplerStates[6] = SamplerWrapPoint; - samplerStates[7] = SamplerClampPoint; + samplerStates[7] = SamplerWrapPoint; + samplerStates[8] = SamplerClampPoint; }; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 0ebcd3794d..6040e06859 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -85,6 +85,65 @@ vec3 getDistanceVectorToPlane( float negFarPlaneDotEye, vec3 direction, vec4 pla return direction.xyz * t; } +struct ProbeInfo +{ + vec4 ambientCol; + mat4 xform; + vec3 offset; + vec3 refScale; + vec4 probeConfigData; + int flags; +}; + +ProbeInfo createProbeinfo(sampler2D atlasTex, vec3 eyePosWorld, int slot) +{ + ProbeInfo probeInfo; + + int entry = 0; + probeInfo.ambientCol.r = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; + probeInfo.ambientCol.g = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; + probeInfo.ambientCol.b = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; //3 + probeInfo.ambientCol.a = texelFetch(atlasTex, ivec2(entry,slot),0).r; + + for (int x=0;x<4;x++) + { + for (int y=0;y<4;y++) + { + entry++; //19 + probeInfo.xform[y][x] = texelFetch(atlasTex, ivec2(entry,slot),0).r; + } + } + entry++; + probeInfo.offset.x = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; + probeInfo.offset.y = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; //22 + probeInfo.offset.z = texelFetch(atlasTex, ivec2(entry,slot),0).r; + + entry++; + probeInfo.refScale.x = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; + probeInfo.refScale.y = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; //25 + probeInfo.refScale.z = texelFetch(atlasTex, ivec2(entry,slot),0).r; + + entry++; + probeInfo.probeConfigData.r = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; + probeInfo.probeConfigData.g = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; + probeInfo.probeConfigData.b = texelFetch(atlasTex, ivec2(entry,slot),0).r; + entry++; //29 + probeInfo.probeConfigData.a = texelFetch(atlasTex, ivec2(entry,slot),0).r; + + entry++; //30 + probeInfo.flags = floatBitsToInt(texelFetch(atlasTex, ivec2(entry,slot),0).r); + return probeInfo; +} + struct Surface { vec3 P; // world space position @@ -392,7 +451,7 @@ vec4 compute4Lights( Surface surface, //Probe IBL stuff float defineSphereSpaceInfluence(vec3 wsPosition, vec3 wsProbePosition, float radius, float atten) { - float3 L = (wsProbePosition.xyz - wsPosition); + vec3 L = (wsProbePosition.xyz - wsPosition); float innerRadius = radius-(radius*atten); float contribution = 1.0-pow(saturate(length(L)/mix(radius, innerRadius, atten)), M_2PI_F*(1.0-atten)); return saturate(contribution); @@ -412,6 +471,16 @@ float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuatio return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist)); } +float defineFauxSpaceInfluence(vec3 wsPosition, mat4 worldMat, float attenuation) +{ + vec3 surfPosLS = wsPosition-worldMat[3].xyz; + + float baseVal = 0.25; + float dist = getDistBoxToPoint(surfPosLS, vec3(baseVal, baseVal, baseVal)); + return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist)); +} + + // Box Projected IBL Lighting // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ // and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ @@ -452,7 +521,7 @@ void dampen(inout Surface surface, sampler2D WetnessTexture, float accumTime, fl wetness = pow(wetness*ang*degree,3); surface.roughness = lerp(surface.roughness, 0.04f, wetness); - surface.baseColor.rgb = lerp(surface.baseColor.rgb, surface.baseColor.rgb*0.6+float3(0.4,0.4,0.4)*wetness, wetness); + surface.baseColor.rgb = lerp(surface.baseColor.rgb, surface.baseColor.rgb*0.6+vec3(0.4,0.4,0.4)*wetness, wetness); surface.metalness = lerp(surface.metalness, 0.96, wetness); updateSurface(surface); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index a2e8d2f4e4..c375c6a9df 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -86,6 +86,67 @@ inline float3 getDistanceVectorToPlane( float negFarPlaneDotEye, float3 directio return direction.xyz * t; } +struct ProbeInfo +{ + float4 ambientCol; + float4x4 xform; + float3 offset; + float3 refScale; + float4 probeConfigData; + int flags; +}; + +inline ProbeInfo createProbeinfo(TORQUE_SAMPLER2D(atlasTex),float3 eyePosWorld, int slot) +{ + ProbeInfo probeInfo = (ProbeInfo)0; + + int entry = 0; + probeInfo.ambientCol.r = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; + probeInfo.ambientCol.g = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; + probeInfo.ambientCol.b = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; //3 + probeInfo.ambientCol.a = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + + [unroll] + for (int x=0;x<4;x++) + { + [unroll] + for (int y=0;y<4;y++) + { + entry++; //19 + probeInfo.xform[y][x] = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + } + } + entry++; + probeInfo.offset.x = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; + probeInfo.offset.y = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; //22 + probeInfo.offset.z = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + + entry++; + probeInfo.refScale.x = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; + probeInfo.refScale.y = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; //25 + probeInfo.refScale.z = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + + entry++; + probeInfo.probeConfigData.r = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; + probeInfo.probeConfigData.g = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; + probeInfo.probeConfigData.b = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + entry++; //29 + probeInfo.probeConfigData.a = TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r; + + entry++; //30 + probeInfo.flags = asuint(TORQUE_TEX2D_PIX(atlasTex, int2(entry,slot)).r); + return probeInfo; +} + struct Surface { float3 P; // world space position @@ -414,6 +475,15 @@ float defineBoxSpaceInfluence(float3 wsPosition, float4x4 worldToObj, float atte return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist)); } +float defineFauxSpaceInfluence(float3 wsPosition, float4x4 worldMat, float attenuation) +{ + float3 surfPosLS = wsPosition-worldMat[3].xyz; + + float baseVal = 0.25; + float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal)); + return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist)); +} + // Box Projected IBL Lighting // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ // and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl index 6e603b5fac..d9b2cc5547 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -25,6 +25,7 @@ uniform int numProbes; uniform samplerCubeArray specularCubemapAR; uniform samplerCubeArray irradianceCubemapAR; uniform sampler2D WetnessTexture; +uniform sampler2D probeAtlas; #ifdef USE_SSAO_MASK uniform sampler2D ssaoMask; uniform vec4 rtParams7; @@ -214,6 +215,12 @@ void main() // Final color output after environment lighting vec3 finalColor = diffuse + specularCol * horizon; finalColor *= surface.ao; + ProbeInfo probeInfo = createProbeinfo(probeAtlas, eyePosWorld,0); + + float contribution = defineFauxSpaceInfluence(surface.P, probeInfo.xform, probeInfo.probeConfigData.a); + contribution = max(contribution,0); + OUT_col = lerp(vec4(0,0,1.0,0), probeInfo.ambientCol,contribution); + return; if(isCapturing == 1) OUT_col = vec4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),0); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl index df444d6668..0f6f88c402 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl @@ -22,10 +22,13 @@ TORQUE_UNIFORM_SAMPLERCUBEARRAY(specularCubemapAR, 4); TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5); TORQUE_UNIFORM_SAMPLER2D(WetnessTexture, 6); +TORQUE_UNIFORM_SAMPLER2D(probeAtlas, 7); + #ifdef USE_SSAO_MASK -TORQUE_UNIFORM_SAMPLER2D(ssaoMask, 7); +TORQUE_UNIFORM_SAMPLER2D(ssaoMask, 8); uniform float4 rtParams7; #endif + uniform float accumTime; uniform float dampness; @@ -195,20 +198,26 @@ float4 main(PFXVertToPix IN) : SV_TARGET float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg; float3 diffuse = irradiance * lerp(surface.baseColor.rgb, float3(0.04f,0.04f,0.04f), surface.metalness); - float3 specularCol = (specular * surface.f0 * envBRDF.x + envBRDF.y)*surface.metalness; + float3 specularCol = (specular * surface.f0 * envBRDF.x + envBRDF.y)*surface.metalness; - float horizonOcclusion = 1.3; + float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); - horizon *= horizon; + horizon *= horizon; // Final color output after environment lighting float3 finalColor = diffuse + specularCol*horizon; finalColor *= surface.ao; + ProbeInfo probeInfo = createProbeinfo(TORQUE_SAMPLER2D_MAKEARG(probeAtlas), eyePosWorld,0); + float contribution = defineFauxSpaceInfluence(surface.P, probeInfo.xform, probeInfo.probeConfigData.a); + contribution = max(contribution,0); + return lerp(float4(0,0,1,0), probeInfo.ambientCol,contribution); + if(isCapturing == 1) return float4(lerp(finalColor, surface.baseColor.rgb,surface.metalness),0); else { return float4((finalColor*ambientColor), 0); } + } diff --git a/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl b/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl index d34869c3b9..dab073c940 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl @@ -52,6 +52,8 @@ #define TORQUE_TEX2DLOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xy,coords.w) #define TORQUE_TEXCUBELOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xyz,coords.w) #define TORQUE_TEXCUBEARRAYLOD(tex,coords,id,lod) texture_##tex.SampleLevel(tex,float4(coords.xyz,id),lod) + +#define TORQUE_TEX2D_PIX(tex,coords) texture_##tex.Load(int3(coords.xy,0)) // Tex2d comparison #define TORQUE_TEX2DCMP(tex,coords,compare) texture_##tex.SampleCmpLevelZero(tex,coords,compare) diff --git a/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl b/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl index 8f4e30a222..79fea96573 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl @@ -30,6 +30,37 @@ static float M_PI_F = 3.14159265358979323846f; static float M_2PI_F = 6.28318530717958647692f; static float M_1OVER_PI_F = 0.31830988618f; +float decode32(float4 rgba) +{ + float Sign = 1.0 - step(128.0,rgba.a)*2.0; + float Exponent = 2.0 * (rgba.a % 128.0) + step(128.0,rgba.b) - 127.0; + float Mantissa = (rgba.b % 128.0)*65536.0 + rgba.g*256.0 +rgba.r + float(0x800000); + float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 )); + return Result; +} + +float RGBAtoFloat(uint4 INrgba) +{ + int convert = (INrgba.a << 24) | (INrgba.b << 16) | (INrgba.g << 8) | INrgba.r; + return asfloat(convert); +} + +float faux5() +{ + int convert = (64 << 24) | (160 << 16) | (0<< 8) | 0; + return asfloat(convert); +} + +float3 RGBAstoCoord(uint4 inCol[3] ) +{ + return float3(RGBAtoFloat(inCol[0]),RGBAtoFloat(inCol[1]),RGBAtoFloat(inCol[2])); +} + +int RGBAtoInt(uint4 INrgba) +{ + return asuint((INrgba.z << 24) | (INrgba.b << 16) | (INrgba.g << 8) | INrgba.r); +} + /// Calculate fog based on a start and end positions in worldSpace. float computeSceneFog( float3 startPos, float3 endPos, diff --git a/Templates/BaseGame/game/data/defaults.tscript b/Templates/BaseGame/game/data/defaults.tscript index a7a57df14a..61b9ba1162 100644 --- a/Templates/BaseGame/game/data/defaults.tscript +++ b/Templates/BaseGame/game/data/defaults.tscript @@ -210,4 +210,6 @@ $pref::PostFX::EnableLightRays = 1; $pref::PostFX::EnableHDR = 1; $pref::PostFX::EnableSSAO = 1; -$pref::PostFX::EnableHDRBloom = 1; \ No newline at end of file +$pref::PostFX::EnableHDRBloom = 1; + +$Probes::AtlasTexture = "probeinfoAtlas.dbm"; \ No newline at end of file