SL-10181, SL-10546
Fix distortion map rendering in deferred mode not including underwater fog effects. Fix distortion map rendering not including post-deferred content at all. Fix distortion map rendering not including anything but sky when camera is underwater. Update sun_up_factor/sunmoon_glow_factor uniforms even when sun disc isn't in use.master
parent
5433ed60ac
commit
65927e0a76
|
|
@ -244,7 +244,7 @@ LLSettingsWater::validation_list_t LLSettingsWater::validationList()
|
|||
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
|
||||
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-10.0f)(10.0f)))));
|
||||
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
|
||||
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f)))));
|
||||
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
|
||||
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
|
||||
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
|
||||
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
|
||||
|
|
@ -290,3 +290,15 @@ LLUUID LLSettingsWater::GetDefaultOpaqueTextureAssetId()
|
|||
{
|
||||
return DEFAULT_OPAQUE_WATER_TEXTURE;
|
||||
}
|
||||
|
||||
F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const
|
||||
{
|
||||
F32 fog_density = getWaterFogDensity();
|
||||
F32 underwater_fog_mod = getFogMod();
|
||||
if (underwater && underwater_fog_mod > 0.0f)
|
||||
{
|
||||
underwater_fog_mod = llclamp(underwater_fog_mod, 0.0f, 10.0f);
|
||||
fog_density = pow(fog_density, underwater_fog_mod);
|
||||
}
|
||||
return fog_density;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ public:
|
|||
return mSettings[SETTING_FOG_DENSITY].asReal();
|
||||
}
|
||||
|
||||
F32 getModifiedWaterFogDensity(bool underwater) const;
|
||||
|
||||
void setWaterFogDensity(F32 val)
|
||||
{
|
||||
setValue(SETTING_FOG_DENSITY, val);
|
||||
|
|
|
|||
|
|
@ -2268,6 +2268,17 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLUserClipPlane::disable()
|
||||
{
|
||||
if (mApply)
|
||||
{
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
mApply = false;
|
||||
}
|
||||
|
||||
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
||||
{
|
||||
glh::matrix4f& P = mProjection;
|
||||
|
|
@ -2296,12 +2307,7 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
|||
|
||||
LLGLUserClipPlane::~LLGLUserClipPlane()
|
||||
{
|
||||
if (mApply)
|
||||
{
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
disable();
|
||||
}
|
||||
|
||||
LLGLNamePool::LLGLNamePool()
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ public:
|
|||
~LLGLUserClipPlane();
|
||||
|
||||
void setPlane(F32 a, F32 b, F32 c, F32 d);
|
||||
void disable();
|
||||
|
||||
private:
|
||||
bool mApply;
|
||||
|
|
|
|||
|
|
@ -215,10 +215,10 @@ void main()
|
|||
// keep it linear
|
||||
//
|
||||
color.rgb += light.rgb;
|
||||
#endif
|
||||
|
||||
#ifdef WATER_FOG
|
||||
color = applyWaterFogView(pos.xyz, color);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
frag_color = color;
|
||||
|
|
|
|||
|
|
@ -37,29 +37,38 @@ uniform sampler2D detail_2;
|
|||
uniform sampler2D detail_3;
|
||||
uniform sampler2D alpha_ramp;
|
||||
|
||||
VARYING vec3 pos;
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec4 vary_texcoord0;
|
||||
VARYING vec4 vary_texcoord1;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 applyWaterFogView(vec3 pos, vec4 c);
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
|
||||
|
||||
vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
|
||||
vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
|
||||
vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
|
||||
vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
|
||||
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
|
||||
|
||||
vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
|
||||
vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
|
||||
vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
|
||||
vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
|
||||
|
||||
float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
|
||||
float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
|
||||
float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
|
||||
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
|
||||
|
||||
frag_data[0] = vec4(outColor.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
|
||||
float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
|
||||
float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
|
||||
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
|
||||
|
||||
#ifdef WATER_FOG
|
||||
outColor = applyWaterFogView(pos.xyz, outColor);
|
||||
#endif
|
||||
|
||||
frag_data[0] = vec4(outColor.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ ATTRIBUTE vec4 diffuse_color;
|
|||
ATTRIBUTE vec2 texcoord0;
|
||||
ATTRIBUTE vec2 texcoord1;
|
||||
|
||||
VARYING vec3 pos;
|
||||
VARYING vec3 vary_normal;
|
||||
|
||||
VARYING vec4 vary_texcoord0;
|
||||
VARYING vec4 vary_texcoord1;
|
||||
|
||||
|
|
@ -43,31 +43,35 @@ uniform vec4 object_plane_t;
|
|||
|
||||
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
|
||||
{
|
||||
vec4 tcoord;
|
||||
|
||||
tcoord.x = dot(vpos, tp0);
|
||||
tcoord.y = dot(vpos, tp1);
|
||||
tcoord.z = tc.z;
|
||||
tcoord.w = tc.w;
|
||||
|
||||
tcoord = mat * tcoord;
|
||||
|
||||
return tcoord;
|
||||
vec4 tcoord;
|
||||
|
||||
tcoord.x = dot(vpos, tp0);
|
||||
tcoord.y = dot(vpos, tp1);
|
||||
tcoord.z = tc.z;
|
||||
tcoord.w = tc.w;
|
||||
|
||||
tcoord = mat * tcoord;
|
||||
|
||||
return tcoord;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
|
||||
vary_normal = normalize(normal_matrix * normal);
|
||||
|
||||
// Transform and pass tex coords
|
||||
vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
|
||||
|
||||
vec4 t = vec4(texcoord1,0,1);
|
||||
|
||||
vary_texcoord0.zw = t.xy;
|
||||
vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
|
||||
vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
|
||||
//transform vertex
|
||||
vec4 pre_pos = vec4(position.xyz, 1.0);
|
||||
vec4 t_pos = modelview_projection_matrix * pre_pos;
|
||||
|
||||
gl_Position = t_pos;
|
||||
pos = t_pos.xyz;
|
||||
|
||||
vary_normal = normalize(normal_matrix * normal);
|
||||
|
||||
// Transform and pass tex coords
|
||||
vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
|
||||
|
||||
vec4 t = vec4(texcoord1,0,1);
|
||||
|
||||
vary_texcoord0.zw = t.xy;
|
||||
vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
|
||||
vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,6 @@ void main()
|
|||
|
||||
//mix with reflection
|
||||
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
|
||||
refcol.rgb = pow(refcol.rgb, vec3(0.45)); // boost the reflect color a little to get stars to show up SL-1475
|
||||
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
|
||||
|
||||
vec4 pos = vary_position;
|
||||
|
|
|
|||
|
|
@ -34,46 +34,46 @@ vec3 getPositionEye();
|
|||
|
||||
vec4 applyWaterFogView(vec3 pos, vec4 color)
|
||||
{
|
||||
vec3 view = normalize(pos);
|
||||
//normalize view vector
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
vec3 view = normalize(pos);
|
||||
//normalize view vector
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 applyWaterFog(vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
return applyWaterFogView(getPositionEye(), color);
|
||||
//normalize view vector
|
||||
return applyWaterFogView(getPositionEye(), color);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
|
|||
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
|
||||
LLFacePool::beginRenderPass(pass);
|
||||
|
||||
sShader = &gDeferredTerrainProgram;
|
||||
sShader = LLPipeline::sUnderWaterRender ? &gDeferredTerrainWaterProgram : &gDeferredTerrainProgram;
|
||||
|
||||
sShader->bind();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -537,7 +537,10 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
|
|||
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
|
||||
|
||||
shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getWaterFogColor().mV);
|
||||
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getWaterFogDensity());
|
||||
|
||||
F32 fog_density = pwater->getModifiedWaterFogDensity(LLPipeline::sUnderWaterRender || (eyedepth <= 0.0f));
|
||||
|
||||
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
|
||||
|
||||
// bind reflection texture from RenderTarget
|
||||
S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
|
||||
|
|
@ -546,7 +549,7 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
|
|||
if (mShaderLevel == 1)
|
||||
{
|
||||
LLColor4 fog_color(pwater->getWaterFogColor(), 0.f);
|
||||
fog_color[3] = pwater->getWaterFogDensity();
|
||||
fog_color[3] = fog_density;
|
||||
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
|
||||
}
|
||||
|
||||
|
|
@ -616,6 +619,8 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
|
|||
{
|
||||
LLGLDisable cullface(GL_CULL_FACE);
|
||||
|
||||
|
||||
|
||||
sNeedsReflectionUpdate = TRUE;
|
||||
sNeedsDistortionUpdate = TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ void LLDrawPoolWLSky::renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 ca
|
|||
sky_shader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize);
|
||||
sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, sun_dir.mV);
|
||||
sky_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, moon_dir.mV);
|
||||
|
||||
|
||||
F32 moisture_level = (float)psky->getSkyMoistureLevel();
|
||||
F32 droplet_radius = (float)psky->getSkyDropletRadius();
|
||||
|
|
@ -233,6 +234,7 @@ void LLDrawPoolWLSky::renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 ca
|
|||
sky_shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
|
||||
|
||||
sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
|
||||
sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0);
|
||||
|
||||
sky_shader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
|
||||
|
||||
|
|
@ -270,6 +272,8 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
|
|||
|
||||
sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
|
||||
|
||||
sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0);
|
||||
|
||||
/// Render the skydome
|
||||
renderDome(origin, camHeightLocal, sky_shader);
|
||||
|
||||
|
|
@ -285,6 +289,8 @@ void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightL
|
|||
{
|
||||
LLGLSPipelineDepthTestSkyBox sky(true, false);
|
||||
sky_shader->bind();
|
||||
sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
|
||||
sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, 1.0f);
|
||||
renderDome(origin, camHeightLocal, sky_shader);
|
||||
sky_shader->unbind();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -585,9 +585,10 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
|
|||
F32 depth = water_height - camera_height;
|
||||
|
||||
// get the water param manager variables
|
||||
float water_fog_density = pwater->getWaterFogDensity();
|
||||
float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f);
|
||||
|
||||
LLColor4 water_fog_color(pwater->getWaterFogColor());
|
||||
|
||||
|
||||
// adjust the color based on depth. We're doing linear approximations
|
||||
float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale");
|
||||
float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),
|
||||
|
|
|
|||
|
|
@ -879,11 +879,15 @@ void LLSettingsVOWater::applySpecial(void *ptarget)
|
|||
{
|
||||
LLGLSLShader *shader = (LLGLSLShader *)ptarget;
|
||||
|
||||
LLEnvironment& env = LLEnvironment::instance();
|
||||
|
||||
if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
|
||||
{
|
||||
F32 water_height = env.getWaterHeight();
|
||||
|
||||
//transform water plane to eye space
|
||||
glh::vec3f norm(0.f, 0.f, 1.f);
|
||||
glh::vec3f p(0.f, 0.f, LLEnvironment::instance().getWaterHeight() + 0.1f);
|
||||
glh::vec3f p(0.f, 0.f, water_height + 0.1f);
|
||||
|
||||
F32 modelView[16];
|
||||
for (U32 i = 0; i < 16; i++)
|
||||
|
|
@ -903,13 +907,18 @@ void LLSettingsVOWater::applySpecial(void *ptarget)
|
|||
|
||||
shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV);
|
||||
|
||||
LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
|
||||
LLVector4 light_direction = env.getClampedLightNorm();
|
||||
|
||||
F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
|
||||
|
||||
shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS);
|
||||
|
||||
F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
|
||||
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - water_height;
|
||||
|
||||
F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(LLPipeline::sUnderWaterRender || (eyedepth <= 0.0f));
|
||||
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
|
||||
|
||||
F32 blend_factor = env.getCurrentWater()->getBlendFactor();
|
||||
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
|
||||
|
||||
LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
|
||||
|
|
@ -941,7 +950,9 @@ LLSettingsWater::parammapping_t LLSettingsVOWater::getParameterMap() const
|
|||
{
|
||||
LLSD water_defaults = LLSettingsWater::defaults();
|
||||
param_map[SETTING_FOG_COLOR] = DefaultParam(LLShaderMgr::WATER_FOGCOLOR, water_defaults[SETTING_FOG_COLOR]);
|
||||
param_map[SETTING_FOG_DENSITY] = DefaultParam(LLShaderMgr::WATER_FOGDENSITY, water_defaults[SETTING_FOG_DENSITY]);
|
||||
|
||||
// let this get set by LLSettingsVOWater::applySpecial so that it can properly reflect the underwater modifier
|
||||
//param_map[SETTING_FOG_DENSITY] = DefaultParam(LLShaderMgr::WATER_FOGDENSITY, water_defaults[SETTING_FOG_DENSITY]);
|
||||
}
|
||||
return param_map;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -285,6 +285,7 @@ extern LLGLSLShader gDeferredSkinnedBumpProgram;
|
|||
extern LLGLSLShader gDeferredSkinnedAlphaProgram;
|
||||
extern LLGLSLShader gDeferredBumpProgram;
|
||||
extern LLGLSLShader gDeferredTerrainProgram;
|
||||
extern LLGLSLShader gDeferredTerrainWaterProgram;
|
||||
extern LLGLSLShader gDeferredTreeProgram;
|
||||
extern LLGLSLShader gDeferredTreeShadowProgram;
|
||||
extern LLGLSLShader gDeferredLightProgram;
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, 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 (!mWaterDeferredScreen.allocate(water_buffer_res, water_buffer_res, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
if (!mWaterDeferredScreen.allocate(water_buffer_res, water_buffer_res, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
if (!mWaterDeferredDepth.allocate(water_buffer_res, water_buffer_res, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
if (!mWaterOcclusionDepth.allocate(water_buffer_res >> 1, water_buffer_res >> 1, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
|
||||
|
|
@ -1255,20 +1255,9 @@ void LLPipeline::createGLBuffers()
|
|||
{ //water reflection texture
|
||||
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
|
||||
|
||||
// Set up SRGB targets if we're doing deferred-path reflection rendering
|
||||
//
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
|
||||
//always use FBO for mWaterDis so it can be used for avatar texture bakes
|
||||
mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
|
||||
//always use FBO for mWaterDis so it can be used for avatar texture bakes
|
||||
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
|
||||
}
|
||||
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
|
||||
//always use FBO for mWaterDis so it can be used for avatar texture bakes
|
||||
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
|
||||
}
|
||||
|
||||
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
|
||||
|
|
@ -9453,8 +9442,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
if (!LLViewerCamera::getInstance()->cameraUnderWater())
|
||||
{ //generate planar reflection map
|
||||
//disable occlusion culling for reflection map for now
|
||||
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
glClearColor(0,0,0,0);
|
||||
|
||||
|
|
@ -9518,6 +9505,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
gPipeline.mWaterDeferredScreen.bindTarget();
|
||||
gPipeline.mWaterDeferredScreen.clear();
|
||||
renderGeomDeferred(camera);
|
||||
renderGeomPostDeferred(camera);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -9573,6 +9561,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
renderGeomDeferred(camera);
|
||||
renderGeomPostDeferred(camera);
|
||||
|
||||
gPipeline.mWaterDeferredScreen.flush();
|
||||
gPipeline.mWaterDeferredDepth.flush();
|
||||
mWaterRef.copyContents(gPipeline.mWaterDeferredScreen, 0, 0, gPipeline.mWaterDeferredScreen.getWidth(), gPipeline.mWaterDeferredScreen.getHeight(),
|
||||
|
|
@ -9609,12 +9599,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
END_RENDER_TYPES);
|
||||
stop_glerror();
|
||||
|
||||
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
|
||||
|
||||
bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
|
||||
|
||||
if (!LLPipeline::sUnderWaterRender)
|
||||
// intentionally inverted so that distortion map contents (objects under the water when we're above it)
|
||||
// will properly include water fog effects
|
||||
LLPipeline::sUnderWaterRender = !camera_is_underwater;
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_GROUND,
|
||||
LLPipeline::RENDER_TYPE_SKY,
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_CLOUDS,
|
||||
LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
END_RENDER_TYPES);
|
||||
|
|
@ -9640,27 +9634,34 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
LLPlane plane(pnorm, -water_height * LLPipeline::sDistortionWaterClipPlaneMargin);
|
||||
LLGLUserClipPlane clip_plane(plane, mReflectionModelView, projection);
|
||||
|
||||
static LLCullResult result;
|
||||
updateCull(camera, result, water_clip, &plane);
|
||||
stateSort(camera, result);
|
||||
static LLCullResult refracted_objects;
|
||||
updateCull(camera, refracted_objects, water_clip, &plane);
|
||||
stateSort(camera, refracted_objects);
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
mWaterDis.clear();
|
||||
gGL.setColorMask(true, false);
|
||||
|
||||
// ignore clip plane if we're underwater and viewing distortion map of objects above waterline
|
||||
if (camera_is_underwater)
|
||||
{
|
||||
clip_plane.disable();
|
||||
}
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
mWaterDis.flush();
|
||||
gGL.setColorMask(true, true);
|
||||
glClearColor(0,0,0,0);
|
||||
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
|
||||
gPipeline.mWaterDeferredDepth.bindTarget();
|
||||
gPipeline.mWaterDeferredDepth.clear();
|
||||
gPipeline.mWaterDeferredScreen.bindTarget();
|
||||
gPipeline.mWaterDeferredScreen.clear();
|
||||
gPipeline.grabReferences(result);
|
||||
gPipeline.grabReferences(refracted_objects);
|
||||
gGL.setColorMask(true, false);
|
||||
|
||||
renderGeomDeferred(camera);
|
||||
renderGeomPostDeferred(camera);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -9684,7 +9685,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
gPipeline.mWaterDeferredScreen.flush();
|
||||
gPipeline.mWaterDeferredDepth.flush();
|
||||
mWaterDis.copyContents(gPipeline.mWaterDeferredScreen, 0, 0, gPipeline.mWaterDeferredScreen.getWidth(), gPipeline.mWaterDeferredScreen.getHeight(),
|
||||
0, 0, gPipeline.mWaterDeferredDepth.getWidth(), gPipeline.mWaterDeferredDepth.getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
0, 0, gPipeline.mWaterDis.getWidth(), gPipeline.mWaterDis.getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@
|
|||
initial_value="0"
|
||||
layout="top"
|
||||
left_delta="15"
|
||||
max_val="10"
|
||||
min_val="0.0"
|
||||
max_val="20.0"
|
||||
name="water_underwater_mod"
|
||||
top_delta="20"
|
||||
width="150"
|
||||
|
|
|
|||
Loading…
Reference in New Issue