summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorGraham Madarasz <graham@lindenlab.com>2019-05-13 20:57:11 +0000
committerGraham Madarasz <graham@lindenlab.com>2019-05-13 20:57:11 +0000
commit5196b7eac970f7f2b451f0cdf10cb4f6f5997a75 (patch)
treeeb9f66bada72ce544345586694d3cf27c322e31a /indra
parentce910edb0ed6222ad402e4310ccef6a0d0207dd0 (diff)
parent61c2f390210720132c861a157b66cc77fe273d51 (diff)
Merged in graham_linden/viewer-eep-g (pull request #391)
SL-10996, SL-11149
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/transportF.glsl12
-rw-r--r--indra/newview/llvosky.cpp8
-rw-r--r--indra/newview/pipeline.cpp1378
9 files changed, 685 insertions, 746 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
index bea016300d..4134220306 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
@@ -50,7 +50,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul,
{
float offset = shadow_bias * bias_mul;
stc.xyz /= stc.w;
- stc.z += offset * 3.0;
+ stc.z += offset * 2.0;
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs * 4.0;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 8fea4e5d27..180f38b1e1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -157,6 +157,6 @@ void main()
vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
frag_data[0] = vec4(color.rgb, 0); // diffuse
- frag_data[1] = vec4(specular * 0.15, 0.5); // speccolor, spec
+ frag_data[1] = vec4(specular * 0.5, 0.5); // speccolor, spec
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 03e5143fca..e41b4b99a3 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -190,11 +190,10 @@ vec3 post_atmo = color.rgb;
bloom = fogged.a;
#endif
+// srgb colorspace debuggables
//color.rgb = amblit;
-//color.rgb = vec3(ambient);
//color.rgb = sunlit;
//color.rgb = post_ambient;
-//color.rgb = vec3(final_da);
//color.rgb = sun_contrib;
//color.rgb = post_sunlight;
//color.rgb = diffuse_srgb.rgb;
@@ -208,6 +207,11 @@ vec3 post_atmo = color.rgb;
color.rgb = srgb_to_linear(color.rgb);
}
+// linear debuggables
+//color.rgb = vec3(final_da);
+//color.rgb = vec3(ambient);
+//color.rgb = vec3(scol);
+
frag_color.rgb = color.rgb;
frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index 4ac44feee5..d66983a951 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -22,8 +22,6 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
// VARYING param funcs
void setSunlitColor(vec3 v);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index 2683b06e1b..2de708d94b 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
@@ -51,11 +51,11 @@ vec3 atmosTransport(vec3 light)
vec3 fullbrightAtmosTransport(vec3 light)
{
float brightness = dot(light.rgb, vec3(0.33333));
- return atmosTransportFrag(light, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation());
+ return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation());
}
vec3 fullbrightShinyAtmosTransport(vec3 light)
{
float brightness = dot(light.rgb, vec3(0.33333));
- return atmosTransportFrag(light, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation());
+ return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation());
}
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
index c0a0d4782d..88dfa8a907 100644
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
@@ -37,22 +37,29 @@ uniform vec4 blue_density;
uniform float haze_horizon;
uniform float haze_density;
uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
uniform float scene_light_strength;
uniform mat3 ssao_effect_mat;
+uniform int no_atmo;
+uniform float sun_moon_glow_factor;
vec3 scaleSoftClipFrag(vec3 light);
vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
{
- light *= atten.r;
- light += additive;
- return (2.0 * light);
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ light *= atten.r;
+ light += additive;
+ return light * 2.0;
}
vec3 atmosLighting(vec3 light)
{
return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
index e7e56087ab..08eb119510 100644
--- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
@@ -35,10 +35,12 @@ uniform int no_atmo;
vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
{
if (no_atmo == 1)
- {
+ {
return light;
}
- return (light + additive) * atten * 2.0;
+ light *= atten.r;
+ light += additive;
+ return light * 2.0;
}
vec3 atmosTransport(vec3 light)
@@ -48,10 +50,12 @@ vec3 atmosTransport(vec3 light)
vec3 fullbrightAtmosTransport(vec3 light)
{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation());
}
vec3 fullbrightShinyAtmosTransport(vec3 light)
{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation());
}
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index a181fdaf50..7e0f377953 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -207,10 +207,14 @@ void LLSkyTex::create(const F32 brightness)
void LLSkyTex::createGLImage(S32 which)
{
- if (LLPipeline::RenderDeferred) {
+#if USE_SRGB_DECODE
+ if (LLPipeline::RenderDeferred)
+ {
mTexture[which]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
}
- else {
+ else
+#endif
+ {
mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
}
mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 211993fb46..628e7ae2d7 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6215,7 +6215,16 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
mMoonDir.setVec(moon_dir);
// calculates diffuse sunlight per-pixel downstream, just provide setting sunlight_color
- mSunDiffuse.setVec(psky->getSunlightColor());
+ if (canUseWindLightShaders())
+ {
+ mSunDiffuse.setVec(psky->getSunlightColor());
+ }
+ else
+ {
+ // not using atmo shaders, use CPU-generated attenuated sunlight diffuse...
+ mSunDiffuse.setVec(psky->getSunDiffuse());
+ }
+
mMoonDiffuse.setVec(psky->getMoonDiffuse());
F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
@@ -7551,7 +7560,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- mScreen.bindTexture(0, 0, LLTexUnit::TFO_BILINEAR);
+ mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
gGL.color4f(1,1,1,1);
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
@@ -7784,7 +7793,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mScreen.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f);
@@ -7823,7 +7832,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mDeferredLight.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
@@ -7867,7 +7876,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mScreen.bindTexture(0, channel);
}
if (!LLViewerCamera::getInstance()->cameraUnderWater())
@@ -7915,7 +7924,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mScreen.bindTexture(0, channel);
}
if (!LLViewerCamera::getInstance()->cameraUnderWater())
@@ -7962,7 +7971,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mDeferredLight.bindTexture(0, channel);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -8217,7 +8226,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM);
if (channel > -1)
{
- mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mGlow[1].bindTexture(0, channel);
}
stop_glerror();
@@ -10019,862 +10028,775 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow
void LLPipeline::generateSunShadow(LLCamera& camera)
{
- if (!sRenderDeferred || RenderShadowDetail <= 0)
- {
- if (mNeedsShadowTargetClear)
- {
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
- for (S32 j = 0; j < 6; j++)
- {
- LLRenderTarget* shadow_target = getShadowTarget(j);
- if (shadow_target)
- {
- shadow_target->bindTarget();
- shadow_target->clear();
- shadow_target->flush();
- }
- }
- mNeedsShadowTargetClear = false;
- }
-
- return;
- }
-
- mNeedsShadowTargetClear = true;
-
- LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
-
- LLEnvironment& environment = LLEnvironment::instance();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
-
- bool skip_avatar_update = false;
- if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
- {
- skip_avatar_update = true;
- }
-
- F64 last_modelview[16];
- F64 last_projection[16];
- for (U32 i = 0; i < 16; i++)
- { //store last_modelview of world camera
- last_modelview[i] = gGLLastModelView[i];
- last_projection[i] = gGLLastProjection[i];
- }
-
- pushRenderTypeMask();
- andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
- LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_GRASS,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_TREE,
- LLPipeline::RENDER_TYPE_TERRAIN,
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_PASS_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_GRASS,
- LLPipeline::RENDER_TYPE_PASS_SIMPLE,
- LLPipeline::RENDER_TYPE_PASS_BUMP,
- 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);
-
- S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
-
- // if not using VSM, disable color writes
- if (shadow_detail <= 2)
- {
- gGL.setColorMask(false, false);
- }
+ if (!sRenderDeferred || RenderShadowDetail <= 0)
+ {
+ return;
+ }
- bool sun_up = environment.getIsSunUp();
- bool moon_up = environment.getIsMoonUp();
+ LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
- bool ignore_shadows = (shadow_detail == 0); // explicitly disabled shadows
+ bool skip_avatar_update = false;
+ if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
+ {
- // no sun or moon, no shadows
- if (!sun_up && !moon_up)
- {
- ignore_shadows |= true;
- }
- // only moon and moon is black
- else if (!sun_up && moon_up & (mMoonDiffuse == LLColor4::black))
- {
- ignore_shadows |= true;
- }
- // only sun and sun is black
- else if (!moon_up && sun_up && (mSunDiffuse == LLColor4::black))
- {
- ignore_shadows |= true;
- }
- // both up, but both black
- else if ((mSunDiffuse == LLColor4::black) && (mMoonDiffuse == LLColor4::black))
- {
- ignore_shadows |= true;
- }
+ skip_avatar_update = true;
+ }
- if (ignore_shadows)
- { //sun diffuse is totally black, shadows don't matter
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
+ }
- for (S32 j = 0; j < 4; j++)
- {
- LLRenderTarget* shadow_target = getShadowTarget(j);
- if (shadow_target)
- {
- shadow_target->bindTarget();
- shadow_target->clear();
- shadow_target->flush();
- }
- }
+ F64 last_modelview[16];
+ F64 last_projection[16];
+ for (U32 i = 0; i < 16; i++)
+ { //store last_modelview of world camera
+ last_modelview[i] = gGLLastModelView[i];
+ last_projection[i] = gGLLastProjection[i];
+ }
- if (shadow_detail == 0)
- {
- for (S32 j = 4; j < 6; j++)
- {
- LLRenderTarget* shadow_target = getShadowTarget(j);
- if (shadow_target)
- {
- shadow_target->bindTarget();
- shadow_target->clear();
- shadow_target->flush();
- }
- }
- }
- }
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
+ LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_GRASS,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_TREE,
+ LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_VOIDWATER,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ 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);
- //get sun view matrix
-
- //store current projection/modelview matrix
- glh::matrix4f saved_proj = get_current_projection();
- glh::matrix4f saved_view = get_current_modelview();
- glh::matrix4f inv_view = saved_view.inverse();
+ LLEnvironment& environment = LLEnvironment::instance();
- glh::matrix4f view[6];
- glh::matrix4f proj[6];
-
- //clip contains parallel split distances for 3 splits
- LLVector3 clip = RenderShadowClipPlanes;
+ //get sun view matrix
+
+ //store current projection/modelview matrix
+ glh::matrix4f saved_proj = get_current_projection();
+ glh::matrix4f saved_view = get_current_modelview();
+ glh::matrix4f inv_view = saved_view.inverse();
- //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
+ glh::matrix4f view[6];
+ glh::matrix4f proj[6];
+
+ //clip contains parallel split distances for 3 splits
+ LLVector3 clip = RenderShadowClipPlanes;
- //far clip on last split is minimum of camera view distance and 128
- mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
+ LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
- clip = RenderShadowOrthoClipPlanes;
- mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
+ //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
- //currently used for amount to extrude frusta corners for constructing shadow frusta
- //LLVector3 n = RenderShadowNearDist;
- //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
+ //far clip on last split is minimum of camera view distance and 128
+ mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
- LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
+ clip = RenderShadowOrthoClipPlanes;
+ mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
- //put together a universal "near clip" plane for shadow frusta
- LLPlane shadow_near_clip;
- {
- LLVector3 p = gAgent.getPositionAgent();
- p += caster_dir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, caster_dir);
- }
+ //currently used for amount to extrude frusta corners for constructing shadow frusta
+ //LLVector3 n = RenderShadowNearDist;
+ //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
- LLVector3 lightDir = -caster_dir;
- lightDir.normVec();
+ //put together a universal "near clip" plane for shadow frusta
+ LLPlane shadow_near_clip;
+ {
+ LLVector3 p = gAgent.getPositionAgent();
+ p += caster_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, caster_dir);
+ }
- glh::vec3f light_dir(lightDir.mV);
+ LLVector3 lightDir = -caster_dir;
+ lightDir.normVec();
- //create light space camera matrix
-
- LLVector3 at = lightDir;
+ glh::vec3f light_dir(lightDir.mV);
- LLVector3 up = camera.getAtAxis();
+ //create light space camera matrix
+
+ LLVector3 at = lightDir;
- if (fabsf(up*lightDir) > 0.75f)
- {
- up = camera.getUpAxis();
- }
+ LLVector3 up = camera.getAtAxis();
- /*LLVector3 left = up%at;
- up = at%left;*/
+ if (fabsf(up*lightDir) > 0.75f)
+ {
+ up = camera.getUpAxis();
+ }
- up.normVec();
- at.normVec();
-
- LLCamera main_camera = camera;
-
- F32 near_clip = 0.f;
- {
- //get visible point cloud
- std::vector<LLVector3> fp;
+ /*LLVector3 left = up%at;
+ up = at%left;*/
- main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum);
-
- LLVector3 min,max;
- getVisiblePointCloud(main_camera,min,max,fp);
+ up.normVec();
+ at.normVec();
+
+
+ LLCamera main_camera = camera;
+
+ F32 near_clip = 0.f;
+ {
+ //get visible point cloud
+ std::vector<LLVector3> fp;
- if (fp.empty())
- {
- if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
- {
- mShadowCamera[0] = main_camera;
- mShadowExtents[0][0] = min;
- mShadowExtents[0][1] = max;
-
- mShadowFrustPoints[0].clear();
- mShadowFrustPoints[1].clear();
- mShadowFrustPoints[2].clear();
- mShadowFrustPoints[3].clear();
- }
- popRenderTypeMask();
+ main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum);
+
+ LLVector3 min,max;
+ getVisiblePointCloud(main_camera,min,max,fp);
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
- }
+ if (fp.empty())
+ {
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowCamera[0] = main_camera;
+ mShadowExtents[0][0] = min;
+ mShadowExtents[0][1] = max;
- return;
- }
+ mShadowFrustPoints[0].clear();
+ mShadowFrustPoints[1].clear();
+ mShadowFrustPoints[2].clear();
+ mShadowFrustPoints[3].clear();
+ }
+ popRenderTypeMask();
- //get good split distances for frustum
- for (U32 i = 0; i < fp.size(); ++i)
- {
- glh::vec3f v(fp[i].mV);
- saved_view.mult_matrix_vec(v);
- fp[i].setVec(v.v);
- }
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ }
- min = fp[0];
- max = fp[0];
+ return;
+ }
- //get camera space bounding box
- for (U32 i = 1; i < fp.size(); ++i)
- {
- update_min_max(min, max, fp[i]);
- }
+ //get good split distances for frustum
+ for (U32 i = 0; i < fp.size(); ++i)
+ {
+ glh::vec3f v(fp[i].mV);
+ saved_view.mult_matrix_vec(v);
+ fp[i].setVec(v.v);
+ }
- near_clip = -max.mV[2];
- F32 far_clip = -min.mV[2]*2.f;
+ min = fp[0];
+ max = fp[0];
- //far_clip = llmin(far_clip, 128.f);
- far_clip = llmin(far_clip, camera.getFar());
+ //get camera space bounding box
+ for (U32 i = 1; i < fp.size(); ++i)
+ {
+ update_min_max(min, max, fp[i]);
+ }
- F32 range = far_clip-near_clip;
+ near_clip = llclamp(-max.mV[2], 0.01f, 4.0f);
+ F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f);
- LLVector3 split_exp = RenderShadowSplitExponent;
+ //far_clip = llmin(far_clip, 128.f);
+ far_clip = llmin(far_clip, camera.getFar());
- F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
-
- da = powf(da, split_exp.mV[2]);
+ F32 range = far_clip-near_clip;
- F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
-
- for (U32 i = 0; i < 4; ++i)
- {
- F32 x = (F32)(i+1)/4.f;
- x = powf(x, sxp);
- mSunClipPlanes.mV[i] = near_clip+range*x;
- }
+ LLVector3 split_exp = RenderShadowSplitExponent;
- mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding
- }
+ F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
+
+ da = powf(da, split_exp.mV[2]);
- // convenience array of 4 near clip plane distances
- F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
+ F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
+
+ for (U32 i = 0; i < 4; ++i)
+ {
+ F32 x = (F32)(i+1)/4.f;
+ x = powf(x, sxp);
+ mSunClipPlanes.mV[i] = near_clip+range*x;
+ }
- if (!ignore_shadows)
- {
- for (S32 j = 0; j < 4; j++)
- {
- LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_SETUP);
+ mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding
+ }
- if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
- {
- mShadowFrustPoints[j].clear();
- }
+ // convenience array of 4 near clip plane distances
+ F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
+
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
+ if (mSunDiffuse == LLColor4::black)
+ { //sun diffuse is totally black, shadows don't matter
+ LLGLDepthTest depth(GL_TRUE);
- //restore render matrices
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
+ for (S32 j = 0; j < 4; j++)
+ {
+ mShadow[j].bindTarget();
+ mShadow[j].clear();
+ mShadow[j].flush();
+ }
+ }
+ else
+ {
+ for (S32 j = 0; j < 4; j++)
+ {
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowFrustPoints[j].clear();
+ }
- LLVector3 eye = camera.getOrigin();
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
- //camera used for shadow cull/render
- LLCamera shadow_cam;
-
- //create world space camera frustum for this split
- shadow_cam = camera;
- shadow_cam.setFar(16.f);
-
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ //restore render matrices
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
- LLVector3* frust = shadow_cam.mAgentFrustum;
+ LLVector3 eye = camera.getOrigin();
- LLVector3 pn = shadow_cam.getAtAxis();
-
- LLVector3 min, max;
+ //camera used for shadow cull/render
+ LLCamera shadow_cam;
+
+ //create world space camera frustum for this split
+ shadow_cam = camera;
+ shadow_cam.setFar(16.f);
+
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- //construct 8 corners of split frustum section
- for (U32 i = 0; i < 4; i++)
- {
- LLVector3 delta = frust[i+4]-eye;
- delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;
- delta.normVec();
- F32 dp = delta*pn;
- frust[i] = eye + (delta*dist[j]*0.75f)/dp;
- frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp;
- }
-
- shadow_cam.calcAgentFrustumPlanes(frust);
- shadow_cam.mFrustumCornerDist = 0.f;
-
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
- {
- mShadowCamera[j] = shadow_cam;
- }
+ LLVector3* frust = shadow_cam.mAgentFrustum;
- std::vector<LLVector3> fp;
+ LLVector3 pn = shadow_cam.getAtAxis();
+
+ LLVector3 min, max;
- if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
- {
- //no possible shadow receivers
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
- {
- mShadowExtents[j][0] = LLVector3();
- mShadowExtents[j][1] = LLVector3();
- mShadowCamera[j+4] = shadow_cam;
- }
+ //construct 8 corners of split frustum section
+ for (U32 i = 0; i < 4; i++)
+ {
+ LLVector3 delta = frust[i+4]-eye;
+ delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;
+ delta.normVec();
+ F32 dp = delta*pn;
+ frust[i] = eye + (delta*dist[j]*0.75f)/dp;
+ frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp;
+ }
+
+ shadow_cam.calcAgentFrustumPlanes(frust);
+ shadow_cam.mFrustumCornerDist = 0.f;
+
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowCamera[j] = shadow_cam;
+ }
- LLRenderTarget* shadow_target = getShadowTarget(j);
- if (shadow_target)
- {
- shadow_target->bindTarget();
- {
- LLGLDepthTest depth(GL_TRUE);
- shadow_target->clear();
- }
- shadow_target->flush();
- }
+ std::vector<LLVector3> fp;
- mShadowError.mV[j] = 0.f;
- mShadowFOV.mV[j] = 0.f;
+ if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
+ {
+ //no possible shadow receivers
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowExtents[j][0] = LLVector3();
+ mShadowExtents[j][1] = LLVector3();
+ mShadowCamera[j+4] = shadow_cam;
+ }
- continue;
- }
+ mShadow[j].bindTarget();
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ mShadow[j].clear();
+ }
+ mShadow[j].flush();
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
- {
- mShadowExtents[j][0] = min;
- mShadowExtents[j][1] = max;
- mShadowFrustPoints[j] = fp;
- }
-
+ mShadowError.mV[j] = 0.f;
+ mShadowFOV.mV[j] = 0.f;
- //find a good origin for shadow projection
- LLVector3 origin;
+ continue;
+ }
- //get a temporary view projection
- view[j] = look(camera.getOrigin(), lightDir, -up);
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowExtents[j][0] = min;
+ mShadowExtents[j][1] = max;
+ mShadowFrustPoints[j] = fp;
+ }
+
- std::vector<LLVector3> wpf;
+ //find a good origin for shadow projection
+ LLVector3 origin;
- for (U32 i = 0; i < fp.size(); i++)
- {
- glh::vec3f p = glh::vec3f(fp[i].mV);
- view[j].mult_matrix_vec(p);
- wpf.push_back(LLVector3(p.v));
- }
+ //get a temporary view projection
+ view[j] = look(camera.getOrigin(), lightDir, -up);
- min = wpf[0];
- max = wpf[0];
+ std::vector<LLVector3> wpf;
- for (U32 i = 0; i < fp.size(); ++i)
- { //get AABB in camera space
- update_min_max(min, max, wpf[i]);
- }
+ for (U32 i = 0; i < fp.size(); i++)
+ {
+ glh::vec3f p = glh::vec3f(fp[i].mV);
+ view[j].mult_matrix_vec(p);
+ wpf.push_back(LLVector3(p.v));
+ }
- // Construct a perspective transform with perspective along y-axis that contains
- // points in wpf
- //Known:
- // - far clip plane
- // - near clip plane
- // - points in frustum
- //Find:
- // - origin
-
- //get some "interesting" points of reference
- LLVector3 center = (min+max)*0.5f;
- LLVector3 size = (max-min)*0.5f;
- LLVector3 near_center = center;
- near_center.mV[1] += size.mV[1]*2.f;
-
-
- //put all points in wpf in quadrant 0, reletive to center of min/max
- //get the best fit line using least squares
- F32 bfm = 0.f;
- F32 bfb = 0.f;
+ min = wpf[0];
+ max = wpf[0];
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- wpf[i] -= center;
- wpf[i].mV[0] = fabsf(wpf[i].mV[0]);
- wpf[i].mV[2] = fabsf(wpf[i].mV[2]);
- }
+ for (U32 i = 0; i < fp.size(); ++i)
+ { //get AABB in camera space
+ update_min_max(min, max, wpf[i]);
+ }
- if (!wpf.empty())
- {
- F32 sx = 0.f;
- F32 sx2 = 0.f;
- F32 sy = 0.f;
- F32 sxy = 0.f;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- sx += wpf[i].mV[0];
- sx2 += wpf[i].mV[0]*wpf[i].mV[0];
- sy += wpf[i].mV[1];
- sxy += wpf[i].mV[0]*wpf[i].mV[1];
- }
+ // Construct a perspective transform with perspective along y-axis that contains
+ // points in wpf
+ //Known:
+ // - far clip plane
+ // - near clip plane
+ // - points in frustum
+ //Find:
+ // - origin
- bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2);
- bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2);
- }
-
- {
- // best fit line is y=bfm*x+bfb
-
- //find point that is furthest to the right of line
- F32 off_x = -1.f;
- LLVector3 lp;
+ //get some "interesting" points of reference
+ LLVector3 center = (min+max)*0.5f;
+ LLVector3 size = (max-min)*0.5f;
+ LLVector3 near_center = center;
+ near_center.mV[1] += size.mV[1]*2.f;
+
+
+ //put all points in wpf in quadrant 0, reletive to center of min/max
+ //get the best fit line using least squares
+ F32 bfm = 0.f;
+ F32 bfb = 0.f;
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- //y = bfm*x+bfb
- //x = (y-bfb)/bfm
- F32 lx = (wpf[i].mV[1]-bfb)/bfm;
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ wpf[i] -= center;
+ wpf[i].mV[0] = fabsf(wpf[i].mV[0]);
+ wpf[i].mV[2] = fabsf(wpf[i].mV[2]);
+ }
- lx = wpf[i].mV[0]-lx;
-
- if (off_x < lx)
- {
- off_x = lx;
- lp = wpf[i];
- }
- }
+ if (!wpf.empty())
+ {
+ F32 sx = 0.f;
+ F32 sx2 = 0.f;
+ F32 sy = 0.f;
+ F32 sxy = 0.f;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ sx += wpf[i].mV[0];
+ sx2 += wpf[i].mV[0]*wpf[i].mV[0];
+ sy += wpf[i].mV[1];
+ sxy += wpf[i].mV[0]*wpf[i].mV[1];
+ }
- //get line with slope bfm through lp
- // bfb = y-bfm*x
- bfb = lp.mV[1]-bfm*lp.mV[0];
+ bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2);
+ bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2);
+ }
+
+ {
+ // best fit line is y=bfm*x+bfb
+
+ //find point that is furthest to the right of line
+ F32 off_x = -1.f;
+ LLVector3 lp;
- //calculate error
- mShadowError.mV[j] = 0.f;
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ //y = bfm*x+bfb
+ //x = (y-bfb)/bfm
+ F32 lx = (wpf[i].mV[1]-bfb)/bfm;
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- F32 lx = (wpf[i].mV[1]-bfb)/bfm;
- mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx);
- }
+ lx = wpf[i].mV[0]-lx;
+
+ if (off_x < lx)
+ {
+ off_x = lx;
+ lp = wpf[i];
+ }
+ }
- mShadowError.mV[j] /= wpf.size();
- mShadowError.mV[j] /= size.mV[0];
+ //get line with slope bfm through lp
+ // bfb = y-bfm*x
+ bfb = lp.mV[1]-bfm*lp.mV[0];
- if (mShadowError.mV[j] > RenderShadowErrorCutoff)
- { //just use ortho projection
- mShadowFOV.mV[j] = -1.f;
- origin.clearVec();
- proj[j] = gl_ortho(min.mV[0], max.mV[0],
- min.mV[1], max.mV[1],
- -max.mV[2], -min.mV[2]);
- }
- else
- {
- //origin is where line x = 0;
- origin.setVec(0,bfb,0);
+ //calculate error
+ mShadowError.mV[j] = 0.f;
- F32 fovz = 1.f;
- F32 fovx = 1.f;
-
- LLVector3 zp;
- LLVector3 xp;
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ F32 lx = (wpf[i].mV[1]-bfb)/bfm;
+ mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx);
+ }
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- LLVector3 atz = wpf[i]-origin;
- atz.mV[0] = 0.f;
- atz.normVec();
- if (fovz > -atz.mV[1])
- {
- zp = wpf[i];
- fovz = -atz.mV[1];
- }
-
- LLVector3 atx = wpf[i]-origin;
- atx.mV[2] = 0.f;
- atx.normVec();
- if (fovx > -atx.mV[1])
- {
- fovx = -atx.mV[1];
- xp = wpf[i];
- }
- }
+ mShadowError.mV[j] /= wpf.size();
+ mShadowError.mV[j] /= size.mV[0];
- fovx = acos(fovx);
- fovz = acos(fovz);
+ if (mShadowError.mV[j] > RenderShadowErrorCutoff)
+ { //just use ortho projection
+ mShadowFOV.mV[j] = -1.f;
+ origin.clearVec();
+ proj[j] = gl_ortho(min.mV[0], max.mV[0],
+ min.mV[1], max.mV[1],
+ -max.mV[2], -min.mV[2]);
+ }
+ else
+ {
+ //origin is where line x = 0;
+ origin.setVec(0,bfb,0);
- F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f);
-
- mShadowFOV.mV[j] = fovx;
-
- if (fovx < cutoff && fovz > cutoff)
- {
- //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff
- F32 d = zp.mV[2]/tan(cutoff);
- F32 ny = zp.mV[1] + fabsf(d);
+ F32 fovz = 1.f;
+ F32 fovx = 1.f;
+
+ LLVector3 zp;
+ LLVector3 xp;
- origin.mV[1] = ny;
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ LLVector3 atz = wpf[i]-origin;
+ atz.mV[0] = 0.f;
+ atz.normVec();
+ if (fovz > -atz.mV[1])
+ {
+ zp = wpf[i];
+ fovz = -atz.mV[1];
+ }
+
+ LLVector3 atx = wpf[i]-origin;
+ atx.mV[2] = 0.f;
+ atx.normVec();
+ if (fovx > -atx.mV[1])
+ {
+ fovx = -atx.mV[1];
+ xp = wpf[i];
+ }
+ }
- fovz = 1.f;
- fovx = 1.f;
+ fovx = acos(fovx);
+ fovz = acos(fovz);
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- LLVector3 atz = wpf[i]-origin;
- atz.mV[0] = 0.f;
- atz.normVec();
- fovz = llmin(fovz, -atz.mV[1]);
-
- LLVector3 atx = wpf[i]-origin;
- atx.mV[2] = 0.f;
- atx.normVec();
- fovx = llmin(fovx, -atx.mV[1]);
- }
+ F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f);
+
+ mShadowFOV.mV[j] = fovx;
+
+ if (fovx < cutoff && fovz > cutoff)
+ {
+ //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff
+ F32 d = zp.mV[2]/tan(cutoff);
+ F32 ny = zp.mV[1] + fabsf(d);
- fovx = acos(fovx);
- fovz = acos(fovz);
+ origin.mV[1] = ny;
- mShadowFOV.mV[j] = cutoff;
- }
+ fovz = 1.f;
+ fovx = 1.f;
-
- origin += center;
-
- F32 ynear = -(max.mV[1]-origin.mV[1]);
- F32 yfar = -(min.mV[1]-origin.mV[1]);
-
- if (ynear < 0.1f) //keep a sensible near clip plane
- {
- F32 diff = 0.1f-ynear;
- origin.mV[1] += diff;
- ynear += diff;
- yfar += diff;
- }
-
- if (fovx > cutoff)
- { //just use ortho projection
- origin.clearVec();
- mShadowError.mV[j] = -1.f;
- proj[j] = gl_ortho(min.mV[0], max.mV[0],
- min.mV[1], max.mV[1],
- -max.mV[2], -min.mV[2]);
- }
- else
- {
- //get perspective projection
- view[j] = view[j].inverse();
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ LLVector3 atz = wpf[i]-origin;
+ atz.mV[0] = 0.f;
+ atz.normVec();
+ fovz = llmin(fovz, -atz.mV[1]);
+
+ LLVector3 atx = wpf[i]-origin;
+ atx.mV[2] = 0.f;
+ atx.normVec();
+ fovx = llmin(fovx, -atx.mV[1]);
+ }
- glh::vec3f origin_agent(origin.mV);
-
- //translate view to origin
- view[j].mult_matrix_vec(origin_agent);
+ fovx = acos(fovx);
+ fovz = acos(fovz);
- eye = LLVector3(origin_agent.v);
+ mShadowFOV.mV[j] = cutoff;
+ }
- if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
- {
- mShadowFrustOrigin[j] = eye;
- }
-
- view[j] = look(LLVector3(origin_agent.v), lightDir, -up);
+
+ origin += center;
+
+ F32 ynear = -(max.mV[1]-origin.mV[1]);
+ F32 yfar = -(min.mV[1]-origin.mV[1]);
+
+ if (ynear < 0.1f) //keep a sensible near clip plane
+ {
+ F32 diff = 0.1f-ynear;
+ origin.mV[1] += diff;
+ ynear += diff;
+ yfar += diff;
+ }
+
+ if (fovx > cutoff)
+ { //just use ortho projection
+ origin.clearVec();
+ mShadowError.mV[j] = -1.f;
+ proj[j] = gl_ortho(min.mV[0], max.mV[0],
+ min.mV[1], max.mV[1],
+ -max.mV[2], -min.mV[2]);
+ }
+ else
+ {
+ //get perspective projection
+ view[j] = view[j].inverse();
- F32 fx = 1.f/tanf(fovx);
- F32 fz = 1.f/tanf(fovz);
+ glh::vec3f origin_agent(origin.mV);
+
+ //translate view to origin
+ view[j].mult_matrix_vec(origin_agent);
- proj[j] = glh::matrix4f(-fx, 0, 0, 0,
- 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar),
- 0, 0, -fz, 0,
- 0, -1.f, 0, 0);
- }
- }
- }
+ eye = LLVector3(origin_agent.v);
- //shadow_cam.setFar(128.f);
- shadow_cam.setOriginAndLookAt(eye, up, center);
+ if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowFrustOrigin[j] = eye;
+ }
+
+ view[j] = look(LLVector3(origin_agent.v), lightDir, -up);
- shadow_cam.setOrigin(0,0,0);
+ F32 fx = 1.f/tanf(fovx);
+ F32 fz = 1.f/tanf(fovz);
- set_current_modelview(view[j]);
- set_current_projection(proj[j]);
+ proj[j] = glh::matrix4f(-fx, 0, 0, 0,
+ 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar),
+ 0, 0, -fz, 0,
+ 0, -1.f, 0, 0);
+ }
+ }
+ }
- shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
- shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip);
+ //shadow_cam.setFar(128.f);
+ shadow_cam.setOriginAndLookAt(eye, up, center);
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ shadow_cam.setOrigin(0,0,0);
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
- set_current_modelview(view[j]);
- set_current_projection(proj[j]);
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- for (U32 i = 0; i < 16; i++)
- {
- gGLLastModelView[i] = mShadowModelview[j].m[i];
- gGLLastProjection[i] = mShadowProjection[j].m[i];
- }
+ //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
+ shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip);
- mShadowModelview[j] = view[j];
- mShadowProjection[j] = proj[j];
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
-
- mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
-
- stop_glerror();
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
- LLRenderTarget* shadow_target = getShadowTarget(j);
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLLastModelView[i] = mShadowModelview[j].m[i];
+ gGLLastProjection[i] = mShadowProjection[j].m[i];
+ }
- if (shadow_target)
- {
- shadow_target->bindTarget();
- shadow_target->getViewport(gGLViewport);
- shadow_target->clear();
+ mShadowModelview[j] = view[j];
+ mShadowProjection[j] = proj[j];
+ mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
+
+ stop_glerror();
- U32 target_width = shadow_target->getWidth();
+ mShadow[j].bindTarget();
+ mShadow[j].getViewport(gGLViewport);
+ mShadow[j].clear();
+
+ U32 target_width = mShadow[j].getWidth();
- {
- LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_RENDER_DIRECTIONAL);
+ {
+ static LLCullResult result[4];
+ renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width);
+ }
- static LLCullResult result[4];
- renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
- }
+ mShadow[j].flush();
+
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowCamera[j+4] = shadow_cam;
+ }
+ }
+ }
- shadow_target->flush();
- }
+
+ //hack to disable projector shadows
+ bool gen_shadow = RenderShadowDetail > 1;
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
- {
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- mShadowCamera[j+4] = shadow_cam;
- }
- }
- }
+ if (gen_shadow)
+ {
+ LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
+ F32 fade_amt = gFrameIntervalSeconds.value()
+ * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
-
- //hack to disable projector shadows
- bool gen_shadow = RenderShadowDetail > 1;
+ //update shadow targets
+ for (U32 i = 0; i < 2; i++)
+ { //for each current shadow
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
- if (gen_shadow)
- {
- LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_SPOT_SETUP);
-
- LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
- F32 fade_amt = gFrameIntervalSeconds.value()
- * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
-
- //update shadow targets
- for (U32 i = 0; i < 2; i++)
- { //for each current shadow
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
-
- if (mShadowSpotLight[i].notNull() &&
- (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
- mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
- { //keep this spotlight
- mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
- }
- else
- { //fade out this light
- mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
-
- if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
- { //faded out, grab one of the pending spots (whichever one isn't already taken)
- if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[0];
- }
- else
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[1];
- }
- }
- }
- }
+ if (mShadowSpotLight[i].notNull() &&
+ (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
+ mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
+ { //keep this spotlight
+ mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
+ }
+ else
+ { //fade out this light
+ mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
+
+ if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
+ { //faded out, grab one of the pending spots (whichever one isn't already taken)
+ if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[0];
+ }
+ else
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+ }
+ }
+ }
+ }
- for (S32 i = 0; i < 2; i++)
- {
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
+ for (S32 i = 0; i < 2; i++)
+ {
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
- if (mShadowSpotLight[i].isNull())
- {
- continue;
- }
+ if (mShadowSpotLight[i].isNull())
+ {
+ continue;
+ }
- LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+ LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
- if (!volume)
- {
- mShadowSpotLight[i] = NULL;
- continue;
- }
+ if (!volume)
+ {
+ mShadowSpotLight[i] = NULL;
+ continue;
+ }
- LLDrawable* drawable = mShadowSpotLight[i];
+ LLDrawable* drawable = mShadowSpotLight[i];
- LLVector3 params = volume->getSpotLightParams();
- F32 fov = params.mV[0];
+ LLVector3 params = volume->getSpotLightParams();
+ F32 fov = params.mV[0];
- //get agent->light space matrix (modelview)
- LLVector3 center = drawable->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
+ //get agent->light space matrix (modelview)
+ LLVector3 center = drawable->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
- //get near clip plane
- LLVector3 scale = volume->getScale();
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
+ //get near clip plane
+ LLVector3 scale = volume->getScale();
+ LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
+ at_axis *= quat;
- LLVector3 np = center+at_axis;
- at_axis.normVec();
+ LLVector3 np = center+at_axis;
+ at_axis.normVec();
- //get origin that has given fov for plane np, at_axis, and given scale
- F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+ //get origin that has given fov for plane np, at_axis, and given scale
+ F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
- LLVector3 origin = np - at_axis*dist;
+ LLVector3 origin = np - at_axis*dist;
- LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+ LLMatrix4 mat(quat, LLVector4(origin, 1.f));
- view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+ view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
- view[i+4] = view[i+4].inverse();
+ view[i+4] = view[i+4].inverse();
- //get perspective matrix
- F32 near_clip = dist+0.01f;
- F32 width = scale.mV[VX];
- F32 height = scale.mV[VY];
- F32 far_clip = dist+volume->getLightRadius()*1.5f;
+ //get perspective matrix
+ F32 near_clip = dist+0.01f;
+ F32 width = scale.mV[VX];
+ F32 height = scale.mV[VY];
+ F32 far_clip = dist+volume->getLightRadius()*1.5f;
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width/height;
+
+ proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
- set_current_modelview(view[i+4]);
- set_current_projection(proj[i+4]);
+ set_current_modelview(view[i+4]);
+ set_current_projection(proj[i+4]);
- mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
-
- for (U32 j = 0; j < 16; j++)
- {
- gGLLastModelView[j] = mShadowModelview[i+4].m[j];
- gGLLastProjection[j] = mShadowProjection[i+4].m[j];
- }
+ mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
+
+ for (U32 j = 0; j < 16; j++)
+ {
+ gGLLastModelView[j] = mShadowModelview[i+4].m[j];
+ gGLLastProjection[j] = mShadowProjection[i+4].m[j];
+ }
- mShadowModelview[i+4] = view[i+4];
- mShadowProjection[i+4] = proj[i+4];
+ mShadowModelview[i+4] = view[i+4];
+ mShadowProjection[i+4] = proj[i+4];
- LLCamera shadow_cam = camera;
- shadow_cam.setFar(far_clip);
- shadow_cam.setOrigin(origin);
+ LLCamera shadow_cam = camera;
+ shadow_cam.setFar(far_clip);
+ shadow_cam.setOrigin(origin);
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- stop_glerror();
+ stop_glerror();
- LLRenderTarget* shadow_target = getShadowTarget(i + 4);
+ mShadow[i+4].bindTarget();
+ mShadow[i+4].getViewport(gGLViewport);
+ mShadow[i+4].clear();
- if (shadow_target)
- {
- LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_SPOT_RENDER);
+ U32 target_width = mShadow[i+4].getWidth();
- shadow_target->bindTarget();
- shadow_target->getViewport(gGLViewport);
- shadow_target->clear();
-
- U32 target_width = shadow_target->getWidth();
+ static LLCullResult result[2];
- static LLCullResult result[2];
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
+ renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
- shadow_target->flush();
- }
- }
- }
- else
- { //no spotlight shadows
- mShadowSpotLight[0] = mShadowSpotLight[1] = NULL;
- }
+ mShadow[i+4].flush();
+ }
+ }
+ else
+ { //no spotlight shadows
+ mShadowSpotLight[0] = mShadowSpotLight[1] = NULL;
+ }
- if (!CameraOffset)
- {
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
- }
- else
- {
- set_current_modelview(view[1]);
- set_current_projection(proj[1]);
- gGL.loadMatrix(view[1].m);
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.loadMatrix(proj[1].m);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
- gGL.setColorMask(true, false);
+ if (!CameraOffset)
+ {
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
+ }
+ else
+ {
+ set_current_modelview(view[1]);
+ set_current_projection(proj[1]);
+ gGL.loadMatrix(view[1].m);
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.loadMatrix(proj[1].m);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+ gGL.setColorMask(true, false);
- for (U32 i = 0; i < 16; i++)
- {
- gGLLastModelView[i] = last_modelview[i];
- gGLLastProjection[i] = last_projection[i];
- }
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLLastModelView[i] = last_modelview[i];
+ gGLLastProjection[i] = last_projection[i];
+ }
- popRenderTypeMask();
+ popRenderTypeMask();
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
- }
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ }
}
void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture)