Updated rigged mesh face batch/pool handling.

Fixed issue with fullbright and glow occlusion.
RenderTransparentWater toggling should work more gracefully.
Fixed some bugs in general drawpool classification for faces. Bump pool was superceding more than it should have.
This commit is contained in:
Shyotl
2014-03-27 21:27:40 -05:00
parent bb0f17ae6f
commit 5988f6cf88
7 changed files with 157 additions and 49 deletions

View File

@@ -1951,7 +1951,7 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
renderRigged(avatar, RIGGED_ALPHA);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
//gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.setColorMask(true, false);
}
}
@@ -1969,7 +1969,7 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
//gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.setColorMask(true, false);
}
}

View File

@@ -548,11 +548,17 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
{
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightWaterProgram.bind();
//gDeferredFullbrightWaterProgram.bind();
//Use alpha-mask version to ignore alpha values while still allowing us to occlude glow.
gDeferredFullbrightAlphaMaskWaterProgram.bind();
gDeferredFullbrightAlphaMaskWaterProgram.setMinimumAlpha(0.f);
}
else
{
gDeferredFullbrightProgram.bind();
//gDeferredFullbrightProgram.bind();
//Use alpha-mask version to ignore alpha values while still allowing us to occlude glow.
gDeferredFullbrightAlphaMaskProgram.bind();
gDeferredFullbrightAlphaMaskProgram.setMinimumAlpha(0.f);
}
}
@@ -573,11 +579,11 @@ void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
{
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightWaterProgram.unbind();
gDeferredFullbrightAlphaMaskWaterProgram.unbind();
}
else
{
gDeferredFullbrightProgram.unbind();
gDeferredFullbrightAlphaMaskProgram.unbind();
}
LLRenderPass::endRenderPass(pass);
}

View File

@@ -1338,9 +1338,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
if (shiny_in_alpha)
if(getPoolType() == LLDrawPool::POOL_FULLBRIGHT)
{
color.mV[3] = 1.f; //Simple fullbright reads alpha for fog contrib, not shiny/transparency, so since opaque, force to 1.
}
else if (shiny_in_alpha)
{
GLfloat alpha[4] =
{
0.00f,

View File

@@ -204,6 +204,12 @@ bool handleRenderAvatarComplexityLimitChanged(const LLSD& newvalue)
bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
{
LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && gSavedSettings.getBOOL("VertexShaderEnable");
if (gPipeline.isInit()) //If water is opaque then distortion/reflection fbos will not be needed.
{
gPipeline.releaseGLBuffers();
gPipeline.createGLBuffers();
}
LLWorld::getInstance()->updateWaterObjects();
return true;
}

View File

@@ -4191,10 +4191,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
U32 pool_type = facep->getPoolType();
bool cmp_bump = (type == LLRenderPass::PASS_BUMP) || (type == LLRenderPass::PASS_POST_BUMP);
bool cmp_shiny = !alt_batching ? !!mat : ((type == LLRenderPass::PASS_SHINY) || (type == LLRenderPass::PASS_FULLBRIGHT_SHINY) || (type == LLRenderPass::PASS_INVISI_SHINY));
bool cmp_mat = !alt_batching || LLPipeline::sRenderDeferred && ((facep->getPoolType() == LLDrawPool::POOL_MATERIALS) || (facep->getPoolType() == LLDrawPool::POOL_ALPHA));
bool cmp_mat = (!alt_batching) || LLPipeline::sRenderDeferred && facep->getTextureEntry()->getColor().mV[3] >= 0.999f &&
((pool_type == LLDrawPool::POOL_MATERIALS) || (pool_type == LLDrawPool::POOL_ALPHA));
bool cmp_shiny = (!alt_batching) ? !!mat : (mat && cmp_mat);
bool cmp_fullbright = !alt_batching || cmp_shiny || pool_type == LLDrawPool::POOL_ALPHA;
U8 bump = facep->getTextureEntry()->getBumpmap();
U8 shiny = facep->getTextureEntry()->getShiny();
@@ -4209,7 +4213,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 shader_mask = 0xFFFFFFFF; //no shader
if (mat)
if (mat && cmp_mat)
{
if (type == LLRenderPass::PASS_ALPHA)
{
@@ -4255,9 +4259,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
#endif
(!cmp_mat || draw_vec[idx]->mMaterial == mat) &&
//draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright &&
(!cmp_fullbright || draw_vec[idx]->mFullbright == fullbright) &&
(!cmp_bump || draw_vec[idx]->mBump == bump) &&
(!cmp_shiny || !!draw_vec[idx]->mShiny == !!shiny) &&
(!cmp_shiny || draw_vec[idx]->mShiny == shiny) &&
//(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat &&
draw_vec[idx]->mModelMatrix == model_mat &&
@@ -4539,6 +4543,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
bool is_rigged = false;
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
//for each face
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
@@ -4647,7 +4653,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
LLMaterial* mat = te->getMaterialParams().get();
if(!alt_batching)
{
if (mat && LLPipeline::sRenderDeferred)
{
U8 alpha_mode = mat->getDiffuseAlphaMode();
@@ -4760,6 +4768,68 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
}
}
else
{
if(type == LLDrawPool::POOL_ALPHA)
{
if(te->getColor().mV[3] > 0.f)
{
U32 mask = te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA;
if (mat && LLPipeline::sRenderDeferred && te->getColor().mV[3] >= 0.999f )
{
if(mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND);
else
mask = mat->getShaderMask();
}
pool->addRiggedFace(facep, mask);
}
}
else if(!LLPipeline::sRenderDeferred)
{
if(type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
else if(type == LLDrawPool::POOL_SIMPLE || type == LLDrawPool::POOL_ALPHA_MASK)
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
else if(type == LLDrawPool::POOL_BUMP) //Either shiny, or bump (which isn't used in non-deferred)
{
if(te->getShiny())
pool->addRiggedFace(facep, te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY);
else
pool->addRiggedFace(facep, te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
}
else
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
else
{
if( type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
//Annoying exception to the rule. getPoolTypeFromTE will return POOL_ALPHA_MASK for legacy bumpmaps, but there is no POOL_ALPHA_MASK in deferred.
else if(type == LLDrawPool::POOL_MATERIALS || (type == LLDrawPool::POOL_ALPHA_MASK && mat))
{
pool->addRiggedFace(facep, mat->getShaderMask());
}
else if (type == LLDrawPool::POOL_BUMP && te->getBumpmap())
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
}
else
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
}
}
}
}
continue;
@@ -4804,8 +4874,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
bool force_fullbright = group->isHUDGroup();
BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
U32 type = gPipeline.getPoolTypeFromTE(te, tex);
@@ -4836,7 +4904,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
}
else if (force_fullbright)
else if (force_fullbright) //Hud is done in a forward render. Fullbright cannot be shared with simple.
{
if(type == LLDrawPool::POOL_ALPHA_MASK)
type = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK;
@@ -5368,11 +5436,9 @@ struct CompareBatchBreakerModified
return lte->getMaterialParams() < rte->getMaterialParams();
}
else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny()))
{
return lte->getShiny() < rte->getShiny();
}
else
{
return lhs->getTexture() < rhs->getTexture();
@@ -5396,9 +5462,11 @@ struct CompareBatchBreakerModified
return !(batch_left < batch_right);
}
bool batch_shiny = (!LLPipeline::sRenderDeferred || lhs->isState(LLFace::FULLBRIGHT)) && lhs->getPoolType() == LLDrawPool::POOL_BUMP;
static const LLCachedControl<bool> sh_fullbright_deferred("SHFullbrightDeferred",true);
bool batch_shiny = (!LLPipeline::sRenderDeferred || (sh_fullbright_deferred && lhs->isState(LLFace::FULLBRIGHT))) && lhs->getPoolType() == LLDrawPool::POOL_BUMP;
bool batch_fullbright = sh_fullbright_deferred || !LLPipeline::sRenderDeferred && lhs->getPoolType() == LLDrawPool::POOL_ALPHA;
if (lhs->isState(LLFace::FULLBRIGHT) != rhs->isState(LLFace::FULLBRIGHT))
if (batch_fullbright && lhs->isState(LLFace::FULLBRIGHT) != rhs->isState(LLFace::FULLBRIGHT))
{
return lhs->isState(LLFace::FULLBRIGHT) < rhs->isState(LLFace::FULLBRIGHT);
}
@@ -6196,21 +6264,40 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
llassert_always(mask & LLVertexBuffer::MAP_NORMAL);
}
if (is_fullbright)
if(LLPipeline::sRenderDeferred)
{
registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT);
if(is_bump)
registerFace(group, facep, LLPipeline::sRenderDeferred ? LLRenderPass::PASS_POST_BUMP : LLRenderPass::PASS_BUMP);
static const LLCachedControl<bool> sh_fullbright_deferred("SHFullbrightDeferred",true);
if(sh_fullbright_deferred && is_fullbright)
{
registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT);
if(is_bump)
{
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
else
{
//is_bump should always be true.
registerFace(group, facep, is_bump ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_SIMPLE);
}
}
else
{
registerFace(group, facep, (LLPipeline::sRenderDeferred || !is_shiny_shader) ? LLRenderPass::PASS_SIMPLE : LLRenderPass::PASS_SHINY);
if (is_fullbright )
{
registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT);
}
else
{
registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_SHINY : LLRenderPass::PASS_SIMPLE);
}
if(is_bump)
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
if(is_shiny_fixed)
registerFace(group, facep, LLRenderPass::PASS_SHINY);
if(is_shiny_fixed)
registerFace(group, facep, LLRenderPass::PASS_SHINY);
}
}
}
if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)

View File

@@ -166,7 +166,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
static const LLCachedControl<bool> render_transparent_water("RenderTransparentWater",false);
static const LLCachedControl<U32> water_subdiv("SianaVoidWaterSubdivision", 16);
const S32 size = (render_transparent_water && LLGLSLShader::sNoFixedFunction) ? water_subdiv : 1;
const S32 size = ((render_transparent_water || LLPipeline::sRenderDeferred) && LLGLSLShader::sNoFixedFunction) ? water_subdiv : 1;
const S32 num_quads = size * size;
face->setSize(vertices_per_quad * num_quads,
indices_per_quad * num_quads);

View File

@@ -1567,34 +1567,39 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
else
{
static const LLCachedControl<bool> sh_fullbright_deferred("SHFullbrightDeferred",true);
//Bump goes into bump pool unless using deferred and there's a normal map that takes precedence.
bool legacy_bump = (!LLPipeline::sRenderDeferred || !mat || mat->getNormalID().isNull()) && LLPipeline::sRenderBump && te->getBumpmap() && te->getBumpmap() < 18;
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
else if ((!LLPipeline::sRenderDeferred || !mat || mat->getNormalID().isNull()) && LLPipeline::sRenderBump && te->getBumpmap() && te->getBumpmap() < 18)
{
return LLDrawPool::POOL_BUMP; //Bump goes into bump pool unless using deferred and there's a normal map that takes precedence.
}
else if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
if(te->getFullbright())
if(!LLPipeline::sRenderDeferred || legacy_bump)
{
return te->getFullbright() ? LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK : LLDrawPool::POOL_ALPHA_MASK;
}
else if(te->getFullbright() && !mat->getEnvironmentIntensity() && !te->getShiny())
{
return LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK;
}
else
{
return LLPipeline::sRenderDeferred ? LLDrawPool::POOL_MATERIALS : LLDrawPool::POOL_ALPHA_MASK;
}
return LLDrawPool::POOL_MATERIALS;
}
else if (legacy_bump)
{
return LLDrawPool::POOL_BUMP;
}
else if(LLPipeline::sRenderDeferred && mat)
{
if(te->getFullbright() && mat->getEnvironmentIntensity())
if(te->getFullbright() && !mat->getEnvironmentIntensity() && !te->getShiny())
{
return LLDrawPool::POOL_FULLBRIGHT;
return sh_fullbright_deferred ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE;
}
return LLDrawPool::POOL_MATERIALS;
}
else if(te->getFullbright())
else if((sh_fullbright_deferred || !LLPipeline::sRenderDeferred) && te->getFullbright())
{
return (LLPipeline::sRenderBump && te->getShiny()) ? LLDrawPool::POOL_BUMP : LLDrawPool::POOL_FULLBRIGHT;
}
@@ -8558,10 +8563,10 @@ void LLPipeline::renderDeferredLighting()
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
//LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_GLOW,
LLPipeline::RENDER_TYPE_BUMP,
/*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used.
LLPipeline::RENDER_TYPE_PASS_SIMPLE,
LLPipeline::RENDER_TYPE_PASS_ALPHA,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_BUMP,
@@ -8573,7 +8578,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
@@ -9181,10 +9186,10 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
//LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_GLOW,
LLPipeline::RENDER_TYPE_BUMP,
/*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used.
LLPipeline::RENDER_TYPE_PASS_SIMPLE,
LLPipeline::RENDER_TYPE_PASS_ALPHA,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_BUMP,
@@ -9196,7 +9201,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
@@ -9401,7 +9406,8 @@ inline float sgn(float a)
void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
static const LLCachedControl<bool> render_transparent_water("RenderTransparentWater",false);
if ((render_transparent_water || LLPipeline::sRenderDeferred) && LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
{
BOOL skip_avatar_update = FALSE;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)