diff --git a/Engine/source/renderInstance/renderPrePassMgr.cpp b/Engine/source/renderInstance/renderPrePassMgr.cpp index 326f346a0..4f08dc6ea 100644 --- a/Engine/source/renderInstance/renderPrePassMgr.cpp +++ b/Engine/source/renderInstance/renderPrePassMgr.cpp @@ -36,6 +36,7 @@ #include "scene/sceneRenderState.h" #include "gfx/gfxStringEnumTranslate.h" #include "gfx/gfxDebugEvent.h" +#include "gfx/gfxCardProfile.h" #include "materials/customMaterialDefinition.h" #include "lighting/advanced/advancedLightManager.h" #include "lighting/advanced/advancedLightBinManager.h" @@ -44,10 +45,17 @@ #include "terrain/terrCellMaterial.h" #include "math/mathUtils.h" #include "math/util/matrixSet.h" +#include "gfx/gfxTextureManager.h" +#include "gfx/primBuilder.h" +#include "gfx/gfxDrawUtil.h" +#include "materials/shaderData.h" +#include "gfx/sim/cubemapData.h" const MatInstanceHookType PrePassMatInstanceHook::Type( "PrePass" ); const String RenderPrePassMgr::BufferName("prepass"); const RenderInstType RenderPrePassMgr::RIT_PrePass("PrePass"); +const String RenderPrePassMgr::ColorBufferName("color"); +const String RenderPrePassMgr::MatInfoBufferName("matinfo"); IMPLEMENT_CONOBJECT(RenderPrePassMgr); @@ -79,6 +87,7 @@ RenderPrePassMgr::RenderPrePassMgr( bool gatherDepth, mPrePassMatInstance( NULL ) { notifyType( RenderPassManager::RIT_Decal ); + notifyType( RenderPassManager::RIT_DecalRoad ); notifyType( RenderPassManager::RIT_Mesh ); notifyType( RenderPassManager::RIT_Terrain ); notifyType( RenderPassManager::RIT_Object ); @@ -90,6 +99,10 @@ RenderPrePassMgr::RenderPrePassMgr( bool gatherDepth, GFXShader::addGlobalMacro( "TORQUE_LINEAR_DEPTH" ); mNamedTarget.registerWithName( BufferName ); + mColorTarget.registerWithName( ColorBufferName ); + mMatInfoTarget.registerWithName( MatInfoBufferName ); + + mClearGBufferShader = NULL; _registerFeatures(); } @@ -98,6 +111,8 @@ RenderPrePassMgr::~RenderPrePassMgr() { GFXShader::removeGlobalMacro( "TORQUE_LINEAR_DEPTH" ); + mColorTarget.release(); + mMatInfoTarget.release(); _unregisterFeatures(); SAFE_DELETE( mPrePassMatInstance ); } @@ -119,6 +134,8 @@ bool RenderPrePassMgr::setTargetSize(const Point2I &newTargetSize) { bool ret = Parent::setTargetSize( newTargetSize ); mNamedTarget.setViewport( GFX->getViewport() ); + mColorTarget.setViewport( GFX->getViewport() ); + mMatInfoTarget.setViewport( GFX->getViewport() ); return ret; } @@ -135,6 +152,40 @@ bool RenderPrePassMgr::_updateTargets() // reload materials, the conditioner needs to alter the generated shaders } + GFXFormat colorFormat = mTargetFormat; + bool independentMrtBitDepth = GFX->getCardProfiler()->queryProfile("independentMrtBitDepth", false); + //If independent bit depth on a MRT is supported than just use 8bit channels for the albedo color. + if(independentMrtBitDepth) + colorFormat = GFXFormatR8G8B8A8; + + // andrewmac: Deferred Shading Color Buffer + if (mColorTex.getFormat() != colorFormat || mColorTex.getWidthHeight() != mTargetSize || GFX->recentlyReset()) + { + mColorTarget.release(); + mColorTex.set(mTargetSize.x, mTargetSize.y, colorFormat, + &GFXDefaultRenderTargetProfile, avar("%s() - (line %d)", __FUNCTION__, __LINE__), + 1, GFXTextureManager::AA_MATCH_BACKBUFFER); + mColorTarget.setTexture(mColorTex); + + for (U32 i = 0; i < mTargetChainLength; i++) + mTargetChain[i]->attachTexture(GFXTextureTarget::Color1, mColorTarget.getTexture()); + } + + // andrewmac: Deferred Shading Material Info Buffer + if (mMatInfoTex.getFormat() != colorFormat || mMatInfoTex.getWidthHeight() != mTargetSize || GFX->recentlyReset()) + { + mMatInfoTarget.release(); + mMatInfoTex.set(mTargetSize.x, mTargetSize.y, colorFormat, + &GFXDefaultRenderTargetProfile, avar("%s() - (line %d)", __FUNCTION__, __LINE__), + 1, GFXTextureManager::AA_MATCH_BACKBUFFER); + mMatInfoTarget.setTexture(mMatInfoTex); + + for (U32 i = 0; i < mTargetChainLength; i++) + mTargetChain[i]->attachTexture(GFXTextureTarget::Color2, mMatInfoTarget.getTexture()); + } + + GFX->finalizeReset(); + // Attach the light info buffer as a second render target, if there is // lightmapped geometry in the scene. AdvancedLightBinManager *lightBin; @@ -154,11 +205,13 @@ bool RenderPrePassMgr::_updateTargets() for ( U32 i = 0; i < mTargetChainLength; i++ ) { GFXTexHandle lightInfoTex = lightBin->getTargetTexture(0, i); - mTargetChain[i]->attachTexture(GFXTextureTarget::Color1, lightInfoTex); + mTargetChain[i]->attachTexture(GFXTextureTarget::Color3, lightInfoTex); } } } + _initShaders(); + return ret; } @@ -191,7 +244,7 @@ void RenderPrePassMgr::addElement( RenderInst *inst ) return; // First what type of render instance is it? - const bool isDecalMeshInst = inst->type == RenderPassManager::RIT_Decal; + const bool isDecalMeshInst = ((inst->type == RenderPassManager::RIT_Decal)||(inst->type == RenderPassManager::RIT_DecalRoad)); const bool isMeshInst = inst->type == RenderPassManager::RIT_Mesh; @@ -280,9 +333,8 @@ void RenderPrePassMgr::render( SceneRenderState *state ) // Tell the superclass we're about to render const bool isRenderingToTarget = _onPreRender(state); - // Clear all the buffers to white so that the - // default depth is to the far plane. - GFX->clear( GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI::WHITE, 1.0f, 0); + // Clear all z-buffer, and g-buffer. + clearBuffers(); // Restore transforms MatrixSet &matrixSet = getRenderPass()->getMatrixSet(); @@ -329,7 +381,13 @@ void RenderPrePassMgr::render( SceneRenderState *state ) GFX->drawPrimitive( ri->prim ); } - + // init loop data + GFXTextureObject *lastLM = NULL; + GFXCubemap *lastCubemap = NULL; + GFXTextureObject *lastReflectTex = NULL; + GFXTextureObject *lastMiscTex = NULL; + GFXTextureObject *lastAccuTex = NULL; + // Next render all the meshes. itr = mElementList.begin(); for ( ; itr != mElementList.end(); ) @@ -363,12 +421,11 @@ void RenderPrePassMgr::render( SceneRenderState *state ) // Set up SG data for this instance. setupSGData( passRI, sgData ); + mat->setSceneInfo(state, sgData); matrixSet.setWorld(*passRI->objectToWorld); matrixSet.setView(*passRI->worldToCamera); matrixSet.setProjection(*passRI->projection); - - mat->setSceneInfo(state, sgData); mat->setTransforms(matrixSet, state); // If we're instanced then don't render yet. @@ -385,6 +442,43 @@ void RenderPrePassMgr::render( SceneRenderState *state ) continue; } + bool dirty = false; + + // set the lightmaps if different + if( passRI->lightmap && passRI->lightmap != lastLM ) + { + sgData.lightmap = passRI->lightmap; + lastLM = passRI->lightmap; + dirty = true; + } + + // set the cubemap if different. + if ( passRI->cubemap != lastCubemap ) + { + sgData.cubemap = passRI->cubemap; + lastCubemap = passRI->cubemap; + dirty = true; + } + + if ( passRI->reflectTex != lastReflectTex ) + { + sgData.reflectTex = passRI->reflectTex; + lastReflectTex = passRI->reflectTex; + dirty = true; + } + + // Update accumulation texture if it changed. + // Note: accumulation texture can be NULL, and must be updated. + if (passRI->accuTex != lastAccuTex) + { + sgData.accuTex = passRI->accuTex; + lastAccuTex = lastAccuTex; + dirty = true; + } + + if ( dirty ) + mat->setTextureStages( state, sgData ); + // Setup the vertex and index buffers. mat->setBuffers( passRI->vertBuff, passRI->primBuff ); @@ -525,6 +619,31 @@ void ProcessedPrePassMaterial::_determineFeatures( U32 stageNum, #ifndef TORQUE_DEDICATED + //tag all materials running through prepass as deferred + newFeatures.addFeature(MFT_isDeferred); + + // Deferred Shading : Diffuse + if (mStages[stageNum].getTex( MFT_DiffuseMap )) + { + newFeatures.addFeature(MFT_DiffuseMap); + } + newFeatures.addFeature( MFT_DiffuseColor ); + + // Deferred Shading : Specular + if( mStages[stageNum].getTex( MFT_SpecularMap ) ) + { + newFeatures.addFeature( MFT_DeferredSpecMap ); + } + else if ( mMaterial->mPixelSpecular[stageNum] ) + { + newFeatures.addFeature( MFT_DeferredSpecVars ); + } + else + newFeatures.addFeature(MFT_DeferredEmptySpec); + + // Deferred Shading : Material Info Flags + newFeatures.addFeature( MFT_DeferredMatInfoFlags ); + for ( U32 i=0; i < fd.features.getCount(); i++ ) { const FeatureType &type = fd.features.getAt( i ); @@ -553,7 +672,10 @@ void ProcessedPrePassMaterial::_determineFeatures( U32 stageNum, type == MFT_InterlacedPrePass || type == MFT_Visibility || type == MFT_UseInstancing || - type == MFT_DiffuseVertColor ) + type == MFT_DiffuseVertColor || + type == MFT_DetailMap || + type == MFT_DetailNormalMap || + type == MFT_DiffuseMapAtlas) newFeatures.addFeature( type ); // Add any transform features. @@ -563,11 +685,39 @@ void ProcessedPrePassMaterial::_determineFeatures( U32 stageNum, newFeatures.addFeature( type ); } + if (mMaterial->mAccuEnabled[stageNum]) + { + newFeatures.addFeature(MFT_AccuMap); + mHasAccumulation = true; + } + + // we need both diffuse and normal maps + sm3 to have an accu map + if (newFeatures[MFT_AccuMap] && + (!newFeatures[MFT_DiffuseMap] || + !newFeatures[MFT_NormalMap] || + GFX->getPixelShaderVersion() < 3.0f)) { + AssertWarn(false, "SAHARA: Using an Accu Map requires SM 3.0 and a normal map."); + newFeatures.removeFeature(MFT_AccuMap); + mHasAccumulation = false; + } + + // if we still have the AccuMap feature, we add all accu constant features + if (newFeatures[MFT_AccuMap]) { + // add the dependencies of the accu map + newFeatures.addFeature(MFT_AccuScale); + newFeatures.addFeature(MFT_AccuDirection); + newFeatures.addFeature(MFT_AccuStrength); + newFeatures.addFeature(MFT_AccuCoverage); + newFeatures.addFeature(MFT_AccuSpecular); + // now remove some features that are not compatible with this + newFeatures.removeFeature(MFT_UseInstancing); + } + // If there is lightmapped geometry support, add the MRT light buffer features if(bEnableMRTLightmap) { // If this material has a lightmap, pass it through, and flag it to - // send it's output to RenderTarget1 + // send it's output to RenderTarget3 if( fd.features.hasFeature( MFT_ToneMap ) ) { newFeatures.addFeature( MFT_ToneMap ); @@ -590,10 +740,16 @@ void ProcessedPrePassMaterial::_determineFeatures( U32 stageNum, else { // If this object isn't lightmapped, add a zero-output feature to it - newFeatures.addFeature( MFT_RenderTarget1_Zero ); + newFeatures.addFeature( MFT_RenderTarget3_Zero ); } } + // cubemaps only available on stage 0 for now - bramage + if ( stageNum < 1 && + ( ( mMaterial->mCubemapData && mMaterial->mCubemapData->mCubemap ) || + mMaterial->mDynamicCubemap ) ) + newFeatures.addFeature( MFT_CubeMap ); + #endif // Set the new features. @@ -602,8 +758,54 @@ void ProcessedPrePassMaterial::_determineFeatures( U32 stageNum, U32 ProcessedPrePassMaterial::getNumStages() { - // Return 1 stage so this material gets processed for sure - return 1; + // Loops through all stages to determine how many + // stages we actually use. + // + // The first stage is always active else we shouldn't be + // creating the material to begin with. + U32 numStages = 1; + + U32 i; + for( i=1; imCubemapData || mMaterial->mDynamicCubemap ) + { + numStages++; + continue; + } + } + + // If we have a texture for the a feature the + // stage is active. + if ( mStages[i].hasValidTex() ) + stageActive = true; + + // If this stage has specular lighting, it's active + if ( mMaterial->mPixelSpecular[i] ) + stageActive = true; + + // If this stage has diffuse color, it's active + if ( mMaterial->mDiffuse[i].alpha > 0 && + mMaterial->mDiffuse[i] != ColorF::WHITE ) + stageActive = true; + + // If we have a Material that is vertex lit + // then it may not have a texture + if( mMaterial->mVertLit[i] ) + stageActive = true; + + // Increment the number of active stages + numStages += stageActive; + } + + return numStages; } void ProcessedPrePassMaterial::addStateBlockDesc(const GFXStateBlockDesc& desc) @@ -633,7 +835,7 @@ void ProcessedPrePassMaterial::addStateBlockDesc(const GFXStateBlockDesc& desc) if ( isTranslucent ) { prePassStateBlock.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha ); - prePassStateBlock.setColorWrites( true, true, false, false ); + prePassStateBlock.setColorWrites(false, false, false, true); } // Enable z reads, but only enable zwrites if we're not translucent. @@ -663,7 +865,22 @@ ProcessedMaterial* PrePassMatInstance::getShaderMaterial() bool PrePassMatInstance::init( const FeatureSet &features, const GFXVertexFormat *vertexFormat ) { - return Parent::init( features, vertexFormat ); + bool vaild = Parent::init(features, vertexFormat); + + if (mMaterial && mMaterial->mDiffuseMapFilename[0].isNotEmpty() && mMaterial->mDiffuseMapFilename[0].substr(0, 1).equal("#")) + { + String texTargetBufferName = mMaterial->mDiffuseMapFilename[0].substr(1, mMaterial->mDiffuseMapFilename[0].length() - 1); + NamedTexTarget *texTarget = NamedTexTarget::find(texTargetBufferName); + RenderPassData* rpd = getPass(0); + + if (rpd) + { + rpd->mTexSlot[0].texTarget = texTarget; + rpd->mTexType[0] = Material::TexTarget; + rpd->mSamplerNames[0] = "diffuseMap"; + } + } + return vaild; } PrePassMatInstanceHook::PrePassMatInstanceHook( MatInstance *baseMatInst, @@ -850,3 +1067,77 @@ Var* LinearEyeDepthConditioner::printMethodHeader( MethodType methodType, const return retVal; } + +void RenderPrePassMgr::_initShaders() +{ + if ( mClearGBufferShader ) return; + + // Find ShaderData + ShaderData *shaderData; + mClearGBufferShader = Sim::findObject( "ClearGBufferShader", shaderData ) ? shaderData->getShader() : NULL; + if ( !mClearGBufferShader ) + Con::errorf( "RenderPrePassMgr::_initShaders - could not find ClearGBufferShader" ); + + // Create StateBlocks + GFXStateBlockDesc desc; + desc.setCullMode( GFXCullNone ); + desc.setBlend( true ); + desc.setZReadWrite( false, false ); + desc.samplersDefined = true; + desc.samplers[0].addressModeU = GFXAddressWrap; + desc.samplers[0].addressModeV = GFXAddressWrap; + desc.samplers[0].addressModeW = GFXAddressWrap; + desc.samplers[0].magFilter = GFXTextureFilterLinear; + desc.samplers[0].minFilter = GFXTextureFilterLinear; + desc.samplers[0].mipFilter = GFXTextureFilterLinear; + desc.samplers[0].textureColorOp = GFXTOPModulate; + + mStateblock = GFX->createStateBlock( desc ); + + // Set up shader constants. + mShaderConsts = mClearGBufferShader->allocConstBuffer(); + mSpecularStrengthSC = mClearGBufferShader->getShaderConstHandle( "$specularStrength" ); + mSpecularPowerSC = mClearGBufferShader->getShaderConstHandle( "$specularPower" ); +} + +void RenderPrePassMgr::clearBuffers() +{ + // Clear z-buffer. + GFX->clear( GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI::ZERO, 1.0f, 0); + + if ( !mClearGBufferShader ) + return; + + GFXTransformSaver saver; + + // Clear the g-buffer. + RectI box(-1, -1, 3, 3); + GFX->setWorldMatrix( MatrixF::Identity ); + GFX->setViewMatrix( MatrixF::Identity ); + GFX->setProjectionMatrix( MatrixF::Identity ); + + GFX->setShader(mClearGBufferShader); + GFX->setStateBlock(mStateblock); + + Point2F nw(-0.5,-0.5); + Point2F ne(0.5,-0.5); + + GFXVertexBufferHandle verts(GFX, 4, GFXBufferTypeVolatile); + verts.lock(); + + F32 ulOffset = 0.5f - GFX->getFillConventionOffset(); + + Point2F upperLeft(-1.0, -1.0); + Point2F lowerRight(1.0, 1.0); + + verts[0].point.set( upperLeft.x+nw.x+ulOffset, upperLeft.y+nw.y+ulOffset, 0.0f ); + verts[1].point.set( lowerRight.x+ne.x, upperLeft.y+ne.y+ulOffset, 0.0f ); + verts[2].point.set( upperLeft.x-ne.x+ulOffset, lowerRight.y-ne.y, 0.0f ); + verts[3].point.set( lowerRight.x-nw.x, lowerRight.y-nw.y, 0.0f ); + + verts.unlock(); + + GFX->setVertexBuffer( verts ); + GFX->drawPrimitive( GFXTriangleStrip, 0, 2 ); + GFX->setShader(NULL); +} diff --git a/Engine/source/renderInstance/renderPrePassMgr.h b/Engine/source/renderInstance/renderPrePassMgr.h index 70a36eb84..bf36c6218 100644 --- a/Engine/source/renderInstance/renderPrePassMgr.h +++ b/Engine/source/renderInstance/renderPrePassMgr.h @@ -43,6 +43,10 @@ public: // registered buffer name static const String BufferName; + // andremwac: Deferred Rendering + static const String ColorBufferName; + static const String MatInfoBufferName; + // Generic PrePass Render Instance Type static const RenderInstType RIT_PrePass; @@ -93,6 +97,22 @@ protected: virtual void _createPrePassMaterial(); bool _lightManagerActivate(bool active); + + // Deferred Shading + GFXVertexBufferHandle mClearGBufferVerts; + GFXShaderRef mClearGBufferShader; + GFXStateBlockRef mStateblock; + NamedTexTarget mColorTarget; + NamedTexTarget mMatInfoTarget; + GFXTexHandle mColorTex; + GFXTexHandle mMatInfoTex; + GFXShaderConstBufferRef mShaderConsts; + GFXShaderConstHandle *mSpecularStrengthSC; + GFXShaderConstHandle *mSpecularPowerSC; + +public: + void clearBuffers(); + void _initShaders(); }; //------------------------------------------------------------------------------ diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/deferredShading.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/deferredShading.cs new file mode 100644 index 000000000..8a1df2c67 --- /dev/null +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/deferredShading.cs @@ -0,0 +1,147 @@ +singleton ShaderData( ClearGBufferShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/deferredClearGBufferP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl"; + + pixVersion = 2.0; +}; + +singleton ShaderData( DeferredColorShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/deferredColorShaderP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/deferredColorShaderP.glsl"; + + pixVersion = 2.0; +}; + +// Primary Deferred Shader +new GFXStateBlockData( AL_DeferredShadingState : PFX_DefaultStateBlock ) +{ + cullMode = GFXCullNone; + + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendSrcAlpha; + blendDest = GFXBlendInvSrcAlpha; + + samplersDefined = true; + samplerStates[0] = SamplerWrapLinear; + samplerStates[1] = SamplerWrapLinear; + samplerStates[2] = SamplerWrapLinear; + samplerStates[3] = SamplerWrapLinear; +}; + +new ShaderData( AL_DeferredShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/deferredShadingP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/deferredShadingP.glsl"; + + samplerNames[0] = "colorBufferTex"; + samplerNames[1] = "lightPrePassTex"; + samplerNames[2] = "matInfoTex"; + samplerNames[3] = "prepassTex"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_DeferredShading ) +{ + renderTime = "PFXBeforeBin"; + renderBin = "SkyBin"; + shader = AL_DeferredShader; + stateBlock = AL_DeferredShadingState; + texture[0] = "#color"; + texture[1] = "#lightinfo"; + texture[2] = "#matinfo"; + texture[3] = "#prepass"; + + target = "$backBuffer"; + renderPriority = 10000; + allowReflectPass = true; +}; + +// Debug Shaders. +new ShaderData( AL_ColorBufferShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgColorBufferP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl"; + + samplerNames[0] = "colorBufferTex"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_ColorBufferVisualize ) +{ + shader = AL_ColorBufferShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#color"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +/// Toggles the visualization of the AL lighting specular power buffer. +function toggleColorBufferViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_ColorBufferShaderVar = AL_ColorBufferVisualize.isEnabled() ? false : true; + AL_ColorBufferVisualize.toggle(); + } + else if ( %enable ) + { + AL_DeferredShading.disable(); + AL_ColorBufferVisualize.enable(); + } + else if ( !%enable ) + { + AL_ColorBufferVisualize.disable(); + AL_DeferredShading.enable(); + } +} + +new ShaderData( AL_SpecMapShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl"; + + samplerNames[0] = "matinfoTex"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_SpecMapVisualize ) +{ + shader = AL_SpecMapShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#matinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +/// Toggles the visualization of the AL lighting specular power buffer. +function toggleSpecMapViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_SpecMapShaderVar = AL_SpecMapVisualize.isEnabled() ? false : true; + AL_SpecMapVisualize.toggle(); + } + else if ( %enable ) + AL_SpecMapVisualize.enable(); + else if ( !%enable ) + AL_SpecMapVisualize.disable(); +} \ No newline at end of file diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/lightViz.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/lightViz.cs index 22665120d..fcaf72942 100644 --- a/Templates/Full/game/core/scripts/client/lighting/advanced/lightViz.cs +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/lightViz.cs @@ -56,7 +56,7 @@ new ShaderData( AL_DepthVisualizeShader ) OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl"; - samplerNames[0] = "prepassBuffer"; + samplerNames[0] = "prepassTex"; samplerNames[1] = "depthViz"; pixVersion = 2.0; @@ -113,7 +113,7 @@ new ShaderData( AL_NormalsVisualizeShader ) OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl"; - samplerNames[0] = "prepassBuffer"; + samplerNames[0] = "prepassTex"; pixVersion = 2.0; }; @@ -149,7 +149,7 @@ new ShaderData( AL_LightColorVisualizeShader ) OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl"; - samplerNames[0] = "lightInfoBuffer"; + samplerNames[0] = "lightPrePassTex"; pixVersion = 2.0; }; @@ -184,7 +184,7 @@ new ShaderData( AL_LightSpecularVisualizeShader ) OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl"; - samplerNames[0] = "lightInfoBuffer"; + samplerNames[0] = "lightPrePassTex"; pixVersion = 2.0; }; @@ -280,3 +280,16 @@ function toggleLightSpecularViz( %enable ) AL_LightSpecularVisualize.disable(); } +function toggleBackbufferViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_BackbufferVisualizeVar = AL_DeferredShading.isEnabled() ? true : false; + AL_DeferredShading.toggle(); + } + else if ( %enable ) + AL_DeferredShading.disable(); + else if ( !%enable ) + AL_DeferredShading.enable(); +} + diff --git a/Templates/Full/game/shaders/common/lighting/advanced/dbgColorBufferP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/dbgColorBufferP.hlsl new file mode 100644 index 000000000..349c943f9 --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/dbgColorBufferP.hlsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D colorBufferTex : register(S0) ) : COLOR0 +{ + return float4(tex2D( colorBufferTex, IN.uv0 ).rgb, 1.0); +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl new file mode 100644 index 000000000..ba5f2c0e1 --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D matinfoTex : register(S0) ) : COLOR0 +{ + float specular = tex2D( matinfoTex, IN.uv0 ).b; + return float4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl new file mode 100644 index 000000000..df9870248 --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +struct Fragout +{ + float4 col : COLOR0; + float4 col1 : COLOR1; + float4 col2 : COLOR2; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ) +{ + Fragout OUT; + + // Clear Prepass Buffer ( Normals/Depth ); + OUT.col = float4(1.0, 1.0, 1.0, 1.0); + + // Clear Color Buffer. + OUT.col1 = float4(0.0, 0.0, 0.0, 1.0); + + // Clear Material Info Buffer. + OUT.col2 = float4(0.0, 0.0, 0.0, 1.0); + + return OUT; +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/deferredShadingP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/deferredShadingP.hlsl new file mode 100644 index 000000000..80e6acde0 --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/deferredShadingP.hlsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" +#include "shaders/common/torque.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D colorBufferTex : register(S0), + uniform sampler2D lightPrePassTex : register(S1), + uniform sampler2D matInfoTex : register(S2), + uniform sampler2D prepassTex : register(S3)) : COLOR0 +{ + float4 lightBuffer = tex2D( lightPrePassTex, IN.uv0 ); + float4 colorBuffer = tex2D( colorBufferTex, IN.uv0 ); + float4 matInfo = tex2D( matInfoTex, IN.uv0 ); + float specular = saturate(lightBuffer.a); + float depth = prepassUncondition( prepassTex, IN.uv0 ).w; + + if (depth>0.9999) + return float4(0,0,0,0); + + // Diffuse Color Altered by Metalness + bool metalness = getFlag(matInfo.r, 3); + if ( metalness ) + { + colorBuffer *= (1.0 - colorBuffer.a); + } + + colorBuffer *= float4(lightBuffer.rgb, 1.0); + colorBuffer += float4(specular, specular, specular, 1.0); + + return hdrEncode( float4(colorBuffer.rgb, 1.0) ); +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl new file mode 100644 index 000000000..48a96d47d --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../../postfx/gl/postFx.glsl" + +uniform sampler2D colorBufferTex; + +out vec4 OUT_FragColor0; + +void main() +{ + OUT_FragColor0 = vec4(texture( colorBufferTex, uv0 ).rgb, 1.0); +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl new file mode 100644 index 000000000..4ba9f6734 --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../../postfx/gl/postFx.glsl" + +uniform sampler2D matinfoTex; + +out vec4 OUT_FragColor0; + +void main() +{ + float specular = texture( matinfoTex, uv0 ).a; + OUT_FragColor0 = vec4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl new file mode 100644 index 000000000..39dc0dc9f --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +out vec4 OUT_col; +out vec4 OUT_col1; +out vec4 OUT_col2; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Clear Prepass Buffer ( Normals/Depth ); + OUT_col = vec4(1.0, 1.0, 1.0, 1.0); + + // Clear Color Buffer. + OUT_col1 = vec4(0.0, 0.0, 0.0, 1.0); + + // Clear Material Info Buffer. + OUT_col2 = vec4(0.0, 0.0, 0.0, 1.0); +} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/deferredShadingP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/deferredShadingP.glsl new file mode 100644 index 000000000..4ee4b1d81 --- /dev/null +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/deferredShadingP.glsl @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../../postfx/gl/postFx.glsl" +#include "../../../gl/torque.glsl" + +uniform sampler2D colorBufferTex; +uniform sampler2D lightPrePassTex; +uniform sampler2D matInfoTex; +uniform sampler2D prepassTex; + +out vec4 OUT_col; + +void main() +{ + float depth = prepassUncondition( prepassTex, uv0 ).w; + if (depth>0.9999) + { + OUT_col = vec4(0.0); + return; + } + vec4 lightBuffer = texture( lightPrePassTex, uv0 ); + vec4 colorBuffer = texture( colorBufferTex, uv0 ); + vec4 matInfo = texture( matInfoTex, uv0 ); + float specular = clamp(lightBuffer.a,0.0,1.0); + + // Diffuse Color Altered by Metalness + bool metalness = getFlag(matInfo.r, 3); + if ( metalness ) + { + colorBuffer *= (1.0 - colorBuffer.a); + } + + colorBuffer *= vec4(lightBuffer.rgb, 1.0); + colorBuffer += vec4(specular, specular, specular, 1.0); + + OUT_col = hdrEncode( vec4(colorBuffer.rgb, 1.0) ); +} diff --git a/Templates/Full/game/tools/worldEditor/main.cs b/Templates/Full/game/tools/worldEditor/main.cs index a6ecb2872..59301ea53 100644 --- a/Templates/Full/game/tools/worldEditor/main.cs +++ b/Templates/Full/game/tools/worldEditor/main.cs @@ -120,6 +120,9 @@ function initializeWorldEditor() EVisibility.addOption( "AL: Light Specular Viz", "$AL_LightSpecularVisualizeVar", "toggleLightSpecularViz" ); EVisibility.addOption( "AL: Normals Viz", "$AL_NormalsVisualizeVar", "toggleNormalsViz" ); EVisibility.addOption( "AL: Depth Viz", "$AL_DepthVisualizeVar", "toggleDepthViz" ); + EVisibility.addOption( "AL: Color Buffer", "$AL_ColorBufferShaderVar", "toggleColorBufferViz" ); + EVisibility.addOption( "AL: Spec Map", "$AL_SpecMapShaderVar", "toggleSpecMapViz"); + EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" ); EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" ); EVisibility.addOption( "AL: PSSM Cascade Viz", "$AL::PSSMDebugRender", "" ); EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" );