diff --git a/source/renderer/DecalRData.cpp b/source/renderer/DecalRData.cpp index 2694af746a..46113611a0 100644 --- a/source/renderer/DecalRData.cpp +++ b/source/renderer/DecalRData.cpp @@ -48,7 +48,8 @@ namespace struct SDecalBatch { CDecalRData* decal; - CShaderTechniquePtr shaderTech; + CStrIntern shaderEffect; + CShaderDefines shaderDefines; CVertexBuffer::VBChunk* vertices; CVertexBuffer::VBChunk* indices; }; @@ -57,8 +58,10 @@ struct SDecalBatchComparator { bool operator()(const SDecalBatch& lhs, const SDecalBatch& rhs) const { - if (lhs.shaderTech != rhs.shaderTech) - return lhs.shaderTech < rhs.shaderTech; + if (lhs.shaderEffect != rhs.shaderEffect) + return lhs.shaderEffect < rhs.shaderEffect; + if (lhs.shaderDefines != rhs.shaderDefines) + return lhs.shaderDefines < rhs.shaderDefines; const CMaterial& lhsMaterial = lhs.decal->GetDecal()->m_Decal.m_Material; const CMaterial& rhsMaterial = rhs.decal->GetDecal()->m_Decal.m_Material; if (lhsMaterial.GetDiffuseTexture() != rhsMaterial.GetDiffuseTexture()) @@ -111,7 +114,7 @@ void CDecalRData::RenderDecals( for (CDecalRData* decal : decals) { - CMaterial &material = decal->m_Decal->m_Decal.m_Material; + CMaterial& material = decal->m_Decal->m_Decal.m_Material; if (material.GetShaderEffect().empty()) { @@ -119,23 +122,13 @@ void CDecalRData::RenderDecals( continue; } - CShaderDefines defines = contextDecal; - defines.SetMany(material.GetShaderDefines()); - CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect( - material.GetShaderEffect(), defines); - if (!techBase) - { - LOGERROR("Terrain renderer failed to load shader effect (%s)\n", - material.GetShaderEffect().string().c_str()); - continue; - } - if (material.GetSamplers().empty() || !decal->m_VBDecals || !decal->m_VBDecalsIndices) continue; SDecalBatch batch; batch.decal = decal; - batch.shaderTech = techBase; + batch.shaderEffect = material.GetShaderEffect(); + batch.shaderDefines = material.GetShaderDefines(); batch.vertices = decal->m_VBDecals.Get(); batch.indices = decal->m_VBDecalsIndices.Get(); @@ -150,12 +143,25 @@ void CDecalRData::RenderDecals( CVertexBuffer* lastIB = nullptr; for (auto itTechBegin = batches.begin(), itTechEnd = batches.begin(); itTechBegin != batches.end(); itTechBegin = itTechEnd) { - while (itTechEnd != batches.end() && itTechBegin->shaderTech == itTechEnd->shaderTech) + while (itTechEnd != batches.end() && + itTechBegin->shaderEffect == itTechEnd->shaderEffect && + itTechBegin->shaderDefines == itTechEnd->shaderDefines) + { ++itTechEnd; + } + + CShaderDefines defines = contextDecal; + defines.SetMany(itTechBegin->shaderDefines); + CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect( + itTechBegin->shaderEffect, defines); + if (!techBase) + { + LOGERROR("Terrain renderer failed to load shader effect (%s)\n", + itTechBegin->shaderEffect.c_str()); + continue; + } - const CShaderTechniquePtr& techBase = itTechBegin->shaderTech; const int numPasses = techBase->GetNumPasses(); - for (int pass = 0; pass < numPasses; ++pass) { Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc = diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp index 3d3f14a8de..7db8efaa6a 100644 --- a/source/renderer/PatchRData.cpp +++ b/source/renderer/PatchRData.cpp @@ -712,7 +712,7 @@ using VertexBufferBatches = PooledBatchMap; using TextureBatches = PooledBatchMap; // Group batches by shaders. -using ShaderTechniqueBatches = PooledBatchMap; +using ShaderTechniqueBatches = PooledBatchMap, TextureBatches>; void CPatchRData::RenderBases( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, @@ -740,15 +740,11 @@ void CPatchRData::RenderBases( LOGERROR("Terrain renderer failed to load shader effect.\n"); continue; } - CShaderDefines defines = context; - defines.SetMany(material.GetShaderDefines()); - CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect( - material.GetShaderEffect(), defines); BatchElements& batch = PooledPairGet( PooledMapGet( PooledMapGet( - PooledMapGet(batches, techBase, arena), + PooledMapGet(batches, std::make_pair(material.GetShaderEffect(), material.GetShaderDefines()), arena), splat.m_Texture, arena ), patch->m_VBBase->m_Owner, arena @@ -767,7 +763,11 @@ void CPatchRData::RenderBases( // Render each batch for (ShaderTechniqueBatches::iterator itTech = batches.begin(); itTech != batches.end(); ++itTech) { - const CShaderTechniquePtr& techBase = itTech->first; + CShaderDefines defines = context; + defines.SetMany(itTech->first.second); + CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect( + itTech->first.first, defines); + const int numPasses = techBase->GetNumPasses(); for (int pass = 0; pass < numPasses; ++pass) {