summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r--indra/newview/pipeline.cpp220
1 files changed, 198 insertions, 22 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9f0e2906d0..f664e06dd5 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -232,6 +232,7 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
+LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");
LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
@@ -261,6 +262,7 @@ std::string gPoolNames[] =
"POOL_GROUND",
"POOL_FULLBRIGHT",
"POOL_BUMP",
+ "POOL_MATERIALS",
"POOL_TERRAIN,"
"POOL_SKY",
"POOL_WL_SKY",
@@ -376,6 +378,7 @@ BOOL LLPipeline::sRenderDeferred = FALSE;
BOOL LLPipeline::sMemAllocationThrottled = FALSE;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
+BOOL LLPipeline::sRenderingHUDs;
static LLCullResult* sCull = NULL;
@@ -396,7 +399,7 @@ void validate_framebuffer_object();
bool addDeferredAttachments(LLRenderTarget& target)
{
return target.addColorAttachment(GL_RGBA) && //specular
- target.addColorAttachment(GL_RGBA); //normal+z
+ target.addColorAttachment(GL_RGBA); //normal+z
}
LLPipeline::LLPipeline() :
@@ -486,6 +489,7 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_FULLBRIGHT);
getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
@@ -904,11 +908,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
BOOL ssao = RenderDeferredSSAO;
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mDeferredScreen.allocate(resX, resY, GL_RGBA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!addDeferredAttachments(mDeferredScreen)) return false;
-
- if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+ if (!mScreen.allocate(resX, resY, GL_RGBA12, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
@@ -1200,7 +1204,7 @@ void LLPipeline::createGLBuffers()
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
+ mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE);
}
allocateScreenBuffer(resX,resY);
@@ -1251,13 +1255,18 @@ void LLPipeline::createGLBuffers()
gBumpImageList.restoreGL();
}
+F32 lerpf(F32 a, F32 b, F32 w)
+{
+ return a + w * (b - a);
+}
+
void LLPipeline::createLUTBuffers()
{
if (sRenderDeferred)
{
if (!mLightFunc)
{
- U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ /*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
U8* ls = new U8[lightResX*lightResY];
F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
@@ -1293,11 +1302,61 @@ void LLPipeline::createLUTBuffers()
// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
}
+ }*/
+
+
+ U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
+ F32* ls = new F32[lightResX*lightResY];
+ //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
+ for (U32 y = 0; y < lightResY; ++y)
+ {
+ for (U32 x = 0; x < lightResX; ++x)
+ {
+ ls[y*lightResX+x] = 0;
+ F32 sa = (F32) x/(lightResX-1);
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * 368;
+
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
+
+ // Apply our normalization function.
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+
+ spec = llclamp(spec, 0.f, 1.f);
+ spec = powf(spec, 0.6f);
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
+
+
+ //beckmann distribution
+ /*F32 alpha = acosf((F32) x/(lightResX-1));
+ F32 m = 1.f - (F32) y/(lightResY-1);
+
+ F32 cos4_alpha = cosf(alpha);
+ cos4_alpha *= cos4_alpha;
+ cos4_alpha *= cos4_alpha;
+
+ F32 tan_alpha = tanf(alpha);
+ F32 tan2_alpha = tan_alpha*tan_alpha;
+
+ F32 k = expf(-(tan2_alpha)/(m*m)) /
+ (3.14159f*m*m*cos4_alpha);
+
+ ls[y*lightResX+x] = k;*/
+ }
}
LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
@@ -1526,7 +1585,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_BUMP:
poolp = mBumpPool;
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
case LLDrawPool::POOL_ALPHA:
poolp = mAlphaPool;
break;
@@ -1595,14 +1656,41 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
-
+
+ if (alpha && te->getMaterialParams())
+ {
+ switch (te->getMaterialParams()->getDiffuseAlphaMode())
+ {
+ case 1:
+ alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
+ break;
+ case 0: //alpha mode set to none, never go to alpha pool
+ case 3: //alpha mode set to emissive, never go to alpha pool
+ alpha = false;
+ break;
+ default: //alpha mode set to "mask", go to alpha pool if fullbright
+ if (te->getFullbright())
+ {
+ alpha = true;
+ }
+ else
+ {
+ alpha = false; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
+ }
+ break;
+ }
+ }
+
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
- else if ((te->getBumpmap() || te->getShiny()))
+ else if ((te->getBumpmap() || te->getShiny()) && te->getMaterialID().isNull())
{
return LLDrawPool::POOL_BUMP;
+ } else if (!te->getMaterialID().isNull() && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
}
else
{
@@ -3571,8 +3659,8 @@ void LLPipeline::postSort(LLCamera& camera)
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED) ||
+ if ((sUseOcclusion &&
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
(RenderAutoHideSurfaceAreaLimit > 0.f &&
group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
{
@@ -4994,8 +5082,8 @@ void LLPipeline::renderDebug()
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
- if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) ||
- !hud_only && hasRenderType(part->mDrawableType) )
+ if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
+ (!hud_only && hasRenderType(part->mDrawableType)) )
{
part->renderDebug();
}
@@ -5377,7 +5465,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mBumpPool = new_poolp;
}
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ llwarns << "Ignorning duplicate materials pool." << llendl;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA:
if( mAlphaPool )
{
@@ -5386,7 +5484,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
else
{
- mAlphaPool = new_poolp;
+ mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
}
break;
@@ -5517,7 +5615,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
llassert( poolp == mBumpPool );
mBumpPool = NULL;
break;
-
+
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
case LLDrawPool::POOL_ALPHA:
llassert( poolp == mAlphaPool );
mAlphaPool = NULL;
@@ -6889,6 +6992,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text
gGLLastMatrix = NULL;
}
+void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
+{
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ mAlphaPool->pushMaskBatches(type, mask, texture, batch_texture);
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
+
+
void apply_cube_face_rotation(U32 face)
{
switch (face)
@@ -7331,6 +7445,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mScreen.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
@@ -7372,6 +7493,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
mScreen.bindTexture(0, channel);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -7792,6 +7920,22 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
}
}
+LLColor3 pow3f(LLColor3 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
+LLVector4 pow4fsrgb(LLVector4 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");
static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");
static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map");
@@ -8230,7 +8374,7 @@ void LLPipeline::renderDeferredLighting()
light_colors.pop_front();
far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
-
+ //col[count] = pow4fsrgb(col[count], 2.2f);
count++;
if (count == max_count || fullscreen_lights.empty())
{
@@ -8867,7 +9011,15 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY
+ LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
LLGLEnable cull(GL_CULL_FACE);
@@ -8938,7 +9090,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LLFastTimer ftm(FTM_SHADOW_ALPHA);
gDeferredShadowAlphaMaskProgram.bind();
- gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
U32 mask = LLVertexBuffer::MAP_VERTEX |
@@ -8946,10 +9097,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
- renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
+
+ mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+
gDeferredTreeShadowProgram.bind();
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
@@ -9283,6 +9443,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
END_RENDER_TYPES);
gGL.setColorMask(false, false);