diff --git a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp index 88e91156d..63f910f05 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp @@ -151,7 +151,13 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te mTargetSize.set( tex->getSize().x, tex->getSize().y ); mTargetFormat = tex->getFormat(); } - } + } + + if (mGenMips) + { + mTargetSRViews[slot] = d3dto->getSRView(); + mTargetSRViews[slot]->AddRef(); + } } // Update surface size diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp index dd34b9ec5..e24a6f5dd 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp @@ -105,7 +105,7 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex, } if( !forceMips && !retTex->mProfile->isSystemMemory() && - numMipLevels == 0 && + (numMipLevels == 0 || numMipLevels > 1)&& !(depth > 0) ) { miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index b0a897501..5180a04a8 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1414,13 +1414,13 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, { inOutNumMips = 1; } - else if( !isPow2( width ) || !isPow2( height ) ) + else if (!isPow2(width) || !isPow2(height)) { // If a texture is not power-of-2 in size for both dimensions, it must // have only 1 mip level. - inOutNumMips = 1; + inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1; } - + // Check format, and compatibility with texture profile requirements bool autoGenSupp = ( inOutNumMips == 0 ); diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index ad08b9391..0ac10a879 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -142,25 +142,23 @@ IMPLEMENT_CONOBJECT(PostEffect); GFX_ImplementTextureProfile( PostFxTextureProfile, GFXTextureProfile::DiffuseMap, - GFXTextureProfile::Static | GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap, + GFXTextureProfile::Static | GFXTextureProfile::PreserveSize, GFXTextureProfile::NONE ); GFX_ImplementTextureProfile( PostFxTextureSRGBProfile, GFXTextureProfile::DiffuseMap, - GFXTextureProfile::Static | GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::SRGB, + GFXTextureProfile::Static | GFXTextureProfile::PreserveSize | GFXTextureProfile::SRGB, GFXTextureProfile::NONE); GFX_ImplementTextureProfile( VRTextureProfile, GFXTextureProfile::DiffuseMap, GFXTextureProfile::PreserveSize | - GFXTextureProfile::RenderTarget | - GFXTextureProfile::NoMipmap, + GFXTextureProfile::RenderTarget, GFXTextureProfile::NONE ); GFX_ImplementTextureProfile( VRDepthProfile, GFXTextureProfile::DiffuseMap, GFXTextureProfile::PreserveSize | - GFXTextureProfile::NoMipmap | GFXTextureProfile::ZTarget, GFXTextureProfile::NONE ); @@ -501,7 +499,8 @@ PostEffect::PostEffect() mInvCameraTransSC(NULL), mMatCameraToScreenSC(NULL), mMatScreenToCameraSC(NULL), - mIsCapturingSC(NULL) + mIsCapturingSC(NULL), + mMipCap(1) { dMemset( mTexSRGB, 0, sizeof(bool) * NumTextures); dMemset( mActiveTextures, 0, sizeof( GFXTextureObject* ) * NumTextures ); @@ -509,7 +508,7 @@ PostEffect::PostEffect() dMemset( mActiveTextureViewport, 0, sizeof( RectI ) * NumTextures ); dMemset( mTexSizeSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures ); dMemset( mRenderTargetParamsSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures ); - + dMemset(mMipCountSC, 0, sizeof(GFXShaderConstHandle*) * NumTextures); } PostEffect::~PostEffect() @@ -538,6 +537,9 @@ void PostEffect::initPersistFields() addField( "targetScale", TypePoint2F, Offset( mTargetScale, PostEffect ), "If targetSize is zero this is used to set a relative size from the current target." ); + + addField("mipCap", TypePoint2F, Offset(mMipCap, PostEffect), + "generate up to this many mips. 0 = all, 1 = none, >1 = as specified max."); //todo: de-stupid addField( "targetSize", TypePoint2I, Offset( mTargetSize, PostEffect ), "If non-zero this is used as the absolute target size." ); @@ -760,6 +762,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) { mTexSizeSC[i] = mShader->getShaderConstHandle(String::ToString("$texSize%d", i)); mRenderTargetParamsSC[i] = mShader->getShaderConstHandle(String::ToString("$rtParams%d",i)); + mMipCountSC[i] = mShader->getShaderConstHandle(String::ToString("$mipCount%d", i)); } mTargetViewportSC = mShader->getShaderConstHandle( "$targetViewport" ); @@ -843,6 +846,11 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) texSizeConst.y = (F32)mActiveTextures[i]->getHeight(); mShaderConsts->set( mTexSizeSC[i], texSizeConst ); } + + if (mMipCountSC[i]->isValid()) + { + mShaderConsts->set(mMipCountSC[i], (S32)mActiveTextures[i]->getMipLevels()); + } } for ( U32 i = 0; i < NumTextures; i++ ) @@ -1265,7 +1273,7 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg mTargetTex.getWidthHeight() != targetSize ) { mTargetTex.set( targetSize.x, targetSize.y, mTargetFormat, - &PostFxTargetProfile, "PostEffect::_setupTarget" ); + &PostFxTargetProfile, "PostEffect::_setupTarget", mMipCap); if ( mTargetClear == PFXTargetClear_OnCreate ) *outClearTarget = true; diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index bf83812d1..101f171dc 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -133,6 +133,7 @@ protected: GFXShaderConstHandle *mTexSizeSC[NumTextures]; GFXShaderConstHandle *mRenderTargetParamsSC[NumTextures]; + GFXShaderConstHandle* mMipCountSC[NumTextures]; GFXShaderConstHandle *mViewportOffsetSC; @@ -176,6 +177,7 @@ protected: String mTargetName; GFXTexHandle mTargetTex; + S32 mMipCap; String mTargetDepthStencilName; GFXTexHandle mTargetDepthStencil; diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript index b15f48d61..ff2586d20 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript @@ -117,8 +117,7 @@ singleton ShaderData( HDR_BloomUpSampleShader ) OGLVertexShaderFile= $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl"; OGLPixelShaderFile = "./HDR_Bloom/upSampleP.glsl"; - samplerNames[0] = "$nxtTex"; - samplerNames[1] = "$mipTex"; + samplerNames[0] = "$hdrbloomDown"; pixVersion = 3.0; }; @@ -292,13 +291,7 @@ function HDRPostFX::setShaderConsts( %this ) %bloom.skip = (!$PostFX::HDRPostFX::enableBloom || !$pref::PostFX::EnableHDRBloom); %bloom.setShaderConst("$threshold", $PostFX::HDRPostFX::threshold); - - for (%idx = 0; %idx < %this.mipsCount; %idx++) - { - %mip = %bloom.getObject(%this.mipsCount + %idx); - %mip.setShaderConst("$filterRadius", $PostFX::HDRPostFX::radius); - %mip.setShaderConst("$mipId", %idx); - } + %bloom-->upFX.setShaderConst("$filterRadius", $PostFX::HDRPostFX::radius); %strength = $PostFX::HDRPostFX::intensity; if (!$PostFX::HDRPostFX::enableBloom || !$pref::PostFX::EnableHDRBloom) @@ -524,50 +517,36 @@ function HDRPostFX::SetupBloomFX( %this ) shader = HDR_BloomThresholdShader; stateBlock = HDR_DownSampleStateBlock; texture[0] = "#hdrInitBloom"; - target = "#hdrbloom_0"; + target = "#hdrbloomIn"; + mipCap = "5"; targetFormat = %this.mipTexFormat; }; - - %textureName = "#hdrbloom_0"; - for (%idx = 0; %idx < %this.mipsCount; %idx++) - { - %mipName = "hdrbloom_" @ (%idx + 1); - %mipFX = new PostEffect() - { - internalName = %mipName; - allowReflectPass = false; - shader = HDR_BloomDownSampleShader; - stateBlock = HDR_DownSampleStateBlock; - texture[0] = %textureName; - target = "#" @ %mipName; - targetScale = "0.5 0.5"; - targetFormat = %this.mipTexFormat; - }; - - %bloomFX.add(%mipFX); - %textureName = "#" @ %mipName; - } - for (%idx = %this.mipsCount - 1; %idx >= 0; %idx--) + %downFX = new PostEffect() { - %nxt = "#hdrbloom_" @ %idx; - %mipName = "hdrbloom_up_" @ %idx; - - %mipFX = new PostEffect() - { - internalName = %mipName; - allowReflectPass = false; - shader = HDR_BloomUpSampleShader; - stateBlock = HDR_DownSampleStateBlock; - texture[0] = %nxt; - texture[1] = %textureName; - target = "#" @ %mipName; - targetFormat = %this.mipTexFormat; - }; - - %bloomFX.add(%mipFX); - %textureName = "#" @ %mipName; - } + internalName = "downFX"; + allowReflectPass = false; + shader = HDR_BloomDownSampleShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "#hdrbloomIn"; + target = "#hdrbloomDown"; + mipCap = "5"; + targetScale = "0.5 0.5"; + targetFormat = %this.mipTexFormat; + }; + %bloomFX.add(%downFX); + + %upFX = new PostEffect() + { + internalName = "upFX"; + allowReflectPass = false; + shader = HDR_BloomUpSampleShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "#hdrbloomDown"; + target = "#hdrbloomUp"; + targetFormat = %this.mipTexFormat; + }; + %bloomFX.add(%upFX); %finalFX = new PostEffect() { @@ -575,7 +554,7 @@ function HDRPostFX::SetupBloomFX( %this ) allowReflectPass = false; shader = HDR_BloomDirtShader; stateBlock = HDR_LensDirtStateBlock; - texture[0] = "#hdrbloom_up_0"; + texture[0] = "#hdrbloomUp"; target = "#hdrbloom_end"; targetFormat = %this.mipTexFormat; }; diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl index 6ac8ce668..c358087f6 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl @@ -25,7 +25,7 @@ TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); uniform float2 oneOverTargetSize; -uniform int mipId; +uniform int mipCount0; float4 main(PFXVertToPix IN) : TORQUE_TARGET0 { @@ -33,49 +33,51 @@ float4 main(PFXVertToPix IN) : TORQUE_TARGET0 float x = oneOverTargetSize.x; float y = oneOverTargetSize.y; - float3 a = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y + 2*y)).rgb; - float3 b = TORQUE_TEX2D(inputTex, float2(IN.uv0.x , IN.uv0.y + 2*y)).rgb; - float3 c = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y + 2*y)).rgb; - - float3 d = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y)).rgb; - float3 e = TORQUE_TEX2D(inputTex, float2(IN.uv0.x , IN.uv0.y)).rgb; - float3 f = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y)).rgb; - - float3 g = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y - 2*y)).rgb; - float3 h = TORQUE_TEX2D(inputTex, float2(IN.uv0.x , IN.uv0.y - 2*y)).rgb; - float3 i = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y - 2*y)).rgb; - - float3 j = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - x, IN.uv0.y + y)).rgb; - float3 k = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + x, IN.uv0.y + y)).rgb; - float3 l = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - x, IN.uv0.y - y)).rgb; - float3 m = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + x, IN.uv0.y - y)).rgb; - - float3 group[5]; - switch (mipId) + for (int mipId = 0; mipId