diff options
Diffstat (limited to 'indra/newview')
105 files changed, 4741 insertions, 4286 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fe6f5ca4a0..9b474284ff 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -365,6 +365,7 @@ set(viewer_SOURCE_FILES lljoystickbutton.cpp lllandmarkactions.cpp lllandmarklist.cpp + lllegacyatmospherics.cpp lllistbrowser.cpp lllistcontextmenu.cpp lllistview.cpp diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 380d7762d6..951c8edcc7 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -51,6 +51,7 @@ <key>tags</key> <array> <!-- sample entry for debugging specific items + <string>ShaderLoading</string> <string>Avatar</string> <string>Inventory</string> <string>SceneLoadTiming</string> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c89887c56e..04237a6012 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8653,7 +8653,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>RenderLocalLights</key> <map> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index b9c8f34cb0..2234ceeb53 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -39,19 +39,6 @@ out vec4 frag_color; uniform float display_gamma; uniform vec4 gamma; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 ambient; -uniform vec4 blue_horizon; -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 env_mat; uniform mat3 ssao_effect_mat; @@ -84,12 +71,6 @@ VARYING vec3 vary_norm; VARYING vec4 vertex_color; #endif -vec3 vary_PositionEye; -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - uniform mat4 inv_proj; uniform vec2 screen_res; @@ -98,59 +79,20 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); +vec2 encode_normal (vec3 n); +vec3 decode_normal (vec2 enc); -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 scaleFragSoftClip(vec3 l); +vec3 atmosFragAmbient(vec3 light, vec3 sunlit); +vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten); +vec3 atmosFragAffectDirectionalLight(float light, vec3 sunlit); +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); vec3 calcDirectionalLight(vec3 n, vec3 l) { @@ -219,237 +161,6 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc) } #endif -#ifdef WATER_FOG -uniform vec4 waterPlane; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; - -vec4 applyWaterFogDeferred(vec3 pos, vec4 color) -{ - //normalize view vector - vec3 view = normalize(pos); - 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); - - 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; -} -#endif - -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) - + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x - + tmpAmbient))); - - //brightness of surface both sunlight and ambient - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} - -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength)); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength)); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f)); -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity); -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - vec3 zeroes = vec3(0.0f, 0.0f, 0.0f); - vec3 ones = vec3(1.0f, 1.0f, 1.0f); - - light = ones - clamp(light, zeroes, ones); - light = ones - pow(light, gamma.xxx); - - return light; -} - -vec3 fullbrightAtmosTransport(vec3 light) { - float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); -} - -vec3 fullbrightScaleSoftClip(vec3 light) -{ - //soft clip effect: - return light; -} void main() { @@ -566,10 +277,15 @@ void main() vec3 norm = vary_norm; - calcAtmospherics(pos.xyz, 1.0); + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; + + calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); vec2 abnormal = encode_normal(norm.xyz); - norm.xyz = decode_normal(abnormal.xy); + norm.xyz = decode_normal(abnormal.xy); float da = dot(norm.xyz, sun_dir.xyz); @@ -581,7 +297,7 @@ void main() vec4 color = vec4(0,0,0,0); - color.rgb = atmosAmbient(color.rgb); + color.rgb = atmosFragAmbient(color.rgb, amblit); color.a = final_alpha; float ambient = abs(da); @@ -590,13 +306,13 @@ void main() ambient = (1.0-ambient); color.rgb *= ambient; - color.rgb += atmosAffectDirectionalLight(final_da); + color.rgb += atmosFragAffectDirectionalLight(final_da, sunlit); color.rgb *= gamma_diff.rgb; //color.rgb = mix(diff.rgb, color.rgb, final_alpha); - color.rgb = atmosLighting(color.rgb); - color.rgb = scaleSoftClip(color.rgb); + color.rgb = atmosFragLighting(color.rgb, additive, atten); + color.rgb = scaleFragSoftClip(color.rgb); vec4 light = vec4(0,0,0,0); @@ -621,9 +337,8 @@ void main() color.rgb = linear_to_srgb(color.rgb); #ifdef WATER_FOG - color = applyWaterFogDeferred(pos.xyz, color); + color = applyWaterFogView(pos.xyz, color); #endif - #endif frag_color = color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl index 22c9a4d14e..8e9a5fcd41 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl @@ -22,6 +22,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 662c762bca..60d83cc623 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -36,11 +38,7 @@ uniform float minimum_alpha; VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index b809b73973..8e46425ea8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -22,7 +22,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index cbd8d2ebfc..b56abb66d1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -61,22 +61,7 @@ vec4 getPosition(vec2 pos_screen) return pos; } -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 decode_normal (vec2 enc); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 58fb01d200..b5677a07ee 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -22,6 +22,8 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ + +/*[EXTRA_CODE_HERE]*/ #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; @@ -40,11 +42,7 @@ VARYING vec3 vary_mat2; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index 1d8ca04ccd..7b971fcc66 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -22,7 +22,7 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - +/*[EXTRA_CODE_HERE]*/ #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index 7930b5d18b..b328ee9483 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -37,11 +39,7 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 8525e13333..fc5c86b4d6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -36,11 +38,7 @@ uniform float minimum_alpha; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index 37d70a2412..1bb8eb8bd0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -23,6 +23,7 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; @@ -37,11 +38,7 @@ uniform sampler2D diffuseMap; VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 6befb1bd8b..8319e61242 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -22,6 +22,8 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ + +/*[EXTRA_CODE_HERE]*/ #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; @@ -35,11 +37,7 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index adc361d7a2..828c325c9d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -33,12 +35,7 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 756e625d07..134e9c3b4c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -41,43 +41,12 @@ VARYING vec3 vary_position; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; - -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -} +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); vec3 fullbrightAtmosTransportDeferred(vec3 light) { @@ -94,52 +63,6 @@ vec3 fullbrightScaleSoftClipDeferred(vec3 light) uniform float minimum_alpha; #endif -#ifdef WATER_FOG -uniform vec4 waterPlane; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; - -vec4 applyWaterFogDeferred(vec3 pos, vec4 color) -{ - //normalize view vector - vec3 view = normalize(pos); - 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); - - 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; -} -#endif - void main() { #if HAS_DIFFUSE_LOOKUP @@ -166,7 +89,7 @@ void main() #ifdef WATER_FOG vec3 pos = vary_position; - vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha)); + vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha)); color.rgb = fogged.rgb; color.a = fogged.a; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl index b0db9876d3..30e560450b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ - +/*[EXTRA_CODE_HERE]*/ #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index f8fdde43f9..6ba16b169c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -38,41 +40,7 @@ uniform sampler2D specularMap; VARYING vec2 vary_texcoord0; -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} +vec3 linear_to_srgb(vec3 cl); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index dcf474824d..be1003a7e0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -22,8 +22,8 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - -uniform sampler2DRect diffuseMap; + +/*[EXTRA_CODE_HERE]*/ #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -31,6 +31,7 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif +uniform sampler2DRect diffuseMap; VARYING vec2 vary_fragcoord; void main() diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 07d28ed4cd..a90e433622 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #define DIFFUSE_ALPHA_MODE_IGNORE 0 #define DIFFUSE_ALPHA_MODE_BLEND 1 #define DIFFUSE_ALPHA_MODE_MASK 2 @@ -31,42 +33,18 @@ uniform float emissive_brightness; uniform float display_gamma; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -} +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} +vec3 atmosFragAmbient(vec3 l, vec3 ambient); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleFragSoftClip(vec3 l); +vec3 atmosFragAffectDirectionalLight(float intensity, vec3 sunlit); +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten); #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) @@ -116,19 +94,6 @@ uniform vec4 morphFactor; uniform vec3 camPosLocal; //uniform vec4 camPosWorld; uniform vec4 gamma; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 ambient; -uniform vec4 blue_horizon; -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 env_mat; uniform mat3 ssao_effect_mat; @@ -137,13 +102,6 @@ VARYING vec2 vary_fragcoord; VARYING vec3 vary_position; -vec3 vary_PositionEye; - -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - uniform mat4 inv_proj; uniform vec2 screen_res; @@ -152,52 +110,6 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; -#ifdef WATER_FOG -uniform vec4 waterPlane; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; - -vec4 applyWaterFogDeferred(vec3 pos, vec4 color) -{ - //normalize view vector - vec3 view = normalize(pos); - 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); - - 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; -} -#endif - vec3 calcDirectionalLight(vec3 n, vec3 l) { float a = max(dot(n,l),0.0); @@ -283,198 +195,6 @@ vec4 getPosition_d(vec2 pos_screen, float depth) return pos; } -#ifndef WATER_FOG -vec3 getPositionEye() -{ - return vary_PositionEye; -} -#endif - -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) - + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x - + tmpAmbient))); - - //brightness of surface both sunlight and ambient - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} - -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength)); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength)); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f)); -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity); -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - vec3 zeroes = vec3(0.0f, 0.0f, 0.0f); - vec3 ones = vec3(1.0f, 1.0f, 1.0f); - - light = ones - clamp(light, zeroes, ones); - light = ones - pow(light, gamma.xxx); - - return light; -} - -vec3 fullbrightAtmosTransport(vec3 light) { - float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); -} - -vec3 fullbrightScaleSoftClip(vec3 light) -{ - //soft clip effect: - return light; -} #else #ifdef DEFINE_GL_FRAGCOLOR @@ -515,22 +235,8 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec2 encode_normal(vec3 n); +vec3 decode_normal (vec2 enc); void main() { @@ -673,7 +379,12 @@ void main() vec3 col = vec3(0.0f,0.0f,0.0f); float bloom = 0.0; - calcAtmospherics(pos.xyz, 1.0); + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; + + calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); @@ -686,7 +397,7 @@ void main() final_da = min(final_da, 1.0f); final_da = pow(final_da, 1.0/1.3); - col.rgb = atmosAmbient(col); + col.rgb = atmosFragAmbient(col, amblit); float ambient = min(abs(da), 1.0); ambient *= 0.5; @@ -695,7 +406,7 @@ void main() col.rgb *= ambient; - col.rgb = col.rgb + atmosAffectDirectionalLight(final_da); + col.rgb = col.rgb + atmosFragAffectDirectionalLight(final_da, sunlit); col.rgb *= gamma_diff.rgb; @@ -708,7 +419,7 @@ void main() // float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r); + vec3 dumbshiny = sunlit*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; @@ -742,8 +453,8 @@ void main() //col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); //col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); - col = atmosLighting(col); - col = scaleSoftClip(col); + col = atmosFragLighting(col, additive, atten); + col = scaleFragSoftClip(col); //convert to linear space before adding local lights col = srgb_to_linear(col); @@ -771,7 +482,7 @@ void main() col.rgb = linear_to_srgb(col.rgb); #ifdef WATER_FOG - vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al)); + vec4 temp = applyWaterFogView(pos, vec4(col.rgb, al)); col.rgb = temp.rgb; al = temp.a; #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 9974f8f31b..d1ac19270d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -57,22 +57,7 @@ uniform float far_z; uniform mat4 inv_proj; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 decode_normal (vec2 enc); vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 3a3e871ade..1d75322b4c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -30,14 +30,14 @@ #extension GL_ARB_texture_rectangle : enable #extension GL_ARB_shader_texture_lod : enable +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else #define frag_color gl_FragColor #endif -/*[EXTRA_CODE_HERE]*/ - uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect depthMap; @@ -72,59 +72,9 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} - +vec3 decode_normal (vec2 enc); +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index aba4a01754..13b803e03e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -56,22 +56,7 @@ uniform vec2 screen_res; uniform mat4 inv_proj; uniform vec4 viewport; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 decode_normal (vec2 enc); vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 6669947d1b..cbc19bbba3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -40,25 +40,7 @@ VARYING vec2 vary_fragcoord; uniform float display_gamma; -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} - +vec3 linear_to_srgb(vec3 cl); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 018ced4cad..e33254304b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl new file mode 100644 index 0000000000..12bc690553 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl @@ -0,0 +1,55 @@ +/** + * @file shadowAlphaMaskF.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D diffuseMap; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING float pos_w; + +VARYING float target_pos_x; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void main() +{ + float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; + + frag_color = vec4(alpha, alpha, alpha, 1); + +#if !DEPTH_CLAMP + gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); +#endif +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl new file mode 100644 index 0000000000..11411a605c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl @@ -0,0 +1,67 @@ +/** + * @file shadowAlphaMaskV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; +uniform float shadow_target_width; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec2 texcoord0; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING float pos_w; + +VARYING float target_pos_x; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void passTextureIndex(); + +void main() +{ + //transform vertex + vec4 pre_pos = vec4(position.xyz, 1.0); + vec4 pos = modelview_projection_matrix * pre_pos; + target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + + pos_w = pos.w; + +#if !DEPTH_CLAMP + pos_zd2 = pos.z * 0.5; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else + gl_Position = pos; +#endif + + passTextureIndex(); + + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + vertex_color = diffuse_color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index 91a96977f0..ae1b19a35c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index 3d1b182875..242aef821d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 22f4729e2e..4511237e4d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -1,5 +1,5 @@ /** - * @file WLSkyF.glsl + * @file class1/deferred/skyF.glsl * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 7f1a8cce0d..fbfd43a4da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -51,83 +51,32 @@ uniform vec4 morphFactor; uniform vec3 camPosLocal; //uniform vec4 camPosWorld; uniform vec4 gamma; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 ambient; -uniform vec4 blue_horizon; -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 global_gamma; -uniform float scene_light_strength; uniform mat3 env_mat; uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; VARYING vec2 vary_fragcoord; -vec3 vary_PositionEye; - -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - uniform mat4 inv_proj; uniform vec2 screen_res; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -} +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); +vec3 decode_normal (vec2 enc); +vec3 atmosFragAmbient(vec3 l, vec3 ambient); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleFragSoftClip(vec3 l); +vec3 atmosFragAffectDirectionalLight(float intensity, vec3 sunlit); +vec3 fullbrightFragAtmosTransport(vec3 l, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClipFrag(vec3 l, vec3 atten); -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten); vec4 getPosition_d(vec2 pos_screen, float depth) { @@ -147,243 +96,6 @@ vec4 getPosition(vec2 pos_screen) return getPosition_d(pos_screen, depth); } -vec3 getPositionEye() -{ - return vary_PositionEye; -} -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - - -#ifdef WATER_FOG -uniform vec4 waterPlane; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; - -vec4 applyWaterFogDeferred(vec3 pos, vec4 color) -{ - //normalize view vector - vec3 view = normalize(pos); - 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); - - 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; -} -#endif - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) - + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x - + tmpAmbient))); - - //brightness of surface both sunlight and ambient - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} - -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} - -vec3 fullbrightAtmosTransport(vec3 light) { - float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); -} - - - -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / scene_light_strength ); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * scene_light_strength); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + light / 2.0; -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * lightIntensity; -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, gamma.xxx); - - return light; -} - - -vec3 fullbrightScaleSoftClip(vec3 light) -{ - //soft clip effect: - return light; -} void main() { @@ -411,9 +123,13 @@ void main() vec3 col; float bloom = 0.0; { - calcAtmospherics(pos.xyz, 1.0); + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; + calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); - col = atmosAmbient(vec3(0)); + col = atmosFragAmbient(vec3(0), amblit); float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); ambient *= 0.5; ambient *= ambient; @@ -421,7 +137,7 @@ void main() col.rgb *= ambient; - col += atmosAffectDirectionalLight(final_da); + col += atmosFragAffectDirectionalLight(final_da, sunlit); col *= diffuse.rgb; @@ -433,7 +149,7 @@ void main() // float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r); + vec3 dumbshiny = sunlit*(texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; @@ -457,12 +173,12 @@ void main() if (norm.w < 0.5) { - col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); - col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); + col = mix(atmosFragLighting(col, additive, atten), fullbrightFragAtmosTransport(col, atten, additive), diffuse.a); + col = mix(scaleFragSoftClip(col), fullbrightScaleSoftClipFrag(col, atten), diffuse.a); } #ifdef WATER_FOG - vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom)); + vec4 fogged = applyWaterFogView(pos,vec4(col, bloom)); col = fogged.rgb; bloom = fogged.a; #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index f1aec315cc..2b6428963d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -70,59 +70,9 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} +vec3 decode_normal (vec2 enc); +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); vec4 correctWithGamma(vec4 col) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl index 821058804c..029a98e16a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 930255729b..403df87853 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -51,22 +51,7 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 decode_normal (vec2 enc); vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 52a429465f..0cd90b0d97 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -39,11 +41,7 @@ VARYING vec3 vary_normal; VARYING vec4 vary_texcoord0; VARYING vec4 vary_texcoord1; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 808750496f..89e354558a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -37,11 +39,7 @@ VARYING vec2 vary_texcoord0; uniform float minimum_alpha; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl index d4d2f5f571..e34d75ba1d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl index 78f841c733..3a8565ee38 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -56,48 +58,10 @@ VARYING vec4 refCoord; VARYING vec4 littleWave; VARYING vec4 view; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec2 encode_normal(vec3 n); vec4 applyWaterFog(vec4 color, vec3 viewVec) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 37dcd3ad34..b321eb508b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -69,48 +69,8 @@ VARYING vec4 littleWave; VARYING vec4 view; VARYING vec4 vary_position; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} +vec3 srgb_to_linear(vec3 cs); +vec2 encode_normal(vec3 n); void main() { diff --git a/indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl new file mode 100644 index 0000000000..0abb1e43db --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/environment/decodeNormF.glsl @@ -0,0 +1,11 @@ +vec3 decode_normal (vec2 enc) +{ + vec2 fenc = enc*4-2; + float f = dot(fenc,fenc); + float g = sqrt(1-f/4); + vec3 n; + n.xy = fenc*g; + n.z = 1-f/2; + return n; +} + diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl new file mode 100644 index 0000000000..ee21715c1d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl @@ -0,0 +1,7 @@ + +vec2 encode_normal(vec3 n) +{ + float f = sqrt(8 * n.z + 8); + return n.xy / f + 0.5; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl index 6cc1e6e798..835662732a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl @@ -1,5 +1,5 @@ /** - * @file srgb.glsl + * @file srgbF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,14 +27,18 @@ vec3 srgb_to_linear(vec3 cs) { vec3 low_range = cs / vec3(12.92); vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); +#ifdef OLD_SELECT vec3 result; result.r = lte.r ? low_range.r : high_range.r; result.g = lte.g ? low_range.g : high_range.g; result.b = lte.b ? low_range.b : high_range.b; return result; +#else + return mix(high_range, low_range, lte); +#endif + } vec3 linear_to_srgb(vec3 cl) @@ -42,13 +46,17 @@ vec3 linear_to_srgb(vec3 cl) cl = clamp(cl, vec3(0), vec3(1)); vec3 low_range = cl * 12.92; vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); +#ifdef OLD_SELECT vec3 result; result.r = lt.r ? low_range.r : high_range.r; result.g = lt.g ? low_range.g : high_range.g; result.b = lt.b ? low_range.b : high_range.b; - return result; + return result; +#else + return mix(high_range, low_range, lt); +#endif + } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 4bdfce9260..a7c28a1ac3 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -33,10 +33,10 @@ uniform float waterFogKS; vec3 getPositionEye(); -vec4 applyWaterFog(vec4 color) +vec4 applyWaterFogView(vec3 pos, vec4 color) { + vec3 view = normalize(pos); //normalize view vector - vec3 view = normalize(getPositionEye()); float es = -(dot(view, waterPlane.xyz)); //find intersection point with water plane and eye vector @@ -47,7 +47,7 @@ vec4 applyWaterFog(vec4 color) vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); //get object depth - float depth = length(getPositionEye() - int_v); + float depth = length(pos - int_v); //get "thickness" of water float l = max(depth, 0.1); @@ -72,3 +72,9 @@ vec4 applyWaterFog(vec4 color) return color; } +vec4 applyWaterFog(vec4 color) +{ + //normalize view vector + return applyWaterFogView(getPositionEye(), color); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl index 5c088b3a3c..b5bbbb5c73 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -25,14 +25,14 @@ #extension GL_ARB_texture_rectangle : enable +/*[EXTRA_CODE_HERE]*/ + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else #define frag_color gl_FragColor #endif -/*[EXTRA_CODE_HERE]*/ - uniform sampler2D glowMap; uniform sampler2DRect screenMap; diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index aacc503e13..584bd568c5 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -31,3 +31,8 @@ vec3 atmosLighting(vec3 light) return light; } + +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor) { + /* stub function for fallback compatibility on class1 hardware */ +} + diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl new file mode 100644 index 0000000000..3f70a8935b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl @@ -0,0 +1,55 @@ +/** + * @file atmosphericsHelpersF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +uniform vec4 sunlight_color; +uniform vec4 light_ambient; + +vec3 atmosAmbient(vec3 light) +{ + return light + light_ambient.rgb; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return sunlight_color.rgb * lightIntensity; +} + +vec3 atmosGetDiffuseSunlightColor() +{ + return sunlight_color.rgb; +} + +vec3 scaleDownLight(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + +vec3 scaleUpLight(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index b9bb522842..864ba4859d 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -71,59 +71,9 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); +vec3 decode_normal (vec2 enc); vec4 correctWithGamma(vec4 col) { diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index cf076d156a..371b32406c 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -70,69 +70,20 @@ uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; VARYING vec2 vary_fragcoord; -vec3 vary_PositionEye; - -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - uniform mat4 inv_proj; uniform vec2 screen_res; -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); +vec3 decode_normal (vec2 enc); -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 atmosFragAmbient(vec3 l, vec3 ambient); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleFragSoftClip(vec3 l); +vec3 atmosFragAffectDirectionalLight(float intensity, vec3 sunlit); +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten); +vec3 fullbrightFragAtmosTransport(vec3 l, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClipFrag(vec3 l, vec3 atten); vec4 getPosition_d(vec2 pos_screen, float depth) { @@ -152,243 +103,11 @@ vec4 getPosition(vec2 pos_screen) return getPosition_d(pos_screen, depth); } -vec3 getPositionEye() -{ - return vary_PositionEye; -} -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) - + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x - + tmpAmbient))); - - //brightness of surface both sunlight and ambient - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} #ifdef WATER_FOG -uniform vec4 waterPlane; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; - -vec4 applyWaterFogDeferred(vec3 pos, vec4 color) -{ - //normalize view vector - vec3 view = normalize(pos); - 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); - - 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 applyWaterFogDeferred(vec3 pos, vec4 color); #endif -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} - -vec3 fullbrightAtmosTransport(vec3 light) { - float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); -} - - - -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / scene_light_strength ); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * scene_light_strength); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + light / 2.0; -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * lightIntensity; -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, gamma.xxx); - - return light; -} - - -vec3 fullbrightScaleSoftClip(vec3 light) -{ - //soft clip effect: - return light; -} - void main() { vec2 tc = vary_fragcoord.xy; @@ -422,10 +141,15 @@ void main() float ambocc = scol_ambocc.g; + + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; - calcAtmospherics(pos.xyz, ambocc); + calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten); - col = atmosAmbient(vec3(0)); + col = atmosFragAmbient(vec3(0), amblit); float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); ambient *= 0.5; ambient *= ambient; @@ -433,7 +157,7 @@ void main() col.rgb *= ambient; - col += atmosAffectDirectionalLight(max(min(da, scol), 0.0)); + col += atmosFragAffectDirectionalLight(max(min(da, scol), 0.0), sunlit); col *= diffuse.rgb; @@ -445,7 +169,7 @@ void main() // float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r); + vec3 dumbshiny = sunlit*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; @@ -469,8 +193,8 @@ void main() if (norm.w < 0.5) { - col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); - col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); + col = mix(atmosFragLighting(col, additive, atten), fullbrightFragAtmosTransport(col, atten, additive), diffuse.a); + col = mix(scaleFragSoftClip(col), fullbrightScaleSoftClipFrag(col, atten), diffuse.a); } #ifdef WATER_FOG diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index b2d9de6e73..a7da140b31 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -71,59 +71,9 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -vec3 srgb_to_linear(vec3 cs) -{ - vec3 low_range = cs / vec3(12.92); - vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - bvec3 lte = lessThanEqual(cs,vec3(0.04045)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -vec3 linear_to_srgb(vec3 cl) -{ - cl = clamp(cl, vec3(0), vec3(1)); - vec3 low_range = cl * 12.92; - vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - bvec3 lt = lessThan(cl,vec3(0.0031308)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} +vec3 decode_normal (vec2 enc); +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cl); vec4 correctWithGamma(vec4 col) { diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 265da8df99..aa5e99a2f7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -67,22 +67,7 @@ uniform float shadow_offset; uniform float spot_shadow_bias; uniform float spot_shadow_offset; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 decode_normal (vec2 enc); vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 5c6fe30daa..58f3f2f91e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -68,22 +68,7 @@ uniform float shadow_offset; uniform float spot_shadow_bias; uniform float spot_shadow_offset; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} +vec3 decode_normal (vec2 enc); vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index fea3cbf69b..fee1a7f311 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -22,23 +22,127 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - - - -////////////////////////////////////////////////////////// -// The fragment shader for the terrain atmospherics -////////////////////////////////////////////////////////// vec3 getAdditiveColor(); vec3 getAtmosAttenuation(); uniform sampler2D cloudMap; +uniform vec4 gamma; uniform vec4 cloud_pos_density1; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +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; -vec3 atmosLighting(vec3 light) +vec3 scaleFragSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + return light; +} + +vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); + light *= atten.r; + light += additive; return (2.0 * light); } +vec3 atmosLighting(vec3 light) +{ + return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation()); +} + +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten) { + + vec3 P = inPositionEye; + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier); + + //final atmosphere attenuation factor + atten = temp1.rgb; + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + additive = + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + + tmpAmbient)); + + //brightness of surface both sunlight and ambient + sunlit = vec3(sunlight * .5); + amblit = vec3(tmpAmbient * .25); + additive *= vec3(1.0 - temp1); +} + diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl new file mode 100644 index 0000000000..3582759e62 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl @@ -0,0 +1,49 @@ +/** + * @file atmosphericsHelpersV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Output variables + +uniform float scene_light_strength; + +vec3 atmosFragAmbient(vec3 light, vec3 amblit) +{ + return amblit + light / 2.0; +} + +vec3 atmosFragAffectDirectionalLight(float lightIntensity, vec3 sunlit) +{ + return sunlit * lightIntensity; +} + +vec3 scaleDownLightFrag(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLightFrag(vec3 light) +{ + return (light * scene_light_strength); +} + diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl index 478373d729..2db633cd01 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -38,7 +38,12 @@ vec3 scaleSoftClip(vec3 light) { return light; } +vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 atten) +{ + return mix(scaleSoftClip(light.rgb), light.rgb, atten); +} + vec3 fullbrightScaleSoftClip(vec3 light) { - return mix(scaleSoftClip(light.rgb), light.rgb, getAtmosAttenuation()); + return fullbrightScaleSoftClipFrag(light.rgb, getAtmosAttenuation()); } diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl index e2a2367626..2a0ca35278 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -1,5 +1,5 @@ /** - * @file WLSkyF.glsl + * @file class2/windlight/skyF.glsl * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index 8a8e4cb0f6..82e1d7fe35 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -33,21 +33,30 @@ vec3 getAtmosAttenuation(); uniform sampler2D cloudMap; uniform vec4 cloud_pos_density1; -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; +vec3 atmosFragTransport(vec3 light, vec3 atten, vec3 additive) { + light *= atten.r; + light += additive * 2.0; return light; } -vec3 fullbrightAtmosTransport(vec3 light) { +vec3 fullbrightFragAtmosTransport(vec3 light, vec3 atten, vec3 additive) { float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); + return mix(atmosFragTransport(light.rgb, atten, additive), light.rgb + additive.rgb, brightness * brightness); } -vec3 fullbrightShinyAtmosTransport(vec3 light) { +vec3 fullbrightFragShinyAtmosTransport(vec3 light, vec3 atten, vec3 additive) { float brightness = dot(light.rgb, vec3(0.33333)); + return mix(atmosFragTransport(light.rgb, atten, additive), (light.rgb + additive.rgb) * (2.0 - brightness), brightness * brightness); +} - return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); +vec3 atmosTransport(vec3 light) { + return atmosFragTransport(light, getAtmosAttenuation(), getAdditiveColor()); } +vec3 fullbrightAtmosTransport(vec3 light) { + return fullbrightFragAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor()); +} + +vec3 fullbrightShinyAtmosTransport(vec3 light) { + return fullbrightFragShinyAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor()); +} diff --git a/indra/newview/app_settings/shaders/class3/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl index 96c70651b1..96c70651b1 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl diff --git a/indra/newview/app_settings/shaders/class3/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl index c1dd45cd67..c1dd45cd67 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl diff --git a/indra/newview/app_settings/shaders/class3/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl index c71eaf4b13..5185a9f8f4 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl @@ -29,16 +29,18 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif +in vec3 view_pos; in vec3 view_dir; uniform vec3 cameraPosLocal; -uniform vec3 sun_direction; -uniform vec2 sun_size; +uniform vec3 sun_dir; +uniform float sun_size; uniform sampler2D cloud_noise_texture; uniform sampler2D transmittance_texture; uniform sampler3D scattering_texture; -uniform sampler3D mie_scattering_texture; +uniform sampler3D single_mie_scattering_texture; +uniform sampler2D irradiance_texture; vec3 GetSolarLuminance(); vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance); @@ -49,23 +51,35 @@ void main() { vec3 view_direction = normalize(view_dir); - vec3 camPos = cameraPosLocal; + vec3 sun_direction = sun_dir; + + vec3 camPos = cameraPosLocal + vec3(0, 0, 6360.0f); vec3 transmittance; + vec3 sky_illum; vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance); + vec3 radiance2 = GetSunAndSkyIlluminance(camPos, view_direction, sun_direction, sky_illum); radiance *= transmittance; + vec3 solar_luminance = transmittance * GetSolarLuminance(); + // If the view ray intersects the Sun, add the Sun radiance. - if (dot(view_direction, sun_direction) >= sun_size.y) + if (dot(view_direction, sun_direction) >= sun_size) { - radiance = radiance + transmittance * GetSolarLuminance(); + radiance = radiance + solar_luminance; } - vec3 color = vec3(1.0) - exp(-radiance); - color = pow(color, vec3(1.0 / 2.2)); + vec3 color = radiance; + + color = vec3(1.0) - exp(-color * 0.0001); + + //float d = dot(view_direction, sun_direction); + //frag_color.rgb = vec3(d, d >= sun_size ? 1.0f : 0.0f, 0.0f); frag_color.rgb = color; - + //frag_color.rgb = vec3(dot(view_direction, sun_direction) > 0.95f ? 1.0 : 0.0, 0,0); + frag_color.rgb = normalize(view_pos); + frag_color.a = 1.0; } diff --git a/indra/newview/app_settings/shaders/class3/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl index 52a7595379..cf3eb658fc 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl @@ -23,21 +23,29 @@ * $/LicenseInfo$ */ +uniform vec3 cameraPosLocal; uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix; +uniform mat4 inv_proj; +uniform mat4 inv_modelview; ATTRIBUTE vec3 position; // Inputs uniform vec3 camPosLocal; +out vec3 view_pos; out vec3 view_dir; void main() { - // World / view / projection - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + // pass through untransformed fullscreen pos (clipspace) + gl_Position = vec4(position.xyz, 1.0); + + view_pos = (inv_proj * vec4(position, 1.0f)).xyz; // this will be normalized in the frag shader... - view_dir = position.xyz - camPosLocal.xyz; + //view_dir = (inv_modelview * view_pos).xyz; + view_dir = view_pos - camPosLocal; } diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl index d27363a60c..fed3edf7de 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl +++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl @@ -32,11 +32,13 @@ out vec4 frag_color; in vec3 view_dir; uniform vec3 cameraPosLocal; -uniform vec3 sun_direction; +uniform vec3 sun_dir; +uniform float sun_size; uniform sampler2D transmittance_texture; uniform sampler3D scattering_texture; uniform sampler3D mie_scattering_texture; +uniform sampler2D irradiance_texture; vec3 GetSolarLuminance(); vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance); @@ -49,20 +51,22 @@ void main() vec3 camPos = cameraPosLocal; vec3 transmittance; - vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance); + vec3 sky_illum; + vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_dir, transmittance); + vec3 radiance2 = GetSunAndSkyIlluminance(camPos, view_direction, sun_dir, sky_illum); - radiance *= transmittance; + //radiance *= transmittance; // If the view ray intersects the Sun, add the Sun radiance. - if (dot(view_direction, sun_direction) >= sun_size.y) + if (dot(view_direction, sun_dir) >= sun_size) { radiance = radiance + transmittance * GetSolarLuminance(); } - vec3 color = vec3(1.0) - exp(-radiance); - color = pow(color, vec3(1.0 / 2.2)); + //vec3 color = vec3(1.0) - exp(-radiance); + //color = pow(color, vec3(1.0 / 2.2)); - frag_color.rgb = color; + frag_color.rgb = radiance; frag_color.a = 1.0; } diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl new file mode 100644 index 0000000000..fee1a7f311 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl @@ -0,0 +1,148 @@ +/** + * @file atmosphericsF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +vec3 getAdditiveColor(); +vec3 getAtmosAttenuation(); + +uniform sampler2D cloudMap; +uniform vec4 gamma; +uniform vec4 cloud_pos_density1; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +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; + +vec3 scaleFragSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + return light; +} + +vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) +{ + light *= atten.r; + light += additive; + return (2.0 * light); +} + +vec3 atmosLighting(vec3 light) +{ + return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation()); +} + +void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten) { + + vec3 P = inPositionEye; + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier); + + //final atmosphere attenuation factor + atten = temp1.rgb; + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + additive = + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + + tmpAmbient)); + + //brightness of surface both sunlight and ambient + sunlit = vec3(sunlight * .5); + amblit = vec3(tmpAmbient * .25); + additive *= vec3(1.0 - temp1); +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl new file mode 100644 index 0000000000..3270c243a4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl @@ -0,0 +1,133 @@ +/** + * @file atmosphericsV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// VARYING param funcs +void setSunlitColor(vec3 v); +void setAmblitColor(vec3 v); +void setAdditiveColor(vec3 v); +void setAtmosAttenuation(vec3 v); +void setPositionEye(vec3 v); + +vec3 getAdditiveColor(); + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +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; + +void calcAtmospherics(vec3 inPositionEye) { + + vec3 P = inPositionEye; + setPositionEye(P); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + //tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl index 8a8e4cb0f6..82e1d7fe35 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl @@ -33,21 +33,30 @@ vec3 getAtmosAttenuation(); uniform sampler2D cloudMap; uniform vec4 cloud_pos_density1; -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; +vec3 atmosFragTransport(vec3 light, vec3 atten, vec3 additive) { + light *= atten.r; + light += additive * 2.0; return light; } -vec3 fullbrightAtmosTransport(vec3 light) { +vec3 fullbrightFragAtmosTransport(vec3 light, vec3 atten, vec3 additive) { float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); + return mix(atmosFragTransport(light.rgb, atten, additive), light.rgb + additive.rgb, brightness * brightness); } -vec3 fullbrightShinyAtmosTransport(vec3 light) { +vec3 fullbrightFragShinyAtmosTransport(vec3 light, vec3 atten, vec3 additive) { float brightness = dot(light.rgb, vec3(0.33333)); + return mix(atmosFragTransport(light.rgb, atten, additive), (light.rgb + additive.rgb) * (2.0 - brightness), brightness * brightness); +} - return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); +vec3 atmosTransport(vec3 light) { + return atmosFragTransport(light, getAtmosAttenuation(), getAdditiveColor()); } +vec3 fullbrightAtmosTransport(vec3 light) { + return fullbrightFragAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor()); +} + +vec3 fullbrightShinyAtmosTransport(vec3 light) { + return fullbrightFragShinyAtmosTransport(light, getAtmosAttenuation(), getAdditiveColor()); +} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b3f0a810b4..b927a52e77 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4876,7 +4876,6 @@ void LLAppViewer::idle() // // Update weather effects // - gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets // Update wind vector LLVector3 wind_position_region; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index bc299cc89f..11d8dd2e1c 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -46,22 +46,22 @@ public: enum { // Correspond to LLPipeline render type - POOL_SIMPLE = 1, + POOL_SKY = 1, + POOL_WL_SKY, + POOL_TERRAIN, POOL_GROUND, + POOL_GRASS, + POOL_VOIDWATER, + POOL_WATER, + POOL_SIMPLE, POOL_FULLBRIGHT, POOL_BUMP, - POOL_MATERIALS, - POOL_TERRAIN, - POOL_SKY, - POOL_WL_SKY, + POOL_MATERIALS, POOL_TREE, POOL_ALPHA_MASK, - POOL_FULLBRIGHT_ALPHA_MASK, - POOL_GRASS, + POOL_FULLBRIGHT_ALPHA_MASK, POOL_INVISIBLE, // see below * - POOL_AVATAR, - POOL_VOIDWATER, - POOL_WATER, + POOL_AVATAR, POOL_GLOW, POOL_ALPHA, NUM_POOL_TYPES, diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp index 59c3fbf7a1..e5ce0413b1 100644 --- a/indra/newview/lldrawpoolground.cpp +++ b/indra/newview/lldrawpoolground.cpp @@ -68,7 +68,7 @@ void LLDrawPoolGround::render(S32 pass) LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - LLGLSquashToFarClip far_clip(glh_get_current_projection()); + LLGLSquashToFarClip far_clip(get_current_projection()); F32 water_height = gAgent.getRegion()->getWaterHeight(); gGL.pushMatrix(); diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index bdb16abc78..2e4506ce47 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -102,7 +102,7 @@ void LLDrawPoolSky::render(S32 pass) LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - LLGLSquashToFarClip far_clip(glh_get_current_projection()); + LLGLSquashToFarClip far_clip(get_current_projection()); LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 567172e647..9cd59c61ec 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -488,49 +488,38 @@ void LLDrawPoolWater::shade() LLVector3 light_dir; LLColor3 light_color; - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsWater::ptr_t pwater = environment.getCurrentWater(); + LLSettingsSky::ptr_t psky = environment.getCurrentSky(); - light_dir = psky->getLightDirection(); - if (LLEnvironment::instance().getIsDayTime()) + light_dir = environment.getLightDirection(); + light_dir.normalize(); + + bool sun_up = environment.getIsSunUp(); + bool moon_up = environment.getIsMoonUp(); + + if (sun_up) { - light_color = psky->getSunAmbient(); - light_diffuse = psky->getSunDiffuse(); - light_diffuse.normalize(); - light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); - light_diffuse *= (light_exp + 0.25f); + light_color = light_color + psky->getSunAmbient(); + light_diffuse += psky->getSunDiffuse(); } - else + + light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); + + if (moon_up) { - light_color = psky->getMoonAmbient(); - light_diffuse = psky->getMoonDiffuse(); - light_diffuse.normalize(); - light_diffuse *= 0.5f; - light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); + LLColor3 moon_diffuse_color = psky->getMoonDiffuse(); + light_color += moon_diffuse_color; + light_diffuse += moon_diffuse_color * 0.5f; + + if (!sun_up) + { + light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); + } } -// if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) -// { -// light_dir = gSky.getSunDirection(); -// light_dir.normVec(); -// light_color = gSky.getSunDiffuseColor(); -// if(gSky.mVOSkyp) { -// light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); -// light_diffuse.normVec(); -// } -// light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); -// light_diffuse *= light_exp + 0.25f; -// } -// else -// { -// light_dir = gSky.getMoonDirection(); -// light_dir.normVec(); -// light_color = gSky.getMoonDiffuseColor(); -// light_diffuse = gSky.mVOSkyp->getMoon().getColorCached(); -// light_diffuse.normVec(); -// light_diffuse *= 0.5f; -// light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); -// } + light_diffuse.normalize(); + light_diffuse *= (light_exp + 0.25f); light_exp *= light_exp; light_exp *= light_exp; @@ -609,8 +598,8 @@ void LLDrawPoolWater::shade() if (screentex > -1) { - shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getFogColor().mV); - shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getFogDensity()); + shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getWaterFogColor().mV); + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getWaterFogDensity()); gPipeline.mWaterDis.bindTexture(0, screentex); } @@ -620,8 +609,8 @@ void LLDrawPoolWater::shade() if (mVertexShaderLevel == 1) { - LLColor4 fog_color(pwater->getFogColor(), 0.f); - fog_color[3] = pwater->getFogDensity(); + LLColor4 fog_color(pwater->getWaterFogColor(), 0.f); + fog_color[3] = pwater->getWaterFogDensity(); shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); } @@ -706,7 +695,7 @@ void LLDrawPoolWater::shade() } else { - LLGLSquashToFarClip far_clip(glh_get_current_projection()); + LLGLSquashToFarClip far_clip(get_current_projection()); face->renderIndexed(); } } diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index a28041034b..def81e46fc 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -44,6 +44,8 @@ #include "llenvironment.h" #include "llatmosphere.h" +static LLStaticHashedString sCamPosLocal("camPosLocal"); + LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL; LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; @@ -124,95 +126,92 @@ void LLDrawPoolWLSky::endDeferredPass(S32 pass) } -void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const +void LLDrawPoolWLSky::renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const { - llassert_always(NULL != shader); - - static LLStaticHashedString sCamPosLocal("camPosLocal"); - - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - - if (gPipeline.useAdvancedAtmospherics()) - { - // Draw WL Sky w/ normal cam pos (where you are) for adv atmo sky - sky_shader->uniform3f(sCamPosLocal, origin.mV[0], origin.mV[1], origin.mV[2]); + // Draw WL Sky w/ normal cam pos (where you are) for adv atmo sky + //gGL.syncMatrices(); + sky_shader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); + gSky.mVOWLSkyp->drawFsSky(); +} -// TBD replace this with a FS tri pass, there's little point to the tess when you have fragment shaders... +void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const +{ + llassert_always(NULL != shader); - gSky.mVOWLSkyp->drawDome(); - } - else - { - gGL.pushMatrix(); + gGL.pushMatrix(); - //chop off translation - if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f) - { - gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f); - } - else - { - gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - } + //chop off translation + if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f) + { + gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f); + } + else + { + gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); + } - // the windlight sky dome works most conveniently in a coordinate system - // where Y is up, so permute our basis vectors accordingly. - gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); + // the windlight sky dome works most conveniently in a coordinate system + // where Y is up, so permute our basis vectors accordingly. + gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); - gGL.scalef(0.333f, 0.333f, 0.333f); + gGL.scalef(0.333f, 0.333f, 0.333f); - gGL.translatef(0.f,-camHeightLocal, 0.f); + gGL.translatef(0.f,-camHeightLocal, 0.f); - // Draw WL Sky - shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); + // Draw WL Sky + shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); - gSky.mVOWLSkyp->drawDome(); + gSky.mVOWLSkyp->drawDome(); - gGL.popMatrix(); - } + gGL.popMatrix(); } -void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const +void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const { - if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) - { - LLGLDisable blend(GL_BLEND); - + if (gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders() && gAtmosphere) + { sky_shader->bind(); - if (gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders() && gAtmosphere) - { - // bind precomputed textures necessary for calculating sun and sky luminance - sky_shader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); - sky_shader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); - sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); + // bind precomputed textures necessary for calculating sun and sky luminance + sky_shader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); + sky_shader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); + sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); + sky_shader->bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); + + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + LLVector4 light_dir = LLEnvironment::instance().getClampedLightNorm(); - static float sunSize = (float)cos(0.0005); + F32 sunSize = (float)cosf(psky->getSunArcRadians()); + sky_shader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize); + sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, light_dir.mV); - sky_shader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize); + // clouds are rendered along with sky in adv atmo + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull()) + { + sky_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, sCloudNoiseTexture); + } - static LLVector3 solDir(0.7f, 0.2f, 0.2f); + renderFsSky(camPosLocal, camHeightLocal, sky_shader); - //neither of these appear to track with the env settings, would the real sun please stand up. - //sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, gPipeline.mTransformedSunDir.mV); - //sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, gSky.mVOSkyp->getSun().getDirection().mV); - solDir.normalize(); + sky_shader->unbind(); + } +} - sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, solDir.mV); +void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const +{ + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - // clouds are rendered along with sky in adv atmo - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull()) - { - sky_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, sCloudNoiseTexture); - } - } + if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) + { + LLGLDisable blend(GL_BLEND); + sky_shader->bind(); - /// Render the skydome - renderDome(camHeightLocal, sky_shader); + /// Render the skydome + renderDome(origin, camHeightLocal, sky_shader); sky_shader->unbind(); - } + } } void LLDrawPoolWLSky::renderStars(void) const @@ -274,7 +273,7 @@ void LLDrawPoolWLSky::renderStars(void) const } } -void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const +void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const { if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull()) { @@ -286,7 +285,7 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const cloud_shader->bind(); /// Render the skydome - renderDome(camHeightLocal, cloud_shader); +//renderDome(camPosLocal, camHeightLocal, cloud_shader); cloud_shader->unbind(); } @@ -319,17 +318,18 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() // since LLImageGL::bind detects that it's a noop, and optimizes it out. gGL.getTexUnit(0)->bind(face->getTexture()); LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); - F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; + + /*F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; if (a > 0.f) { a = a*a*4.f; - } - - color.mV[3] = llclamp(a, 0.f, 1.f); + } + color.mV[3] = llclamp(a, 0.f, 1.f);*/ if (gPipeline.canUseVertexShaders()) { gHighlightProgram.bind(); + gHighlightProgram.uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV); } LLFacePool::LLOverrideFaceColor color_override(this, color); @@ -360,35 +360,42 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) gGL.setColorMask(true, false); - LLGLSquashToFarClip far_clip(glh_get_current_projection()); + LLGLSquashToFarClip far_clip(get_current_projection()); - renderSkyHaze(camHeightLocal); + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - if (!gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders()) + if (gPipeline.canUseWindLightShaders()) { - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - gGL.pushMatrix(); + if (gPipeline.useAdvancedAtmospherics()) + { + renderSkyHazeDeferred(origin, camHeightLocal); + } + else + { + renderSkyHaze(origin, camHeightLocal); + + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); + gGL.pushMatrix(); - - gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); + gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - gDeferredStarProgram.bind(); - // *NOTE: have to bind a texture here since register combiners blending in - // renderStars() requires something to be bound and we might as well only - // bind the moon's texture once. - gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); + gDeferredStarProgram.bind(); + // *NOTE: have to bind a texture here since register combiners blending in + // renderStars() requires something to be bound and we might as well only + // bind the moon's texture once. + gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); - renderHeavenlyBodies(); + renderHeavenlyBodies(); - renderStars(); + renderStars(); - gDeferredStarProgram.unbind(); + gDeferredStarProgram.unbind(); - gGL.popMatrix(); - } + gGL.popMatrix(); - renderSkyClouds(camHeightLocal); - + renderSkyClouds(origin, camHeightLocal); + } + } gGL.setColorMask(true, true); } @@ -406,13 +413,16 @@ void LLDrawPoolWLSky::render(S32 pass) LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDisable clip(GL_CLIP_PLANE0); - LLGLSquashToFarClip far_clip(glh_get_current_projection()); + LLGLSquashToFarClip far_clip(get_current_projection()); + + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - renderSkyHaze(camHeightLocal); + renderSkyHaze(origin, camHeightLocal); - if (!gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders()) + bool use_advanced = gPipeline.useAdvancedAtmospherics(); + + if (!use_advanced) { - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); gGL.pushMatrix(); gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); @@ -429,7 +439,7 @@ void LLDrawPoolWLSky::render(S32 pass) gGL.popMatrix(); } - renderSkyClouds(camHeightLocal); + renderSkyClouds(origin, camHeightLocal); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index 586219e4bc..2beb2867db 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -34,12 +34,13 @@ class LLGLSLShader; class LLDrawPoolWLSky : public LLDrawPool { public: - static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0; - static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; - - static const U32 ADV_ATMO_SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX; + static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX + | LLVertexBuffer::MAP_TEXCOORD0; + static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX + | LLVertexBuffer::MAP_COLOR + | LLVertexBuffer::MAP_TEXCOORD0; + static const U32 ADV_ATMO_SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX + | LLVertexBuffer::MAP_TEXCOORD0; LLDrawPoolWLSky(void); /*virtual*/ ~LLDrawPoolWLSky(); @@ -72,10 +73,13 @@ public: static void cleanupGL(); static void restoreGL(); private: - void renderDome(F32 camHeightLocal, LLGLSLShader * shader) const; - void renderSkyHaze(F32 camHeightLocal) const; + void renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const; + void renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const; + void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const; + void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const; + void renderStars(void) const; - void renderSkyClouds(F32 camHeightLocal) const; + void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const; void renderHeavenlyBodies(); private: diff --git a/indra/newview/llenvadapters.cpp b/indra/newview/llenvadapters.cpp new file mode 100644 index 0000000000..fdbcf68fa4 --- /dev/null +++ b/indra/newview/llenvadapters.cpp @@ -0,0 +1,67 @@ +/** + * @file llenvadapters.cpp + * @brief Declaration of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llenvadapters.h" + +#include "llsettingssky.h" +#include "llsettingswater.h" +//========================================================================= + +LLSkySettingsAdapter::LLSkySettingsAdapter(): + mWLGamma(1.0f, LLSettingsSky::SETTING_GAMMA), + + // Lighting + mLightnorm(LLColor4(0.f, 0.707f, -0.707f, 1.f), LLSettingsSky::SETTING_LIGHT_NORMAL), + mSunlight(LLColor4(0.5f, 0.5f, 0.5f, 1.0f), LLSettingsSky::SETTING_SUNLIGHT_COLOR, "WLSunlight"), + + mGlow(LLColor4(18.0f, 0.0f, -0.01f, 1.0f), LLSettingsSky::SETTING_GLOW), + // Clouds + mCloudColor(LLColor4(0.5f, 0.5f, 0.5f, 1.0f), LLSettingsSky::SETTING_CLOUD_COLOR, "WLCloudColor"), + mCloudMain(LLColor4(0.5f, 0.5f, 0.125f, 1.0f), LLSettingsSky::SETTING_CLOUD_POS_DENSITY1), + mCloudCoverage(0.0f, LLSettingsSky::SETTING_CLOUD_SHADOW), + mCloudDetail(LLColor4(0.0f, 0.0f, 0.0f, 1.0f), LLSettingsSky::SETTING_CLOUD_POS_DENSITY2), + mCloudScale(0.42f, LLSettingsSky::SETTING_CLOUD_SCALE) +{ + +} + +LLWatterSettingsAdapter::LLWatterSettingsAdapter(): + mFogColor(LLColor4((22.f / 255.f), (43.f / 255.f), (54.f / 255.f), (0.0f)), LLSettingsWater::SETTING_FOG_COLOR, "WaterFogColor"), + mFogDensity(4, LLSettingsWater::SETTING_FOG_DENSITY, 2), + mUnderWaterFogMod(0.25, LLSettingsWater::SETTING_FOG_MOD), + mNormalScale(LLVector3(2.f, 2.f, 2.f), LLSettingsWater::SETTING_NORMAL_SCALE), + mFresnelScale(0.5f, LLSettingsWater::SETTING_FRESNEL_SCALE), + mFresnelOffset(0.4f, LLSettingsWater::SETTING_FRESNEL_OFFSET), + mScaleAbove(0.025f, LLSettingsWater::SETTING_SCALE_ABOVE), + mScaleBelow(0.2f, LLSettingsWater::SETTING_SCALE_BELOW), + mBlurMultiplier(0.1f, LLSettingsWater::SETTING_BLUR_MULTIPILER), + mWave1Dir(LLVector2(0.5f, 0.5f), LLSettingsWater::SETTING_WAVE1_DIR), + mWave2Dir(LLVector2(0.5f, 0.5f), LLSettingsWater::SETTING_WAVE2_DIR) + +{ + +} diff --git a/indra/newview/llenvadapters.h b/indra/newview/llenvadapters.h new file mode 100644 index 0000000000..bd58db0589 --- /dev/null +++ b/indra/newview/llenvadapters.h @@ -0,0 +1,459 @@ +/** + * @file llenvadapters.h + * @brief Declaration of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_ENVADAPTERS_H +#define LL_ENVADAPTERS_H + +#include "v3math.h" +#include "v3color.h" +#include "v4math.h" +#include "llsettingsbase.h" +#include "llsettingssky.h" + +class WLColorControl +{ +public: + inline WLColorControl(LLColor4 color, const std::string& n, const std::string& slider_name = std::string()): + mColor(color), + mName(n), + mSliderName(slider_name), + mHasSliderName(false), + mIsSunOrAmbientColor(false), + mIsBlueHorizonOrDensity(false) + { + // if there's a slider name, say we have one + mHasSliderName = !mSliderName.empty(); + + // if it's the sun controller + mIsSunOrAmbientColor = (mSliderName == "WLSunlight" || mSliderName == "WLAmbient"); + mIsBlueHorizonOrDensity = (mSliderName == "WLBlueHorizon" || mSliderName == "WLBlueDensity"); + } + + inline void setColor4(const LLColor4 & val) + { + mColor = val; + } + + inline void setColor3(const LLColor3 & val) + { + mColor = val; + } + + inline LLColor4 getColor4() const + { + return mColor; + } + + inline LLColor3 getColor3(void) const + { + return vec4to3(mColor); + } + + inline void update(const LLSettingsBase::ptr_t &psetting) const + { + psetting->setValue(mName, mColor); + } + + inline bool getHasSliderName() const + { + return mHasSliderName; + } + + inline std::string getSliderName() const + { + return mSliderName; + } + + inline bool getIsSunOrAmbientColor() const + { + return mIsSunOrAmbientColor; + } + + inline bool getIsBlueHorizonOrDensity() const + { + return mIsBlueHorizonOrDensity; + } + + inline F32 getRed() const + { + return mColor[0]; + } + + inline F32 getGreen() const + { + return mColor[1]; + } + + inline F32 getBlue() const + { + return mColor[2]; + } + + inline F32 getIntensity() const + { + return mColor[3]; + } + + inline void setRed(F32 red) + { + mColor[0] = red; + } + + inline void setGreen(F32 green) + { + mColor[1] = green; + } + + inline void setBlue(F32 blue) + { + mColor[2] = blue; + } + + inline void setIntensity(F32 intensity) + { + mColor[3] = intensity; + } + +private: + LLColor4 mColor; /// [3] is intensity, not alpha + std::string mName; /// name to use to dereference params + std::string mSliderName; /// name of the slider in menu + bool mHasSliderName; /// only set slider name for true color types + bool mIsSunOrAmbientColor; /// flag for if it's the sun or ambient color controller + bool mIsBlueHorizonOrDensity; /// flag for if it's the Blue Horizon or Density color controller + +}; + +// float slider control +class WLFloatControl +{ +public: + inline WLFloatControl(F32 val, const std::string& n, F32 m = 1.0f): + x(val), + mName(n), + mult(m) + { + } + + inline WLFloatControl &operator = (F32 val) + { + x = val; + return *this; + } + + inline operator F32 (void) const + { + return x; + } + + inline void update(const LLSettingsBase::ptr_t &psetting) const + { + psetting->setValue(mName, x); + } + + inline F32 getMult() const + { + return mult; + } + + inline void setValue(F32 val) + { + x = val; + } + +private: + F32 x; + std::string mName; + F32 mult; +}; + +class WLXFloatControl +{ +public: + inline WLXFloatControl(F32 val, const std::string& n, F32 b): + mExp(val), + mBase(b), + mName(n) + { + } + + inline WLXFloatControl & operator = (F32 val) + { + mExp = log(val) / log(mBase); + + return *this; + } + + inline operator F32 (void) const + { + return pow(mBase, mExp); + } + + inline void update(const LLSettingsBase::ptr_t &psetting) const + { + psetting->setValue(mName, pow(mBase, mExp)); + } + + inline F32 getExp() const + { + return mExp; + } + + inline void setExp(F32 val) + { + mExp = val; + } + + inline F32 getBase() const + { + return mBase; + } + + inline void setBase(F32 val) + { + mBase = val; + } + +private: + F32 mExp; + F32 mBase; + std::string mName; +}; + +class WLVect2Control +{ +public: + inline WLVect2Control(LLVector2 val, const std::string& n): + mU(val.mV[0]), + mV(val.mV[1]), + mName(n) + { + } + + inline WLVect2Control & operator = (const LLVector2 & val) + { + mU = val.mV[0]; + mV = val.mV[1]; + + return *this; + } + + inline void update(const LLSettingsBase::ptr_t &psetting) const + { + psetting->setValue(mName, LLVector2(mU, mV)); + } + + inline F32 getU() const + { + return mU; + } + + inline void setU(F32 val) + { + mU = val; + } + + inline F32 getV() const + { + return mV; + } + + inline void setV(F32 val) + { + mV = val; + } + +private: + F32 mU; + F32 mV; + std::string mName; +}; + +class WLVect3Control +{ +public: + inline WLVect3Control(LLVector3 val, const std::string& n): + mX(val.mV[0]), + mY(val.mV[1]), + mZ(val.mV[2]), + mName(n) + { + } + + inline WLVect3Control & operator = (const LLVector3 & val) + { + mX = val.mV[0]; + mY = val.mV[1]; + mZ = val.mV[2]; + + return *this; + } + + inline void update(const LLSettingsBase::ptr_t &psetting) const + { + psetting->setValue(mName, LLVector3(mX, mY, mZ)); + } + + inline F32 getX() const + { + return mX; + } + + inline void setX(F32 val) + { + mX = val; + } + + inline F32 getY() const + { + return mY; + } + + inline void setY(F32 val) + { + mY = val; + } + + inline F32 getZ() const + { + return mZ; + } + + inline void setZ(F32 val) + { + mZ = val; + } + +private: + F32 mX; + F32 mY; + F32 mZ; + std::string mName; +}; + +class LLDensityProfileSettingsAdapter +{ +public: + LLDensityProfileSettingsAdapter(const std::string& config, int layerIndex = 0) + : mConfig(config) + , mLayerIndex(layerIndex) + , mLayerWidth(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH) + , mExpTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM) + , mExpScale(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR) + , mLinTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM) + , mConstantTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM) + {} + +protected: + std::string mConfig; + int mLayerIndex; + WLFloatControl mLayerWidth; // 0.0 -> to top of atmosphere, however big that may be. + WLFloatControl mExpTerm; + WLFloatControl mExpScale; + WLFloatControl mLinTerm; + WLFloatControl mConstantTerm; +}; + +class LLRayleighDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter +{ +public: + LLRayleighDensityProfileSettingsAdapter(int layerIndex = 0) + : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_RAYLEIGH_CONFIG, layerIndex) + { + } +}; + +class LLMieDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter +{ +public: + LLMieDensityProfileSettingsAdapter(int layerIndex = 0) + : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_MIE_CONFIG, layerIndex) + , mAnisotropy(0.8f, LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR) + { + } + +protected: + WLFloatControl mAnisotropy; +}; + +class LLAbsorptionDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter +{ +public: + LLAbsorptionDensityProfileSettingsAdapter(int layerIndex = 0) + : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_ABSORPTION_CONFIG, layerIndex) + { + } +}; + +//------------------------------------------------------------------------- +class LLSkySettingsAdapter +{ +public: + typedef std::shared_ptr<LLSkySettingsAdapter> ptr_t; + + LLSkySettingsAdapter(); + + WLFloatControl mWLGamma; + + /// Lighting + WLColorControl mLightnorm; + WLColorControl mSunlight; + WLColorControl mGlow; + + /// Clouds + WLColorControl mCloudColor; + WLColorControl mCloudMain; + WLFloatControl mCloudCoverage; + WLColorControl mCloudDetail; + WLFloatControl mCloudScale; +}; + +class LLWatterSettingsAdapter +{ +public: + typedef std::shared_ptr<LLWatterSettingsAdapter> ptr_t; + + LLWatterSettingsAdapter(); + + WLColorControl mFogColor; + WLXFloatControl mFogDensity; + WLFloatControl mUnderWaterFogMod; + + /// wavelet scales and directions + WLVect3Control mNormalScale; + WLVect2Control mWave1Dir; + WLVect2Control mWave2Dir; + + // controls how water is reflected and refracted + WLFloatControl mFresnelScale; + WLFloatControl mFresnelOffset; + WLFloatControl mScaleAbove; + WLFloatControl mScaleBelow; + WLFloatControl mBlurMultiplier; + +}; + +#endif // LL_ENVIRONMENT_H diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 21ecf7741b..e9c27a7794 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -56,6 +56,10 @@ #include <boost/make_shared.hpp> +#include "llatmosphere.h" + +#pragma optimize("", off) + //define EXPORT_PRESETS 1 //========================================================================= namespace @@ -239,7 +243,6 @@ const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f); const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg -const F32 LLEnvironment::NIGHTTIME_ELEVATION_COS(LLSky::NIGHTTIME_ELEVATION_COS); //------------------------------------------------------------------------- LLEnvironment::LLEnvironment(): @@ -308,6 +311,56 @@ bool LLEnvironment::canEdit() const return true; } +void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky) +{ + settingsOut.m_skyBottomRadius = psky->getSkyBottomRadius(); + settingsOut.m_skyTopRadius = psky->getSkyTopRadius(); + settingsOut.m_sunArcRadians = psky->getSunArcRadians(); + settingsOut.m_mieAnisotropy = psky->getMieAnisotropy(); + + LLSD rayleigh = psky->getRayleighConfigs(); + settingsOut.m_rayleighProfile.clear(); + for (LLSD::array_iterator itf = rayleigh.beginArray(); itf != rayleigh.endArray(); ++itf) + { + atmosphere::DensityProfileLayer layer; + LLSD& layerConfig = (*itf); + layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); + layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); + layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); + layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); + layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); + settingsOut.m_rayleighProfile.push_back(layer); + } + + LLSD mie = psky->getMieConfigs(); + settingsOut.m_mieProfile.clear(); + for (LLSD::array_iterator itf = mie.beginArray(); itf != mie.endArray(); ++itf) + { + atmosphere::DensityProfileLayer layer; + LLSD& layerConfig = (*itf); + layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); + layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); + layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); + layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); + layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); + settingsOut.m_mieProfile.push_back(layer); + } + + LLSD absorption = psky->getAbsorptionConfigs(); + settingsOut.m_absorptionProfile.clear(); + for (LLSD::array_iterator itf = absorption.beginArray(); itf != absorption.endArray(); ++itf) + { + atmosphere::DensityProfileLayer layer; + LLSD& layerConfig = (*itf); + layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); + layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); + layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); + layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); + layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); + settingsOut.m_absorptionProfile.push_back(layer); + } +} + bool LLEnvironment::isExtendedEnvironmentEnabled() const { return !gAgent.getRegionCapability("ExtEnvironment").empty(); @@ -380,9 +433,14 @@ F32 LLEnvironment::getWaterHeight() const return gAgent.getRegion()->getWaterHeight(); } -bool LLEnvironment::getIsDayTime() const +bool LLEnvironment::getIsSunUp() const +{ + return mCurrentEnvironment->getSky()->getIsSunUp(); +} + +bool LLEnvironment::getIsMoonUp() const { - return mCurrentEnvironment->getSky()->getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS; + return mCurrentEnvironment->getSky()->getIsMoonUp(); } //------------------------------------------------------------------------- @@ -629,6 +687,52 @@ void LLEnvironment::updateEnvironment(F64Seconds transition, bool forced) } } +LLVector3 LLEnvironment::getLightDirection() const +{ + LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky(); + if (!psky) + { + return LLVector3(0, 0, 1); + } + return psky->getLightDirection(); +} + +LLVector4 LLEnvironment::toCFR(const LLVector3 vec) const +{ + LLVector4 vec_cfr(vec.mV[1], vec.mV[0], vec.mV[2], 0.0f); + return vec_cfr; +} + +LLVector4 LLEnvironment::toLightNorm(const LLVector3 vec) const +{ + LLVector4 vec_ogl(vec.mV[1], vec.mV[2], vec.mV[0], 0.0f); + return vec_ogl; +} + +LLVector4 LLEnvironment::getLightDirectionCFR() const +{ + LLVector3 light_direction = getLightDirection(); + LLVector4 light_direction_cfr = toCFR(light_direction); + return light_direction_cfr; +} + +LLVector4 LLEnvironment::getClampedLightNorm() const +{ + LLVector3 light_direction = getLightDirection(); + if (light_direction.mV[2] < -0.1f) + { + light_direction.mV[2] = -0.1f; + } + return toLightNorm(light_direction); +} + +LLVector4 LLEnvironment::getRotatedLightNorm() const +{ + LLVector3 light_direction = getLightDirection(); + light_direction *= LLQuaternion(-mLastCamYaw, LLVector3(0.f, 1.f, 0.f)); + return toLightNorm(light_direction); +} + //------------------------------------------------------------------------- void LLEnvironment::update(const LLViewerCamera * cam) { @@ -643,18 +747,14 @@ void LLEnvironment::update(const LLViewerCamera * cam) // update clouds, sun, and general updateCloudScroll(); - F32 camYaw = cam->getYaw(); + // cache this for use in rotating the rotated light vec for shader param updates later... + mLastCamYaw = cam->getYaw() + SUN_DELTA_YAW; stop_glerror(); // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { - LLVector3 lightNorm3( getLightDirection() ); - - lightNorm3 *= LLQuaternion(-(camYaw + SUN_DELTA_YAW), LLVector3(0.f, 1.f, 0.f)); - mRotatedLight = LLVector4(lightNorm3, 0.f); - LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; end_shaders = LLViewerShaderMgr::instance()->endShaders(); for (shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) @@ -693,12 +793,24 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS LLSettingsBase::parammapping_t params = psetting->getParameterMap(); for (auto &it: params) { - if (!psetting->mSettings.has(it.first)) + LLSD value; + + bool found_in_settings = psetting->mSettings.has(it.first); + bool found_in_legacy_settings = !found_in_settings && psetting->mSettings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE].has(it.first); + + if (!found_in_settings && !found_in_legacy_settings) continue; - LLSD value = psetting->mSettings[it.first]; - LLSD::Type setting_type = value.type(); + if (found_in_settings) + { + value = psetting->mSettings[it.first]; + } + else if (found_in_legacy_settings) + { + value = psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE][it.first]; + } + LLSD::Type setting_type = value.type(); stop_glerror(); switch (setting_type) { @@ -754,26 +866,10 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader) { if (gPipeline.canUseWindLightShaders()) - { - updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky()); + { updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater()); - } - - if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) - { - stop_glerror(); - shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLight.mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); - stop_glerror(); - } - else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) - { - stop_glerror(); - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, getClampedLightDirection().mV); - stop_glerror(); - } - - shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, getSceneLightStrength()); + updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky()); + } } LLEnvironment::list_name_id_t LLEnvironment::getSkyList() const @@ -1594,7 +1690,15 @@ void LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky) mInitialized = false; mSky = psky; + mSky->update(); mBlenderSky.reset(); + + if (gAtmosphere) + { + AtmosphericModelSettings settings; + LLEnvironment::getAtmosphericModelSettings(settings, psky); + gAtmosphere->configureAtmosphericModel(settings); + } } void LLEnvironment::DayInstance::setWater(const LLSettingsWater::ptr_t &pwater) @@ -1605,6 +1709,7 @@ void LLEnvironment::DayInstance::setWater(const LLSettingsWater::ptr_t &pwater) mInitialized = false; mWater = pwater; + mWater->update(); mBlenderWater.reset(); } diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 32ce99ccc9..0fbc49bc7d 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -41,6 +41,7 @@ //------------------------------------------------------------------------- class LLViewerCamera; class LLGLSLShader; +class AtmosphericModelSettings; //------------------------------------------------------------------------- class LLEnvironment : public LLSingleton<LLEnvironment> @@ -144,6 +145,8 @@ public: LLSettingsSky::ptr_t getCurrentSky() const { return mCurrentEnvironment->getSky(); } LLSettingsWater::ptr_t getCurrentWater() const { return mCurrentEnvironment->getWater(); } + static void getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky); + void update(const LLViewerCamera * cam); void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting); @@ -185,15 +188,23 @@ public: F32 getCamHeight() const; F32 getWaterHeight() const; - bool getIsDayTime() const; // "Day Time" is defined as the sun above the horizon. - bool getIsNightTime() const { return !getIsDayTime(); } // "Not Day Time" + bool getIsSunUp() const; + bool getIsMoonUp() const; + + // Returns either sun or moon direction (depending on which is up and stronger) + // Light direction in +x right, +z up, +y at internal coord sys + LLVector3 getLightDirection() const; + + // Returns light direction converted to CFR coord system + LLVector4 getLightDirectionCFR() const; - inline F32 getSceneLightStrength() const { return mSceneLightStrength; } - inline void setSceneLightStrength(F32 light_strength) { mSceneLightStrength = light_strength; } + // Returns light direction converted to OGL coord system + // and clamped above -0.1f in Y to avoid render artifacts in sky shaders + LLVector4 getClampedLightNorm() const; - inline LLVector4 getLightDirection() const { return ((mCurrentEnvironment->getSky()) ? LLVector4(mCurrentEnvironment->getSky()->getLightDirection(), 0.0f) : LLVector4()); } - inline LLVector4 getClampedLightDirection() const { return LLVector4(mCurrentEnvironment->getSky()->getClampedLightDirection(), 0.0f); } - inline LLVector4 getRotatedLight() const { return mRotatedLight; } + // Returns light direction converted to OGL coord system + // and rotated by last cam yaw needed by water rendering shaders + LLVector4 getRotatedLightNorm() const; static LLSettingsWater::ptr_t createWaterFromLegacyPreset(const std::string filename); static LLSettingsSky::ptr_t createSkyFromLegacyPreset(const std::string filename); @@ -225,6 +236,9 @@ protected: virtual void initSingleton(); private: + LLVector4 toCFR(const LLVector3 vec) const; + LLVector4 toLightNorm(const LLVector3 vec) const; + class DayInstance { public: @@ -301,7 +315,7 @@ private: }; static const F32 SUN_DELTA_YAW; - static const F32 NIGHTTIME_ELEVATION_COS; + F32 mLastCamYaw = 0.0f; typedef std::map<LLUUID, LLSettingsBase::ptr_t> AssetSettingMap_t; @@ -332,9 +346,6 @@ private: namedSettingMap_t mDayCycleByName; AssetSettingMap_t mDayCycleById; - F32 mSceneLightStrength; - LLVector4 mRotatedLight; - UserPrefs mUserPrefs; change_signal_t mSkyListChange; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 7f7d7f3dcc..3f2247c9c5 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1630,7 +1630,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, // that emboss mapping always shows up on the upward faces of cubes when // it's noon (since a lot of builders build with the sun forced to noon). LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir; - LLVector3 moon_ray = gSky.getMoonDirection(); + LLVector3 moon_ray = gSky.mVOSkyp->getMoon().getDirection(); LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp new file mode 100644 index 0000000000..6bdc5ee823 --- /dev/null +++ b/indra/newview/llfloatereditsky.cpp @@ -0,0 +1,699 @@ +/** + * @file llfloatereditsky.cpp + * @brief Floater to create or edit a sky preset + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatereditsky.h" + +#include <boost/make_shared.hpp> + +// libs +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llmultisliderctrl.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llsliderctrl.h" +#include "lltabcontainer.h" +#include "lltimectrl.h" +#include "lljoystickbutton.h" + +// newview +#include "llagent.h" +#include "llcolorswatch.h" +#include "llregioninfomodel.h" +#include "llviewerregion.h" + +#include "v3colorutil.h" +#include "llenvironment.h" +#include "llenvadapters.h" + +namespace +{ + const F32 WL_SUN_AMBIENT_SLIDER_SCALE(3.0f); + const F32 WL_BLUE_HORIZON_DENSITY_SCALE(2.0f); + const F32 WL_CLOUD_SLIDER_SCALE(1.0f); +} + + +static F32 time24_to_sun_pos(F32 time24) +{ + F32 sun_pos = fmodf((time24 - 6) / 24.0f, 1.0f); + if (sun_pos < 0) ++sun_pos; + return sun_pos; +} + +LLFloaterEditSky::LLFloaterEditSky(const LLSD &key): + LLFloater(key), + mSkyPresetNameEditor(NULL), + mSkyPresetCombo(NULL), + mMakeDefaultCheckBox(NULL), + mSaveButton(NULL), + mSkyAdapter() +{ +} + +// virtual +BOOL LLFloaterEditSky::postBuild() +{ + mSkyPresetNameEditor = getChild<LLLineEditor>("sky_preset_name"); + mSkyPresetCombo = getChild<LLComboBox>("sky_preset_combo"); + mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb"); + mSaveButton = getChild<LLButton>("save"); + mSkyAdapter = boost::make_shared<LLSkySettingsAdapter>(); + + LLEnvironment::instance().setSkyListChange(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this)); + + initCallbacks(); + +// // Create the sun position scrubber on the slider. +// getChild<LLMultiSliderCtrl>("WLSunPos")->addSlider(12.f); + + return TRUE; +} + +// virtual +void LLFloaterEditSky::onOpen(const LLSD& key) +{ + bool new_preset = isNewPreset(); + std::string param = key.asString(); + std::string floater_title = getString(std::string("title_") + param); + std::string hint = getString(std::string("hint_" + param)); + + // Update floater title. + setTitle(floater_title); + + // Update the hint at the top. + getChild<LLUICtrl>("hint")->setValue(hint); + + // Hide the hint to the right of the combo if we're invoked to create a new preset. + getChildView("note")->setVisible(!new_preset); + + // Switch between the sky presets combobox and preset name input field. + mSkyPresetCombo->setVisible(!new_preset); + mSkyPresetNameEditor->setVisible(new_preset); + + reset(); +} + +// virtual +void LLFloaterEditSky::onClose(bool app_quitting) +{ + if (!app_quitting) // there's no point to change environment if we're quitting + { + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } +} + +// virtual +void LLFloaterEditSky::draw() +{ + syncControls(); + LLFloater::draw(); +} + +void LLFloaterEditSky::initCallbacks(void) +{ + // *TODO: warn user if a region environment update comes while we're editing a region sky preset. + + mSkyPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this), NULL); + mSkyPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditSky::onSkyPresetSelected, this)); + mSkyPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this)); + + mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnSave, this)); + getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this)); + + // Connect to region info updates. + LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditSky::onRegionInfoUpdate, this)); + + // sunlight + getChild<LLUICtrl>("WLSunlight")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &mSkyAdapter->mSunlight)); + + // glow + getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowRMoved, this, _1, &mSkyAdapter->mGlow)); + getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowBMoved, this, _1, &mSkyAdapter->mGlow)); + + // time of day +// getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &mSkyAdapter->mLightnorm)); // multi-slider +// getChild<LLTimeCtrl>("WLDayTime")->setCommitCallback(boost::bind(&LLFloaterEditSky::onTimeChanged, this)); // time ctrl +// getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &mSkyAdapter->mLightnorm)); + getChild<LLJoystickQuaternion>("WLSunRotation")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunRotationChanged, this)); + getChild<LLJoystickQuaternion>("WLMoonRotation")->setCommitCallback(boost::bind(&LLFloaterEditSky::onMoonRotationChanged, this)); + + // Clouds + + // Cloud Color + getChild<LLUICtrl>("WLCloudColor")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &mSkyAdapter->mCloudColor)); + + // Cloud + getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &mSkyAdapter->mCloudMain)); + getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &mSkyAdapter->mCloudMain)); + getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &mSkyAdapter->mCloudMain)); + + // Cloud Detail + getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &mSkyAdapter->mCloudDetail)); + getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &mSkyAdapter->mCloudDetail)); + getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &mSkyAdapter->mCloudDetail)); + + // Cloud extras + getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &mSkyAdapter->mCloudCoverage)); + getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &mSkyAdapter->mCloudScale)); + getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXMoved, this, _1)); + getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYMoved, this, _1)); + + + // Dome + getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &mSkyAdapter->mWLGamma)); + getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterEditSky::onStarAlphaMoved, this, _1)); +} + +//================================================================================================= + +void LLFloaterEditSky::syncControls() +{ + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + mEditSettings = psky; + + std::string name = psky->getName(); + + mSkyPresetNameEditor->setText(name); + mSkyPresetCombo->setValue(name); + + // Lighting + + // sunlight + mSkyAdapter->mSunlight.setColor3( psky->getSunlightColor() ); + setColorSwatch("WLSunlight", mSkyAdapter->mSunlight, WL_SUN_AMBIENT_SLIDER_SCALE); + + // glow + mSkyAdapter->mGlow.setColor3( psky->getGlow() ); + childSetValue("WLGlowR", 2 - mSkyAdapter->mGlow.getRed() / 20.0f); + childSetValue("WLGlowB", -mSkyAdapter->mGlow.getBlue() / 5.0f); + +// LLSettingsSky::azimalt_t azal = psky->getSunRotationAzAl(); +// +// F32 time24 = sun_pos_to_time24(azal.second / F_TWO_PI); +// getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE); +// getChild<LLTimeCtrl>("WLDayTime")->setTime24(time24); +// childSetValue("WLEastAngle", azal.first / F_TWO_PI); + getChild<LLJoystickQuaternion>("WLSunRotation")->setRotation(psky->getSunRotation()); + getChild<LLJoystickQuaternion>("WLMoonRotation")->setRotation(psky->getMoonRotation()); + + // Clouds + + // Cloud Color + mSkyAdapter->mCloudColor.setColor3( psky->getCloudColor() ); + setColorSwatch("WLCloudColor", mSkyAdapter->mCloudColor, WL_CLOUD_SLIDER_SCALE); + + // Cloud + mSkyAdapter->mCloudMain.setColor3( psky->getCloudPosDensity1() ); + childSetValue("WLCloudX", mSkyAdapter->mCloudMain.getRed()); + childSetValue("WLCloudY", mSkyAdapter->mCloudMain.getGreen()); + childSetValue("WLCloudDensity", mSkyAdapter->mCloudMain.getBlue()); + + // Cloud Detail + mSkyAdapter->mCloudDetail.setColor3( psky->getCloudPosDensity2() ); + childSetValue("WLCloudDetailX", mSkyAdapter->mCloudDetail.getRed()); + childSetValue("WLCloudDetailY", mSkyAdapter->mCloudDetail.getGreen()); + childSetValue("WLCloudDetailDensity", mSkyAdapter->mCloudDetail.getBlue()); + + // Cloud extras + mSkyAdapter->mCloudCoverage = psky->getCloudShadow(); + mSkyAdapter->mCloudScale = psky->getCloudScale(); + childSetValue("WLCloudCoverage", (F32) mSkyAdapter->mCloudCoverage); + childSetValue("WLCloudScale", (F32) mSkyAdapter->mCloudScale); + + // cloud scrolling + LLVector2 scroll_rate = psky->getCloudScrollRate(); + + // LAPRAS: These should go away... + childDisable("WLCloudLockX"); + childDisable("WLCloudLockY"); + + // disable if locked, enable if not + childEnable("WLCloudScrollX"); + childEnable("WLCloudScrollY"); + + // *HACK cloud scrolling is off my an additive of 10 + childSetValue("WLCloudScrollX", scroll_rate[0] - 10.0f); + childSetValue("WLCloudScrollY", scroll_rate[1] - 10.0f); + + // Tweak extras + + mSkyAdapter->mWLGamma = psky->getGamma(); + childSetValue("WLGamma", (F32) mSkyAdapter->mWLGamma); + + childSetValue("WLStarAlpha", psky->getStarBrightness()); +} + +void LLFloaterEditSky::setColorSwatch(const std::string& name, const WLColorControl& from_ctrl, F32 k) +{ + // Set the value, dividing it by <k> first. + LLColor4 color = from_ctrl.getColor4(); + getChild<LLColorSwatchCtrl>(name)->set(color / k); +} + +// color control callbacks +void LLFloaterEditSky::onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl) +{ + LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl); + LLColor4 color_vec(swatch->get().mV); + + // Multiply RGB values by the appropriate factor. + F32 k = WL_CLOUD_SLIDER_SCALE; + if (color_ctrl->getIsSunOrAmbientColor()) + { + k = WL_SUN_AMBIENT_SLIDER_SCALE; + } + else if (color_ctrl->getIsBlueHorizonOrDensity()) + { + k = WL_BLUE_HORIZON_DENSITY_SCALE; + } + + color_vec *= k; // intensity isn't affected by the multiplication + + // Set intensity to maximum of the RGB values. + color_vec.mV[3] = color_max(color_vec); + + // Apply the new RGBI value. + color_ctrl->setColor4(color_vec); + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditSky::onColorControlRMoved(LLUICtrl* ctrl, void* userdata) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + F32 red_value = sldr_ctrl->getValueF32(); + F32 k = 1.0f; + + if (color_ctrl->getIsSunOrAmbientColor()) + { + k = WL_SUN_AMBIENT_SLIDER_SCALE; + } + if (color_ctrl->getIsBlueHorizonOrDensity()) + { + k = WL_BLUE_HORIZON_DENSITY_SCALE; + } + color_ctrl->setRed(red_value * k); + + adjustIntensity(color_ctrl, red_value, k); + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditSky::onColorControlGMoved(LLUICtrl* ctrl, void* userdata) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + F32 green_value = sldr_ctrl->getValueF32(); + F32 k = 1.0f; + + if (color_ctrl->getIsSunOrAmbientColor()) + { + k = WL_SUN_AMBIENT_SLIDER_SCALE; + } + if (color_ctrl->getIsBlueHorizonOrDensity()) + { + k = WL_BLUE_HORIZON_DENSITY_SCALE; + } + color_ctrl->setGreen(green_value * k); + + adjustIntensity(color_ctrl, green_value, k); + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditSky::onColorControlBMoved(LLUICtrl* ctrl, void* userdata) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + F32 blue_value = sldr_ctrl->getValueF32(); + F32 k = 1.0f; + + if (color_ctrl->getIsSunOrAmbientColor()) + { + k = WL_SUN_AMBIENT_SLIDER_SCALE; + } + if (color_ctrl->getIsBlueHorizonOrDensity()) + { + k = WL_BLUE_HORIZON_DENSITY_SCALE; + } + color_ctrl->setBlue(blue_value * k); + + adjustIntensity(color_ctrl, blue_value, k); + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditSky::adjustIntensity(WLColorControl *ctrl, F32 val, F32 scale) +{ + if (ctrl->getHasSliderName()) + { + LLColor4 color = ctrl->getColor4(); + F32 i = color_max(color) / scale; + ctrl->setIntensity(i); + std::string name = ctrl->getSliderName(); + name.append("I"); + + childSetValue(name, i); + } +} + + +/// GLOW SPECIFIC CODE +void LLFloaterEditSky::onGlowRMoved(LLUICtrl* ctrl, void* userdata) +{ + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + // scaled by 20 + color_ctrl->setRed((2 - sldr_ctrl->getValueF32()) * 20); + + color_ctrl->update(mEditSettings); +} + +/// \NOTE that we want NEGATIVE (-) B +void LLFloaterEditSky::onGlowBMoved(LLUICtrl* ctrl, void* userdata) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + /// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big + color_ctrl->setBlue(-sldr_ctrl->getValueF32() * 5); + + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditSky::onFloatControlMoved(LLUICtrl* ctrl, void* userdata) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLFloatControl * floatControl = static_cast<WLFloatControl *>(userdata); + + floatControl->setValue(sldr_ctrl->getValueF32() / floatControl->getMult()); + + floatControl->update(mEditSettings); +} + + +// Lighting callbacks + +// time of day +void LLFloaterEditSky::onSunMoved(LLUICtrl* ctrl, void* userdata) +{ + LLMultiSliderCtrl* sun_msldr = getChild<LLMultiSliderCtrl>("WLSunPos"); + LLSliderCtrl* east_sldr = getChild<LLSliderCtrl>("WLEastAngle"); + LLTimeCtrl* time_ctrl = getChild<LLTimeCtrl>("WLDayTime"); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + F32 time24 = sun_msldr->getCurSliderValue(); + time_ctrl->setTime24(time24); // sync the time ctrl with the new sun position + + // get the two angles + F32 azimuth = F_TWO_PI * east_sldr->getValueF32(); + F32 altitude = F_TWO_PI * time24_to_sun_pos(time24); + mEditSettings->setSunRotation(azimuth, altitude); + mEditSettings->setMoonRotation(azimuth + F_PI, -altitude); + + LLVector4 sunnorm( mEditSettings->getSunDirection(), 1.f ); + + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditSky::onTimeChanged() +{ + F32 time24 = getChild<LLTimeCtrl>("WLDayTime")->getTime24(); + getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE); + onSunMoved(getChild<LLUICtrl>("WLSunPos"), &(mSkyAdapter->mLightnorm)); +} + +void LLFloaterEditSky::onSunRotationChanged() +{ + LLJoystickQuaternion* sun_spinner = getChild<LLJoystickQuaternion>("WLSunRotation"); + LLQuaternion sunrot(sun_spinner->getRotation()); + + mEditSettings->setSunRotation(sunrot); +} + +void LLFloaterEditSky::onMoonRotationChanged() +{ + LLJoystickQuaternion* moon_spinner = getChild<LLJoystickQuaternion>("WLMoonRotation"); + LLQuaternion moonrot(moon_spinner->getRotation()); + + mEditSettings->setMoonRotation(moonrot); +} + +void LLFloaterEditSky::onStarAlphaMoved(LLUICtrl* ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + mEditSettings->setStarBrightness(sldr_ctrl->getValueF32()); +} + +// Clouds +void LLFloaterEditSky::onCloudScrollXMoved(LLUICtrl* ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + // *HACK all cloud scrolling is off by an additive of 10. + mEditSettings->setCloudScrollRateX(sldr_ctrl->getValueF32() + 10.0f); +} + +void LLFloaterEditSky::onCloudScrollYMoved(LLUICtrl* ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + // *HACK all cloud scrolling is off by an additive of 10. + mEditSettings->setCloudScrollRateY(sldr_ctrl->getValueF32() + 10.0f); +} + +//================================================================================================= + +void LLFloaterEditSky::reset() +{ + if (isNewPreset()) + { + mSkyPresetNameEditor->setValue(LLSD()); + mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name + } + else + { + refreshSkyPresetsList(); + + // Disable controls until a sky preset to edit is selected. + enableEditing(false); + } +} + +bool LLFloaterEditSky::isNewPreset() const +{ + return mKey.asString() == "new"; +} + +void LLFloaterEditSky::refreshSkyPresetsList() +{ + mSkyPresetCombo->removeall(); + + LLEnvironment::list_name_id_t list = LLEnvironment::instance().getSkyList(); + + for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it) + { + mSkyPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second)); + } + + mSkyPresetCombo->setLabel(getString("combo_label")); +} + +void LLFloaterEditSky::enableEditing(bool enable) +{ + // Enable/disable the tab and their contents. + LLTabContainer* tab_container = getChild<LLTabContainer>("WindLight Tabs"); + tab_container->setEnabled(enable); + for (S32 i = 0; i < tab_container->getTabCount(); ++i) + { + tab_container->enableTabButton(i, enable); + tab_container->getPanelByIndex(i)->setCtrlsEnabled(enable); + } + + // Enable/disable saving. + mSaveButton->setEnabled(enable); + mMakeDefaultCheckBox->setEnabled(enable); +} + +void LLFloaterEditSky::saveRegionSky() +{ +#if 0 + LLWLParamKey key(getSelectedSkyPreset()); + llassert(key.scope == LLEnvKey::SCOPE_REGION); + + LL_DEBUGS("Windlight") << "Saving region sky preset: " << key.name << LL_ENDL; + LLWLParamManager& wl_mgr = LLWLParamManager::instance(); + wl_mgr.mCurParams.mName = key.name; + wl_mgr.setParamSet(key, wl_mgr.mCurParams); + + // *TODO: save to cached region settings. + LL_WARNS("Windlight") << "Saving region sky is not fully implemented yet" << LL_ENDL; +#endif +} + +std::string LLFloaterEditSky::getSelectedPresetName() const +{ + std::string name; + if (mSkyPresetNameEditor->getVisible()) + { + name = mSkyPresetNameEditor->getText(); + } + else + { + LLSD combo_val = mSkyPresetCombo->getValue(); + name = combo_val[0].asString(); + } + + return name; +} + +void LLFloaterEditSky::onSkyPresetNameEdited() +{ + std::string name = mSkyPresetNameEditor->getText(); + LLSettingsWater::ptr_t psky = LLEnvironment::instance().getCurrentWater(); + + psky->setName(name); +} + +void LLFloaterEditSky::onSkyPresetSelected() +{ + std::string name; + + name = getSelectedPresetName(); + + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName(name); + + if (!psky) + { + LL_WARNS("WATEREDIT") << "Could not find water preset" << LL_ENDL; + enableEditing(false); + return; + } + + psky = psky->buildClone(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, psky); + mEditSettings = psky; + + syncControls(); + enableEditing(true); + +} + +bool LLFloaterEditSky::onSaveAnswer(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + // If they choose save, do it. Otherwise, don't do anything + if (option == 0) + { + onSaveConfirmed(); + } + + return false; +} + +void LLFloaterEditSky::onSaveConfirmed() +{ + // Save currently displayed water params to the selected preset. + std::string name = mEditSettings->getName(); + + LL_DEBUGS("Windlight") << "Saving sky preset " << name << LL_ENDL; + + LLEnvironment::instance().addSky(mEditSettings); + + // Change preference if requested. + if (mMakeDefaultCheckBox->getEnabled() && mMakeDefaultCheckBox->getValue()) + { + LL_DEBUGS("Windlight") << name << " is now the new preferred sky preset" << LL_ENDL; + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings); + } + + closeFloater(); +} + +void LLFloaterEditSky::onBtnSave() +{ + LLEnvironment::instance().addSky(mEditSettings); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings); + + closeFloater(); +} + +void LLFloaterEditSky::onBtnCancel() +{ + closeFloater(); +} + +void LLFloaterEditSky::onSkyPresetListChange() +{ + refreshSkyPresetsList(); +} + +void LLFloaterEditSky::onRegionSettingsChange() +{ +#if 0 + // If creating a new sky, don't bother. + if (isNewPreset()) + { + return; + } + + if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) // if editing a region sky + { + // reset the floater to its initial state + reset(); + + // *TODO: Notify user? + } + else // editing a local sky + { + refreshSkyPresetsList(); + } +#endif +} + +void LLFloaterEditSky::onRegionInfoUpdate() +{ +#if 0 + bool can_edit = true; + + // If we've selected a region sky preset for editing. + if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) + { + // check whether we have the access + can_edit = LLEnvManagerNew::canEditRegionSettings(); + } + + enableEditing(can_edit); +#endif +} diff --git a/indra/newview/llfloatereditwater.cpp b/indra/newview/llfloatereditwater.cpp new file mode 100644 index 0000000000..6e7b777e70 --- /dev/null +++ b/indra/newview/llfloatereditwater.cpp @@ -0,0 +1,526 @@ +/** + * @file llfloatereditwater.cpp + * @brief Floater to create or edit a water preset + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatereditwater.h" + +#include <boost/make_shared.hpp> + +// libs +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcolorswatch.h" +#include "llcombobox.h" +//#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llsliderctrl.h" +#include "lltexturectrl.h" + +// newview +#include "llagent.h" +#include "llregioninfomodel.h" +#include "llviewerregion.h" + +#include "llenvironment.h" +#include "llsettingswater.h" +#include "llenvadapters.h" + +#include "v3colorutil.h" + +#undef max // Fixes a Windows compiler error + +LLFloaterEditWater::LLFloaterEditWater(const LLSD &key): + LLFloater(key), + mWaterPresetNameEditor(NULL), + mWaterPresetCombo(NULL), + mMakeDefaultCheckBox(NULL), + mSaveButton(NULL), + mWaterAdapter() +{ +} + +// virtual +BOOL LLFloaterEditWater::postBuild() +{ + mWaterPresetNameEditor = getChild<LLLineEditor>("water_preset_name"); + mWaterPresetCombo = getChild<LLComboBox>("water_preset_combo"); + mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb"); + mSaveButton = getChild<LLButton>("save"); + + mWaterAdapter = boost::make_shared<LLWatterSettingsAdapter>(); + + LLEnvironment::instance().setWaterListChange(boost::bind(&LLFloaterEditWater::onWaterPresetListChange, this)); + + initCallbacks(); + refreshWaterPresetsList(); + syncControls(); + + return TRUE; +} + +// virtual +void LLFloaterEditWater::onOpen(const LLSD& key) +{ + bool new_preset = isNewPreset(); + std::string param = key.asString(); + std::string floater_title = getString(std::string("title_") + param); + std::string hint = getString(std::string("hint_" + param)); + + // Update floater title. + setTitle(floater_title); + + // Update the hint at the top. + getChild<LLUICtrl>("hint")->setValue(hint); + + // Hide the hint to the right of the combo if we're invoked to create a new preset. + getChildView("note")->setVisible(!new_preset); + + // Switch between the water presets combobox and preset name input field. + mWaterPresetCombo->setVisible(!new_preset); + mWaterPresetNameEditor->setVisible(new_preset); + + reset(); +} + +// virtual +void LLFloaterEditWater::onClose(bool app_quitting) +{ + if (!app_quitting) // there's no point to change environment if we're quitting + { + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } +} + +// virtual +void LLFloaterEditWater::draw() +{ + syncControls(); + LLFloater::draw(); +} + +void LLFloaterEditWater::initCallbacks(void) +{ + mWaterPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditWater::onWaterPresetNameEdited, this), NULL); + mWaterPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditWater::onWaterPresetSelected, this)); + mWaterPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditWater::onWaterPresetNameEdited, this)); + + mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnSave, this)); + getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnCancel, this)); + + // Connect to region info updates. + LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditWater::onRegionInfoUpdate, this)); + + //------------------------------------------------------------------------- + + getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterEditWater::onColorControlMoved, this, _1, &mWaterAdapter->mFogColor)); + + // fog density + getChild<LLUICtrl>("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterEditWater::onExpFloatControlMoved, this, _1, &mWaterAdapter->mFogDensity)); + getChild<LLUICtrl>("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mUnderWaterFogMod)); + + // blue density + getChild<LLUICtrl>("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlXMoved, this, _1, &mWaterAdapter->mNormalScale)); + getChild<LLUICtrl>("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlYMoved, this, _1, &mWaterAdapter->mNormalScale)); + getChild<LLUICtrl>("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlZMoved, this, _1, &mWaterAdapter->mNormalScale)); + + // fresnel + getChild<LLUICtrl>("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mFresnelScale)); + getChild<LLUICtrl>("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mFresnelOffset)); + + // scale above/below + getChild<LLUICtrl>("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mScaleAbove)); + getChild<LLUICtrl>("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mScaleBelow)); + + // blur mult + getChild<LLUICtrl>("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mBlurMultiplier)); + + // wave direction + getChild<LLUICtrl>("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &mWaterAdapter->mWave1Dir)); + getChild<LLUICtrl>("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &mWaterAdapter->mWave1Dir)); + getChild<LLUICtrl>("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &mWaterAdapter->mWave2Dir)); + getChild<LLUICtrl>("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &mWaterAdapter->mWave2Dir)); + + LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("WaterNormalMap"); + texture_ctrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL); + texture_ctrl->setCommitCallback(boost::bind(&LLFloaterEditWater::onNormalMapPicked, this, _1)); +} + +//============================================================================= + +void LLFloaterEditWater::syncControls() +{ + // *TODO: Eliminate slow getChild() calls. + + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); + mEditSettings = pwater; + + std::string name = pwater->getName(); + mWaterPresetNameEditor->setText(name); + mWaterPresetCombo->setValue(name); + + //getChild<LLUICtrl>("WaterGlow")->setValue(col.mV[3]); + getChild<LLColorSwatchCtrl>("WaterFogColor")->set(LLColor4(pwater->getWaterFogColor())); + + // fog and wavelets + mWaterAdapter->mFogDensity = pwater->getWaterFogDensity(); + getChild<LLUICtrl>("WaterFogDensity")->setValue(mWaterAdapter->mFogDensity.getExp()); + + mWaterAdapter->mUnderWaterFogMod = pwater->getFogMod(); + getChild<LLUICtrl>("WaterUnderWaterFogMod")->setValue(static_cast<F32>(mWaterAdapter->mUnderWaterFogMod)); + + mWaterAdapter->mNormalScale = pwater->getNormalScale(); + getChild<LLUICtrl>("WaterNormalScaleX")->setValue(mWaterAdapter->mNormalScale.getX()); + getChild<LLUICtrl>("WaterNormalScaleY")->setValue(mWaterAdapter->mNormalScale.getY()); + getChild<LLUICtrl>("WaterNormalScaleZ")->setValue(mWaterAdapter->mNormalScale.getZ()); + + // Fresnel + mWaterAdapter->mFresnelScale = pwater->getFresnelScale(); + getChild<LLUICtrl>("WaterFresnelScale")->setValue(static_cast<F32>(mWaterAdapter->mFresnelScale)); + mWaterAdapter->mFresnelOffset = pwater->getFresnelOffset(); + getChild<LLUICtrl>("WaterFresnelOffset")->setValue(static_cast<F32>(mWaterAdapter->mFresnelOffset)); + + // Scale Above/Below + mWaterAdapter->mScaleAbove = pwater->getScaleAbove(); + getChild<LLUICtrl>("WaterScaleAbove")->setValue(static_cast<F32>(mWaterAdapter->mScaleAbove)); + mWaterAdapter->mScaleBelow = pwater->getScaleBelow(); + getChild<LLUICtrl>("WaterScaleBelow")->setValue(static_cast<F32>(mWaterAdapter->mScaleBelow)); + + // blur mult + mWaterAdapter->mBlurMultiplier = pwater->getBlurMultiplier(); + getChild<LLUICtrl>("WaterBlurMult")->setValue(static_cast<F32>(mWaterAdapter->mBlurMultiplier)); + + // wave directions + mWaterAdapter->mWave1Dir = pwater->getWave1Dir(); + getChild<LLUICtrl>("WaterWave1DirX")->setValue(mWaterAdapter->mWave1Dir.getU()); + getChild<LLUICtrl>("WaterWave1DirY")->setValue(mWaterAdapter->mWave1Dir.getV()); + + mWaterAdapter->mWave2Dir = pwater->getWave2Dir(); + getChild<LLUICtrl>("WaterWave2DirX")->setValue(mWaterAdapter->mWave2Dir.getU()); + getChild<LLUICtrl>("WaterWave2DirY")->setValue(mWaterAdapter->mWave2Dir.getV()); + + LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("WaterNormalMap"); + textCtrl->setImageAssetID(pwater->getNormalMapID()); +} + + +// vector control callbacks +void LLFloaterEditWater::onVector3ControlXMoved(LLUICtrl* ctrl, WLVect3Control* vector_ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + vector_ctrl->setX( sldr_ctrl->getValueF32() ); + vector_ctrl->update(mEditSettings); +} + +// vector control callbacks +void LLFloaterEditWater::onVector3ControlYMoved(LLUICtrl* ctrl, WLVect3Control* vector_ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + vector_ctrl->setY(sldr_ctrl->getValueF32()); + vector_ctrl->update(mEditSettings); +} + +// vector control callbacks +void LLFloaterEditWater::onVector3ControlZMoved(LLUICtrl* ctrl, WLVect3Control* vector_ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + vector_ctrl->setZ(sldr_ctrl->getValueF32()); + vector_ctrl->update(mEditSettings); +} + + +// vector control callbacks +void LLFloaterEditWater::onVector2ControlXMoved(LLUICtrl* ctrl, WLVect2Control* vector_ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + vector_ctrl->setU(sldr_ctrl->getValueF32()); + vector_ctrl->update(mEditSettings); +} + +// vector control callbacks +void LLFloaterEditWater::onVector2ControlYMoved(LLUICtrl* ctrl, WLVect2Control* vector_ctrl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + vector_ctrl->setV(sldr_ctrl->getValueF32()); + vector_ctrl->update(mEditSettings); +} + +void LLFloaterEditWater::onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* floatControl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + floatControl->setValue(sldr_ctrl->getValueF32()); + floatControl->update(mEditSettings); +} + +void LLFloaterEditWater::onExpFloatControlMoved(LLUICtrl* ctrl, WLXFloatControl* expFloatControl) +{ + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + expFloatControl->setExp(sldr_ctrl->getValueF32()); + expFloatControl->update(mEditSettings); +} + +void LLFloaterEditWater::onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl) +{ + LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl); + color_ctrl->setColor4( swatch->get() ); + color_ctrl->update(mEditSettings); +} + +void LLFloaterEditWater::onNormalMapPicked(LLUICtrl* ctrl) +{ + LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(ctrl); + LLUUID textID = textCtrl->getImageAssetID(); + mEditSettings->setNormalMapID(textID); +} + +//============================================================================= + +void LLFloaterEditWater::reset() +{ + if (isNewPreset()) + { + mWaterPresetNameEditor->setValue(LLSD()); + mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name + } + else + { + refreshWaterPresetsList(); + + // Disable controls until a water preset to edit is selected. + enableEditing(false); + } +} + +bool LLFloaterEditWater::isNewPreset() const +{ + return mKey.asString() == "new"; +} + +void LLFloaterEditWater::refreshWaterPresetsList() +{ + mWaterPresetCombo->removeall(); + + LLEnvironment::list_name_id_t list = LLEnvironment::instance().getWaterList(); + + for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it) + { + mWaterPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second)); + } + + mWaterPresetCombo->setLabel(getString("combo_label")); +} + +void LLFloaterEditWater::enableEditing(bool enable) +{ + // Enable/disable water controls. + getChild<LLPanel>("panel_water_preset")->setCtrlsEnabled(enable); + + // Enable/disable saving. + mSaveButton->setEnabled(enable); + mMakeDefaultCheckBox->setEnabled(enable); +} + +void LLFloaterEditWater::saveRegionWater() +{ +#if 0 + llassert(getCurrentScope() == LLEnvKey::SCOPE_REGION); // make sure we're editing region water + + LL_DEBUGS("Windlight") << "Saving region water preset" << LL_ENDL; + + //LLWaterParamSet region_water = water_mgr.mCurParams; + + // *TODO: save to cached region settings. + LL_WARNS("Windlight") << "Saving region water is not fully implemented yet" << LL_ENDL; +#endif +} + +#if 0 +std::string LLFloaterEditWater::getCurrentPresetName() const +{ + std::string name; + LLEnvKey::EScope scope; + getSelectedPreset(name, scope); + return name; +} +#endif + +#if 0 +LLEnvKey::EScope LLFloaterEditWater::getCurrentScope() const +{ + std::string name; + LLEnvKey::EScope scope; + getSelectedPreset(name, scope); + return scope; +} +#endif + +std::string LLFloaterEditWater::getSelectedPresetName() const +{ + std::string name; + if (mWaterPresetNameEditor->getVisible()) + { + name = mWaterPresetNameEditor->getText(); + } + else + { + LLSD combo_val = mWaterPresetCombo->getValue(); + name = combo_val[0].asString(); + } + + return name; +} + +void LLFloaterEditWater::onWaterPresetNameEdited() +{ + std::string name = mWaterPresetNameEditor->getText(); + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); + + pwater->setName(name); +#if 0 + // Disable saving a water preset having empty name. + mSaveButton->setEnabled(!getCurrentPresetName().empty()); +#endif +} + +void LLFloaterEditWater::onWaterPresetSelected() +{ + std::string name; + + name = getSelectedPresetName(); + + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().findWaterByName(name); + + if (!pwater) + { + LL_WARNS("WATEREDIT") << "Could not find water preset" << LL_ENDL; + enableEditing(false); + return; + } + + pwater = pwater->buildClone(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, pwater); + mEditSettings = pwater; + + syncControls(); + enableEditing(true); +} + +bool LLFloaterEditWater::onSaveAnswer(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + // If they choose save, do it. Otherwise, don't do anything + if (option == 0) + { + onSaveConfirmed(); + } + + return false; +} + +void LLFloaterEditWater::onSaveConfirmed() +{ + // Save currently displayed water params to the selected preset. + std::string name = mEditSettings->getName(); + + LL_DEBUGS("Windlight") << "Saving sky preset " << name << LL_ENDL; + + LLEnvironment::instance().addWater(mEditSettings); + + // Change preference if requested. + if (mMakeDefaultCheckBox->getEnabled() && mMakeDefaultCheckBox->getValue()) + { + LL_DEBUGS("Windlight") << name << " is now the new preferred water preset" << LL_ENDL; + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings); + } + + closeFloater(); +} + +void LLFloaterEditWater::onBtnSave() +{ + LLEnvironment::instance().addWater(mEditSettings); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings); + + closeFloater(); +} + +void LLFloaterEditWater::onBtnCancel() +{ + closeFloater(); +} + +void LLFloaterEditWater::onWaterPresetListChange() +{ + refreshWaterPresetsList(); +} + +void LLFloaterEditWater::onRegionSettingsChange() +{ +#if 0 + // If creating a new preset, don't bother. + if (isNewPreset()) + { + return; + } + + if (getCurrentScope() == LLEnvKey::SCOPE_REGION) // if editing region water + { + // reset the floater to its initial state + reset(); + + // *TODO: Notify user? + } + else // editing a local preset + { + refreshWaterPresetsList(); + } +#endif +} + +void LLFloaterEditWater::onRegionInfoUpdate() +{ +#if 0 + bool can_edit = true; + + // If we've selected the region water for editing. + if (getCurrentScope() == LLEnvKey::SCOPE_REGION) + { + // check whether we have the access + can_edit = LLEnvManagerNew::canEditRegionSettings(); + } + + enableEditing(can_edit); +#endif +} diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp new file mode 100644 index 0000000000..59cfab61fd --- /dev/null +++ b/indra/newview/lllegacyatmospherics.cpp @@ -0,0 +1,645 @@ +/** + * @file lllegacyatmospherics.cpp + * @brief LLAtmospherics class implementation + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lllegacyatmospherics.h" + +#include "llfeaturemanager.h" +#include "llviewercontrol.h" +#include "llframetimer.h" + +#include "llagent.h" +#include "llagentcamera.h" +#include "lldrawable.h" +#include "llface.h" +#include "llglheaders.h" +#include "llsky.h" +#include "llviewercamera.h" +#include "llviewertexturelist.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llworld.h" +#include "pipeline.h" +#include "v3colorutil.h" + +#include "llsettingssky.h" +#include "llenvironment.h" +#include "lldrawpoolwater.h" + +class LLFastLn +{ +public: + LLFastLn() + { + mTable[0] = 0; + for( S32 i = 1; i < 257; i++ ) + { + mTable[i] = log((F32)i); + } + } + + F32 ln( F32 x ) + { + const F32 OO_255 = 0.003921568627450980392156862745098f; + const F32 LN_255 = 5.5412635451584261462455391880218f; + + if( x < OO_255 ) + { + return log(x); + } + else + if( x < 1 ) + { + x *= 255.f; + S32 index = llfloor(x); + F32 t = x - index; + F32 low = mTable[index]; + F32 high = mTable[index + 1]; + return low + t * (high - low) - LN_255; + } + else + if( x <= 255 ) + { + S32 index = llfloor(x); + F32 t = x - index; + F32 low = mTable[index]; + F32 high = mTable[index + 1]; + return low + t * (high - low); + } + else + { + return log( x ); + } + } + + F32 pow( F32 x, F32 y ) + { + return (F32)LL_FAST_EXP(y * ln(x)); + } + + +private: + F32 mTable[257]; // index 0 is unused +}; + +static LLFastLn gFastLn; + + +// Functions used a lot. + +inline F32 LLHaze::calcPhase(const F32 cos_theta) const +{ + const F32 g2 = mG * mG; + const F32 den = 1 + g2 - 2 * mG * cos_theta; + return (1 - g2) * gFastLn.pow(den, -1.5); +} + +inline void color_pow(LLColor3 &col, const F32 e) +{ + col.mV[0] = gFastLn.pow(col.mV[0], e); + col.mV[1] = gFastLn.pow(col.mV[1], e); + col.mV[2] = gFastLn.pow(col.mV[2], e); +} + +inline LLColor3 color_norm(const LLColor3 &col) +{ + const F32 m = color_max(col); + if (m > 1.f) + { + return 1.f/m * col; + } + else return col; +} + +inline void color_gamma_correct(LLColor3 &col) +{ + const F32 gamma_inv = 1.f/1.2f; + if (col.mV[0] != 0.f) + { + col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv); + } + if (col.mV[1] != 0.f) + { + col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv); + } + if (col.mV[2] != 0.f) + { + col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv); + } +} + +static LLColor3 calc_air_sca_sea_level() +{ + static LLColor3 WAVE_LEN(675, 520, 445); + static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); + static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); + static LLColor3 n4 = n21 * n21; + static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; + static LLColor3 wl4 = wl2 * wl2; + static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; + static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); + return dens_div_N * mult_const.divide(wl4); +} + +// static constants. +LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); +F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel); +F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; + +/*************************************** + Atmospherics +***************************************/ + +LLAtmospherics::LLAtmospherics() +: mCloudDensity(0.2f), + mWind(0.f), + mWorldScale(1.f) +{ + /// WL PARAMS + mInitialized = FALSE; + mUpdateTimer.reset(); + mAmbientScale = gSavedSettings.getF32("SkyAmbientScale"); + mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift"); + mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f; + mFogColor.mV[VALPHA] = 0.0f; + mFogRatio = 1.2f; + mHazeConcentration = 0.f; + mInterpVal = 0.f; +} + + +LLAtmospherics::~LLAtmospherics() +{ +} + +void LLAtmospherics::init() +{ + const F32 haze_int = color_intens(mHaze.calcSigSca(0)); + mHazeConcentration = haze_int / (color_intens(mHaze.calcAirSca(0)) + haze_int); + mInitialized = true; +} + +LLColor4 LLAtmospherics::calcSkyColorInDir(const LLVector3 &dir, bool isShiny) +{ + F32 saturation = 0.3f; + if (dir.mV[VZ] < -0.02f) + { + LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f); + if (isShiny) + { + LLColor3 desat_fog = LLColor3(mFogColor); + F32 brightness = desat_fog.brightness(); + // So that shiny somewhat shows up at night. + if (brightness < 0.15f) + { + brightness = 0.15f; + desat_fog = smear(0.15f); + } + LLColor3 greyscale = smear(brightness); + desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation); + if (!gPipeline.canUseWindLightShaders()) + { + col = LLColor4(desat_fog, 0.f); + } + else + { + col = LLColor4(desat_fog * 0.5f, 0.f); + } + } + float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]); + x *= x; + col.mV[0] *= x*x; + col.mV[1] *= powf(x, 2.5f); + col.mV[2] *= x*x*x; + return col; + } + + // undo OGL_TO_CFR_ROTATION and negate vertical direction. + LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]); + + AtmosphericsVars vars; + calcSkyColorWLVert(Pn, vars); + + LLColor3 sky_color = calcSkyColorWLFrag(Pn, vars); + if (isShiny) + { + F32 brightness = sky_color.brightness(); + LLColor3 greyscale = smear(brightness); + sky_color = sky_color * saturation + greyscale * (1.0f - saturation); + sky_color *= (0.5f + 0.5f * brightness); + } + return LLColor4(sky_color, 0.0f); +} + +void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars) +{ +// LEGACY_ATMOSPHERICS + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + + LLColor3 blue_density = psky->getBlueDensity(); + LLColor3 blue_horizon = psky->getBlueHorizon(); + F32 haze_density = psky->getHazeDensity(); + F32 haze_horizon = psky->getHazeHorizon(); + F32 density_multiplier = psky->getDensityMultiplier(); + + F32 max_y = psky->getMaxY(); + LLVector3 lightnorm = LLVector3(LLEnvironment::instance().getClampedLightNorm()); + + // project the direction ray onto the sky dome. + F32 phi = acos(Pn[1]); + F32 sinA = sin(F_PI - phi); + if (fabsf(sinA) < 0.01f) + { //avoid division by zero + sinA = 0.01f; + } + + F32 Plen = psky->getDomeRadius() * sin(F_PI + phi + asin(psky->getDomeOffset() * sinA)) / sinA; + + Pn *= Plen; + + vars.horizontalProjection[0] = LLVector2(Pn[0], Pn[2]); + vars.horizontalProjection[0] /= - 2.f * Plen; + + // Set altitude + if (Pn[1] > 0.f) + { + Pn *= (max_y / Pn[1]); + } + else + { + Pn *= (-32000.f / Pn[1]); + } + + Plen = Pn.length(); + Pn /= Plen; + + // Initialize temp variables + LLColor3 sunlight = psky->getSunlightColor(); + LLColor3 ambient = psky->getAmbientColor(); + + LLColor3 glow = psky->getGlow(); + F32 cloud_shadow = psky->getCloudShadow(); + + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + LLColor3 light_atten = psky->getLightAttenuation(psky->getMaxY()); + + // Calculate relative weights + LLColor3 temp2(0.f, 0.f, 0.f); + LLColor3 temp1 = psky->getLightTransmittance(); + + LLColor3 blue_weight = componentDiv(blue_density, temp1); + LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); + + temp2.mV[1] = 1.f / temp2.mV[1]; + componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + + // Distance + temp2.mV[2] = Plen * density_multiplier; + + // Transparency (-> temp1) + temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); + + + // Compute haze glow + temp2.mV[0] = Pn * lightnorm; + + temp2.mV[0] = 1.f - temp2.mV[0]; + // temp2.x is 0 at the sun and increases away from sun + temp2.mV[0] = llmax(temp2.mV[0], .001f); + // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.mV[0] *= glow.mV[0]; + // Higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]); + // glow.z should be negative, so we're doing a sort of (1 / "angle") function + + // Add "minimum anti-solar illumination" + temp2.mV[0] += .25f; + + + // Haze color above cloud + vars.hazeColor = (blue_horizon * blue_weight * (sunlight + ambient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient)); + + // Increase ambient when there are more clouds + LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; + + // Dim sunlight by cloud shadow percentage + sunlight *= (1.f - cloud_shadow); + + // Haze color below cloud + vars.hazeColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)); + + // Final atmosphere additive + componentMultBy(vars.hazeColor, LLColor3::white - temp1); + + sunlight = psky->getSunlightColor(); + temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f); + temp2.mV[1] = 1.f / temp2.mV[1]; + componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + + // Attenuate cloud color by atmosphere + temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds + + // At horizon, blend high altitude sky color towards the darker color below the clouds + vars.hazeColor += componentMult(vars.hazeColorBelowCloud - vars.hazeColor, LLColor3::white - componentSqrt(temp1)); + + if (Pn[1] < 0.f) + { + // Eric's original: + // LLColor3 dark_brown(0.143f, 0.129f, 0.114f); + LLColor3 dark_brown(0.082f, 0.076f, 0.066f); + LLColor3 brown(0.430f, 0.386f, 0.322f); + LLColor3 sky_lighting = sunlight + ambient; + F32 haze_brightness = vars.hazeColor.brightness(); + + if (Pn[1] < -0.05f) + { + vars.hazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness; + } + + if (Pn[1] > -0.1f) + { + vars.hazeColor = colorMix(LLColor3::white * haze_brightness, vars.hazeColor, fabs((Pn[1] + 0.05f) * -20.f)); + } + } +} + +LLColor3 LLAtmospherics::calcSkyColorWLFrag(LLVector3 & Pn, AtmosphericsVars& vars) +{ + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + + + LLColor3 res; + LLColor3 color0 = vars.hazeColor; + + if (!gPipeline.canUseWindLightShaders()) + { + res = psky->gammaCorrect(color0 * 2.0f); + } + else + { + res = color0; + } + +#ifndef LL_RELEASE_FOR_DOWNLOAD + F32 gamma = psky->getGamma(); + LLColor3 color2 = 2.f * color0; + LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2); + componentPow(color3, gamma); + color3 = LLColor3(1.f, 1.f, 1.f) - color3; + + static enum { + OUT_DEFAULT = 0, + OUT_SKY_BLUE = 1, + OUT_RED = 2, + OUT_PN = 3, + OUT_HAZE = 4, + } debugOut = OUT_DEFAULT; + + switch(debugOut) + { + case OUT_DEFAULT: + break; + case OUT_SKY_BLUE: + res = LLColor3(0.4f, 0.4f, 0.9f); + break; + case OUT_RED: + res = LLColor3(1.f, 0.f, 0.f); + break; + case OUT_PN: + res = LLColor3(Pn[0], Pn[1], Pn[2]); + break; + case OUT_HAZE: + res = vars.hazeColor; + break; + } +#endif // LL_RELEASE_FOR_DOWNLOAD + return res; +} + +void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) +{ + LLVector3 tosun = tosun_in; + + if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) + { + if (!LLGLSLShader::sNoFixedFunction) + { + glFogf(GL_FOG_DENSITY, 0); + glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); + glFogf(GL_FOG_END, 1000000.f); + } + return; + } + + const BOOL hide_clip_plane = TRUE; + LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); + + const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; + // LLWorld::getInstance()->getWaterHeight(); + F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2]; + + F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear(); + camera_height += near_clip_height; + + F32 fog_distance = 0.f; + LLColor3 res_color[3]; + + LLColor3 sky_fog_color = LLColor3::white; + LLColor3 render_fog_color = LLColor3::white; + + const F32 tosun_z = tosun.mV[VZ]; + tosun.mV[VZ] = 0.f; + tosun.normalize(); + LLVector3 perp_tosun; + perp_tosun.mV[VX] = -tosun.mV[VY]; + perp_tosun.mV[VY] = tosun.mV[VX]; + LLVector3 tosun_45 = tosun + perp_tosun; + tosun_45.normalize(); + + F32 delta = 0.06f; + tosun.mV[VZ] = delta; + perp_tosun.mV[VZ] = delta; + tosun_45.mV[VZ] = delta; + tosun.normalize(); + perp_tosun.normalize(); + tosun_45.normalize(); + + // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. + res_color[0] = calcSkyColorInDir(tosun); + res_color[1] = calcSkyColorInDir(perp_tosun); + res_color[2] = calcSkyColorInDir(tosun_45); + + sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); + + F32 full_off = -0.25f; + F32 full_on = 0.00f; + F32 on = (tosun_z - full_off) / (full_on - full_off); + on = llclamp(on, 0.01f, 1.f); + sky_fog_color *= 0.5f * on; + + + // We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ??? + S32 i; + for (i = 0; i < 3; i++) + { + sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]); + } + + color_gamma_correct(sky_fog_color); + + render_fog_color = sky_fog_color; + + F32 fog_density = 0.f; + fog_distance = mFogRatio * distance; + + if (camera_height > water_height) + { + LLColor4 fog(render_fog_color); + if (!LLGLSLShader::sNoFixedFunction) + { + glFogfv(GL_FOG_COLOR, fog.mV); + } + mGLFogCol = fog; + + if (hide_clip_plane) + { + // For now, set the density to extend to the cull distance. + const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) + fog_density = f_log/fog_distance; + if (!LLGLSLShader::sNoFixedFunction) + { + glFogi(GL_FOG_MODE, GL_EXP2); + } + } + else + { + const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) + fog_density = (f_log)/fog_distance; + if (!LLGLSLShader::sNoFixedFunction) + { + glFogi(GL_FOG_MODE, GL_EXP); + } + } + } + else + { + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); + F32 depth = water_height - camera_height; + + // get the water param manager variables + float water_fog_density = pwater->getWaterFogDensity(); + 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), + gSavedSettings.getF32("WaterGLFogDepthFloor")); + + LLColor4 fogCol = water_fog_color * depth_modifier; + fogCol.setAlpha(1); + + // set the gl fog color + mGLFogCol = fogCol; + + // set the density based on what the shaders use + fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); + + if (!LLGLSLShader::sNoFixedFunction) + { + glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); + glFogi(GL_FOG_MODE, GL_EXP2); + } + } + + mFogColor = sky_fog_color; + mFogColor.setAlpha(1); + + LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f; + + if (!LLGLSLShader::sNoFixedFunction) + { + LLGLSFog gls_fog; + glFogf(GL_FOG_END, fog_distance*2.2f); + glFogf(GL_FOG_DENSITY, fog_density); + glHint(GL_FOG_HINT, GL_NICEST); + } + stop_glerror(); +} + +// Functions used a lot. +F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply) +{ + F32 mv = color_max(col); + if (0 == mv) + { + return 0; + } + + col *= 1.f / mv; + color_pow(col, e); + if (postmultiply) + { + col *= mv; + } + return mv; +} + +// Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis. +// Range of output is 0.0f to 2pi //359.99999...f +// Returns 0.0f when "v" = +/- z_axis. +F32 azimuth(const LLVector3 &v) +{ + F32 azimuth = 0.0f; + if (v.mV[VX] == 0.0f) + { + if (v.mV[VY] > 0.0f) + { + azimuth = F_PI * 0.5f; + } + else if (v.mV[VY] < 0.0f) + { + azimuth = F_PI * 1.5f;// 270.f; + } + } + else + { + azimuth = (F32) atan(v.mV[VY] / v.mV[VX]); + if (v.mV[VX] < 0.0f) + { + azimuth += F_PI; + } + else if (v.mV[VY] < 0.0f) + { + azimuth += F_PI * 2; + } + } + return azimuth; +} diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h new file mode 100644 index 0000000000..ded7e1f554 --- /dev/null +++ b/indra/newview/lllegacyatmospherics.h @@ -0,0 +1,250 @@ +/** + * @file lllegacyatmospherics.h + * @brief LLVOSky class header file + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLLEGACYATMOSPHERICS_H +#define LL_LLLEGACYATMOSPHERICS_H + +#include "stdtypes.h" +#include "v3color.h" +#include "v4coloru.h" +#include "llviewertexture.h" +#include "llviewerobject.h" +#include "llframetimer.h" +#include "v3colorutil.h" +#include "llsettingssky.h" + +////////////////////////////////// +// +// Lots of constants +// +// Will clean these up at some point... +// + +const F32 HORIZON_DIST = 1024.0f; +const F32 ATM_EXP_FALLOFF = 0.000126f; +const F32 ATM_SEA_LEVEL_NDENS = 2.55e25f; +const F32 ATM_HEIGHT = 100000.f; + +// constants used in calculation of scattering coeff of clear air +const F32 sigma = 0.035f; +const F32 fsigma = (6.f + 3.f * sigma) / (6.f-7.f*sigma); +const F64 Ndens = 2.55e25; +const F64 Ndens2 = Ndens*Ndens; + +class LLFace; +class LLHaze; + +LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length) +{ + LLColor3 refr_ind; + for (S32 i = 0; i < 3; ++i) + { + const F32 wl2 = wave_length.mV[i] * wave_length.mV[i] * 1e-6f; + refr_ind.mV[i] = 6.43e3f + ( 2.95e6f / ( 146.0f - 1.f/wl2 ) ) + ( 2.55e4f / ( 41.0f - 1.f/wl2 ) ); + refr_ind.mV[i] *= 1.0e-8f; + refr_ind.mV[i] += 1.f; + } + return refr_ind; +} + + +class LLHaze +{ +public: + LLHaze() : mG(0), mFalloff(1), mAbsCoef(0.f) {mSigSca.setToBlack();} + LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) : + mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f) + { + mAbsCoef = color_intens(mSigSca) / sAirScaIntense; + } + + LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g), + mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo) + { + mAbsCoef = 0.01f * sca / sAirScaAvg; + } + +/* Proportion of light that is scattered into 'path' from 'in' over distance dt. */ +/* assumes that vectors 'path' and 'in' are normalized. Scattering coef / 2pi */ + + LL_FORCE_INLINE LLColor3 calcAirSca(const F32 h) + { + return calcFalloff(h) * sAirScaSeaLevel; + } + + LL_FORCE_INLINE void calcAirSca(const F32 h, LLColor3 &result) + { + result = sAirScaSeaLevel; + result *= calcFalloff(h); + } + + F32 getG() const { return mG; } + + void setG(const F32 g) + { + mG = g; + } + + const LLColor3& getSigSca() const // sea level + { + return mSigSca; + } + + void setSigSca(const LLColor3& s) + { + mSigSca = s; + mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense; + } + + void setSigSca(const F32 s0, const F32 s1, const F32 s2) + { + mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2); + mAbsCoef = 0.01f * (s0 + s1 + s2) / 3; + } + + F32 getFalloff() const + { + return mFalloff; + } + + void setFalloff(const F32 fo) + { + mFalloff = fo; + } + + F32 getAbsCoef() const + { + return mAbsCoef; + } + + inline static F32 calcFalloff(const F32 h) + { + return (h <= 0) ? 1.0f : (F32)LL_FAST_EXP(-ATM_EXP_FALLOFF * h); + } + + inline LLColor3 calcSigSca(const F32 h) const + { + return calcFalloff(h * mFalloff) * mSigSca; + } + + inline void calcSigSca(const F32 h, LLColor3 &result) const + { + result = mSigSca; + result *= calcFalloff(h * mFalloff); + } + + LLColor3 calcSigExt(const F32 h) const + { + return calcFalloff(h * mFalloff) * (1 + mAbsCoef) * mSigSca; + } + + F32 calcPhase(const F32 cos_theta) const; + +private: + static LLColor3 const sAirScaSeaLevel; + static F32 const sAirScaIntense; + static F32 const sAirScaAvg; + +protected: + F32 mG; + LLColor3 mSigSca; + F32 mFalloff; // 1 - slow, >1 - faster + F32 mAbsCoef; +}; + + +class LLCubeMap; + +class AtmosphericsVars +{ +public: + AtmosphericsVars() + : hazeColor(0,0,0) + , hazeColorBelowCloud(0,0,0) + , cloudColorSun(0,0,0) + , cloudColorAmbient(0,0,0) + , cloudDensity(0.0f) + { + horizontalProjection[0] = LLVector2(0,0); + horizontalProjection[1] = LLVector2(0,0); + } + + LLColor3 hazeColor; + LLColor3 hazeColorBelowCloud; + LLColor3 cloudColorSun; + LLColor3 cloudColorAmbient; + F32 cloudDensity; + LLVector2 horizontalProjection[2]; +}; + +class LLAtmospherics +{ +public: + LLAtmospherics(); + ~LLAtmospherics(); + + void init(); + void updateFog(const F32 distance, const LLVector3& tosun); + + const LLHaze& getHaze() const { return mHaze; } + LLHaze& getHaze() { return mHaze; } + F32 getHazeConcentration() const { return mHazeConcentration; } + void setHaze(const LLHaze& h) { mHaze = h; } + void setFogRatio(const F32 fog_ratio) { mFogRatio = fog_ratio; } + + F32 getFogRatio() const { return mFogRatio; } + LLColor4 getFogColor() const { return mFogColor; } + LLColor4 getGLFogColor() const { return mGLFogCol; } + + void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; } + void setWind ( const LLVector3& wind ) { mWind = wind.length(); } + + LLColor4 calcSkyColorInDir(const LLVector3& dir, bool isShiny = false); + +protected: + + void calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars); + LLColor3 calcSkyColorWLFrag(LLVector3 & Pn, AtmosphericsVars& vars); + LLColor3 getHazeColor(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, F32 costheta, F32 cloud_shadow); + + LLHaze mHaze; + F32 mHazeConcentration; + F32 mCloudDensity; + F32 mWind; + BOOL mInitialized; + LLVector3 mLastLightingDirection; + LLColor3 mLastTotalAmbient; + F32 mAmbientScale; + LLColor3 mNightColorShift; + F32 mInterpVal; + LLColor4 mFogColor; + LLColor4 mGLFogCol; + F32 mFogRatio; + F32 mWorldScale; + LLFrameTimer mUpdateTimer; +}; + +#endif diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp index 5904b5a542..940b171dfe 100644 --- a/indra/newview/llpaneleditwater.cpp +++ b/indra/newview/llpaneleditwater.cpp @@ -123,8 +123,8 @@ void LLPanelSettingsWaterMainTab::refresh() setEnabled(TRUE); setAllChildrenEnabled(TRUE); - mClrFogColor->set(mWaterSettings->getFogColor()); - getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setValue(mWaterSettings->getFogDensity()); + mClrFogColor->set(mWaterSettings->getWaterFogColor()); + getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setValue(mWaterSettings->getWaterFogDensity()); getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setValue(mWaterSettings->getFogMod()); mTxtNormalMap->setValue(mWaterSettings->getNormalMapID()); LLVector2 vect2 = mWaterSettings->getWave1Dir(); @@ -148,12 +148,12 @@ void LLPanelSettingsWaterMainTab::refresh() void LLPanelSettingsWaterMainTab::onFogColorChanged() { - mWaterSettings->setFogColor(LLColor3(mClrFogColor->get())); + mWaterSettings->setWaterFogColor(LLColor3(mClrFogColor->get())); } void LLPanelSettingsWaterMainTab::onFogDensityChanged() { - mWaterSettings->setFogDensity(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal()); + mWaterSettings->setWaterFogDensity(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal()); } void LLPanelSettingsWaterMainTab::onFogUnderWaterChanged() diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 5f413fc3c0..3d3dccee0b 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -64,8 +64,8 @@ #include "llvector4a.h" // Functions pulled from pipeline.cpp -glh::matrix4f glh_get_current_modelview(); -glh::matrix4f glh_get_current_projection(); +glh::matrix4f get_current_modelview(); +glh::matrix4f get_current_projection(); // Functions pulled from llviewerdisplay.cpp bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model); @@ -642,7 +642,7 @@ void LLPanelPrimMediaControls::updateShape() glh::matrix4f mat; if (!is_hud) { - mat = glh_get_current_projection() * glh_get_current_modelview(); + mat = get_current_projection() * get_current_modelview(); } else { glh::matrix4f proj, modelview; diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 1ac607cd1f..d5bcbd1894 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -58,6 +58,8 @@ #include "llassetstorage.h" #include "llvfile.h" +#pragma optimize("", off) + #undef VERIFY_LEGACY_CONVERSION //========================================================================= @@ -427,23 +429,19 @@ LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings) { -// LEGACY_ATMOSPHERICS // These will need to be inferred from new settings' density profiles - legacy[SETTING_AMBIENT] = ensureArray4(settings[SETTING_AMBIENT], 1.0f); - legacy[SETTING_BLUE_DENSITY] = ensureArray4(settings[SETTING_BLUE_DENSITY], 1.0); - legacy[SETTING_BLUE_HORIZON] = ensureArray4(settings[SETTING_BLUE_HORIZON], 1.0); - legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(settings[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); - legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(settings[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); - legacy[SETTING_HAZE_DENSITY] = LLSDArray(settings[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f); - legacy[SETTING_HAZE_HORIZON] = LLSDArray(settings[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f); - - //legacy[SETTING_AMBIENT] = LLColor4::black.getValue(); - //legacy[SETTING_BLUE_DENSITY] = LLColor4(0.2447, 0.4487, 0.7599, 0.0).getValue(); - //legacy[SETTING_BLUE_HORIZON] = LLColor4(0.4954, 0.4954, 0.6399, 0.0).getValue(); - //legacy[SETTING_HAZE_DENSITY] = LLSDArray(0.6999f)(0.0f)(0.0f)(1.0f); - //legacy[SETTING_HAZE_HORIZON] = LLSDArray(0.1899f)(0.0f)(0.0f)(1.0f); - //legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(0.0001f)(0.0f)(0.0f)(1.0f);LLSD::Real(0.0001); - //legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(0.8f)(0.0f)(0.0f)(1.0f); + if (settings.has(SETTING_LEGACY_HAZE)) + { + LLSD legacyhaze = settings[SETTING_LEGACY_HAZE]; + + legacy[SETTING_AMBIENT] = ensureArray4(legacyhaze[SETTING_AMBIENT], 1.0f); + legacy[SETTING_BLUE_DENSITY] = ensureArray4(legacyhaze[SETTING_BLUE_DENSITY], 1.0); + legacy[SETTING_BLUE_HORIZON] = ensureArray4(legacyhaze[SETTING_BLUE_HORIZON], 1.0); + legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); + legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); + legacy[SETTING_HAZE_DENSITY] = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f); + legacy[SETTING_HAZE_HORIZON] = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f); + } } LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isAdvanced) @@ -468,11 +466,18 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS]; legacy[SETTING_SUNLIGHT_COLOR] = ensureArray4(settings[SETTING_SUNLIGHT_COLOR], 1.0f); - LLSettingsSky::azimalt_t azialt = psky->getSunRotationAzAl(); + LLQuaternion sunquat = psky->getSunRotation(); + + F32 roll; + F32 pitch; + F32 yaw; - legacy[SETTING_LEGACY_EAST_ANGLE] = azialt.first; - legacy[SETTING_LEGACY_SUN_ANGLE] = azialt.second; + // get euler angles in right-handed X right, Y up, Z at + sunquat.getEulerAngles(&roll, &pitch, &yaw); + legacy[SETTING_LEGACY_EAST_ANGLE] = yaw; + legacy[SETTING_LEGACY_SUN_ANGLE] = -pitch; + return legacy; } @@ -480,30 +485,51 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA void LLSettingsVOSky::updateSettings() { LLSettingsSky::updateSettings(); - - LLVector3 sun_direction = getSunDirection(); + LLVector3 sun_direction = getSunDirection(); LLVector3 moon_direction = getMoonDirection(); - // set direction (in CRF) and don't allow overriding - LLVector3 crf_sunDirection(sun_direction.mV[2], sun_direction.mV[0], sun_direction.mV[1]); - LLVector3 crf_moonDirection(moon_direction.mV[2], moon_direction.mV[0], moon_direction.mV[1]); - - gSky.setSunDirection(crf_sunDirection, crf_moonDirection); + F32 dp = getLightDirection() * LLVector3(0.0f, 0.0f, 1.0f); + if (dp < 0) + { + dp = 0; + } + dp = llmax(dp, 0.1f); + + // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio + // between sunlight and point lights in windlight to normalize point lights. + F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); + mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); + + // Axis swaps convert from +x right, +z up, +y at + // to CFR +x at, +z up, +y right coord sys + LLVector3 sun_direction_cfr(sun_direction.mV[0], -sun_direction.mV[1], sun_direction.mV[2]); + LLVector3 moon_direction_cfr(moon_direction.mV[0], -moon_direction.mV[1], moon_direction.mV[2]); + gSky.setSunAndMoonDirectionsCFR(sun_direction_cfr, moon_direction_cfr); } void LLSettingsVOSky::applySpecial(void *ptarget) { LLGLSLShader *shader = (LLGLSLShader *)ptarget; - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, getClampedLightDirection().mV); + LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); - shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0); + if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) + { + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); + } + else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) + { + LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV); - { LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta()); shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); - } + } + + shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength); + shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0); } LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const @@ -656,12 +682,16 @@ void LLSettingsVOWater::applySpecial(void *ptarget) { LLGLSLShader *shader = (LLGLSLShader *)ptarget; - shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, getWaterPlane().mV); - shader->uniform1f(LLShaderMgr::WATER_FOGKS, getWaterFogKS()); + if (shader->mShaderGroup == LLGLSLShader::SG_WATER) + { + shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, getWaterPlane().mV); + shader->uniform1f(LLShaderMgr::WATER_FOGKS, getWaterFogKS()); - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLEnvironment::instance().getRotatedLight().mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); - shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); + LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm(); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); + } } void LLSettingsVOWater::updateSettings() @@ -695,7 +725,7 @@ void LLSettingsVOWater::updateSettings() mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); - LLVector4 light_direction = LLEnvironment::instance().getLightDirection(); + LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); mWaterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); } @@ -812,9 +842,9 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®io for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm) { - LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second); std::string newname = "sky:" + (*itm).first; - + LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second); + newsettings[SETTING_NAME] = newname; frames[newname] = newsettings; diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index 3339aaf037..2f91117858 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -107,6 +107,7 @@ protected: virtual parammapping_t getParameterMap() const override; bool m_isAdvanced = false; + F32 mSceneLightStrength = 3.0f; }; //========================================================================= diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index fb3123fd81..41fe206ada 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -51,18 +51,16 @@ #include "llvosky.h" #include "llcubemap.h" #include "llviewercontrol.h" +#include "llenvironment.h" #include "llvowlsky.h" F32 azimuth_from_vector(const LLVector3 &v); F32 elevation_from_vector(const LLVector3 &v); -LLSky gSky; -// ---------------- LLSky ---------------- - -const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees -const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); +LLSky gSky; +// ---------------- LLSky ---------------- ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -76,7 +74,6 @@ LLSky::LLSky() mLightingGeneration = 0; mUpdatedThisFrame = TRUE; - mSunPhase = 0.f; } @@ -132,191 +129,31 @@ void LLSky::resetVertexBuffers() } } -void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &moon_direction) -{ - if(mVOSkyp.notNull()) { - mVOSkyp->setSunDirection(sun_direction, moon_direction); - } -} - -LLVector3 LLSky::getSunDirection() const -{ - if (mVOSkyp) - { - return mVOSkyp->getToSun(); - } - else - { - return LLVector3::z_axis; - } -} - - -LLVector3 LLSky::getMoonDirection() const -{ - if (mVOSkyp) - { - return mVOSkyp->getToMoon(); - } - else - { - return LLVector3::z_axis; - } -} - - -LLColor4 LLSky::getSunDiffuseColor() const -{ - if (mVOSkyp) - { - return LLColor4(mVOSkyp->getSunDiffuseColor()); - } - else - { - return LLColor4(1.f, 1.f, 1.f, 1.f); - } -} - -LLColor4 LLSky::getSunAmbientColor() const -{ - if (mVOSkyp) - { - return LLColor4(mVOSkyp->getSunAmbientColor()); - } - else - { - return LLColor4(0.f, 0.f, 0.f, 1.f); - } -} - - -LLColor4 LLSky::getMoonDiffuseColor() const +void LLSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_direction, const LLVector3 &moon_direction) { - if (mVOSkyp) - { - return LLColor4(mVOSkyp->getMoonDiffuseColor()); - } - else - { - return LLColor4(1.f, 1.f, 1.f, 1.f); - } -} - -LLColor4 LLSky::getMoonAmbientColor() const -{ - if (mVOSkyp) - { - return LLColor4(mVOSkyp->getMoonAmbientColor()); - } - else - { - return LLColor4(0.f, 0.f, 0.f, 0.f); + if(mVOSkyp.notNull()) { + mVOSkyp->setSunAndMoonDirectionsCFR(sun_direction, moon_direction); } } - -LLColor4 LLSky::getTotalAmbientColor() const -{ - if (mVOSkyp) - { - return mVOSkyp->getTotalAmbientColor(); - } - else - { - return LLColor4(1.f, 1.f, 1.f, 1.f); - } -} - - -BOOL LLSky::sunUp() const -{ - if (mVOSkyp) - { - return mVOSkyp->isSunUp(); - } - else - { - return TRUE; - } -} - - -LLColor4U LLSky::getFadeColor() const -{ - if (mVOSkyp) - { - return mVOSkyp->getFadeColor(); - } - else - { - return LLColor4(1.f, 1.f, 1.f, 1.f); - } -} - - ////////////////////////////////////////////////////////////////////// // Public Methods ////////////////////////////////////////////////////////////////////// -void LLSky::init(const LLVector3 &sun_direction) +void LLSky::init() { - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - mVOWLSkyp = static_cast<LLVOWLSky*>(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, NULL)); - mVOWLSkyp->initSunDirection(sun_direction, LLVector3::zero); + mVOWLSkyp->init(); gPipeline.createObject(mVOWLSkyp.get()); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, NULL); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - - mVOSkyp->initSunDirection(sun_direction, LLVector3()); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - - gPipeline.createObject((LLViewerObject *)mVOSkyp); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); + mVOSkyp->init(); + gPipeline.createObject(mVOSkyp.get()); mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, NULL); - LLVOGround *groundp = mVOGroundp; - gPipeline.createObject((LLViewerObject *)groundp); + gPipeline.createObject(mVOGroundp.get()); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - - gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio")); - - //////////////////////////// - // - // Legacy code, ignore - // - // - - // Get the parameters. - mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition"); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - - if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) - { - setSunDirection(mSunDefaultPosition, -mSunDefaultPosition); - } - else - { - setSunDirection(sun_direction, -sun_direction); - } - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); + gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio")); mUpdatedThisFrame = TRUE; } @@ -339,49 +176,16 @@ void LLSky::setWind(const LLVector3& average_wind) } } - -void LLSky::propagateHeavenlyBodies(F32 dt) -{ -// if (!mOverrideSimSunPosition) -// { -// LLVector3 curr_dir = getSunDirection(); -// LLVector3 diff = mSunTargDir - curr_dir; -// const F32 dist = diff.normVec(); -// if (dist > 0) -// { -// const F32 step = llmin (dist, 0.00005f); -// //const F32 step = min (dist, 0.0001); -// diff *= step; -// curr_dir += diff; -// curr_dir.normVec(); -// if (mVOSkyp) -// { -// mVOSkyp->setSunDirection(curr_dir); -// } -// } -// } -} - -F32 LLSky::getSunPhase() const -{ - return mSunPhase; -} - -void LLSky::setSunPhase(const F32 phase) -{ - mSunPhase = phase; -} - ////////////////////////////////////////////////////////////////////// // Private Methods ////////////////////////////////////////////////////////////////////// -LLColor4 LLSky::getFogColor() const +LLColor4 LLSky::getSkyFogColor() const { if (mVOSkyp) { - return mVOSkyp->getFogColor(); + return mVOSkyp->getSkyFogColor(); } return LLColor4(1.f, 1.f, 1.f, 1.f); diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index 79549948f6..8e86853481 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -48,13 +48,13 @@ public: LLSky(); ~LLSky(); - void init(const LLVector3 &sun_direction); - + void init(); void cleanup(); - void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &moon_direction); + // These directions should be in CFR coord sys (+x at, +z up, +y right) + void setSunAndMoonDirectionsCFR(const LLVector3 &sun_direction, const LLVector3 &moon_direction); - LLColor4 getFogColor() const; + LLColor4 getSkyFogColor() const; void setCloudDensityAtAgent(F32 cloud_density); void setWind(const LLVector3& wind); @@ -63,8 +63,6 @@ public: void updateCull(); void updateSky(); - void propagateHeavenlyBodies(F32 dt); // dt = seconds - S32 mLightingGeneration; BOOL mUpdatedThisFrame; @@ -72,18 +70,6 @@ public: F32 getFogRatio() const; LLColor4U getFadeColor() const; - LLVector3 getSunDirection() const; - LLVector3 getMoonDirection() const; - LLColor4 getSunDiffuseColor() const; - LLColor4 getMoonDiffuseColor() const; - LLColor4 getSunAmbientColor() const; - LLColor4 getMoonAmbientColor() const; - LLColor4 getTotalAmbientColor() const; - BOOL sunUp() const; - - F32 getSunPhase() const; - void setSunPhase(const F32 phase); - void destroyGL(); void restoreGL(); void resetVertexBuffers(); @@ -91,20 +77,11 @@ public: public: LLPointer<LLVOSky> mVOSkyp; // Pointer to the LLVOSky object (only one, ever!) LLPointer<LLVOGround> mVOGroundp; - LLPointer<LLVOWLSky> mVOWLSkyp; - // Legacy stuff - LLVector3 mSunDefaultPosition; - - static const F32 NIGHTTIME_ELEVATION; // degrees - static const F32 NIGHTTIME_ELEVATION_COS; - protected: - F32 mSunPhase; - LLColor4 mFogColor; // Color to use for fog and haze - + LLColor4 mFogColor; }; -extern LLSky gSky; +extern LLSky gSky; #endif diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index deebd91198..e7a149ac0c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -332,7 +332,6 @@ bool idle_startup() static std::string auth_desc; static std::string auth_message; - static LLVector3 initial_sun_direction(1.f, 0.f, 0.f); static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server // last location by default @@ -1467,7 +1466,7 @@ bool idle_startup() LLGLState::checkTextureChannels(); LLEnvironment::instance().loadPreferences(); - gSky.init(initial_sun_direction); + gSky.init(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 6903e69d46..fb96804bfa 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -108,7 +108,7 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) if (gSavedSettings.getBOOL("MouseSun")) { LLVector3 sunpos = LLViewerCamera::getInstance()->getAtAxis(); - gSky.setSunDirection(sunpos, -sunpos); + gSky.setSunAndMoonDirectionsCFR(sunpos, -sunpos); gSavedSettings.setVector3("SkySunDefaultPosition", LLViewerCamera::getInstance()->getAtAxis()); } diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index 2ec5c41b88..728d0c9417 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -570,8 +570,8 @@ void LLTracker::renderBeacon(LLVector3d pos_global, color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstance()->getFar()); } - LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getFogColor(); - LLColor4 fogged_color_under = color_frac * color_under + (1 - color_frac) * gSky.getFogColor(); + LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getSkyFogColor(); + LLColor4 fogged_color_under = color_frac * color_under + (1 - color_frac) * gSky.getSkyFogColor(); F32 FADE_DIST = 3.f; fogged_color.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST)); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 778e275727..27a87ee1a0 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -81,31 +81,6 @@ glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height return glh::matrix4f(m); } -glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) -{ - GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); - - return glh::matrix4f(f/aspect, 0, 0, 0, - 0, f, 0, 0, - 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), - 0, 0, -1.f, 0); -} - -glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up) -{ - LLVector3 f = center-eye; - f.normVec(); - up.normVec(); - LLVector3 s = f % up; - LLVector3 u = s % f; - - return glh::matrix4f(s[0], s[1], s[2], 0, - u[0], u[1], u[2], 0, - -f[0], -f[1], -f[2], 0, - 0, 0, 0, 1); - -} - // Build time optimization, generate this once in .cpp file template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance(); diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 5901de289f..fb07a3fb2d 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -35,14 +35,6 @@ #include "lltrace.h" class LLViewerObject; - -// This rotation matrix moves the default OpenGL reference frame -// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up) -const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X - -1.f, 0.f, 0.f, 0.f, // -X becomes Y - 0.f, 1.f, 0.f, 0.f, // Y becomes Z - 0.f, 0.f, 0.f, 1.f }; - const BOOL FOR_SELECTION = TRUE; const BOOL NOT_FOR_SELECTION = FALSE; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 2893a94dbf..82120db53e 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -729,8 +729,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); - glh::matrix4f proj = glh_get_current_projection(); - glh::matrix4f mod = glh_get_current_modelview(); + glh::matrix4f proj = get_current_projection(); + glh::matrix4f mod = get_current_modelview(); glViewport(0,0,512,512); LLVOAvatar::updateFreezeCounter() ; @@ -739,8 +739,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLVOAvatar::updateImpostors(); } - glh_set_current_projection(proj); - glh_set_current_modelview(mod); + set_current_projection(proj); + set_current_modelview(mod); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.loadMatrix(proj.m); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -920,7 +920,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.mScreen.bindTarget(); if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) { - const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getFogColor(); + const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); } gPipeline.mScreen.clear(); @@ -1078,8 +1078,8 @@ void render_hud_attachments() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - glh::matrix4f current_proj = glh_get_current_projection(); - glh::matrix4f current_mod = glh_get_current_modelview(); + glh::matrix4f current_proj = get_current_projection(); + glh::matrix4f current_mod = get_current_modelview(); // clamp target zoom level to reasonable values gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f); @@ -1171,8 +1171,8 @@ void render_hud_attachments() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); - glh_set_current_projection(current_proj); - glh_set_current_modelview(current_mod); + set_current_projection(current_proj); + set_current_modelview(current_mod); } LLRect get_whole_screen_region() @@ -1254,11 +1254,11 @@ bool setup_hud_matrices(const LLRect& screen_region) // set up transform to keep HUD objects in front of camera gGL.matrixMode(LLRender::MM_PROJECTION); gGL.loadMatrix(proj.m); - glh_set_current_projection(proj); + set_current_projection(proj); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.loadMatrix(model.m); - glh_set_current_modelview(model); + set_current_modelview(model); return TRUE; } @@ -1266,13 +1266,13 @@ void render_ui(F32 zoom_factor, int subfield) { LLGLState::checkStates(); - glh::matrix4f saved_view = glh_get_current_modelview(); + glh::matrix4f saved_view = get_current_modelview(); if (!gSnapshot) { gGL.pushMatrix(); gGL.loadMatrix(gGLLastModelView); - glh_set_current_modelview(glh_copy_matrix(gGLLastModelView)); + set_current_modelview(copy_matrix(gGLLastModelView)); } if(LLSceneMonitor::getInstance()->needsUpdate()) @@ -1335,7 +1335,7 @@ void render_ui(F32 zoom_factor, int subfield) if (!gSnapshot) { - glh_set_current_modelview(saved_view); + set_current_modelview(saved_view); gGL.popMatrix(); } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e4c71c1648..e88afdc465 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3395,6 +3395,7 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) void process_time_synch(LLMessageSystem *mesgsys, void **user_data) { LLVector3 sun_direction; + LLVector3 moon_direction; LLVector3 sun_ang_velocity; F32 phase; U64 space_time_usec; @@ -3416,11 +3417,11 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data) LL_DEBUGS("Windlight Sync") << "Sun phase: " << phase << " rad = " << fmodf(phase / F_TWO_PI + 0.25, 1.f) * 24.f << " h" << LL_ENDL; - gSky.setSunPhase(phase); - if ( !gSavedSettings.getBOOL("SkyOverrideSimSunPosition") ) - { - gSky.setSunDirection(sun_direction, -sun_direction); - } + + /* LAPRAS + We decode these parts of the message but ignore them + as the real values are provided elsewhere. */ + (void)sun_direction, (void)moon_direction, (void)phase; } void process_sound_trigger(LLMessageSystem *msg, void **) diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 6937d064f9..85924a779a 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -34,7 +34,6 @@ #include "lltrans.h" #include "llweb.h" - /// key used to store the grid, and the name attribute in the grid data const std::string GRID_VALUE = "keyname"; /// the value displayed in the grid selector menu, and other human-oriented text @@ -88,6 +87,13 @@ LLGridManager::LLGridManager() // an attacker. Don't want someone snagging a password. std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grids.xml"); + + // fall back to app_settings/grids.xml if it's provided + if (!LLFile::isfile(grid_file)) + { + grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, + "grids.xml"); + } LL_DEBUGS("GridManager")<<LL_ENDL; initialize(grid_file); @@ -133,6 +139,13 @@ void LLGridManager::initialize(const std::string& grid_file) "https://my.aditi.lindenlab.com/", "Aditi"); + // dump example grid file... + //llofstream out_llsd_xml; + //std::string default_grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"); + //out_llsd_xml.open(default_grid_file.c_str()); + //LLSDSerialize::toPrettyXML(mGridList, out_llsd_xml); + //out_llsd_xml.close(); + LLSD other_grids; llifstream llsd_xml; if (!grid_file.empty()) @@ -484,12 +497,19 @@ void LLGridManager::getLoginURIs(const std::string& grid, std::vector<std::strin std::string grid_name = getGrid(grid); if (!grid_name.empty()) { - for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray(); - llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray(); - llsd_uri++) - { - uris.push_back(llsd_uri->asString()); - } + if (mGridList[grid_name][GRID_LOGIN_URI_VALUE].isArray()) + { + for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray(); + llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray(); + llsd_uri++) + { + uris.push_back(llsd_uri->asString()); + } + } + else + { + uris.push_back(mGridList[grid_name][GRID_LOGIN_URI_VALUE].asString()); + } } else { diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 5f0e21db71..7d4d737db4 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -1272,7 +1272,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh { LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW_WATER); - LLGLSquashToFarClip squash(glh_get_current_projection(), 1); + LLGLSquashToFarClip squash(get_current_projection(), 1); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index caf0b0cbf1..d74b77c880 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -42,8 +42,6 @@ #include "m4math.h" // LLMatrix4 #include "llframetimer.h" -#include "llsettingsdaycycle.h" - // Surface id's #define LAND 1 #define WATER 2 @@ -73,13 +71,13 @@ class LLViewerRegionImpl; class LLViewerOctreeGroup; class LLVOCachePartition; -class LLViewerRegion : public LLCapabilityProvider // implements this interface +class LLViewerRegion: public LLCapabilityProvider // implements this interface { public: //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR - typedef enum + typedef enum { - PARTITION_HUD = 0, + PARTITION_HUD=0, PARTITION_TERRAIN, PARTITION_VOIDWATER, PARTITION_WATER, @@ -159,9 +157,7 @@ public: void dirtyHeights(); LLViewerParcelOverlay *getParcelOverlay() const - { - return mParcelOverlay; - } + { return mParcelOverlay; } inline void setRegionFlag(U64 flag, BOOL on); inline BOOL getRegionFlag(U64 flag) const; @@ -199,7 +195,7 @@ public: void setSimAccess(U8 sim_access) { mSimAccess = sim_access; } U8 getSimAccess() const { return mSimAccess; } const std::string getSimAccessString() const; - + // Homestead-related getters; there are no setters as nobody should be // setting them other than the individual message handler which is a member S32 getSimClassID() const { return mClassID; } @@ -220,7 +216,7 @@ public: // Return access icon name static std::string getAccessIcon(U8 sim_access); - + // helper function which just makes sure all interested parties // can process the message. static void processRegionInfo(LLMessageSystem* msg, void**); @@ -238,7 +234,7 @@ public: bool addVisibleGroup(LLViewerOctreeGroup* group); void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child); void addActiveCacheEntry(LLVOCacheEntry* entry); - void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); + void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); void killCacheEntry(U32 local_id); //physically delete the cache entry // Like idleUpdate, but forces everything to complete regardless of @@ -304,7 +300,7 @@ public: U8 getCentralBakeVersion() { return mCentralBakeVersion; } void getInfo(LLSD& info); - + bool meshRezEnabled() const; bool meshUploadEnabled() const; @@ -312,11 +308,11 @@ public: void setSimulatorFeaturesReceived(bool); bool simulatorFeaturesReceived() const; boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb); - - void getSimulatorFeatures(LLSD& info) const; + + void getSimulatorFeatures(LLSD& info) const; void setSimulatorFeatures(const LLSD& info); - + bool dynamicPathfindingEnabled() const; bool avatarHoverHeightEnabled() const; @@ -338,7 +334,7 @@ public: // handle a full update message eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags); - eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); + eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true); bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type); @@ -368,27 +364,27 @@ public: LLVOCachePartition* getVOCachePartition(); bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; - bool childrenObjectReturnable(const std::vector<LLBBox>& boxes) const; + bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const; - void getNeighboringRegions(std::vector<LLViewerRegion*>& uniqueRegions); - void getNeighboringRegionsStatus(std::vector<S32>& regions); + void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector<S32>& regions ); const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } LLViewerRegionImpl * getRegionImplNC() { return mImpl; } // implements the materials capability throttle bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); } void resetMaterialsCapThrottle(); - + U32 getMaxMaterialsPerTransaction() const; void removeFromCreatedList(U32 local_id); - void addToCreatedList(U32 local_id); + void addToCreatedList(U32 local_id); - BOOL isPaused() const { return mPaused; } - S32 getLastUpdate() const { return mLastUpdate; } + BOOL isPaused() const {return mPaused;} + S32 getLastUpdate() const {return mLastUpdate;} - static BOOL isNewObjectCreationThrottleDisabled() { return sNewObjectCreationThrottle < 0; } + static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;} private: void addToVOCacheTree(LLVOCacheEntry* entry); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e9fee8f8b7..6837c6a815 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -46,6 +46,8 @@ #include "llenvironment.h" #include "llatmosphere.h" +#pragma optimize("", off) + #ifdef LL_RELEASE_FOR_DOWNLOAD #define UNIFORM_ERRS LL_WARNS_ONCE("Shader") #else @@ -509,8 +511,9 @@ void LLViewerShaderMgr::setShaders() wl_class = llmin(wl_class, 2); } - if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") - && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) + bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"); + bool useWindLightShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); + if (!hasWindLightShaders || !useWindLightShaders) { // user has disabled WindLight in their settings, downgrade // windlight shaders to stub versions. @@ -544,32 +547,71 @@ void LLViewerShaderMgr::setShaders() // Load all shaders to set max levels loaded = loadShadersEnvironment(); - llassert(loaded); if (loaded) { loaded = loadShadersWater(); + if (loaded) + { + LL_INFOS() << "Loaded water shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load water shaders." << LL_ENDL; + } } if (loaded) { loaded = loadShadersWindLight(); + if (loaded) + { + LL_INFOS() << "Loaded windlight shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL; + } } if (loaded) { loaded = loadShadersEffects(); + if (loaded) + { + LL_INFOS() << "Loaded effects shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load effects shaders." << LL_ENDL; + } } if (loaded) { loaded = loadShadersInterface(); + if (loaded) + { + LL_INFOS() << "Loaded interface shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load interface shaders." << LL_ENDL; + } } if (loaded) { loaded = loadTransformShaders(); + if (loaded) + { + LL_INFOS() << "Loaded transform shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load transform shaders." << LL_ENDL; + } } if (loaded) @@ -628,6 +670,7 @@ void LLViewerShaderMgr::setShaders() if (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) { //disable windlight and try again gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE); + LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL; reentrance = false; setShaders(); return; @@ -636,6 +679,7 @@ void LLViewerShaderMgr::setShaders() if (gSavedSettings.getBOOL("VertexShaderEnable")) { //disable shaders outright and try again gSavedSettings.setBOOL("VertexShaderEnable", FALSE); + LL_WARNS() << "Falling back to no vertex shaders." << LL_ENDL; reentrance = false; setShaders(); return; @@ -645,6 +689,7 @@ void LLViewerShaderMgr::setShaders() if (loaded && !loadShadersDeferred()) { //everything else succeeded but deferred failed, disable deferred and try again gSavedSettings.setBOOL("RenderDeferred", FALSE); + LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL; reentrance = false; setShaders(); return; @@ -898,13 +943,17 @@ BOOL LLViewerShaderMgr::loadBasicShaders() ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); } - std::vector<S32> index_channels; + std::vector<S32> index_channels; index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT]) ); index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mVertexShaderLevel[SHADER_WATER] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mVertexShaderLevel[SHADER_ENVIRONMENT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/decodeNormF.glsl", mVertexShaderLevel[SHADER_ENVIRONMENT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mVertexShaderLevel[SHADER_ENVIRONMENT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); @@ -1180,6 +1229,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; + gDeferredDiffuseProgram.mFeatures.encodesNormal = true; gDeferredDiffuseProgram.mShaderFiles.clear(); gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1191,6 +1241,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader"; + gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear(); gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1202,6 +1253,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; + gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear(); gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1212,6 +1264,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true; gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear(); gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1222,6 +1275,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; + gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true; gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1234,6 +1288,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true; gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1245,6 +1300,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader"; gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true; gDeferredSkinnedBumpProgram.mShaderFiles.clear(); gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1260,6 +1316,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true; + gDeferredSkinnedAlphaProgram.mFeatures.decodesNormal = true; + gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true; + gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; + gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1278,6 +1342,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredBumpProgram.mName = "Deferred Bump Shader"; + gDeferredBumpProgram.mFeatures.encodesNormal = true; gDeferredBumpProgram.mShaderFiles.clear(); gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1322,6 +1387,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() bool has_skin = i & 0x10; gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); + gDeferredMaterialProgram[i].mFeatures.hasSrgb = true; + gDeferredMaterialProgram[i].mFeatures.decodesNormal = true; + gDeferredMaterialProgram[i].mFeatures.encodesNormal = true; + gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true; + gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true; + if (has_skin) { gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true; @@ -1350,6 +1421,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1"); + gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true; + gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true; + gDeferredMaterialWaterProgram[i].mFeatures.decodesNormal = true; + gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true; + gDeferredMaterialWaterProgram[i].mFeatures.calculatesAtmospherics = true; + gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true; + if (has_skin) { gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true; @@ -1382,6 +1460,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredTreeProgram.mName = "Deferred Tree Shader"; gDeferredTreeProgram.mShaderFiles.clear(); + gDeferredTreeProgram.mFeatures.encodesNormal = true; gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredTreeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; @@ -1401,6 +1480,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; + gDeferredImpostorProgram.mFeatures.hasSrgb = true; + gDeferredImpostorProgram.mFeatures.decodesNormal = true; + gDeferredImpostorProgram.mFeatures.encodesNormal = true; gDeferredImpostorProgram.mShaderFiles.clear(); gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1411,6 +1493,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredLightProgram.mName = "Deferred Light Shader"; + gDeferredLightProgram.mFeatures.decodesNormal = true; gDeferredLightProgram.mShaderFiles.clear(); gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1424,6 +1507,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i); + gDeferredMultiLightProgram[i].mFeatures.decodesNormal = true; gDeferredMultiLightProgram[i].mShaderFiles.clear(); gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1437,6 +1521,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; gDeferredSpotLightProgram.mShaderFiles.clear(); + gDeferredSpotLightProgram.mFeatures.hasSrgb = true; + gDeferredSpotLightProgram.mFeatures.decodesNormal = true; gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; @@ -1447,6 +1533,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; + gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true; + gDeferredMultiSpotLightProgram.mFeatures.decodesNormal = true; gDeferredMultiSpotLightProgram.mShaderFiles.clear(); gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1474,6 +1562,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } gDeferredSunProgram.mName = "Deferred Sun Shader"; + gDeferredSunProgram.mFeatures.decodesNormal = true; gDeferredSunProgram.mShaderFiles.clear(); gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB)); gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); @@ -1485,6 +1574,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader"; + gDeferredBlurLightProgram.mFeatures.decodesNormal = true; gDeferredBlurLightProgram.mShaderFiles.clear(); gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1501,6 +1591,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaProgram.mFeatures.hasLighting = false; gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredAlphaProgram.mFeatures.hasSrgb = true; + gDeferredAlphaProgram.mFeatures.decodesNormal = true; + gDeferredAlphaProgram.mFeatures.encodesNormal = true; + gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; + if (mVertexShaderLevel[SHADER_DEFERRED] < 1) { gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; @@ -1527,11 +1623,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader"; + gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader"; gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false; gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false; gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true; + gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true; + gDeferredAlphaImpostorProgram.mFeatures.decodesNormal = true; + gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true; gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels if (mVertexShaderLevel[SHADER_DEFERRED] < 1) { @@ -1566,6 +1665,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaWaterProgram.mFeatures.hasLighting = false; gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true; gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true; + gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true; + gDeferredAlphaWaterProgram.mFeatures.decodesNormal = true; + gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true; + gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true; + if (mVertexShaderLevel[SHADER_DEFERRED] < 1) { gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; @@ -1598,6 +1704,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true; + gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true; gDeferredAvatarEyesProgram.mShaderFiles.clear(); gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1611,6 +1719,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightProgram.mFeatures.hasGamma = true; gDeferredFullbrightProgram.mFeatures.hasTransport = true; + gDeferredFullbrightProgram.mFeatures.hasSrgb = true; gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredFullbrightProgram.mShaderFiles.clear(); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1625,6 +1734,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear(); gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1640,6 +1750,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true; gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true; + gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true; gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredFullbrightWaterProgram.mShaderFiles.clear(); gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1656,6 +1768,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true; gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true; gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear(); gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1689,6 +1803,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; + gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true; gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1732,6 +1847,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true; gDeferredWaterProgram.mFeatures.hasGamma = true; gDeferredWaterProgram.mFeatures.hasTransport = true; + gDeferredWaterProgram.mFeatures.encodesNormal = true; gDeferredWaterProgram.mShaderFiles.clear(); gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1746,6 +1862,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true; gDeferredUnderWaterProgram.mFeatures.hasGamma = true; gDeferredUnderWaterProgram.mFeatures.hasTransport = true; + gDeferredUnderWaterProgram.mFeatures.hasSrgb = true; + gDeferredUnderWaterProgram.mFeatures.encodesNormal = true; gDeferredUnderWaterProgram.mShaderFiles.clear(); gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1757,6 +1875,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredSoftenProgram.mName = "Deferred Soften Shader"; gDeferredSoftenProgram.mShaderFiles.clear(); + gDeferredSoftenProgram.mFeatures.hasSrgb = true; + gDeferredSoftenProgram.mFeatures.decodesNormal = true; + gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSoftenProgram.mFeatures.hasAtmospherics = true; + gDeferredSoftenProgram.mFeatures.hasTransport = true; + gDeferredSoftenProgram.mFeatures.hasGamma = true; + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1780,6 +1905,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1"); gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true; + gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true; + gDeferredSoftenWaterProgram.mFeatures.decodesNormal = true; + gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true; + gDeferredSoftenWaterProgram.mFeatures.hasTransport = true; + gDeferredSoftenWaterProgram.mFeatures.hasGamma = true; if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { //if using SSAO, take screen space light map into account as if shadows are enabled @@ -1850,6 +1982,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gTerrainProgram.mName = "Deferred Terrain Shader"; + gDeferredTerrainProgram.mFeatures.encodesNormal = true; gDeferredTerrainProgram.mShaderFiles.clear(); gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1861,6 +1994,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredAvatarProgram.mName = "Avatar Shader"; gDeferredAvatarProgram.mFeatures.hasSkinning = true; + gDeferredAvatarProgram.mFeatures.encodesNormal = true; gDeferredAvatarProgram.mShaderFiles.clear(); gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1876,6 +2010,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true; + gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true; + gDeferredAvatarAlphaProgram.mFeatures.decodesNormal = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true; + gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; + gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1893,6 +2035,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; + gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true; gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1950,6 +2093,31 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); } + // this shader uses gather so it can't live with the other basic shaders safely + /*if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) + { + gDownsampleMinMaxDepthRectProgram.mName = "DownsampleMinMaxDepthRect Shader"; + gDownsampleMinMaxDepthRectProgram.mShaderFiles.clear(); + gDownsampleMinMaxDepthRectProgram.mShaderFiles.push_back(make_pair("windlight/downsampleMinMaxDepthV.glsl", GL_VERTEX_SHADER_ARB)); + gDownsampleMinMaxDepthRectProgram.mShaderFiles.push_back(make_pair("windlight/downsampleMinMaxDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDownsampleMinMaxDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; + success = gDownsampleMinMaxDepthRectProgram.createShader(NULL, NULL); + }*/ + + // this shader uses gather so it can't live with the other basic shaders safely + /*if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) + { + gInscatterRectProgram.mName = "Inscatter Shader"; + gInscatterRectProgram.mShaderFiles.clear(); + gInscatterRectProgram.mShaderFiles.push_back(make_pair("windlight/advancedAtmoV.glsl", GL_VERTEX_SHADER_ARB)); + gInscatterRectProgram.mShaderFiles.push_back(make_pair("windlight/advancedAtmoF.glsl", GL_FRAGMENT_SHADER_ARB)); + gInscatterRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; + llassert(gAtmosphere != nullptr); + gInscatterRectProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); + success = gInscatterRectProgram.createShader(NULL, NULL); + llassert(success); + }*/ + if (success) { gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; @@ -1964,9 +2132,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); } success = gDeferredWLSkyProgram.createShader(NULL, NULL); + llassert(success); } - if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) + if (success) { gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; gDeferredWLCloudProgram.mShaderFiles.clear(); @@ -1974,7 +2143,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; + if (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3) + { + gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); + } success = gDeferredWLCloudProgram.createShader(NULL, NULL); + llassert(success); } if (success) @@ -2239,6 +2413,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNonIndexedProgram.mFeatures.hasSrgb = true; gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2254,6 +2429,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true; gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true; gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2270,6 +2446,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true; gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true; gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true; gObjectEmissiveNonIndexedProgram.mShaderFiles.clear(); gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2300,6 +2477,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true; gObjectFullbrightNoColorProgram.mFeatures.hasTransport = true; gObjectFullbrightNoColorProgram.mFeatures.isFullbright = true; + gObjectFullbrightNoColorProgram.mFeatures.hasSrgb = true; gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true; gObjectFullbrightNoColorProgram.mShaderFiles.clear(); gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2395,6 +2573,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() { gImpostorProgram.mName = "Impostor Shader"; gImpostorProgram.mFeatures.disableTextureIndex = true; + gImpostorProgram.mFeatures.hasSrgb = true; gImpostorProgram.mShaderFiles.clear(); gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB)); gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2483,6 +2662,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectBumpProgram.mFeatures.hasAtmospherics = true; gObjectBumpProgram.mFeatures.hasLighting = true; gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/ + gObjectBumpProgram.mFeatures.encodesNormal = true; gObjectBumpProgram.mShaderFiles.clear(); gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB)); gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2540,6 +2720,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightProgram.mFeatures.hasGamma = true; gObjectFullbrightProgram.mFeatures.hasTransport = true; gObjectFullbrightProgram.mFeatures.isFullbright = true; + gObjectFullbrightProgram.mFeatures.hasSrgb = true; gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightProgram.mShaderFiles.clear(); gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2571,6 +2752,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectEmissiveProgram.mFeatures.hasGamma = true; gObjectEmissiveProgram.mFeatures.hasTransport = true; gObjectEmissiveProgram.mFeatures.isFullbright = true; + gObjectEmissiveProgram.mFeatures.hasSrgb = true; gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0; gObjectEmissiveProgram.mShaderFiles.clear(); gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2603,6 +2785,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; gObjectFullbrightAlphaMaskProgram.mFeatures.isFullbright = true; gObjectFullbrightAlphaMaskProgram.mFeatures.hasAlphaMask = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear(); gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2725,6 +2908,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true; gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true; gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2741,6 +2925,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true; gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true; gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectEmissiveProgram.mFeatures.hasSrgb = true; gSkinnedObjectEmissiveProgram.mShaderFiles.clear(); gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -3308,30 +3493,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() LLAtmosphere::initClass(); } - // this shader uses gather so it can't live with the other basic shaders safely - /*if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) - { - gDownsampleMinMaxDepthRectProgram.mName = "DownsampleMinMaxDepthRect Shader"; - gDownsampleMinMaxDepthRectProgram.mShaderFiles.clear(); - gDownsampleMinMaxDepthRectProgram.mShaderFiles.push_back(make_pair("windlight/downsampleMinMaxDepthV.glsl", GL_VERTEX_SHADER_ARB)); - gDownsampleMinMaxDepthRectProgram.mShaderFiles.push_back(make_pair("windlight/downsampleMinMaxDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDownsampleMinMaxDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; - success = gDownsampleMinMaxDepthRectProgram.createShader(NULL, NULL); - }*/ - - // this shader uses gather so it can't live with the other basic shaders safely - if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) - { - gInscatterRectProgram.mName = "Inscatter Shader"; - gInscatterRectProgram.mShaderFiles.clear(); - gInscatterRectProgram.mShaderFiles.push_back(make_pair("windlight/advancedAtmoV.glsl", GL_VERTEX_SHADER_ARB)); - gInscatterRectProgram.mShaderFiles.push_back(make_pair("windlight/advancedAtmoF.glsl", GL_FRAGMENT_SHADER_ARB)); - gInscatterRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; - llassert(gAtmosphere != nullptr); - gInscatterRectProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); - success = gInscatterRectProgram.createShader(NULL, NULL); - } - if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) { gWLSkyProgram.mName = "Windlight Sky Shader"; @@ -3344,7 +3505,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gWLSkyProgram.createShader(NULL, NULL); } - if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) + if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) { gWLCloudProgram.mName = "Windlight Cloud Program"; //gWLCloudProgram.mFeatures.hasGamma = true; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f981d40204..1ad71ce93e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -597,7 +597,7 @@ public: addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount)); ypos += y_inc; - addText(xpos, ypos, llformat("%d Render Calls", last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize))); + addText(xpos, ypos, llformat("%d Render Calls", (U32)last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize))); ypos += y_inc; addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 71a7623fb4..52a6395618 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -126,7 +126,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) left_dir.normVec(); // Our center top point - LLColor4 ground_color = gSky.getFogColor(); + LLColor4 ground_color = gSky.getSkyFogColor(); ground_color.mV[3] = 1.f; face->setFaceColor(ground_color); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 9ba6aeb37f..a2ea3181ca 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -53,6 +53,8 @@ #include "llsettingssky.h" #include "llenvironment.h" +#pragma optimize("", off) + #undef min #undef max @@ -71,131 +73,13 @@ static const LLVector2 TEX01 = LLVector2(0.f, 1.f); static const LLVector2 TEX10 = LLVector2(1.f, 0.f); static const LLVector2 TEX11 = LLVector2(1.f, 1.f); +static const F32 LIGHT_DIRECTION_THRESHOLD = (F32) cosf(DEG_TO_RAD * 1.f); +static const F32 COLOR_CHANGE_THRESHOLD = 0.01f; + // Exported globals LLUUID gSunTextureID = IMG_SUN; LLUUID gMoonTextureID = IMG_MOON; -class LLFastLn -{ -public: - LLFastLn() - { - mTable[0] = 0; - for( S32 i = 1; i < 257; i++ ) - { - mTable[i] = log((F32)i); - } - } - - F32 ln( F32 x ) - { - const F32 OO_255 = 0.003921568627450980392156862745098f; - const F32 LN_255 = 5.5412635451584261462455391880218f; - - if( x < OO_255 ) - { - return log(x); - } - else - if( x < 1 ) - { - x *= 255.f; - S32 index = llfloor(x); - F32 t = x - index; - F32 low = mTable[index]; - F32 high = mTable[index + 1]; - return low + t * (high - low) - LN_255; - } - else - if( x <= 255 ) - { - S32 index = llfloor(x); - F32 t = x - index; - F32 low = mTable[index]; - F32 high = mTable[index + 1]; - return low + t * (high - low); - } - else - { - return log( x ); - } - } - - F32 pow( F32 x, F32 y ) - { - return (F32)LL_FAST_EXP(y * ln(x)); - } - - -private: - F32 mTable[257]; // index 0 is unused -}; - -static LLFastLn gFastLn; - - -// Functions used a lot. - -inline F32 LLHaze::calcPhase(const F32 cos_theta) const -{ - const F32 g2 = mG * mG; - const F32 den = 1 + g2 - 2 * mG * cos_theta; - return (1 - g2) * gFastLn.pow(den, -1.5); -} - -inline void color_pow(LLColor3 &col, const F32 e) -{ - col.mV[0] = gFastLn.pow(col.mV[0], e); - col.mV[1] = gFastLn.pow(col.mV[1], e); - col.mV[2] = gFastLn.pow(col.mV[2], e); -} - -inline LLColor3 color_norm(const LLColor3 &col) -{ - const F32 m = color_max(col); - if (m > 1.f) - { - return 1.f/m * col; - } - else return col; -} - -inline void color_gamma_correct(LLColor3 &col) -{ - const F32 gamma_inv = 1.f/1.2f; - if (col.mV[0] != 0.f) - { - col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv); - } - if (col.mV[1] != 0.f) - { - col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv); - } - if (col.mV[2] != 0.f) - { - col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv); - } -} - -static LLColor3 calc_air_sca_sea_level() -{ - static LLColor3 WAVE_LEN(675, 520, 445); - static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); - static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); - static LLColor3 n4 = n21 * n21; - static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; - static LLColor3 wl4 = wl2 * wl2; - static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; - static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); - return dens_div_N * color_div ( mult_const, wl4 ); -} - -// static constants. -LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); -F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel); -F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; - - /*************************************** SkyTex ***************************************/ @@ -306,11 +190,165 @@ void LLSkyTex::bindTexture(BOOL curr) } /*************************************** - Sky + LLHeavenBody ***************************************/ F32 LLHeavenBody::sInterpVal = 0; +LLHeavenBody::LLHeavenBody(const F32 rad) +: mDirectionCached(LLVector3(0,0,0)), + mDirection(LLVector3(0,0,0)), + mIntensity(0.f), + mDiskRadius(rad), + mDraw(FALSE), + mHorizonVisibility(1.f), + mVisibility(1.f), + mVisible(FALSE) +{ + mColor.setToBlack(); + mColorCached.setToBlack(); +} + +const LLVector3& LLHeavenBody::getDirection() const +{ + return mDirection; +} + +void LLHeavenBody::setDirection(const LLVector3 &direction) +{ + mDirection = direction; +} + +void LLHeavenBody::setAngularVelocity(const LLVector3 &ang_vel) +{ + mAngularVelocity = ang_vel; +} + +const LLVector3& LLHeavenBody::getAngularVelocity() const +{ + return mAngularVelocity; +} + +const LLVector3& LLHeavenBody::getDirectionCached() const +{ + return mDirectionCached; +} + +void LLHeavenBody::renewDirection() +{ + mDirectionCached = mDirection; +} + +const LLColor3& LLHeavenBody::getColorCached() const +{ + return mColorCached; +} + +void LLHeavenBody::setColorCached(const LLColor3& c) +{ + mColorCached = c; +} + +const LLColor3& LLHeavenBody::getColor() const +{ + return mColor; +} + +void LLHeavenBody::setColor(const LLColor3& c) +{ + mColor = c; +} + +void LLHeavenBody::renewColor() +{ + mColorCached = mColor; +} + +F32 LLHeavenBody::interpVal() +{ + return sInterpVal; +} + +void LLHeavenBody::setInterpVal(const F32 v) +{ + sInterpVal = v; +} + +LLColor3 LLHeavenBody::getInterpColor() const +{ + return sInterpVal * mColor + (1 - sInterpVal) * mColorCached; +} + +const F32& LLHeavenBody::getVisibility() const +{ + return mVisibility; +} + +void LLHeavenBody::setVisibility(const F32 c) +{ + mVisibility = c; +} + +bool LLHeavenBody::isVisible() const +{ + return mVisible; +} + +void LLHeavenBody::setVisible(const bool v) +{ + mVisible = v; +} + +const F32& LLHeavenBody::getIntensity() const +{ + return mIntensity; +} + +void LLHeavenBody::setIntensity(const F32 c) +{ + mIntensity = c; +} + +void LLHeavenBody::setDiskRadius(const F32 radius) +{ + mDiskRadius = radius; +} + +F32 LLHeavenBody::getDiskRadius() const +{ + return mDiskRadius; +} + +void LLHeavenBody::setDraw(const bool draw) +{ + mDraw = draw; +} + +bool LLHeavenBody::getDraw() const +{ + return mDraw; +} + +const LLVector3& LLHeavenBody::corner(const S32 n) const +{ + return mQuadCorner[n]; +} + +LLVector3& LLHeavenBody::corner(const S32 n) +{ + return mQuadCorner[n]; +} + +const LLVector3* LLHeavenBody::corners() const +{ + return mQuadCorner; +} + +/*************************************** + Sky +***************************************/ + + S32 LLVOSky::sResolution = LLSkyTex::getResolution(); S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y; @@ -348,20 +386,6 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mAtmHeight = ATM_HEIGHT; mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); - // *LAPRAS - mSunDefaultPosition = LLEnvironment::instance().getCurrentSky()->getSunDirection(); - - if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) - { - - initSunDirection(LLVector3(mSunDefaultPosition.mV[2], mSunDefaultPosition.mV[0], mSunDefaultPosition.mV[1]), LLVector3(0, 0, 0)); - } - mAmbientScale = gSavedSettings.getF32("SkyAmbientScale"); - mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift"); - mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f; - mFogColor.mV[VALPHA] = 0.0f; - mFogRatio = 1.2f; - mSun.setIntensity(SUN_INTENSITY); mMoon.setIntensity(0.1f * SUN_INTENSITY); @@ -376,7 +400,6 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mHeavenlyBodyUpdated = FALSE ; mDrawRefl = 0; - mHazeConcentration = 0.f; mInterpVal = 0.f; } @@ -391,13 +414,13 @@ LLVOSky::~LLVOSky() void LLVOSky::init() { - const F32 haze_int = color_intens(mHaze.calcSigSca(0)); - mHazeConcentration = haze_int / - (color_intens(LLHaze::calcAirSca(0)) + haze_int); + llassert(!mInitialized); + + // Update sky at least once to get correct initial sun/moon directions and lighting calcs performed + LLEnvironment::instance().getCurrentSky()->update(); - calcAtmospherics(); + updateDirections(); -// LEGACY_ATMOSPHERICS // Initialize the cached normalized direction vectors for (S32 side = 0; side < 6; ++side) { @@ -468,7 +491,7 @@ void LLVOSky::restoreGL() mBloomTexturep->setNoDelete() ; mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - calcAtmospherics(); + updateDirections(); if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) @@ -484,10 +507,11 @@ void LLVOSky::restoreGL() if(cube_map) { cube_map->init(images); - mForceUpdate = TRUE; } } + mForceUpdate = TRUE; + if (mDrawable) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); @@ -495,7 +519,6 @@ void LLVOSky::restoreGL() } -// LEGACY_ATMOSPHERICS void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) { S32 tile_x = tile % NUM_TILES_X; @@ -541,290 +564,13 @@ void LLVOSky::createSkyTexture(const S32 side, const S32 tile) { for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x) { - mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y); - mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y); - } - } -} - -LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny) -{ - F32 saturation = 0.3f; - if (dir.mV[VZ] < -0.02f) - { - LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f); - if (isShiny) - { - LLColor3 desat_fog = LLColor3(mFogColor); - F32 brightness = desat_fog.brightness(); - // So that shiny somewhat shows up at night. - if (brightness < 0.15f) - { - brightness = 0.15f; - desat_fog = smear(0.15f); - } - LLColor3 greyscale = smear(brightness); - desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation); - if (!gPipeline.canUseWindLightShaders()) - { - col = LLColor4(desat_fog, 0.f); - } - else - { - col = LLColor4(desat_fog * 0.5f, 0.f); - } - } - float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]); - x *= x; - col.mV[0] *= x*x; - col.mV[1] *= powf(x, 2.5f); - col.mV[2] *= x*x*x; - return col; - } - - // undo OGL_TO_CFR_ROTATION and negate vertical direction. - LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]); - - LLColor3 vary_HazeColor(0,0,0); - LLColor3 vary_CloudColorSun(0,0,0); - LLColor3 vary_CloudColorAmbient(0,0,0); - F32 vary_CloudDensity(0); - LLVector2 vary_HorizontalProjection[2]; - vary_HorizontalProjection[0] = LLVector2(0,0); - vary_HorizontalProjection[1] = LLVector2(0,0); - - calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient, - vary_CloudDensity, vary_HorizontalProjection); - - LLColor3 sky_color = calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient, - vary_CloudDensity, vary_HorizontalProjection); - if (isShiny) - { - F32 brightness = sky_color.brightness(); - LLColor3 greyscale = smear(brightness); - sky_color = sky_color * saturation + greyscale * (1.0f - saturation); - sky_color *= (0.5f + 0.5f * brightness); - } - return LLColor4(sky_color, 0.0f); -} - -// turn on floating point precision -// in vs2003 for this function. Otherwise -// sky is aliased looking 7:10 - 8:50 -#if LL_MSVC && __MSVC_VER__ < 8 -#pragma optimize("p", on) -#endif - -void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, - LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, - LLVector2 vary_HorizontalProjection[2]) -{ - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - - LLColor3 blue_density = psky->getBlueDensity(); - F32 max_y = psky->getMaxY(); - LLVector3 lightnorm = psky->getLightNormal(); - - // project the direction ray onto the sky dome. - F32 phi = acos(Pn[1]); - F32 sinA = sin(F_PI - phi); - if (fabsf(sinA) < 0.01f) - { //avoid division by zero - sinA = 0.01f; - } - - F32 Plen = psky->getDomeRadius() * sin(F_PI + phi + asin(psky->getDomeOffset() * sinA)) / sinA; - - Pn *= Plen; - - vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]); - vary_HorizontalProjection[0] /= - 2.f * Plen; - - // Set altitude - if (Pn[1] > 0.f) - { - Pn *= (max_y / Pn[1]); - } - else - { - Pn *= (-32000.f / Pn[1]); - } - - Plen = Pn.length(); - Pn /= Plen; - - // Initialize temp variables - LLColor3 sunlight = psky->getSunlightColor(); - LLColor3 ambient = psky->getAmbientColor(); - LLColor3 blue_horizon = psky->getBlueHorizon(); - F32 haze_density = psky->getHazeDensity(); - F32 haze_horizon = psky->getHazeHorizon(); - F32 density_multiplier = psky->getDensityMultiplier(); - LLColor3 glow = psky->getGlow(); - F32 cloud_shadow = psky->getCloudShadow(); - - // Sunlight attenuation effect (hue and brightness) due to atmosphere - // this is used later for sunlight modulation at various altitudes - LLColor3 light_atten = (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); - - // Calculate relative weights - LLColor3 temp2(0.f, 0.f, 0.f); - LLColor3 temp1 = blue_density + smear(haze_density); - LLColor3 blue_weight = componentDiv(blue_density, temp1); - LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); - - // Compute sunlight from P & lightnorm (for long rays like sky) - temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); - - temp2.mV[1] = 1.f / temp2.mV[1]; - componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); - - // Distance - temp2.mV[2] = Plen * density_multiplier; - - // Transparency (-> temp1) - temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); - - - // Compute haze glow - temp2.mV[0] = Pn * lightnorm; - - temp2.mV[0] = 1.f - temp2.mV[0]; - // temp2.x is 0 at the sun and increases away from sun - temp2.mV[0] = llmax(temp2.mV[0], .001f); - // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.mV[0] *= glow.mV[0]; - // Higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]); - // glow.z should be negative, so we're doing a sort of (1 / "angle") function - - // Add "minimum anti-solar illumination" - temp2.mV[0] += .25f; - - - // Haze color above cloud - vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient)); - - // Increase ambient when there are more clouds - LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; - - // Dim sunlight by cloud shadow percentage - sunlight *= (1.f - cloud_shadow); - - // Haze color below cloud - LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)); - - // Final atmosphere additive - componentMultBy(vary_HazeColor, LLColor3::white - temp1); - - sunlight = psky->getSunlightColor(); - temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f); - temp2.mV[1] = 1.f / temp2.mV[1]; - componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); - - // Attenuate cloud color by atmosphere - temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds - - // At horizon, blend high altitude sky color towards the darker color below the clouds - vary_HazeColor += componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1)); - - if (Pn[1] < 0.f) - { - // Eric's original: - // LLColor3 dark_brown(0.143f, 0.129f, 0.114f); - LLColor3 dark_brown(0.082f, 0.076f, 0.066f); - LLColor3 brown(0.430f, 0.386f, 0.322f); - LLColor3 sky_lighting = sunlight + ambient; - F32 haze_brightness = vary_HazeColor.brightness(); - - if (Pn[1] < -0.05f) - { - vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness; - } - - if (Pn[1] > -0.1f) - { - vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f)); + mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y); + mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y); } } } -#if LL_MSVC && __MSVC_VER__ < 8 -#pragma optimize("p", off) -#endif - -LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, - LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, - LLVector2 vary_HorizontalProjection[2]) -{ - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - F32 gamma = psky->getGamma(); - - LLColor3 res; - LLColor3 color0 = vary_HazeColor; - - if (!gPipeline.canUseWindLightShaders()) - { - LLColor3 color1 = color0 * 2.0f; - color1 = smear(1.f) - componentSaturate(color1); - componentPow(color1, gamma); - res = smear(1.f) - color1; - } - else - { - res = color0; - } - -# ifndef LL_RELEASE_FOR_DOWNLOAD - - LLColor3 color2 = 2.f * color0; - - LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2); - componentPow(color3, gamma); - color3 = LLColor3(1.f, 1.f, 1.f) - color3; - - static enum { - OUT_DEFAULT = 0, - OUT_SKY_BLUE = 1, - OUT_RED = 2, - OUT_PN = 3, - OUT_HAZE = 4, - } debugOut = OUT_DEFAULT; - - switch(debugOut) - { - case OUT_DEFAULT: - break; - case OUT_SKY_BLUE: - res = LLColor3(0.4f, 0.4f, 0.9f); - break; - case OUT_RED: - res = LLColor3(1.f, 0.f, 0.f); - break; - case OUT_PN: - res = LLColor3(Pn[0], Pn[1], Pn[2]); - break; - case OUT_HAZE: - res = vary_HazeColor; - break; - } -# endif // LL_RELEASE_FOR_DOWNLOAD - return res; -} - - -LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) -{ - return componentMult(diffuse, sundiffuse) * 4.0f + - componentMult(ambient, sundiffuse) * 2.0f + sunambient; -} - -LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) -{ - return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f; -} - -void LLVOSky::calcAtmospherics(void) +void LLVOSky::updateDirections(void) { LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); @@ -835,25 +581,13 @@ void LLVOSky::calcAtmospherics(void) mSun.renewColor(); mMoon.renewDirection(); mMoon.renewColor(); - - float dp = getToSunLast() * LLVector3(0,0,1.f); - if (dp < 0) - { - dp = 0; - } - - // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio - // between sunlight and point lights in windlight to normalize point lights. - F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); - LLEnvironment::instance().setSceneLightStrength(2.0f * (1.0f + sun_dynamic_range * dp)); - } void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time) { } -BOOL LLVOSky::updateSky() +bool LLVOSky::updateSky() { LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); @@ -874,16 +608,17 @@ BOOL LLVOSky::updateSky() return TRUE; } -// LEGACY_ATMOSPHERICS static S32 next_frame = 0; const S32 total_no_tiles = 6 * NUM_TILES; const S32 cycle_frame_no = total_no_tiles + 1; - if (mUpdateTimer.getElapsedTimeF32() > 0.001f) + if (mUpdateTimer.getElapsedTimeF32() > 0.025f) { mUpdateTimer.reset(); const S32 frame = next_frame; + mForceUpdate = mForceUpdate || (total_no_tiles == frame); + ++next_frame; next_frame = next_frame % cycle_frame_no; @@ -891,29 +626,29 @@ BOOL LLVOSky::updateSky() // sInterpVal = (F32)next_frame / cycle_frame_no; LLSkyTex::setInterpVal( mInterpVal ); LLHeavenBody::setInterpVal( mInterpVal ); - calcAtmospherics(); + updateDirections(); + + LLVector3 direction = mSun.getDirection(); + direction.normalize(); + const F32 dot_lighting = direction * mLastLightingDirection; + + LLColor3 delta_color; + delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0], + mLastTotalAmbient.mV[1] - total_ambient.mV[1], + mLastTotalAmbient.mV[2] - total_ambient.mV[2]); + + bool light_direction_changed = (dot_lighting >= LIGHT_DIRECTION_THRESHOLD); + bool color_changed = (delta_color.length() >= COLOR_CHANGE_THRESHOLD); + + mForceUpdate = mForceUpdate || light_direction_changed; + mForceUpdate = mForceUpdate || color_changed; + mForceUpdate = mForceUpdate || !mInitialized; - if (mForceUpdate || total_no_tiles == frame) + if (mForceUpdate) { - LLSkyTex::stepCurrent(); - - const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f); - const static F32 COLOR_CHANGE_THRESHOLD = 0.01f; - - LLVector3 direction = mSun.getDirection(); - direction.normalize(); - const F32 dot_lighting = direction * mLastLightingDirection; - - LLColor3 delta_color; - delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0], - mLastTotalAmbient.mV[1] - total_ambient.mV[1], - mLastTotalAmbient.mV[2] - total_ambient.mV[2]); - - if ( mForceUpdate - || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) - || (delta_color.length() > COLOR_CHANGE_THRESHOLD) - || !mInitialized) - && !direction.isExactlyZero())) + LLSkyTex::stepCurrent(); + + if (!direction.isExactlyZero()) { mLastLightingDirection = direction; mLastTotalAmbient = total_ambient; @@ -921,72 +656,55 @@ BOOL LLVOSky::updateSky() if (mCubeMap) { - if (mForceUpdate) - { - updateFog(LLViewerCamera::getInstance()->getFar()); - - for (int side = 0; side < 6; side++) - { - for (int tile = 0; tile < NUM_TILES; tile++) - { - createSkyTexture(side, tile); - } - } + updateFog(LLViewerCamera::getInstance()->getFar()); - calcAtmospherics(); - - for (int side = 0; side < 6; side++) + for (int side = 0; side < 6; side++) + { + for (int tile = 0; tile < NUM_TILES; tile++) { - LLImageRaw* raw1 = mSkyTex[side].getImageRaw(TRUE); - LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE); - raw2->copy(raw1); - mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE)); - - raw1 = mShinyTex[side].getImageRaw(TRUE); - raw2 = mShinyTex[side].getImageRaw(FALSE); - raw2->copy(raw1); - mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE)); + createSkyTexture(side, tile); } - next_frame = 0; } - } - } - /// *TODO really, sky texture and env map should be shared on a single texture - /// I'll let Brad take this at some point - - // update the sky texture - for (S32 i = 0; i < 6; ++i) - { - mSkyTex[i].create(1.0f); - mShinyTex[i].create(1.0f); - } - - // update the environment map - if (mCubeMap) - { - std::vector<LLPointer<LLImageRaw> > images; - images.reserve(6); - for (S32 side = 0; side < 6; side++) - { - images.push_back(mShinyTex[side].getImageRaw(TRUE)); + for (int side = 0; side < 6; side++) + { + LLImageRaw* raw1 = mSkyTex[side].getImageRaw(TRUE); + LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE); + raw2->copy(raw1); + mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE)); + + raw1 = mShinyTex[side].getImageRaw(TRUE); + raw2 = mShinyTex[side].getImageRaw(FALSE); + raw2->copy(raw1); + mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE)); + } + next_frame = 0; + + // update the sky texture + for (S32 i = 0; i < 6; ++i) + { + mSkyTex[i].create(1.0f); + mShinyTex[i].create(1.0f); + } + + // update the environment map + if (mCubeMap) + { + std::vector<LLPointer<LLImageRaw> > images; + images.reserve(6); + for (S32 side = 0; side < 6; side++) + { + images.push_back(mShinyTex[side].getImageRaw(TRUE)); + } + mCubeMap->init(images); + gGL.getTexUnit(0)->disable(); + } } - mCubeMap->init(images); - gGL.getTexUnit(0)->disable(); - } + } gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - // *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad. - //gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - mForceUpdate = FALSE; } - else - { - const S32 side = frame / NUM_TILES; - const S32 tile = frame % NUM_TILES; - createSkyTexture(side, tile); - } } if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer()) @@ -1028,53 +746,6 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline) return mDrawable; } -//by bao -//fake vertex buffer updating -//to guarantee at least updating one VBO buffer every frame -//to walk around the bug caused by ATI card --> DEV-3855 -// -void LLVOSky::createDummyVertexBuffer() -{ - if(!mFace[FACE_DUMMY]) - { - LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY); - mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL); - } - - if(!mFace[FACE_DUMMY]->getVertexBuffer()) - { - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - buff->allocateBuffer(1, 1, TRUE); - mFace[FACE_DUMMY]->setVertexBuffer(buff); - } -} - -static LLTrace::BlockTimerStatHandle FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update"); - -void LLVOSky::updateDummyVertexBuffer() -{ - if(!LLVertexBuffer::sEnableVBOs) - return ; - - if(mHeavenlyBodyUpdated) - { - mHeavenlyBodyUpdated = FALSE ; - return ; - } - - LL_RECORD_BLOCK_TIME(FTM_RENDER_FAKE_VBO_UPDATE) ; - - if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer()) - createDummyVertexBuffer() ; - - LLStrider<LLVector3> vertices ; - mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices, 0); - *vertices = mCameraPosAgent ; - mFace[FACE_DUMMY]->getVertexBuffer()->flush(); -} -//---------------------------------- -//end of fake vertex buffer updating -//---------------------------------- static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry"); BOOL LLVOSky::updateGeometry(LLDrawable *drawable) @@ -1164,18 +835,22 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) LLVector3 up = right % look_at; right.normalize(); up.normalize(); + + bool draw_sun = updateHeavenlyBodyGeometry(drawable, FACE_SUN, mSun, up, right); + bool draw_moon = updateHeavenlyBodyGeometry(drawable, FACE_MOON, mMoon, up, right); - const static F32 elevation_factor = 0.0f/sResolution; - const F32 cos_max_angle = cosHorizon(elevation_factor); - mSun.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_SUN, TRUE, mSun, cos_max_angle, up, right)); - mMoon.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_MOON, FALSE, mMoon, cos_max_angle, up, right)); + draw_sun &= LLEnvironment::getInstance()->getIsSunUp(); + draw_moon &= LLEnvironment::getInstance()->getIsMoonUp(); + + mSun.setDraw(draw_sun); + mMoon.setDraw(draw_moon); const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.01f; // LLWorld::getInstance()->getWaterHeight() + 0.01f; const F32 camera_height = mCameraPosAgent.mV[2]; const F32 height_above_water = camera_height - water_height; - BOOL sun_flag = FALSE; + bool sun_flag = FALSE; if (mSun.isVisible()) { @@ -1191,7 +866,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) if (height_above_water > 0) { - BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; + bool render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; if (sun_flag) { @@ -1219,9 +894,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) return TRUE; } -BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun, - LLHeavenBody& hb, const F32 cos_max_angle, - const LLVector3 &up, const LLVector3 &right) +bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, LLHeavenBody& hb, const LLVector3 &up, const LLVector3 &right) { mHeavenlyBodyUpdated = TRUE ; @@ -1232,52 +905,28 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons S32 index_offset; LLFace *facep; - LLVector3 to_dir = hb.getDirection(); - - if (!is_sun) - { - to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f); - } + LLVector3 to_dir = hb.getDirection(); LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST; - LLVector3 hb_right = to_dir % LLVector3::z_axis; LLVector3 hb_up = hb_right % to_dir; hb_right.normalize(); hb_up.normalize(); - //const static F32 cos_max_turn = sqrt(3.f) / 2; // 30 degrees - //const F32 cos_turn_right = 1. / (llmax(cos_max_turn, hb_right * right)); - //const F32 cos_turn_up = 1. / llmax(cos_max_turn, hb_up * up); - - const F32 enlargm_factor = ( 1 - to_dir.mV[2] ); + const F32 enlargm_factor = ( 1 - to_dir.mV[2] ); F32 horiz_enlargement = 1 + enlargm_factor * 0.3f; F32 vert_enlargement = 1 + enlargm_factor * 0.2f; - // Parameters for the water reflection - hb.setU(HEAVENLY_BODY_FACTOR * horiz_enlargement * hb.getDiskRadius() * hb_right); - hb.setV(HEAVENLY_BODY_FACTOR * vert_enlargement * hb.getDiskRadius() * hb_up); - // End of parameters for the water reflection - - const LLVector3 scaled_right = HEAVENLY_BODY_DIST * hb.getU(); - const LLVector3 scaled_up = HEAVENLY_BODY_DIST * hb.getV(); + const LLVector3 scaled_right = horiz_enlargement * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_right; + const LLVector3 scaled_up = vert_enlargement * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_up; - //const LLVector3 scaled_right = horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_right;//right; - //const LLVector3 scaled_up = vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_up;//up; LLVector3 v_clipped[4]; - hb.corner(0) = draw_pos - scaled_right + scaled_up; - hb.corner(1) = draw_pos - scaled_right - scaled_up; - hb.corner(2) = draw_pos + scaled_right + scaled_up; - hb.corner(3) = draw_pos + scaled_right - scaled_up; + v_clipped[0] = draw_pos - scaled_right + scaled_up; + v_clipped[1] = draw_pos - scaled_right - scaled_up; + v_clipped[2] = draw_pos + scaled_right + scaled_up; + v_clipped[3] = draw_pos + scaled_right - scaled_up; - - F32 t_left, t_right; - if (!clip_quad_to_horizon(t_left, t_right, v_clipped, hb.corners(), cos_max_angle)) - { - hb.setVisible(FALSE); - return FALSE; - } hb.setVisible(TRUE); facep = mFace[f]; @@ -1327,164 +976,9 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons facep->getVertexBuffer()->flush(); - if (is_sun) - { - if ((t_left > 0) && (t_right > 0)) - { - F32 t = (t_left + t_right) * 0.5f; - mSun.setHorizonVisibility(0.5f * (1 + cos(t * F_PI))); - } - else - { - mSun.setHorizonVisibility(); - } - updateSunHaloGeometry(drawable); - } - - return TRUE; -} - - - - -// Clips quads with top and bottom sides parallel to horizon. - -BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4], - const LLVector3 v_corner[4], const F32 cos_max_angle) -{ - t_left = clip_side_to_horizon(v_corner[1], v_corner[0], cos_max_angle); - t_right = clip_side_to_horizon(v_corner[3], v_corner[2], cos_max_angle); - - if ((t_left >= 1) || (t_right >= 1)) - { - return FALSE; - } - - //const BOOL left_clip = (t_left > 0); - //const BOOL right_clip = (t_right > 0); - - //if (!left_clip && !right_clip) - { - for (S32 vtx = 0; vtx < 4; ++vtx) - { - v_clipped[vtx] = v_corner[vtx]; - } - } -/* else - { - v_clipped[0] = v_corner[0]; - v_clipped[1] = left_clip ? ((1 - t_left) * v_corner[1] + t_left * v_corner[0]) - : v_corner[1]; - v_clipped[2] = v_corner[2]; - v_clipped[3] = right_clip ? ((1 - t_right) * v_corner[3] + t_right * v_corner[2]) - : v_corner[3]; - }*/ - return TRUE; } - -F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos_max_angle) -{ - const LLVector3 V = V1 - V0; - const F32 k2 = 1.f/(cos_max_angle * cos_max_angle) - 1; - const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] - k2 * V.mV[2] * V.mV[2]; - const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] - k2 * V0.mV[2] * V.mV[2]; - const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] - k2 * V0.mV[2] * V0.mV[2]; - - if (fabs(A) < 1e-7) - { - return -0.1f; // v0 is cone origin and v1 is on the surface of the cone. - } - - const F32 det = sqrt(B*B - A*C); - const F32 t1 = (-B - det) / A; - const F32 t2 = (-B + det) / A; - const F32 z1 = V0.mV[2] + t1 * V.mV[2]; - const F32 z2 = V0.mV[2] + t2 * V.mV[2]; - if (z1 * cos_max_angle < 0) - { - return t2; - } - else if (z2 * cos_max_angle < 0) - { - return t1; - } - else if ((t1 < 0) || (t1 > 1)) - { - return t2; - } - else - { - return t1; - } -} - - -void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) -{ -#if 0 - const LLVector3* v_corner = mSun.corners(); - - LLStrider<LLVector3> verticesp; - LLStrider<LLVector3> normalsp; - LLStrider<LLVector2> texCoordsp; - LLStrider<U16> indicesp; - S32 index_offset; - LLFace *face; - - const LLVector3 right = 2 * (v_corner[2] - v_corner[0]); - LLVector3 up = 2 * (v_corner[2] - v_corner[3]); - up.normalize(); - F32 size = right.length(); - up = size * up; - const LLVector3 draw_pos = 0.25 * (v_corner[0] + v_corner[1] + v_corner[2] + v_corner[3]); - - LLVector3 v_glow_corner[4]; - - v_glow_corner[0] = draw_pos - right + up; - v_glow_corner[1] = draw_pos - right - up; - v_glow_corner[2] = draw_pos + right + up; - v_glow_corner[3] = draw_pos + right - up; - - face = mFace[FACE_BLOOM]; - - if (face->mVertexBuffer.isNull()) - { - face->setSize(4, 6); - face->setGeomIndex(0); - face->setIndicesIndex(0); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(4, 6, TRUE); - } - - index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); - if (-1 == index_offset) - { - return; - } - - for (S32 vtx = 0; vtx < 4; ++vtx) - { - *(verticesp++) = v_glow_corner[vtx] + mCameraPosAgent; - } - - *(texCoordsp++) = TEX01; - *(texCoordsp++) = TEX00; - *(texCoordsp++) = TEX11; - *(texCoordsp++) = TEX10; - - *indicesp++ = index_offset + 0; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 1; - - *indicesp++ = index_offset + 1; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 3; -#endif -} - - F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top, F32 sin_dir_from_top, F32 diff_angl_dir) { LLVector3 P = p; @@ -1546,9 +1040,6 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLVector3 look_at_right = look_at % LLVector3::z_axis; look_at_right.normalize(); - const static F32 cos_horizon_angle = cosHorizon(0.0f/sResolution); - //const static F32 horizon_angle = acos(cos_horizon_angle); - const F32 enlargm_factor = ( 1 - to_dir.mV[2] ); F32 horiz_enlargement = 1 + enlargm_factor * 0.3f; F32 vert_enlargement = 1 + enlargm_factor * 0.2f; @@ -1563,22 +1054,10 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - Right + Up; v_corner[1] = stretch_corner[1] = hb_pos - Right - Up; - F32 dt_hor, dt; - dt_hor = clip_side_to_horizon(v_corner[1], v_corner[0], cos_horizon_angle); - LLVector2 TEX0t = TEX00; LLVector2 TEX1t = TEX10; LLVector3 lower_corner = v_corner[1]; - if ((dt_hor > 0) && (dt_hor < 1)) - { - TEX0t = LLVector2(0, dt_hor); - TEX1t = LLVector2(1, dt_hor); - lower_corner = (1 - dt_hor) * v_corner[1] + dt_hor * v_corner[0]; - } - else - dt_hor = llmax(0.0f, llmin(1.0f, dt_hor)); - top_hb.normalize(); const F32 cos_angle_of_view = fabs(top_hb.mV[VZ]); const F32 extension = llmin (5.0f, 1.0f / cos_angle_of_view); @@ -1590,9 +1069,6 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, stretch_corner[0] = lower_corner + extension * (stretch_corner[0] - lower_corner); stretch_corner[1] = lower_corner + extension * (stretch_corner[1] - lower_corner); - dt = dt_hor; - - F32 cos_dir_from_top[2]; LLVector3 dir = stretch_corner[0]; @@ -1681,9 +1157,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, F32 dt_tex = dtReflection(P, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); - dt = dt_tex; - TEX0tt = LLVector2(0, dt); - TEX1tt = LLVector2(1, dt); + TEX0tt = LLVector2(0, dt_tex); + TEX1tt = LLVector2(1, dt_tex); quads++; } else @@ -1732,7 +1207,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, const F32 attenuation = min_attenuation + cos_angle_of_view * (max_attenuation - min_attenuation); - LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * mFogColor; + LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor(); face->setFaceColor(hb_refl_col); LLVector3 v_far[2]; @@ -1807,8 +1282,6 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, left *= raws_inv; right *= raws_inv; - F32 dt_raw = dt; - for (S32 raw = 0; raw < raws; ++raw) { F32 dt_v0 = raw * raws_inv; @@ -1817,8 +1290,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; const LLVector3 EL = BL + left; const LLVector3 ER = BR + right; - dt_v0 = dt_raw; - dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); + dt_v0 = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); for (S32 col = 0; col < cols; ++col) { F32 dt_h0 = col * cols_inv; @@ -1850,332 +1322,37 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, } } - - - void LLVOSky::updateFog(const F32 distance) { - -// LEGACY_ATMOSPHERICS - if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) - { - if (!LLGLSLShader::sNoFixedFunction) - { - glFogf(GL_FOG_DENSITY, 0); - glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); - glFogf(GL_FOG_END, 1000000.f); - } - return; - } - - const BOOL hide_clip_plane = TRUE; - LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); - - const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; - // LLWorld::getInstance()->getWaterHeight(); - F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2]; - - F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear(); - camera_height += near_clip_height; - - F32 fog_distance = 0.f; - LLColor3 res_color[3]; - - LLColor3 sky_fog_color = LLColor3::white; - LLColor3 render_fog_color = LLColor3::white; - - LLVector3 tosun = getToSunLast(); - const F32 tosun_z = tosun.mV[VZ]; - tosun.mV[VZ] = 0.f; - tosun.normalize(); - LLVector3 perp_tosun; - perp_tosun.mV[VX] = -tosun.mV[VY]; - perp_tosun.mV[VY] = tosun.mV[VX]; - LLVector3 tosun_45 = tosun + perp_tosun; - tosun_45.normalize(); - - F32 delta = 0.06f; - tosun.mV[VZ] = delta; - perp_tosun.mV[VZ] = delta; - tosun_45.mV[VZ] = delta; - tosun.normalize(); - perp_tosun.normalize(); - tosun_45.normalize(); - - // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. - res_color[0] = calcSkyColorInDir(tosun); - res_color[1] = calcSkyColorInDir(perp_tosun); - res_color[2] = calcSkyColorInDir(tosun_45); - - sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); - - F32 full_off = -0.25f; - F32 full_on = 0.00f; - F32 on = (tosun_z - full_off) / (full_on - full_off); - on = llclamp(on, 0.01f, 1.f); - sky_fog_color *= 0.5f * on; - - - // We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ??? - S32 i; - for (i = 0; i < 3; i++) - { - sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]); - } - - color_gamma_correct(sky_fog_color); - - render_fog_color = sky_fog_color; - - F32 fog_density = 0.f; - fog_distance = mFogRatio * distance; - - if (camera_height > water_height) - { - LLColor4 fog(render_fog_color); - if (!LLGLSLShader::sNoFixedFunction) - { - glFogfv(GL_FOG_COLOR, fog.mV); - } - mGLFogCol = fog; - - if (hide_clip_plane) - { - // For now, set the density to extend to the cull distance. - const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) - fog_density = f_log/fog_distance; - if (!LLGLSLShader::sNoFixedFunction) - { - glFogi(GL_FOG_MODE, GL_EXP2); - } - } - else - { - const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) - fog_density = (f_log)/fog_distance; - if (!LLGLSLShader::sNoFixedFunction) - { - glFogi(GL_FOG_MODE, GL_EXP); - } - } - } - else - { - LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); - F32 depth = water_height - camera_height; - - // get the water param manager variables - float water_fog_density = pwater->getFogDensity(); - LLColor4 water_fog_color(pwater->getFogColor()); - - // 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), - gSavedSettings.getF32("WaterGLFogDepthFloor")); - - LLColor4 fogCol = water_fog_color * depth_modifier; - fogCol.setAlpha(1); - - // set the gl fog color - mGLFogCol = fogCol; - - // set the density based on what the shaders use - fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); - - if (!LLGLSLShader::sNoFixedFunction) - { - glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); - glFogi(GL_FOG_MODE, GL_EXP2); - } - } - - mFogColor = sky_fog_color; - mFogColor.setAlpha(1); - LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f; - - if (!LLGLSLShader::sNoFixedFunction) - { - LLGLSFog gls_fog; - glFogf(GL_FOG_END, fog_distance*2.2f); - glFogf(GL_FOG_DENSITY, fog_density); - glHint(GL_FOG_HINT, GL_NICEST); - } - stop_glerror(); + LLEnvironment& environment = LLEnvironment::instance(); + LLVector3 light_dir = LLVector3(environment.getClampedLightNorm()); + m_legacyAtmospherics.updateFog(distance, light_dir); } - -// Functions used a lot. -F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply) +void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr) { - F32 mv = color_max(col); - if (0 == mv) - { - return 0; - } - - col *= 1.f / mv; - color_pow(col, e); - if (postmultiply) - { - col *= mv; - } - return mv; -} - -// Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis. -// Range of output is 0.0f to 2pi //359.99999...f -// Returns 0.0f when "v" = +/- z_axis. -F32 azimuth(const LLVector3 &v) -{ - F32 azimuth = 0.0f; - if (v.mV[VX] == 0.0f) - { - if (v.mV[VY] > 0.0f) - { - azimuth = F_PI * 0.5f; - } - else if (v.mV[VY] < 0.0f) - { - azimuth = F_PI * 1.5f;// 270.f; - } - } - else - { - azimuth = (F32) atan(v.mV[VY] / v.mV[VX]); - if (v.mV[VX] < 0.0f) - { - azimuth += F_PI; - } - else if (v.mV[VY] < 0.0f) - { - azimuth += F_PI * 2; - } - } - return azimuth; -} + mSun.setDirection(sun_dir_cfr); + mMoon.setDirection(moon_dir_cfr); -void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) -{ - LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; - sun_direction.normalize(); - mSun.setDirection(sun_direction); - mSun.renewDirection(); - mSun.setAngularVelocity(sun_ang_velocity); - mMoon.setDirection(-mSun.getDirection()); - mMoon.renewDirection(); mLastLightingDirection = mSun.getDirection(); - calcAtmospherics(); - - if ( !mInitialized ) - { - init(); - LLSkyTex::stepCurrent(); - } -} - -void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &moon_dir) -{ - LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; - sun_direction.normalize(); - // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping // on the upward facing faces of cubes. - LLVector3 newDir = sun_direction; - - // Same as dot product with the up direction + clamp. - F32 sunDot = llmax(0.f, newDir.mV[2]); - sunDot *= sunDot; - - // Create normalized vector that has the sunDir pushed south about an hour and change. - LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; - - // Blend between normal sun dir and adjusted sun dir based on how close we are - // to having the sun overhead. - mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot); - mBumpSunDir.normalize(); - - F32 dp = mLastLightingDirection * sun_direction; - mSun.setDirection(sun_direction); - - mMoon.setDirection(moon_dir); - calcAtmospherics(); - if (dp < 0.995f) { //the sun jumped a great deal, update immediately - mForceUpdate = TRUE; - } -} - -// void LLVOSky::checkAndLoadSkyTextures(LLDrawPoolWLSky *pskypool) -// { -// LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); -// -// if (mMoonCurrentId != psky->getMoonTextureId()) -// { -// mMoonCurrentId = psky->getMoonTextureId(); -// if (mMoonCurrentId.isNull()) -// { -// mMoonTexturep = NULL; -// mMoon.setDraw(FALSE); -// } -// else -// { -// mMoonTexturep = LLViewerTextureManager::getFetchedTexture(mMoonCurrentId, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -// if (mMoonTexturep) -// { -// mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); -// } -// mMoon.setDraw(TRUE); -// } -// mFace[FACE_MOON] = mDrawable->addFace(pskypool, mMoonTexturep); -// } -// -// if (mSunCurrentId != psky->getSunTextureId()) -// { -// mSunCurrentId = psky->getSunTextureId(); -// if (mSunCurrentId.isNull()) -// { -// mSunTexturep = NULL; -// mSun.setDraw(FALSE); -// } -// else -// { -// mSunTexturep = LLViewerTextureManager::getFetchedTexture(mSunCurrentId, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -// if (mSunTexturep) -// { -// mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); -// } -// mSun.setDraw(TRUE); -// } -// mFace[FACE_SUN] = mDrawable->addFace(pskypool, mSunTexturep); -// } -// } - -LLColor4U LLVOSky::getFadeColor() const -{ - return LLEnvironment::instance().getCurrentSky()->getFadeColor(); -} - -LLColor3 LLVOSky::getSunDiffuseColor() const -{ - return LLEnvironment::instance().getCurrentSky()->getSunDiffuse(); -} + { + // Same as dot product with the up direction + clamp. + F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); + sunDot *= sunDot; -LLColor3 LLVOSky::getMoonDiffuseColor() const -{ - return LLEnvironment::instance().getCurrentSky()->getMoonDiffuse(); -} + // Create normalized vector that has the sunDir pushed south about an hour and change. + LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; -LLColor4 LLVOSky::getSunAmbientColor() const -{ - return LLEnvironment::instance().getCurrentSky()->getSunAmbient(); -} + // Blend between normal sun dir and adjusted sun dir based on how close we are + // to having the sun overhead. + mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); + mBumpSunDir.normalize(); + } -LLColor4 LLVOSky::getMoonAmbientColor() const -{ - return LLEnvironment::instance().getCurrentSky()->getMoonAmbient(); -} + updateDirections(); -LLColor4 LLVOSky::getTotalAmbientColor() const -{ - return LLEnvironment::instance().getCurrentSky()->getTotalAmbient(); + LLSkyTex::stepCurrent(); } diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 2c253aed51..4de3d12068 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -35,36 +35,12 @@ #include "llframetimer.h" #include "v3colorutil.h" #include "llsettingssky.h" +#include "lllegacyatmospherics.h" -////////////////////////////////// -// -// Lots of constants -// -// Will clean these up at some point... -// - -const F32 HORIZON_DIST = 1024.0f; const F32 SKY_BOX_MULT = 16.0f; -const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 10.f; +const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 10.f; const F32 HEAVENLY_BODY_FACTOR = 0.1f; const F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR; -const F32 EARTH_RADIUS = 6.4e6f; // exact radius = 6.37 x 10^6 m -const F32 ATM_EXP_FALLOFF = 0.000126f; -const F32 ATM_SEA_LEVEL_NDENS = 2.55e25f; -// Somewhat arbitrary: -const F32 ATM_HEIGHT = 100000.f; - -const F32 FIRST_STEP = 5000.f; -const F32 INV_FIRST_STEP = 1.f/FIRST_STEP; -const S32 NO_STEPS = 15; -const F32 INV_NO_STEPS = 1.f/NO_STEPS; - - -// constants used in calculation of scattering coeff of clear air -const F32 sigma = 0.035f; -const F32 fsigma = (6.f + 3.f * sigma) / (6.f-7.f*sigma); -const F64 Ndens = 2.55e25; -const F64 Ndens2 = Ndens*Ndens; // HACK: Allow server to change sun and moon IDs. // I can't figure out how to pass the appropriate @@ -72,25 +48,9 @@ const F64 Ndens2 = Ndens*Ndens; extern LLUUID gSunTextureID; extern LLUUID gMoonTextureID; - -LL_FORCE_INLINE LLColor3 color_div(const LLColor3 &col1, const LLColor3 &col2) -{ - return LLColor3( - col1.mV[0] / col2.mV[0], - col1.mV[1] / col2.mV[1], - col1.mV[2] / col2.mV[2] ); -} - -LLColor3 color_norm(const LLColor3 &col); -BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4], - const LLVector3 v_corner[4], const F32 cos_max_angle); -F32 clip_side_to_horizon(const LLVector3& v0, const LLVector3& v1, const F32 cos_max_angle); - - class LLFace; class LLHaze; - class LLSkyTex { friend class LLVOSky; @@ -181,229 +141,63 @@ protected: LLVector3 mAngularVelocity; // velocity of the local heavenly body F32 mDiskRadius; - BOOL mDraw; // FALSE - do not draw. + bool mDraw; // FALSE - do not draw. F32 mHorizonVisibility; // number [0, 1] due to how horizon F32 mVisibility; // same but due to other objects being in throng. - BOOL mVisible; + bool mVisible; static F32 sInterpVal; LLVector3 mQuadCorner[4]; - LLVector3 mU; - LLVector3 mV; LLVector3 mO; public: - LLHeavenBody(const F32 rad) : - mDirectionCached(LLVector3(0,0,0)), - mDirection(LLVector3(0,0,0)), - mIntensity(0.f), - mDiskRadius(rad), mDraw(FALSE), - mHorizonVisibility(1.f), mVisibility(1.f), - mVisible(FALSE) - { - mColor.setToBlack(); - mColorCached.setToBlack(); - } + LLHeavenBody(const F32 rad); ~LLHeavenBody() {} - const LLVector3& getDirection() const { return mDirection; } - void setDirection(const LLVector3 &direction) { mDirection = direction; } - void setAngularVelocity(const LLVector3 &ang_vel) { mAngularVelocity = ang_vel; } - const LLVector3& getAngularVelocity() const { return mAngularVelocity; } - - const LLVector3& getDirectionCached() const { return mDirectionCached; } - void renewDirection() { mDirectionCached = mDirection; } - - const LLColor3& getColorCached() const { return mColorCached; } - void setColorCached(const LLColor3& c) { mColorCached = c; } - const LLColor3& getColor() const { return mColor; } - void setColor(const LLColor3& c) { mColor = c; } - - void renewColor() { mColorCached = mColor; } - - static F32 interpVal() { return sInterpVal; } - static void setInterpVal(const F32 v) { sInterpVal = v; } - - LLColor3 getInterpColor() const - { - return sInterpVal * mColor + (1 - sInterpVal) * mColorCached; - } - - const F32& getHorizonVisibility() const { return mHorizonVisibility; } - void setHorizonVisibility(const F32 c = 1) { mHorizonVisibility = c; } - const F32& getVisibility() const { return mVisibility; } - void setVisibility(const F32 c = 1) { mVisibility = c; } - F32 getHaloBrighness() const - { - return llmax(0.f, llmin(0.9f, mHorizonVisibility)) * mVisibility; - } - BOOL isVisible() const { return mVisible; } - void setVisible(const BOOL v) { mVisible = v; } - - const F32& getIntensity() const { return mIntensity; } - void setIntensity(const F32 c) { mIntensity = c; } - - void setDiskRadius(const F32 radius) { mDiskRadius = radius; } - F32 getDiskRadius() const { return mDiskRadius; } - - void setDraw(const BOOL draw) { mDraw = draw; } - BOOL getDraw() const { return mDraw; } - - const LLVector3& corner(const S32 n) const { return mQuadCorner[n]; } - LLVector3& corner(const S32 n) { return mQuadCorner[n]; } - const LLVector3* corners() const { return mQuadCorner; } - - const LLVector3& getU() const { return mU; } - const LLVector3& getV() const { return mV; } - void setU(const LLVector3& u) { mU = u; } - void setV(const LLVector3& v) { mV = v; } -}; - - -LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length) -{ - LLColor3 refr_ind; - for (S32 i = 0; i < 3; ++i) - { - const F32 wl2 = wave_length.mV[i] * wave_length.mV[i] * 1e-6f; - refr_ind.mV[i] = 6.43e3f + ( 2.95e6f / ( 146.0f - 1.f/wl2 ) ) + ( 2.55e4f / ( 41.0f - 1.f/wl2 ) ); - refr_ind.mV[i] *= 1.0e-8f; - refr_ind.mV[i] += 1.f; - } - return refr_ind; -} - - -class LLHaze -{ -public: - LLHaze() : mG(0), mFalloff(1), mAbsCoef(0.f) {mSigSca.setToBlack();} - LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) : - mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f) - { - mAbsCoef = color_intens(mSigSca) / sAirScaIntense; - } - - LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g), - mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo) - { - mAbsCoef = 0.01f * sca / sAirScaAvg; - } - - F32 getG() const { return mG; } - - void setG(const F32 g) - { - mG = g; - } - - const LLColor3& getSigSca() const // sea level - { - return mSigSca; - } - - void setSigSca(const LLColor3& s) - { - mSigSca = s; - mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense; - } + const LLVector3& getDirection() const; + void setDirection(const LLVector3 &direction); + void setAngularVelocity(const LLVector3 &ang_vel); + const LLVector3& getAngularVelocity() const; - void setSigSca(const F32 s0, const F32 s1, const F32 s2) - { - mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2); - mAbsCoef = 0.01f * (s0 + s1 + s2) / 3; - } - - F32 getFalloff() const - { - return mFalloff; - } + const LLVector3& getDirectionCached() const; + void renewDirection(); - void setFalloff(const F32 fo) - { - mFalloff = fo; - } + const LLColor3& getColorCached() const; + void setColorCached(const LLColor3& c); + const LLColor3& getColor() const; + void setColor(const LLColor3& c); - F32 getAbsCoef() const - { - return mAbsCoef; - } + void renewColor(); - inline static F32 calcFalloff(const F32 h) - { - return (h <= 0) ? 1.0f : (F32)LL_FAST_EXP(-ATM_EXP_FALLOFF * h); - } + static F32 interpVal(); + static void setInterpVal(const F32 v); - inline LLColor3 calcSigSca(const F32 h) const - { - return calcFalloff(h * mFalloff) * mSigSca; - } + LLColor3 getInterpColor() const; - inline void calcSigSca(const F32 h, LLColor3 &result) const - { - result = mSigSca; - result *= calcFalloff(h * mFalloff); - } + const F32& getVisibility() const; + void setVisibility(const F32 c = 1); - LLColor3 calcSigExt(const F32 h) const - { - return calcFalloff(h * mFalloff) * (1 + mAbsCoef) * mSigSca; - } + bool isVisible() const; + void setVisible(const bool v); - F32 calcPhase(const F32 cos_theta) const; + const F32& getIntensity() const; + void setIntensity(const F32 c); - static inline LLColor3 calcAirSca(const F32 h); - static inline void calcAirSca(const F32 h, LLColor3 &result); + void setDiskRadius(const F32 radius); + F32 getDiskRadius() const; -private: - static LLColor3 const sAirScaSeaLevel; - static F32 const sAirScaIntense; - static F32 const sAirScaAvg; + void setDraw(const bool draw); + bool getDraw() const; -protected: - F32 mG; - LLColor3 mSigSca; - F32 mFalloff; // 1 - slow, >1 - faster - F32 mAbsCoef; + const LLVector3& corner(const S32 n) const; + LLVector3& corner(const S32 n); + const LLVector3* corners() const; }; - class LLCubeMap; -// turn on floating point precision -// in vs2003 for this class. Otherwise -// black dots go everywhere from 7:10 - 8:50 -#if LL_MSVC && __MSVC_VER__ < 8 -#pragma optimize("p", on) -#endif - - class LLVOSky : public LLStaticViewerObject { - -public: - void calcAtmospherics(void); - -// LEGACY_ATMOSPHERICS - LLColor3 createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient); - LLColor3 createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient); - - void calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, - LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, - LLVector2 vary_HorizontalProjection[2]); - - LLColor3 calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, - LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, - LLVector2 vary_HorizontalProjection[2]); - LLColor4 calcSkyColorInDir(const LLVector3& dir, bool isShiny = false); - - LLColor3 calcRadianceAtPoint(const LLVector3& pos) const - { - F32 radiance = mBrightnessScaleGuess * mSun.getIntensity(); - return LLColor3(radiance, radiance, radiance); - } - void initSkyTextureDirs(const S32 side, const S32 tile); - void createSkyTexture(const S32 side, const S32 tile); - +public: enum { FACE_SIDE0, @@ -416,7 +210,6 @@ public: FACE_MOON, // was 7 FACE_BLOOM, // was 8 FACE_REFLECTION, // was 10 - FACE_DUMMY, //for an ATI bug --bao FACE_COUNT }; @@ -431,7 +224,7 @@ public: void restoreGL(); /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time); - BOOL updateSky(); + bool updateSky(); // Graphical stuff for objects - maybe broken out into render class // later? @@ -439,53 +232,29 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - const LLHeavenBody& getSun() const { return mSun; } + const LLHeavenBody& getSun() const { return mSun; } const LLHeavenBody& getMoon() const { return mMoon; } - const LLVector3& getToSunLast() const { return mSun.getDirectionCached(); } - const LLVector3& getToSun() const { return mSun.getDirection(); } - const LLVector3& getToMoon() const { return mMoon.getDirection(); } - const LLVector3& getToMoonLast() const { return mMoon.getDirectionCached(); } - BOOL isSunUp() const { return mSun.getDirectionCached().mV[2] > -0.05f; } - - LLColor3 getSunDiffuseColor() const; - LLColor3 getMoonDiffuseColor() const; - LLColor4 getSunAmbientColor() const; - LLColor4 getMoonAmbientColor() const; - LLColor4 getTotalAmbientColor() const; - LLColor4 getFogColor() const { return mFogColor; } - LLColor4 getGLFogColor() const { return mGLFogCol; } - - BOOL isSameFace(S32 idx, const LLFace* face) const { return mFace[idx] == face; } - - void initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity); + bool isSameFace(S32 idx, const LLFace* face) const { return mFace[idx] == face; } - void setSunDirection(const LLVector3 &sun_dir, const LLVector3 &moon_dir); + // directions provided should already be in CFR coord sys (+x at, +z up, +y right) + void setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir, const LLVector3 &moon_dir); - BOOL updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 side, const BOOL is_sun, - LLHeavenBody& hb, const F32 sin_max_angle, - const LLVector3 &up, const LLVector3 &right); - - F32 cosHorizon(const F32 delta = 0) const - { - const F32 sin_angle = EARTH_RADIUS/(EARTH_RADIUS + mCameraPosAgent.mV[2]); - return delta - (F32)sqrt(1.f - sin_angle * sin_angle); - } - - void updateSunHaloGeometry(LLDrawable *drawable); + bool updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 side, LLHeavenBody& hb, const LLVector3 &up, const LLVector3 &right); void updateReflectionGeometry(LLDrawable *drawable, F32 H, const LLHeavenBody& HB); - - const LLHaze& getHaze() const { return mHaze; } - LLHaze& getHaze() { return mHaze; } - F32 getHazeConcentration() const { return mHazeConcentration; } - void setHaze(const LLHaze& h) { mHaze = h; } F32 getWorldScale() const { return mWorldScale; } void setWorldScale(const F32 s) { mWorldScale = s; } void updateFog(const F32 distance); - void setFogRatio(const F32 fog_ratio) { mFogRatio = fog_ratio; } + + void setFogRatio(const F32 fog_ratio) { m_legacyAtmospherics.setFogRatio(fog_ratio); } + F32 getFogRatio() const { return m_legacyAtmospherics.getFogRatio(); } + + LLColor4 getSkyFogColor() const { return m_legacyAtmospherics.getFogColor(); } + LLColor4 getGLFogColor() const { return m_legacyAtmospherics.getGLFogColor(); } + LLColor4U getFadeColor() const; - F32 getFogRatio() const { return mFogRatio; } + void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; } void setWind ( const LLVector3& wind ) { mWind = wind.length(); } @@ -495,7 +264,7 @@ public: LLCubeMap *getCubeMap() const { return mCubeMap; } S32 getDrawRefl() const { return mDrawRefl; } void setDrawRefl(const S32 r) { mDrawRefl = r; } - BOOL isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; } + bool isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; } LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; } LLViewerTexture* getSunTex() const { return mSunTexturep; } @@ -510,6 +279,11 @@ public: protected: ~LLVOSky(); + void updateDirections(void); + + void initSkyTextureDirs(const S32 side, const S32 tile); + void createSkyTexture(const S32 side, const S32 tile); + LLPointer<LLViewerFetchedTexture> mSunTexturep; LLPointer<LLViewerFetchedTexture> mMoonTexturep; LLPointer<LLViewerFetchedTexture> mBloomTexturep; @@ -532,66 +306,27 @@ protected: LLColor3 mBrightestPointNew; F32 mBrightnessScaleGuess; LLColor3 mBrightestPointGuess; - LLHaze mHaze; - F32 mHazeConcentration; - BOOL mWeatherChange; + bool mWeatherChange; F32 mCloudDensity; F32 mWind; - BOOL mInitialized; - BOOL mForceUpdate; //flag to force instantaneous update of cubemap + bool mInitialized; + bool mForceUpdate; //flag to force instantaneous update of cubemap LLVector3 mLastLightingDirection; LLColor3 mLastTotalAmbient; F32 mAmbientScale; LLColor3 mNightColorShift; F32 mInterpVal; - - LLColor4 mFogColor; - LLColor4 mGLFogCol; - - F32 mFogRatio; F32 mWorldScale; - LLPointer<LLCubeMap> mCubeMap; // Cube map for the environment - S32 mDrawRefl; + LLPointer<LLCubeMap> mCubeMap; // Cube map for the environment + S32 mDrawRefl; LLFrameTimer mUpdateTimer; -public: - //by bao - //fake vertex buffer updating - //to guarantee at least updating one VBO buffer every frame - //to work around the bug caused by ATI card --> DEV-3855 - // - void createDummyVertexBuffer() ; - void updateDummyVertexBuffer() ; - - BOOL mHeavenlyBodyUpdated ; -}; - -// turn it off -#if LL_MSVC && __MSVC_VER__ < 8 -#pragma optimize("p", off) -#endif - -// Utility functions -F32 azimuth(const LLVector3 &v); -F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE); - - -/* Proportion of light that is scattered into 'path' from 'in' over distance dt. */ -/* assumes that vectors 'path' and 'in' are normalized. Scattering coef / 2pi */ - -inline LLColor3 LLHaze::calcAirSca(const F32 h) -{ - return calcFalloff(h) * sAirScaSeaLevel; -} - -inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result) -{ - result = sAirScaSeaLevel; - result *= calcFalloff(h); -} + bool mHeavenlyBodyUpdated ; + LLAtmospherics m_legacyAtmospherics; +}; #endif diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 0062eb5edd..bdef2ed9fb 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -36,7 +36,6 @@ #include "llenvironment.h" #include "llsettingssky.h" -#define DOME_SLICES 1 const F32 LLVOWLSky::DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f; const U32 LLVOWLSky::MIN_SKY_DETAIL = 3; @@ -88,11 +87,6 @@ LLVOWLSky::LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regi initStars(); } -void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction, - LLVector3 const & sun_angular_velocity) -{ -} - void LLVOWLSky::idleUpdate(LLAgent &agent, const F64 &time) { @@ -131,167 +125,22 @@ inline F32 LLVOWLSky::calcPhi(U32 i) return (F_PI / 8.f) * t; } -#if !DOME_SLICES -static const F32 Q = (1.f + sqrtf(5.f))/2.f; //golden ratio - -//icosahedron verts (based on asset b0c7b76e-28c6-1f87-a1de-752d5e3cd264, contact Runitai Linden for a copy) -static const LLVector3 icosahedron_vert[] = -{ - LLVector3(0,1.f,Q), - LLVector3(0,-1.f,Q), - LLVector3(0,-1.f,-Q), - LLVector3(0,1.f,-Q), - - LLVector3(Q,0,1.f), - LLVector3(-Q,0,1.f), - LLVector3(-Q,0,-1.f), - LLVector3(Q,0,-1.f), - - LLVector3(1,-Q,0.f), - LLVector3(-1,-Q,0.f), - LLVector3(-1,Q,0.f), - LLVector3(1,Q,0.f), -}; - -//indices -static const U32 icosahedron_ind[] = -{ - 5,0,1, - 10,0,5, - 5,1,9, - 10,5,6, - 6,5,9, - 11,0,10, - 3,11,10, - 3,10,6, - 3,6,2, - 7,3,2, - 8,7,2, - 4,7,8, - 1,4,8, - 9,8,2, - 9,2,6, - 11,3,7, - 4,0,11, - 4,11,7, - 1,0,4, - 1,8,9, -}; - - -//split every triangle in LLVertexBuffer into even fourths (assumes index triangle lists) -void subdivide(LLVertexBuffer& in, LLVertexBuffer* ret) -{ - S32 tri_in = in.getNumIndices()/3; - - ret->allocateBuffer(tri_in*4*3, tri_in*4*3, TRUE); - - LLStrider<LLVector3> vin, vout; - LLStrider<U16> indin, indout; - - ret->getVertexStrider(vout); - in.getVertexStrider(vin); - - ret->getIndexStrider(indout); - in.getIndexStrider(indin); - - - for (S32 i = 0; i < tri_in; i++) - { - LLVector3 v0 = vin[*indin++]; - LLVector3 v1 = vin[*indin++]; - LLVector3 v2 = vin[*indin++]; - - LLVector3 v3 = (v0 + v1) * 0.5f; - LLVector3 v4 = (v1 + v2) * 0.5f; - LLVector3 v5 = (v2 + v0) * 0.5f; - - *vout++ = v0; - *vout++ = v3; - *vout++ = v5; - - *vout++ = v3; - *vout++ = v4; - *vout++ = v5; - - *vout++ = v3; - *vout++ = v1; - *vout++ = v4; - - *vout++ = v5; - *vout++ = v4; - *vout++ = v2; - } - - for (S32 i = 0; i < ret->getNumIndices(); i++) - { - *indout++ = i; - } - -} - -void chop(LLVertexBuffer& in, LLVertexBuffer* out) -{ - //chop off all triangles below horizon - F32 d = LLEnvironment::instance().getCamHeight(); - - std::vector<LLVector3> vert; - - LLStrider<LLVector3> vin; - LLStrider<U16> index; - - in.getVertexStrider(vin); - in.getIndexStrider(index); - - U32 tri_count = in.getNumIndices()/3; - for (U32 i = 0; i < tri_count; i++) - { - LLVector3 &v1 = vin[index[i*3+0]]; - LLVector3 &v2 = vin[index[i*3+1]]; - LLVector3 &v3 = vin[index[i*3+2]]; - - if (v1.mV[1] > d || - v2.mV[1] > d || - v3.mV[1] > d) - { - v1.mV[1] = llmax(v1.mV[1], d); - v2.mV[1] = llmax(v1.mV[1], d); - v3.mV[1] = llmax(v1.mV[1], d); - - vert.push_back(v1); - vert.push_back(v2); - vert.push_back(v3); - } - } - - out->allocateBuffer(vert.size(), vert.size(), TRUE); - - LLStrider<LLVector3> vout; - out->getVertexStrider(vout); - out->getIndexStrider(index); - - for (U32 i = 0; i < vert.size(); i++) - { - *vout++ = vert[i]; - *index++ = i; - } -} -#endif // !DOME_SLICES - void LLVOWLSky::resetVertexBuffers() { - mFanVerts = NULL; + mFanVerts = nullptr; mStripsVerts.clear(); - mStarsVerts = NULL; + mStarsVerts = nullptr; + mFsSkyVerts = nullptr; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } void LLVOWLSky::cleanupGL() { - mFanVerts = NULL; + mFanVerts = nullptr; mStripsVerts.clear(); - mStarsVerts = NULL; + mStarsVerts = nullptr; + mFsSkyVerts = nullptr; LLDrawPoolWLSky::cleanupGL(); } @@ -306,12 +155,54 @@ static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Windlight Sky Geometry"); BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { - LL_RECORD_BLOCK_TIME(FTM_GEO_SKY); + LL_RECORD_BLOCK_TIME(FTM_GEO_SKY); LLStrider<LLVector3> vertices; LLStrider<LLVector2> texCoords; LLStrider<U16> indices; -#if DOME_SLICES + if (gPipeline.useAdvancedAtmospherics()) + { + if (mFsSkyVerts.isNull()) + { + mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + + if (!mFsSkyVerts->allocateBuffer(4, 6, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL; + } + + BOOL success = mFsSkyVerts->getVertexStrider(vertices) + && mFsSkyVerts->getTexCoord0Strider(texCoords) + && mFsSkyVerts->getIndexStrider(indices); + + if(!success) + { + LL_ERRS() << "Failed updating WindLight fullscreen sky geometry." << LL_ENDL; + } + + *vertices++ = LLVector3(-1.0f, -1.0f, 0.0f); + *vertices++ = LLVector3( 1.0f, -1.0f, 0.0f); + *vertices++ = LLVector3(-1.0f, 1.0f, 0.0f); + *vertices++ = LLVector3( 1.0f, 1.0f, 0.0f); + + *texCoords++ = LLVector2(0.0f, 0.0f); + *texCoords++ = LLVector2(1.0f, 0.0f); + *texCoords++ = LLVector2(0.0f, 1.0f); + *texCoords++ = LLVector2(1.0f, 1.0f); + + *indices++ = 0; + *indices++ = 1; + *indices++ = 2; + *indices++ = 1; + *indices++ = 3; + *indices++ = 2; + + mFsSkyVerts->flush(); + } + + return TRUE; + } + { mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); if (!mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE)) @@ -407,85 +298,6 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) LL_INFOS() << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << LL_ENDL; } -#else - mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - - const F32 RADIUS = LLEnvironment::getCurrentSky()->getDomeRadius(); - - LLPointer<LLVertexBuffer> temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); - temp->allocateBuffer(12, 60, TRUE); - - BOOL success = temp->getVertexStrider(vertices) - && temp->getIndexStrider(indices); - - if (success) - { - for (U32 i = 0; i < 12; i++) - { - *vertices++ = icosahedron_vert[i]; - } - - for (U32 i = 0; i < 60; i++) - { - *indices++ = icosahedron_ind[i]; - } - } - - - LLPointer<LLVertexBuffer> temp2; - - for (U32 i = 0; i < 8; i++) - { - temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); - subdivide(*temp, temp2); - temp = temp2; - } - - temp->getVertexStrider(vertices); - for (S32 i = 0; i < temp->getNumVerts(); i++) - { - LLVector3 v = vertices[i]; - v.normVec(); - vertices[i] = v*RADIUS; - } - - temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); - chop(*temp, temp2); - - mStripsVerts->allocateBuffer(temp2->getNumVerts(), temp2->getNumIndices(), TRUE); - - success = mStripsVerts->getVertexStrider(vertices) - && mStripsVerts->getTexCoordStrider(texCoords) - && mStripsVerts->getIndexStrider(indices); - - LLStrider<LLVector3> v; - temp2->getVertexStrider(v); - LLStrider<U16> ind; - temp2->getIndexStrider(ind); - - if (success) - { - for (S32 i = 0; i < temp2->getNumVerts(); ++i) - { - LLVector3 vert = *v++; - vert.normVec(); - F32 z0 = vert.mV[2]; - F32 x0 = vert.mV[0]; - - vert *= RADIUS; - - *vertices++ = vert; - *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f); - } - - for (S32 i = 0; i < temp2->getNumIndices(); ++i) - { - *indices++ = *ind++; - } - } - - mStripsVerts->flush(); -#endif updateStarColors(); updateStarGeometry(drawable); @@ -505,6 +317,23 @@ void LLVOWLSky::drawStars(void) } } +void LLVOWLSky::drawFsSky(void) +{ + if (mFsSkyVerts.isNull()) + { + updateGeometry(mDrawable); + } + + //LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE, GL_ALWAYS); + LLGLDisable disable_blend(GL_BLEND); + + mFsSkyVerts->setBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK); + mFsSkyVerts->drawRange(LLRender::TRIANGLES, 0, mFsSkyVerts->getNumVerts() - 1, mFsSkyVerts->getNumIndices(), 0); + gPipeline.addTrianglesDrawn(mFsSkyVerts->getNumIndices(), LLRender::TRIANGLES); + LLVertexBuffer::unbind(); +} + void LLVOWLSky::drawDome(void) { if (mStripsVerts.empty()) @@ -516,7 +345,6 @@ void LLVOWLSky::drawDome(void) const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; -#if DOME_SLICES std::vector< LLPointer<LLVertexBuffer> >::const_iterator strips_vbo_iter, end_strips; end_strips = mStripsVerts.end(); for(strips_vbo_iter = mStripsVerts.begin(); strips_vbo_iter != end_strips; ++strips_vbo_iter) @@ -532,16 +360,6 @@ void LLVOWLSky::drawDome(void) gPipeline.addTrianglesDrawn(strips_segment->getNumIndices(), LLRender::TRIANGLE_STRIP); } -#else - mStripsVerts->setBuffer(data_mask); - gGL.syncMatrices(); - glDrawRangeElements( - GL_TRIANGLES, - 0, mStripsVerts->getNumVerts()-1, mStripsVerts->getNumIndices(), - GL_UNSIGNED_SHORT, - mStripsVerts->getIndicesPointer()); -#endif - LLVertexBuffer::unbind(); } diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h index 1d419b5fea..3c801d5d57 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -50,9 +50,6 @@ private: public: LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - void initSunDirection(LLVector3 const & sun_direction, - LLVector3 const & sun_angular_velocity); - /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time); /*virtual*/ BOOL isActive(void) const; /*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline); @@ -60,6 +57,7 @@ public: void drawStars(void); void drawDome(void); + void drawFsSky(void); // fullscreen sky for advanced atmo void resetVertexBuffers(void); void cleanupGL(); @@ -93,6 +91,8 @@ private: BOOL updateStarGeometry(LLDrawable *drawable); private: + LLPointer<LLVertexBuffer> mFsSkyVerts; + LLPointer<LLVertexBuffer> mFanVerts; std::vector< LLPointer<LLVertexBuffer> > mStripsVerts; LLPointer<LLVertexBuffer> mStarsVerts; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index a3c15442ad..e80b5cc9ef 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -116,6 +116,8 @@ #include "llenvironment.h" +#pragma optimize("", off) + #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 //#define DEBUG_INDICES @@ -298,62 +300,6 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size); U32 nhpo2(U32 v); LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage); -glh::matrix4f glh_copy_matrix(F32* src) -{ - glh::matrix4f ret; - ret.set_value(src); - return ret; -} - -glh::matrix4f glh_get_current_modelview() -{ - return glh_copy_matrix(gGLModelView); -} - -glh::matrix4f glh_get_current_projection() -{ - return glh_copy_matrix(gGLProjection); -} - -glh::matrix4f glh_get_last_modelview() -{ - return glh_copy_matrix(gGLLastModelView); -} - -glh::matrix4f glh_get_last_projection() -{ - return glh_copy_matrix(gGLLastProjection); -} - -void glh_copy_matrix(const glh::matrix4f& src, F32* dst) -{ - for (U32 i = 0; i < 16; i++) - { - dst[i] = src.m[i]; - } -} - -void glh_set_current_modelview(const glh::matrix4f& mat) -{ - glh_copy_matrix(mat, gGLModelView); -} - -void glh_set_current_projection(glh::matrix4f& mat) -{ - glh_copy_matrix(mat, gGLProjection); -} - -glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) -{ - glh::matrix4f ret( - 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), - 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), - 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), - 0.f, 0.f, 0.f, 1.f); - - return ret; -} - void display_update_camera(); //---------------------------------------- @@ -983,7 +929,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) for (U32 i = 0; i < 4; i++) { if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; - if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; + if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; } } else @@ -1445,9 +1391,9 @@ bool LLPipeline::canUseVertexShaders() bool LLPipeline::canUseWindLightShaders() const { - return (!LLPipeline::sDisableShaders && - gWLSkyProgram.mProgramObject != 0 && - LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); + bool usingWindlight = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1; + bool haveShaders = ((gWLSkyProgram.mProgramObject != 0) || (gDeferredWLSkyProgram.mProgramObject != 0)); + return (!LLPipeline::sDisableShaders && haveShaders && usingWindlight); } bool LLPipeline::canUseWindLightShadersOnObjects() const @@ -2201,7 +2147,7 @@ void check_references(LLSpatialGroup* group, LLFace* face) void LLPipeline::checkReferences(LLFace* face) { -#if 0 +#if CHECK_PIPELINE_REFERENCES if (sCull) { for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) @@ -2233,7 +2179,7 @@ void LLPipeline::checkReferences(LLFace* face) void LLPipeline::checkReferences(LLDrawable* drawable) { -#if 0 +#if CHECK_PIPELINE_REFERENCES if (sCull) { for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) @@ -2284,7 +2230,7 @@ void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) void LLPipeline::checkReferences(LLDrawInfo* draw_info) { -#if 0 +#if CHECK_PIPELINE_REFERENCES if (sCull) { for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) @@ -2310,7 +2256,7 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info) void LLPipeline::checkReferences(LLSpatialGroup* group) { -#if 0 +#if CHECK_PIPELINE_REFERENCES if (sCull) { for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) @@ -2483,8 +2429,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } } - glh::matrix4f modelview = glh_get_last_modelview(); - glh::matrix4f proj = glh_get_last_projection(); + glh::matrix4f modelview = get_last_modelview(); + glh::matrix4f proj = get_last_projection(); LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -6075,8 +6021,9 @@ void LLPipeline::setupAvatarLights(bool for_edit) } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) { - LLVector3 opposite_pos = -1.f * mSunDir; - LLVector3 orthog_light_pos = mSunDir % LLVector3::z_axis; + LLVector3 sun_dir = LLVector3(mSunDir); + LLVector3 opposite_pos = -sun_dir; + LLVector3 orthog_light_pos = sun_dir % LLVector3::z_axis; LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); backlight_pos.normalize(); @@ -6091,7 +6038,7 @@ void LLPipeline::setupAvatarLights(bool for_edit) } } F32 backlight_mag; - if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) + if (LLEnvironment::instance().getIsSunUp()) { backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; } @@ -6300,25 +6247,29 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) { assertInitialized(); + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsSky::ptr_t psky = environment.getCurrentSky(); + // Ambient if (!LLGLSLShader::sNoFixedFunction) { gGL.syncMatrices(); - LLColor4 ambient = gSky.getTotalAmbientColor(); + LLColor4 ambient = psky->getTotalAmbient(); gGL.setAmbientLightColor(ambient); } // Light 0 = Sun or Moon (All objects) { - if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) - { - mSunDir.setVec(gSky.getSunDirection()); - mSunDiffuse.setVec(gSky.getSunDiffuseColor()); + LLVector4 light_dir = environment.getLightDirectionCFR(); + mSunDir.setVec(light_dir); + + if (environment.getIsSunUp()) + { + mSunDiffuse.setVec(psky->getSunDiffuse()); } else { - mSunDir.setVec(gSky.getMoonDirection()); - mSunDiffuse.setVec(gSky.getMoonDiffuseColor()); + mSunDiffuse.setVec(psky->getMoonDiffuse()); } F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); @@ -6328,20 +6279,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) } mSunDiffuse.clamp(); - LLVector4 light_pos(mSunDir, 0.0f); LLColor4 light_diffuse = mSunDiffuse; - if (LLPipeline::sRenderDeferred) - { - /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f); - light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f); - light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/ - } - mHWLightColors[0] = light_diffuse; LLLightState* light = gGL.getLight(0); - light->setPosition(light_pos); + light->setPosition(mSunDir); light->setDiffuse(light_diffuse); light->setAmbient(LLColor4::black); light->setSpecular(LLColor4::black); @@ -6560,7 +6503,7 @@ void LLPipeline::enableLights(U32 mask) mLightMask = mask; stop_glerror(); - LLColor4 ambient = gSky.getTotalAmbientColor(); + LLColor4 ambient = LLEnvironment::instance().getCurrentSky()->getTotalAmbient(); gGL.setAmbientLightColor(ambient); } } @@ -8270,7 +8213,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n stop_glerror(); - glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f projection = get_current_projection(); glh::matrix4f inv_proj = projection.inverse(); shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); @@ -8444,7 +8387,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) { - glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); + glh::matrix4f norm_mat = get_current_modelview().inverse().transpose(); shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); } } @@ -8514,7 +8457,7 @@ void LLPipeline::renderDeferredLighting() LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); - glh::matrix4f mat = glh_copy_matrix(gGLModelView); + glh::matrix4f mat = copy_matrix(gGLModelView); LLStrider<LLVector3> vert; mDeferredVB->getVertexStrider(vert); @@ -8525,8 +8468,7 @@ void LLPipeline::renderDeferredLighting() { setupHWLights(NULL); //to set mSunDir; - LLVector4 dir(mSunDir, 0.f); - glh::vec4f tc(dir.mV); + glh::vec4f tc(mSunDir.mV); mat.mult_matrix_vec(tc); mTransformedSunDir.set(tc.v); } @@ -8548,7 +8490,7 @@ void LLPipeline::renderDeferredLighting() mDeferredLight.clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); const U32 slice = 32; F32 offset[slice*3]; @@ -9128,7 +9070,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); - glh::matrix4f mat = glh_copy_matrix(gGLModelView); + glh::matrix4f mat = copy_matrix(gGLModelView); LLStrider<LLVector3> vert; mDeferredVB->getVertexStrider(vert); @@ -9139,8 +9081,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) { setupHWLights(NULL); //to set mSunDir; - LLVector4 dir(mSunDir, 0.f); - glh::vec4f tc(dir.mV); + glh::vec4f tc(mSunDir.mV); mat.mult_matrix_vec(tc); mTransformedSunDir.set(tc.v); } @@ -9162,7 +9103,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) mDeferredLight.clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); const U32 slice = 32; F32 offset[slice*3]; @@ -9181,7 +9122,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) } } -// pretty sure this doesn't work as expected since the shaders using 'shadow_ofset' all declare it as a single uniform float, no array or vec +// pretty sure this doesn't work as expected since the shaders using 'shadow_offset' all declare it as a single uniform float, no array or vec gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset); gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); @@ -9651,7 +9592,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); - glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; + glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent; glh::matrix4f screen_to_light = light_to_screen.inverse(); @@ -9838,7 +9779,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); - glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f projection = get_current_projection(); glh::matrix4f mat; stop_glerror(); @@ -9899,11 +9840,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) mat.set_scale(glh::vec3f(1,1,-1)); mat.set_translate(glh::vec3f(0,0,height*2.f)); - glh::matrix4f current = glh_get_current_modelview(); + glh::matrix4f current = get_current_modelview(); mat = current * mat; - glh_set_current_modelview(mat); + set_current_modelview(mat); gGL.loadMatrix(mat.m); LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); @@ -10014,7 +9955,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_BACK); gGL.popMatrix(); mWaterRef.flush(); - glh_set_current_modelview(current); + set_current_modelview(current); LLPipeline::sUseOcclusion = occlusion; } @@ -10044,7 +9985,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLColor3 col = LLEnvironment::instance().getCurrentWater()->getFogColor(); + LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; @@ -10054,7 +9995,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) { //clip out geometry on the same side of water as the camera - mat = glh_get_current_modelview(); + mat = get_current_modelview(); LLPlane plane(-pnorm, -(pd+pad)); LLGLUserClipPlane clip_plane(plane, mat, projection); @@ -10687,8 +10628,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //get sun view matrix //store current projection/modelview matrix - glh::matrix4f saved_proj = glh_get_current_projection(); - glh::matrix4f saved_view = glh_get_current_modelview(); + glh::matrix4f saved_proj = get_current_projection(); + glh::matrix4f saved_view = get_current_modelview(); glh::matrix4f inv_view = saved_view.inverse(); glh::matrix4f view[6]; @@ -10709,15 +10650,17 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //LLVector3 n = RenderShadowNearDist; //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + LLVector3 sun_dir(mSunDir); + //put together a universal "near clip" plane for shadow frusta LLPlane shadow_near_clip; - { + { LLVector3 p = gAgent.getPositionAgent(); - p += mSunDir * RenderFarClip*2.f; - shadow_near_clip.setVec(p, mSunDir); + p += sun_dir * RenderFarClip*2.f; + shadow_near_clip.setVec(p, sun_dir); } - LLVector3 lightDir = -mSunDir; + LLVector3 lightDir = -sun_dir; lightDir.normVec(); glh::vec3f light_dir(lightDir.mV); @@ -10845,8 +10788,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); //restore render matrices - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + set_current_modelview(saved_view); + set_current_projection(saved_proj); LLVector3 eye = camera.getOrigin(); @@ -11159,8 +11102,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) shadow_cam.setOrigin(0,0,0); - glh_set_current_modelview(view[j]); - glh_set_current_projection(proj[j]); + set_current_modelview(view[j]); + set_current_projection(proj[j]); LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); @@ -11173,8 +11116,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) 0.f, 0.f, 0.5f, 0.5f, 0.f, 0.f, 0.f, 1.f); - glh_set_current_modelview(view[j]); - glh_set_current_projection(proj[j]); + set_current_modelview(view[j]); + set_current_projection(proj[j]); for (U32 i = 0; i < 16; i++) { @@ -11253,8 +11196,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) for (S32 i = 0; i < 2; i++) { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + set_current_modelview(saved_view); + set_current_projection(saved_proj); if (mShadowSpotLight[i].isNull()) { @@ -11314,8 +11257,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) 0.f, 0.f, 0.5f, 0.5f, 0.f, 0.f, 0.f, 1.f); - glh_set_current_modelview(view[i+4]); - glh_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; @@ -11359,13 +11302,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (!CameraOffset) { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + set_current_modelview(saved_view); + set_current_projection(saved_proj); } else { - glh_set_current_modelview(view[1]); - glh_set_current_projection(proj[1]); + 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); @@ -11543,7 +11486,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; F32 aspect = tdim.mV[0]/tdim.mV[1]; glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); - glh_set_current_projection(persp); + set_current_projection(persp); gGL.loadMatrix(persp.m); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -11554,7 +11497,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; gGL.loadMatrix(mat.m); - glh_set_current_modelview(mat); + set_current_modelview(mat); glClearColor(0.0f,0.0f,0.0f,0.0f); gGL.setColorMask(true, true); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 7e19e25884..43aa7d891e 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -61,14 +61,7 @@ bool compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0); bool setup_hud_matrices(); // use whole screen to render hud bool setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking) -glh::matrix4f glh_copy_matrix(F32* src); -glh::matrix4f glh_get_current_modelview(); -void glh_set_current_modelview(const glh::matrix4f& mat); -glh::matrix4f glh_get_current_projection(); -void glh_set_current_projection(glh::matrix4f& mat); -glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); -glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); -glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up); + extern LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY; extern LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS; @@ -662,9 +655,9 @@ public: U32 mTrueNoiseMap; U32 mLightFunc; - LLColor4 mSunDiffuse; - LLVector3 mSunDir; - LLVector3 mTransformedSunDir; + LLColor4 mSunDiffuse; + LLVector4 mSunDir; + LLVector4 mTransformedSunDir; bool mInitialized; bool mVertexShadersEnabled; |