From ed1b78e32235680c3978b9830e5ba81115a0ab7d Mon Sep 17 00:00:00 2001 From: Jonathan Goodman Date: Tue, 28 Aug 2012 10:33:32 -0400 Subject: Added support for adding custom preprocessor definitions (for shader permutations) --- indra/newview/llviewershadermgr.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4b0e0598f6..8c0ec4e275 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -826,12 +826,15 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); } shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); - + + std::map attribs; + attribs["NULL"] = "0"; + // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. for (U32 i = 0; i < shaders.size(); i++) { // Note usage of GL_VERTEX_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0) + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, attribs) == 0) { return FALSE; } @@ -879,11 +882,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); - + for (U32 i = 0; i < shaders.size(); i++) { // Note usage of GL_FRAGMENT_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0) + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, attribs, index_channels[i]) == 0) { return FALSE; } -- cgit v1.2.3 From c911efb953a600092a6213c088d5b94fcf7779d3 Mon Sep 17 00:00:00 2001 From: Jonathan Goodman Date: Wed, 29 Aug 2012 03:41:26 -0400 Subject: Just pass in an empty preprocessor definition map from now on. The shader compiler won't add new #defines if it's empty. --- indra/newview/llviewershadermgr.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview') diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 8c0ec4e275..e70bf013e7 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -828,7 +828,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); std::map attribs; - attribs["NULL"] = "0"; // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. for (U32 i = 0; i < shaders.size(); i++) -- cgit v1.2.3 From d5b45b0b636557333c3408e7a60d5ef587ea99ad Mon Sep 17 00:00:00 2001 From: Jonathan Goodman Date: Wed, 29 Aug 2012 08:02:46 -0400 Subject: Use an unordered map for custom #defines instead of a map. Lookups are faster, and we don't really care about any particular order anyways for these. --- indra/newview/llviewershadermgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview') diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e70bf013e7..43de7450c8 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -827,7 +827,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() } shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); - std::map attribs; + boost::unordered_map attribs; // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. for (U32 i = 0; i < shaders.size(); i++) -- cgit v1.2.3 From 9593e85e144e2141c92abe597653851852501060 Mon Sep 17 00:00:00 2001 From: Jonathan Goodman Date: Sun, 9 Sep 2012 21:01:24 -0400 Subject: Use a customized normalized gaussian specular term. --- .../shaders/class1/deferred/multiPointLightF.glsl | 3 +- .../shaders/class1/deferred/pointLightF.glsl | 3 +- .../shaders/class1/deferred/softenLightF.glsl | 2 +- .../shaders/class2/deferred/softenLightF.glsl | 2 +- indra/newview/pipeline.cpp | 52 +++++++++++----------- 5 files changed, 30 insertions(+), 32 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 7e79317543..9e194cdcd1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -128,8 +128,7 @@ void main() if (sa > 0.0) { - sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); - sa *= noise; + sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); col += da*sa*light_col[i].rgb*spec.rgb; } } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 75757b26c8..6e5ac8317b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -110,8 +110,7 @@ void main() float sa = dot(normalize(lv-normalize(pos)),norm); if (sa > 0.0) { - sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); - sa *= noise; + sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); col += da*sa*color.rgb*spec.rgb; } } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 89448e2167..14eaafeb68 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -301,7 +301,7 @@ void main() // vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); + vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 9df9d75905..457189b48e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -309,7 +309,7 @@ void main() // vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); + vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 920bac93a2..28fc70e38a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -397,7 +397,7 @@ void validate_framebuffer_object(); bool addDeferredAttachments(LLRenderTarget& target) { return target.addColorAttachment(GL_RGBA) && //specular - target.addColorAttachment(GL_RGBA); //normal+z + target.addColorAttachment(GL_RGB10_A2); //normal+z } LLPipeline::LLPipeline() : @@ -863,7 +863,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, 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 (samples > 0) { @@ -1206,6 +1206,11 @@ void LLPipeline::createGLBuffers() gBumpImageList.restoreGL(); } +F32 lerpf(F32 a, F32 b, F32 w) +{ + return a + w * (b - a); +} + void LLPipeline::createLUTBuffers() { if (sRenderDeferred) @@ -1214,45 +1219,40 @@ void LLPipeline::createLUTBuffers() { U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - U8* ls = new U8[lightResX*lightResY]; - F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); - // Calculate the (normalized) Blinn-Phong specular lookup texture. + F32* ls = new F32[lightResX*lightResY]; + //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions. + // Calculate the (normalized) Gaussian 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 * specExp; + F32 spec = (F32) y/(lightResY); + F32 n = spec; - // Nothing special here. Just your typical blinn-phong term. - spec = powf(sa, n); + float angleNormalHalf = acosf(sa); + float exponent = angleNormalHalf / ((1 - n)); + exponent = -(exponent * exponent); + spec = expf(exponent); // 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. - // The only trade off is we have a really low dynamic range. - // This means we have to account for things not being able to exceed 0 to 1 in our shaders. - spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + // This is based around the phong normalization function, trading n+2 for n+1 instead. + // Since we're using a gaussian model here, we actually don't really need as large of an exponent as blinn-phong shading. + // Instead, we assume that the correct exponent is 8 here. + // This was achieved through much tweaking to find a decent "middleground" with our specular highlights with the gaussian term. + // Bigger highlights don't look too soft, smaller highlights don't look too bright, and everything in the middle seems to have a well maintained highlight curvature. + // There isn't really much theory behind this one. This was done purely to produce a nice and mostly customizable BRDF. - // Always sample at a 1.0/2.2 curve. - // This "Gamma corrects" our specular term, boosting our lower exponent reflections. - spec = powf(spec, 1.f/2.2f); + spec = lerpf(spec, spec * (n * 8 + 1) / 4.5, n); - // Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders. - // This allows for our specular term to exceed a value of 1 in our shaders. - // This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1. - // Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times. - // This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents. - // 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); + ls[y*lightResX+x] = spec; } } - LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc); + LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 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); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); -- cgit v1.2.3