diff options
Diffstat (limited to 'indra/newview')
93 files changed, 4737 insertions, 3890 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 964615320d..e7aa884f6b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -187,6 +187,7 @@ set(viewer_SOURCE_FILES      lldrawpoolbump.cpp      lldrawpoolground.cpp      lldrawpoolmaterials.cpp +    lldrawpoolpbropaque.cpp      lldrawpoolsimple.cpp      lldrawpoolsky.cpp      lldrawpoolterrain.cpp @@ -545,6 +546,8 @@ set(viewer_SOURCE_FILES      llproductinforequest.cpp      llprogressview.cpp      llrecentpeople.cpp +    llreflectionmap.cpp +    llreflectionmapmanager.cpp      llregioninfomodel.cpp      llregionposition.cpp      llremoteparcelrequest.cpp @@ -822,6 +825,7 @@ set(viewer_HEADER_FILES      lldrawpoolavatar.h      lldrawpoolbump.h      lldrawpoolmaterials.h +    lldrawpoolpbropaque.h      lldrawpoolground.h      lldrawpoolsimple.h      lldrawpoolsky.h @@ -1169,6 +1173,8 @@ set(viewer_HEADER_FILES      llproductinforequest.h      llprogressview.h      llrecentpeople.h +    llreflectionmap.h +    llreflectionmapmanager.h      llregioninfomodel.h      llregionposition.h      llremoteparcelrequest.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0000ae18bd..f6c5d46c33 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9599,6 +9599,18 @@      <real>368.0</real>    </map> +  <key>RenderPBR</key> +  <map> +    <key>Comment</key> +    <string>Use PBR rendering pipeline (Physically Based Rendering).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +    <key>RenderDeferred</key>    <map>      <key>Comment</key> @@ -10269,7 +10281,41 @@        <integer>2</integer>      </map> -    <key>RenderReflectionRes</key> +  <key>RenderReflectionProbeDrawDistance</key> +  <map> +    <key>Comment</key> +    <string>Camera far clip to use when updating reflection probes.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>64</real> +  </map> +  <key>RenderReflectionProbeAmbiance</key> +  <map> +    <key>Comment</key> +    <string>Amount reflection probes contribute to ambient light.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0</real> +  </map> +  <key>RenderReflectionProbeTextureHackID</key> +  <map> +    <key>Comment</key> +    <string>HACK -- Any object with a diffuse texture with this ID will be treated as a user override reflection probe. (default is "Violet Info Hub" photo from Library)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>6b186931-05da-eafa-a3ed-a012a33bbfb6</string> +  </map> +   +  <key>RenderReflectionRes</key>      <map>        <key>Comment</key>        <string>Reflection map resolution.</string> diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl index 23adbded5e..73c125bbdc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl @@ -29,8 +29,6 @@ uniform sampler2DRect   depthMap;  uniform float ssao_radius;  uniform float ssao_max_radius; -uniform float ssao_factor; -uniform float ssao_factor_inv;  uniform mat4 inv_proj;  uniform vec2 screen_res; @@ -83,14 +81,14 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)  {      float ret = 1.0;      vec3 pos_world = pos.xyz; -    vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy; +          float angle_hidden = 0.0;      float points = 0; -    float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); -          // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) +    float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); +    vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy;      for (int i = 0; i < 8; i++)      {          vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect); @@ -105,14 +103,14 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)          //(k should vary inversely with # of samples, but this is taken care of later)          float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0; -        angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv); +        angle_hidden = angle_hidden + funky_val * min(1.0/dist2, 1.0);          // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"           float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;          points = points + diffz_val;      } -         -    angle_hidden = min(ssao_factor*angle_hidden/points, 1.0); + +    angle_hidden = min(angle_hidden/points, 1.0);      float points_val = (points > 0.0) ? 1.0 : 0.0;      ret = (1.0 - (points_val * angle_hidden)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 596d0274af..fa3634f3b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -69,36 +69,47 @@ void main()      tc_mod *= 2.0;      tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 ); -    for (int i = 1; i < 4; i++) +    // TODO: move this to kern instead of building kernel per pixel +    vec3 k[7]; +    k[0] = kern[0]; +    k[2] = kern[1]; +    k[4] = kern[2]; +    k[6] = kern[3]; + +    k[1] = (k[0]+k[2])*0.5f; +    k[3] = (k[2]+k[4])*0.5f; +    k[5] = (k[4]+k[6])*0.5f; +     +    for (int i = 1; i < 7; i++)      { -        vec2 samptc = tc + kern[i].z*dlt; +        vec2 samptc = tc + k[i].z*dlt*2.0;          vec3 samppos = getPosition(samptc).xyz;           float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane          if (d*d <= pointplanedist_tolerance_pow2)          { -            col += texture2DRect(lightMap, samptc)*kern[i].xyxx; -            defined_weight += kern[i].xy; +            col += texture2DRect(lightMap, samptc)*k[i].xyxx; +            defined_weight += k[i].xy;          }      } -    for (int i = 1; i < 4; i++) +    for (int i = 1; i < 7; i++)      { -        vec2 samptc = tc - kern[i].z*dlt; +        vec2 samptc = tc - k[i].z*dlt*2.0;          vec3 samppos = getPosition(samptc).xyz;           float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane          if (d*d <= pointplanedist_tolerance_pow2)          { -            col += texture2DRect(lightMap, samptc)*kern[i].xyxx; -            defined_weight += kern[i].xy; +            col += texture2DRect(lightMap, samptc)*k[i].xyxx; +            defined_weight += k[i].xy;          }      }      col /= defined_weight.xyxx; -    col.y *= col.y; +    //col.y *= max(col.y, 0.75);      frag_color = col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl index 3bd6b693fa..5264b3b716 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl @@ -45,7 +45,7 @@ ATTRIBUTE vec2 texcoord0;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0;  VARYING vec3 vary_texcoord1; -VARYING vec4 vary_position; +VARYING vec3 vary_position;  #ifdef HAS_SKIN  mat4 getObjectSkinnedTransform(); @@ -62,17 +62,23 @@ void main()      mat4 mat = getObjectSkinnedTransform();      mat = modelview_matrix * mat;      vec4 pos = mat * vert; -    vary_position = gl_Position = projection_matrix * pos; +    gl_Position = projection_matrix * pos;  	vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);  #else  	vec4 pos = (modelview_matrix * vert); -	vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);  	vec3 norm = normalize(normal_matrix * normal);  #endif -	vec3 ref = reflect(pos.xyz, -norm); +    vary_position = pos.xyz;  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz; + +#ifndef HAS_REFLECTION_PROBES	 +    vec3 ref = reflect(pos.xyz, -norm); +	vary_texcoord1 = transpose(normal_matrix) * ref.xyz; +#else +    vary_texcoord1 = norm; +#endif  	calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 09c47165dd..0ae4bbfc5d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -36,7 +36,6 @@ out vec4 frag_color;  uniform sampler2DRect depthMap;  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect; -uniform samplerCube   environmentMap;  uniform sampler2D     noiseMap;  uniform sampler2D     lightFunc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index ec3fb9c543..8dcc18080d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -42,7 +42,6 @@ uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap; -uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap;  uniform sampler2D lightFunc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl new file mode 100644 index 0000000000..cb9cc4958a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -0,0 +1,109 @@ +/**  + * @file pbropaqueF.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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]*/ + +#define DEBUG_BASIC         1 +#define DEBUG_COLOR         0 +#define DEBUG_NORMAL        0 +#define DEBUG_POSITION      0 +#define DEBUG_REFLECT_VEC   0 +#define DEBUG_REFLECT_COLOR 0 + +#ifdef HAS_SPECULAR_MAP +uniform sampler2D specularMap; +#endif +uniform samplerCube environmentMap; +uniform mat3        env_mat; + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif + +VARYING vec3 vary_position; +VARYING vec3 vary_normal; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +#ifdef HAS_SPECULAR_MAP +VARYING vec2 vary_texcoord2; +#endif + +vec2 encode_normal(vec3 n); +vec3 linear_to_srgb(vec3 c); + +struct PBR +{ +    float LdotH; // Light and Half +    float NdotL; // Normal and Light +    float NdotH; // Normal and Half +    float VdotH; // View and Half +}; + +const float M_PI = 3.141592653589793; + +void main() +{ +    vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; + +//#ifdef HAS_SPECULAR_MAP +//#else +    vec4 norm  = vec4(0,0,0,1.0); +    vec3 tnorm = vary_normal; +//#endif +    norm.xyz = normalize(tnorm.xyz); + +    vec3 spec; +    spec.rgb = vec3(vertex_color.a); + +    vec3 pos = vary_position; +    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +    vec3 env_vec = env_mat * refnormpersp; +    vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; + +#if DEBUG_BASIC +    col.rgb = vec3( 1, 0, 1 ); // DEBUG +#endif +#if DEBUG_COLOR +    col.rgb = vertex_color.rgb; +#endif +#if DEBUG_NORMAL +    col.rgb = vary_normal; +#endif +#if DEBUG_POSITION +    col.rgb = vary_position.xyz; +#endif +#if DEBUG_REFLECT_VEC +    col.rgb = refnormpersp; +#endif +#if DEBUG_REFLECT_COLOR +    col.rgb = reflected_color; +#endif + +    frag_data[0] = vec4(col, 0.0); +    frag_data[1] = vec4(spec, vertex_color.a); // spec +    frag_data[2] = vec4(encode_normal(norm.xyz), vertex_color.a, 0.0); +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 6577fe0ecf..72bae808e0 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -1,9 +1,9 @@  /**  - * @file class3/deferred/shadowV.glsl + * @file pbropaqueV.glsl   * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * $LicenseInfo:firstyear=2022&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. + * Copyright (C) 2022, 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 @@ -23,19 +23,18 @@   * $/LicenseInfo$   */ -uniform mat4 modelview_projection_matrix; -uniform float shadow_target_width; +uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -#if !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING vec4 pos; -VARYING float target_pos_x; +VARYING vec3 vary_position; +VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -43,20 +42,13 @@ void passTextureIndex();  void main()  { -	//transform vertex -	vec4 pre_pos = vec4(position.xyz, 1.0); - -	pos = modelview_projection_matrix * pre_pos; +    //transform vertex +    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    vary_position = (modelview_matrix * vec4(position.xyz,1.0)).xyz; +    vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; +    passTextureIndex(); +    vary_normal = normalize(normal_matrix * normal); -#if !defined(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 -	 -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +    vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 18616a9bb3..c1061f1933 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -36,7 +36,6 @@ out vec4 frag_color;  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect normalMap; -uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D lightFunc;  uniform sampler2DRect depthMap; diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl index 345c07a354..8f3e38b08b 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl @@ -1,58 +1,44 @@ -/**  - * @file shadowAlphaMaskF.glsl +/** + * @file class1/deferred/reflectionProbeF.glsl   * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * $LicenseInfo:firstyear=2022&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. - *  + * Copyright (C) 2022, 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 !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING float pos_w; - -VARYING float target_pos_x; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec3 pos; - -vec4 computeMoments(float depth, float a); - -void main()  +// fallback stub -- will be used if actual reflection probe shader failed to load (output pink so it's obvious) +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,  +        vec3 pos, vec3 norm, float glossiness, float envIntensity)  { -	float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; +    ambenv = vec3(1,0,1); +    glossenv = vec3(1,0,1); +    legacyenv = vec3(1,0,1); +} -    frag_color = computeMoments(length(pos), float a); +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm) +{ +    color = vec3(1,0,1); +} -#if !defined(DEPTH_CLAMP) -	gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); -#endif +void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity) +{ +    color = vec3(1,0,1);  } + diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl new file mode 100644 index 0000000000..ea687aab4f --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl @@ -0,0 +1,75 @@ +/**  + * @file reflectionmipF.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ +  +#extension GL_ARB_texture_rectangle : enable + +/*[EXTRA_CODE_HERE]*/ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2DRect screenMap; + +VARYING vec2 vary_texcoord0; + +void main()  +{ +    float w[9]; + +    float c = 1.0/16.0;  //corner weight +    float e = 1.0/8.0; //edge weight +    float m = 1.0/4.0; //middle weight + +    //float wsum = c*4+e*4+m; + +    w[0] = c;   w[1] = e;    w[2] = c; +    w[3] = e;    w[4] = m;     w[5] = e; +    w[6] = c;   w[7] = e;    w[8] = c; +     +    vec2 tc[9]; + +    float ed = 1; +    float cd = 1; + + +    tc[0] = vec2(-cd, cd);    tc[1] = vec2(0, ed);    tc[2] = vec2(cd, cd); +    tc[3] = vec2(-ed, 0);    tc[4] = vec2(0, 0);    tc[5] = vec2(ed, 0); +    tc[6] = vec2(-cd, -cd);    tc[7] = vec2(0, -ed);   tc[8] = vec2(cd, -1); + +    vec3 color = vec3(0,0,0); + +    for (int i = 0; i < 9; ++i) +    { +        color += texture2DRect(screenMap, vary_texcoord0.xy+tc[i]).rgb * w[i]; +        //color += texture2DRect(screenMap, vary_texcoord0.xy+tc[i]*2.0).rgb * w[i]*0.5; +    } + +    //color /= wsum; + +    frag_color = vec4(color, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl new file mode 100644 index 0000000000..8c1323ba1a --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl @@ -0,0 +1,476 @@ +/** + * @file class2/deferred/reflectionProbeF.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ + +#extension GL_ARB_shader_texture_lod : enable + +#define FLT_MAX 3.402823466e+38 + +#define REFMAP_COUNT 256 +#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider + +uniform samplerCubeArray   reflectionProbes; + +layout (std140, binding = 1) uniform ReflectionProbes +{ +    // list of OBBs for user override probes +    // box is a set of 3 planes outward facing planes and the depth of the box along that plane +    // for each box refBox[i]... +    /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation +    //  box[3][0..2] - plane thickness +    mat4 refBox[REFMAP_COUNT]; +    // list of bounding spheres for reflection probes sorted by distance to camera (closest first) +    vec4 refSphere[REFMAP_COUNT]; +    // index  of cube map in reflectionProbes for a corresponding reflection probe +    // e.g. cube map channel of refSphere[2] is stored in refIndex[2] +    // refIndex.x - cubemap channel in reflectionProbes +    // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index) +    // refIndex.z - number of neighbors +    // refIndex.w - priority, if negative, this probe has a box influence +    ivec4 refIndex[REFMAP_COUNT]; + +    // neighbor list data (refSphere indices, not cubemap array layer) +    ivec4 refNeighbor[1024]; + +    // number of reflection probes present in refSphere +    int refmapCount; + +    // intensity of ambient light from reflection probes +    float reflectionAmbiance; +}; + +// Inputs +uniform mat3 env_mat; + +// list of probeIndexes shader will actually use after "getRefIndex" is called +// (stores refIndex/refSphere indices, NOT rerflectionProbes layer) +int probeIndex[REF_SAMPLE_COUNT]; + +// number of probes stored in probeIndex +int probeInfluences = 0; + +bool isAbove(vec3 pos, vec4 plane) +{ +    return (dot(plane.xyz, pos) + plane.w) > 0; +} + +// return true if probe at index i influences position pos +bool shouldSampleProbe(int i, vec3 pos) +{ +    if (refIndex[i].w < 0) +    { +        vec4 v = refBox[i] * vec4(pos, 1.0); +        if (abs(v.x) > 1 ||  +            abs(v.y) > 1 || +            abs(v.z) > 1) +        { +            return false; +        } +    } +    else +    { +        vec3 delta = pos.xyz - refSphere[i].xyz; +        float d = dot(delta, delta); +        float r2 = refSphere[i].w; +        r2 *= r2; + +        if (d > r2) +        { //outside bounding sphere +            return false; +        } +    } + +    return true; +} + +// call before sampleRef +// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT +// overall algorithm --  +void preProbeSample(vec3 pos) +{ +    // TODO: make some sort of structure that reduces the number of distance checks + +    for (int i = 0; i < refmapCount; ++i) +    { +        // found an influencing probe +        if (shouldSampleProbe(i, pos)) +        { +            probeIndex[probeInfluences] = i; +            ++probeInfluences; + +            int neighborIdx = refIndex[i].y; +            if (neighborIdx != -1) +            { +                int neighborCount = min(refIndex[i].z, REF_SAMPLE_COUNT-1); + +                int count = 0; +                while (count < neighborCount) +                { +                    // check up to REF_SAMPLE_COUNT-1 neighbors (neighborIdx is ivec4 index) + +                    int idx = refNeighbor[neighborIdx].x; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    idx = refNeighbor[neighborIdx].y; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    idx = refNeighbor[neighborIdx].z; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    idx = refNeighbor[neighborIdx].w; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    ++neighborIdx; +                } + +                return; +            } +        } +    } +} + +// from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection + +// original reference implementation: +/* +bool intersect(const Ray &ray) const  +{  +        float t0, t1; // solutions for t if the ray intersects  +#if 0  +        // geometric solution +        Vec3f L = center - orig;  +        float tca = L.dotProduct(dir);  +        // if (tca < 0) return false; +        float d2 = L.dotProduct(L) - tca * tca;  +        if (d2 > radius2) return false;  +        float thc = sqrt(radius2 - d2);  +        t0 = tca - thc;  +        t1 = tca + thc;  +#else  +        // analytic solution +        Vec3f L = orig - center;  +        float a = dir.dotProduct(dir);  +        float b = 2 * dir.dotProduct(L);  +        float c = L.dotProduct(L) - radius2;  +        if (!solveQuadratic(a, b, c, t0, t1)) return false;  +#endif  +        if (t0 > t1) std::swap(t0, t1);  +  +        if (t0 < 0) {  +            t0 = t1; // if t0 is negative, let's use t1 instead  +            if (t0 < 0) return false; // both t0 and t1 are negative  +        }  +  +        t = t0;  +  +        return true;  +} */ + +// adapted -- assume that origin is inside sphere, return distance from origin to edge of sphere +vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2) +{  +        float t0, t1; // solutions for t if the ray intersects  + +        vec3 L = center - origin;  +        float tca = dot(L,dir); + +        float d2 = dot(L,L) - tca * tca;  + +        float thc = sqrt(radius2 - d2);  +        t0 = tca - thc;  +        t1 = tca + thc;  +  +        vec3 v = origin + dir * t1; +        return v;  +}  + +// from https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +/* +vec3 DirectionWS = normalize(PositionWS - CameraWS); +vec3 ReflDirectionWS = reflect(DirectionWS, NormalWS); + +// Intersection with OBB convertto unit box space +// Transform in local unit parallax cube space (scaled and rotated) +vec3 RayLS = MulMatrix( float(3x3)WorldToLocal, ReflDirectionWS); +vec3 PositionLS = MulMatrix( WorldToLocal, PositionWS); + +vec3 Unitary = vec3(1.0f, 1.0f, 1.0f); +vec3 FirstPlaneIntersect  = (Unitary - PositionLS) / RayLS; +vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; +vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); +float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z)); + +// Use Distance in WS directly to recover intersection +vec3 IntersectPositionWS = PositionWS + ReflDirectionWS * Distance; +vec3 ReflDirectionWS = IntersectPositionWS - CubemapPositionWS; + +return texCUBE(envMap, ReflDirectionWS); +*/ + +// get point of intersection with given probe's box influence volume +// origin - ray origin in clip space +// dir - ray direction in clip space +// i - probe index in refBox/refSphere +vec3 boxIntersect(vec3 origin, vec3 dir, int i) +{ +    // Intersection with OBB convertto unit box space +    // Transform in local unit parallax cube space (scaled and rotated) +    mat4 clipToLocal = refBox[i]; + +    vec3 RayLS = mat3(clipToLocal) * dir; +    vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; + +    vec3 Unitary = vec3(1.0f, 1.0f, 1.0f); +    vec3 FirstPlaneIntersect  = (Unitary - PositionLS) / RayLS; +    vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; +    vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); +    float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z)); + +    // Use Distance in CS directly to recover intersection +    vec3 IntersectPositionCS = origin + dir * Distance; + +    return IntersectPositionCS; +} + + + +// Tap a sphere based reflection probe +// pos - position of pixel +// dir - pixel normal +// lod - which mip to bias towards (lower is higher res, sharper reflections) +// c - center of probe +// r2 - radius of probe squared +// i - index of probe  +// vi - point at which reflection vector struck the influence volume, in clip space +vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i) +{ +    //lod = max(lod, 1); +    // parallax adjustment + +    vec3 v; +    if (refIndex[i].w < 0) +    { +        v = boxIntersect(pos, dir, i); +    } +    else +    { +        v = sphereIntersect(pos, dir, c, r2); +    } + +    v -= c; +    v = env_mat * v; +    { +        float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res +        return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb; +        //return texture(reflectionProbes, vec4(v.xyz, refIndex[i].x)).rgb; +    } +} + +vec3 sampleProbes(vec3 pos, vec3 dir, float lod) +{ +    float wsum = 0.0; +    vec3 col = vec3(0,0,0); +    float vd2 = dot(pos,pos); // view distance squared + +    for (int idx = 0; idx < probeInfluences; ++idx) +    { +        int i = probeIndex[idx]; +        float r = refSphere[i].w; // radius of sphere volume +        float p = float(abs(refIndex[i].w)); // priority +        float rr = r*r; // radius squred +        float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down) +        vec3 delta = pos.xyz-refSphere[i].xyz; +        float d2 = dot(delta,delta); +        float r2 = r1*r1;  +         +        { +            vec3 refcol = tapRefMap(pos, dir, lod, refSphere[i].xyz, rr, i); +             +            float w = 1.0/d2; + +            float atten = 1.0-max(d2-r2, 0.0)/(rr-r2); +            w *= atten; +            w *= p; // boost weight based on priority +            col += refcol*w; +             +            wsum += w; +        } +    } + +    if (probeInfluences <= 1) +    { //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera  +        for (int idx = 0; idx < 8; ++idx) +        { +            if (refIndex[idx].w < 0) +            { // don't fallback to box probes, they are *very* specific +                continue; +            } +            int i = idx; +            vec3 delta = pos.xyz-refSphere[i].xyz; +            float d2 = dot(delta,delta); +             +            { +                vec3 refcol = tapRefMap(pos, dir, lod, refSphere[i].xyz, d2, i); +                 +                float w = 1.0/d2; +                w *= w; +                col += refcol*w; +                wsum += w; +            } +        } +    } + +    if (wsum > 0.0) +    { +        col *= 1.0/wsum; +    } +     +    return col; +} + +vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod) +{ +    vec3 col = sampleProbes(pos, dir, lod); + +    //desaturate +    vec3 hcol = col *0.5; +     +    col *= 2.0; +    col = vec3( +        col.r + hcol.g + hcol.b, +        col.g + hcol.r + hcol.b, +        col.b + hcol.r + hcol.g +    ); +     +    col *= 0.333333; + +    return col*reflectionAmbiance; + +} + +// brighten a color so that at least one component is 1 +vec3 brighten(vec3 c) +{ +    float m = max(max(c.r, c.g), c.b); + +    if (m == 0) +    { +        return vec3(1,1,1); +    } + +    return c * 1.0/m; +} + + +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,  +        vec3 pos, vec3 norm, float glossiness, float envIntensity) +{ +    // TODO - don't hard code lods +    float reflection_lods = 8; +    preProbeSample(pos); + +    vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + +    ambenv = sampleProbeAmbient(pos, norm, reflection_lods-1); + +    if (glossiness > 0.0) +    { +        float lod = (1.0-glossiness)*reflection_lods; +        glossenv = sampleProbes(pos, normalize(refnormpersp), lod); +    } + +    if (envIntensity > 0.0) +    { +        legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0); +    } +} + +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm) +{ +    glossenv *= 0.35; // fudge darker +    float fresnel = 1.0+dot(normalize(pos.xyz), norm.xyz); +    float minf = spec.a * 0.1; +    fresnel = fresnel * (1.0-minf) + minf; +    glossenv *= spec.rgb*min(fresnel, 1.0); +    color.rgb += glossenv; +} + + void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity) + { +    vec3 reflected_color = legacyenv; //*0.5; //fudge darker +    vec3 lookAt = normalize(pos); +    float fresnel = 1.0+dot(lookAt, norm.xyz); +    fresnel *= fresnel; +    fresnel = min(fresnel+envIntensity, 1.0); +    reflected_color *= (envIntensity*fresnel)*brighten(spec.rgb); +    color = mix(color.rgb, reflected_color, envIntensity); + }
\ No newline at end of file diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl deleted file mode 100644 index d973326f93..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl +++ /dev/null @@ -1,44 +0,0 @@ -/**  - * @file avatarShadowF.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$ - */ - -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform sampler2D diffuseMap; - -VARYING vec4 pos; -VARYING vec2 vary_texcoord0; - -vec4 computeMoments(float depth, float a); - -void main()  -{ -    frag_color = computeMoments(length(pos), 1.0); -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl deleted file mode 100644 index 1a655e6467..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl +++ /dev/null @@ -1,49 +0,0 @@ -/**  - * @file attachmentShadowV.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$ - */ - -uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; -uniform mat4 texture_matrix0; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; - -mat4 getObjectSkinnedTransform(); - -VARYING vec4 pos; - -void main() -{ -	//transform vertex -	mat4 mat = getObjectSkinnedTransform(); -	 -	mat = modelview_matrix * mat; -	pos = (mat*vec4(position.xyz, 1.0)); -	pos = projection_matrix * vec4(pos.xyz, 1.0); - -#if !defined(DEPTH_CLAMP) -	pos.z = max(pos.z, -pos.w+0.01); -#endif -	gl_Position = pos; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl deleted file mode 100644 index 48eefc7a73..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl +++ /dev/null @@ -1,52 +0,0 @@ -/**  - * @file avatarShadowF.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$ - */ - -/*[EXTRA_CODE_HERE]*/  - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform sampler2D diffuseMap; - -#if !defined(DEPTH_CLAMP) -VARYING vec4 post_pos; -#endif - -VARYING vec4 pos; - -vec4 computeMoments(float depth, float a); - -void main()  -{ -    frag_color = computeMoments(length(pos), 1.0); - -#if !defined(DEPTH_CLAMP) -	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); -#endif -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl deleted file mode 100644 index 164b355f20..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl +++ /dev/null @@ -1,68 +0,0 @@ -/**  - * @file avatarShadowV.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$ - */ -  -uniform mat4 projection_matrix; - -mat4 getSkinnedTransform(); - -ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; - -#if !defined(DEPTH_CLAMP) -VARYING vec4 post_pos; -#endif - -VARYING vec4 pos; - -void main() -{ -	vec3 norm; -	 -	vec4 pos_in = vec4(position.xyz, 1.0); -	mat4 trans = getSkinnedTransform(); - -	pos.x = dot(trans[0], pos_in); -	pos.y = dot(trans[1], pos_in); -	pos.z = dot(trans[2], pos_in); -	pos.w = 1.0; -	 -	norm.x = dot(trans[0].xyz, normal); -	norm.y = dot(trans[1].xyz, normal); -	norm.z = dot(trans[2].xyz, normal); -	norm = normalize(norm); -	 -	pos = projection_matrix * pos; - -#if !defined(DEPTH_CLAMP) -	post_pos = pos; -	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); -#else -	gl_Position = pos; -#endif - -} - - diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl deleted file mode 100644 index 32210f60dc..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl +++ /dev/null @@ -1,119 +0,0 @@ -/**  - * @file class3/deferred/cloudsF.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$ - */ -  -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform sampler2D diffuseMap; - -VARYING vec4 pos; -VARYING float target_pos_x; -VARYING float vary_CloudDensity; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec2 vary_texcoord3; - -uniform sampler2D cloud_noise_texture; -uniform sampler2D cloud_noise_texture_next; -uniform float blend_factor; -uniform vec4 cloud_pos_density1; -uniform vec4 cloud_pos_density2; -uniform vec4 cloud_color; -uniform float cloud_shadow; -uniform float cloud_scale; -uniform float cloud_variance; -uniform vec3 camPosLocal; -uniform vec3 sun_dir; -uniform float sun_size; -uniform float far_z; - -vec4 cloudNoise(vec2 uv) -{ -   vec4 a = texture2D(cloud_noise_texture, uv); -   vec4 b = texture2D(cloud_noise_texture_next, uv); -   vec4 cloud_noise_sample = mix(a, b, blend_factor); -   return normalize(cloud_noise_sample); -} - -vec4 computeMoments(float depth, float alpha); - -void main() -{ -    if (cloud_scale >= 0.001) -    { -        // Set variables -        vec2 uv1 = vary_texcoord0.xy; -        vec2 uv2 = vary_texcoord1.xy; -        vec2 uv3 = vary_texcoord2.xy; -        float cloudDensity = 2.0 * (cloud_shadow - 0.25); -     -        vec2 uv4 = vary_texcoord3.xy; -     -        vec2 disturbance  = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f); -        vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f); -     -        // Offset texture coords -        uv1 += cloud_pos_density1.xy + (disturbance * 0.2);    //large texture, visible density -        uv2 += cloud_pos_density1.xy;   //large texture, self shadow -        uv3 += cloud_pos_density2.xy;   //small texture, visible density -        uv4 += cloud_pos_density2.xy;   //small texture, self shadow -     -        float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0); -     -        cloudDensity *= 1.0 - (density_variance * density_variance); -     -        // Compute alpha1, the main cloud opacity -        float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z; -        alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.); -     -        // And smooth -        alpha1 = 1. - alpha1 * alpha1; -        alpha1 = 1. - alpha1 * alpha1;   -     -        if (alpha1 < 0.001f) -        { -            discard; -        } -     -        // Compute alpha2, for self shadowing effect -        // (1 - alpha2) will later be used as percentage of incoming sunlight -        float alpha2 = (cloudNoise(uv2).x - 0.5); -        alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.); -     -        // And smooth -        alpha2 = 1. - alpha2; -        alpha2 = 1. - alpha2 * alpha2;   -     -        frag_color = computeMoments(length(pos), alpha1); -    } -    else -    { -        frag_color = vec4(0); -    } -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl deleted file mode 100644 index effb070f93..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl +++ /dev/null @@ -1,63 +0,0 @@ -/**  - * @file cloudShadowV.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 !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING vec4 pos; -VARYING float target_pos_x; -VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color; - -void passTextureIndex(); - -void main() -{ -	//transform vertex -	vec4 pre_pos = vec4(position.xyz, 1.0); -	pos = modelview_projection_matrix * pre_pos; -	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; - -#if !defined(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/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl deleted file mode 100644 index e40d7e7c75..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl +++ /dev/null @@ -1,166 +0,0 @@ -/**  - * @file class3/deferred/cloudsF.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$ - */ -  -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -///////////////////////////////////////////////////////////////////////// -// The fragment shader for the sky -///////////////////////////////////////////////////////////////////////// - -VARYING vec4 vary_CloudColorSun; -VARYING vec4 vary_CloudColorAmbient; -VARYING float vary_CloudDensity; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec2 vary_texcoord3; -VARYING vec3 vary_pos; - -uniform sampler2D cloud_noise_texture; -uniform sampler2D cloud_noise_texture_next; -uniform float blend_factor; -uniform vec4 cloud_pos_density1; -uniform vec4 cloud_pos_density2; -uniform vec4 cloud_color; -uniform float cloud_shadow; -uniform float cloud_scale; -uniform float cloud_variance; -uniform vec3 camPosLocal; -uniform vec3 sun_dir; -uniform float sun_size; -uniform float far_z; - -uniform sampler2D transmittance_texture; -uniform sampler3D scattering_texture; -uniform sampler3D single_mie_scattering_texture; -uniform sampler2D irradiance_texture; -uniform sampler2D sh_input_r; -uniform sampler2D sh_input_g; -uniform sampler2D sh_input_b; - -vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance); - -/// Soft clips the light with a gamma correction -vec3 scaleSoftClip(vec3 light); - -vec4 cloudNoise(vec2 uv) -{ -   vec4 a = texture2D(cloud_noise_texture, uv); -   vec4 b = texture2D(cloud_noise_texture_next, uv); -   vec4 cloud_noise_sample = mix(a, b, blend_factor); -   return cloud_noise_sample; -} - -void main() -{ -    // Set variables -    vec2 uv1 = vary_texcoord0.xy; -    vec2 uv2 = vary_texcoord1.xy; -    vec2 uv3 = vary_texcoord2.xy; -    float cloudDensity = 2.0 * (cloud_shadow - 0.25); - -    if (cloud_scale < 0.001) -    { -        discard; -    } - -    vec2 uv4 = vary_texcoord3.xy; - -    vec2 disturbance = vec2(cloudNoise(uv1 / 16.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f); - -    // Offset texture coords -    uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density -    uv2 += cloud_pos_density1.xy;   //large texture, self shadow -    uv3 += cloud_pos_density2.xy; //small texture, visible density -    uv4 += cloud_pos_density2.xy;   //small texture, self shadow - -    float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0) * 4.0); - -    cloudDensity *= 1.0 - (density_variance * density_variance); - -    // Compute alpha1, the main cloud opacity -    float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z; -    alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.); - -    // And smooth -    alpha1 = 1. - alpha1 * alpha1; -    alpha1 = 1. - alpha1 * alpha1;   - -    if (alpha1 < 0.001f) -    { -        discard; -    } - -    // Compute alpha2, for self shadowing effect -    // (1 - alpha2) will later be used as percentage of incoming sunlight -    float alpha2 = (cloudNoise(uv2).x - 0.5); -    alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.); - -    // And smooth -    alpha2 = 1. - alpha2; -    alpha2 = 1. - alpha2 * alpha2;   - -    vec3 view_ray = vary_pos.xyz + camPosLocal; - -    vec3 view_direction = normalize(view_ray); -    vec3 sun_direction  = normalize(sun_dir); -    vec3 earth_center   = vec3(0, 0, -6360.0f); -    vec3 camPos = (camPosLocal / 1000.0f) - earth_center; - -    vec3 transmittance; -    vec3 radiance_sun  = GetSkyLuminance(camPos, view_direction, 1.0 - alpha1, sun_direction, transmittance); - -    vec3 sun_color = vec3(1.0) - exp(-radiance_sun * 0.0001); - -    // Combine -    vec4 color; - -    vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); - -    vec4 l1r = texture2D(sh_input_r, vec2(0,0)); -    vec4 l1g = texture2D(sh_input_g, vec2(0,0)); -    vec4 l1b = texture2D(sh_input_b, vec2(0,0)); - -    vec3 sun_indir = vec3(-view_direction.xy, view_direction.z); -    vec3 amb = vec3(dot(l1r, l1tap * vec4(1, sun_indir)), -                    dot(l1g, l1tap * vec4(1, sun_indir)), -                    dot(l1b, l1tap * vec4(1, sun_indir))); - - -    amb = max(vec3(0), amb); - -    color.rgb = sun_color * cloud_color.rgb * (1. - alpha2); -    color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); -    color.rgb += amb; - -    frag_data[0] = vec4(color.rgb, alpha1); -    frag_data[1] = vec4(0); -    frag_data[2] = vec4(0,1,0,1); -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl deleted file mode 100644 index 71e422ddf0..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl +++ /dev/null @@ -1,70 +0,0 @@ -/**  - * @file WLCloudsV.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 mat4 modelview_projection_matrix; -uniform mat4 modelview_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; - -////////////////////////////////////////////////////////////////////////// -// The vertex shader for creating the atmospheric sky -/////////////////////////////////////////////////////////////////////////////// - -// Output parameters -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec2 vary_texcoord3; -VARYING vec3 vary_pos; - -// Inputs -uniform float cloud_scale; -uniform vec4  lightnorm; -uniform vec3  camPosLocal; - -void main() -{ -    vary_pos = position; - -    // World / view / projection -    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - -    // Texture coords -    vary_texcoord0 = texcoord0; -    vary_texcoord0.xy -= 0.5; -    vary_texcoord0.xy /= max(0.001, cloud_scale); -    vary_texcoord0.xy += 0.5; - -    vary_texcoord1 = vary_texcoord0; -    vary_texcoord1.x += lightnorm.x * 0.0125; -    vary_texcoord1.y += lightnorm.z * 0.0125; - -    vary_texcoord2 = vary_texcoord0 * 16.; -    vary_texcoord3 = vary_texcoord1 * 16.; - -    // END CLOUDS -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl deleted file mode 100644 index e27bbce094..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl +++ /dev/null @@ -1,79 +0,0 @@ -/**  - * @file class1/deferred/deferredUtil.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$ - */ - -uniform sampler2DRect   normalMap; -uniform sampler2DRect   depthMap; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec2 getScreenCoordinate(vec2 screenpos) -{ -    vec2 sc = screenpos.xy * 2.0; -    if (screen_res.x > 0 && screen_res.y > 0) -    { -       sc /= screen_res; -    } -    return sc - vec2(1.0, 1.0); -} - -vec3 getNorm(vec2 screenpos) -{ -   vec2 enc = texture2DRect(normalMap, screenpos.xy).xy; -   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; -} - -float getDepth(vec2 pos_screen) -{ -    float depth = texture2DRect(depthMap, pos_screen).r; -    return depth; -} - -vec4 getPosition(vec2 pos_screen) -{ -    float depth = getDepth(pos_screen); -    vec2 sc = getScreenCoordinate(pos_screen); -    vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -    vec4 pos = inv_proj * ndc; -    pos /= pos.w; -    pos.w = 1.0; -    return pos; -} - -vec4 getPositionWithDepth(vec2 pos_screen, float depth) -{ -    vec2 sc = getScreenCoordinate(pos_screen); -    vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -    vec4 pos = inv_proj * ndc; -    pos /= pos.w; -    pos.w = 1.0; -    return pos; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl deleted file mode 100644 index cdaff4b09f..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl +++ /dev/null @@ -1,202 +0,0 @@ -/**  - * @file depthToShadowVolumeG.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$ - */ -#extension GL_ARB_geometry_shader4  : enable -#extension GL_ARB_texture_rectangle : enable - -/*[EXTRA_CODE_HERE]*/ - -layout (triangles) in; -layout (triangle_strip, max_vertices = 128) out; - -uniform sampler2DRect depthMap; -uniform mat4 shadowMatrix[6];  -uniform vec4 lightpos; - -VARYING vec2 vary_texcoord0; - -out vec3 to_vec; - -void cross_products(out vec4 ns[3], int a, int b, int c) -{ -   ns[0] = cross(gl_PositionIn[b].xyz - gl_PositionIn[a].xyz, gl_PositionIn[c].xyz - gl_PositionIn[a].xyz); -   ns[1] = cross(gl_PositionIn[c].xyz - gl_PositionIn[b].xyz, gl_PositionIn[a].xyz - gl_PositionIn[b].xyz); -   ns[2] = cross(gl_PositionIn[a].xyz - gl_PositionIn[c].xyz, gl_PositionIn[b].xyz - gl_PositionIn[c].xyz); -} - -vec3 getLightDirection(vec4 lightpos, vec3 pos) -{ - -    vec3 lightdir = lightpos.xyz - lightpos.w * pos; -    return lightdir; -} - -void emitTri(vec4 v[3]) -{ -    gl_Position = proj_matrix * v[0]; -    EmitVertex(); - -    gl_Position = proj_matrix * v[1]; -    EmitVertex(); - -    gl_Position = proj_matrix * v[2]; -    EmitVertex(); - -    EndPrimitive(); -} - -void emitQuad(vec4 v[4] -{ -    // Emit a quad as a triangle strip. -    gl_Position = proj_matrix*v[0]; -    EmitVertex(); - -    gl_Position = proj_matrix*v[1]; -    EmitVertex(); - -    gl_Position = proj_matrix*v[2]; -    EmitVertex(); - -    gl_Position = proj_matrix*v[3]; -    EmitVertex();  - -    EndPrimitive(); -} - -void emitPrimitives(int layer) -{ -    int i = layer; -    gl_Layer = i; - -    vec4 depth1 = vec4(texture2DRect(depthMap, tc0).rg, texture2DRect(depthMap, tc1).rg)); -    vec3 depth2 = vec4(texture2DRect(depthMap, tc2).rg, texture2DRect(depthMap, tc3).rg)); -    vec3 depth3 = vec4(texture2DRect(depthMap, tc4).rg, texture2DRect(depthMap, tc5).rg)); -    vec3 depth4 = vec4(texture2DRect(depthMap, tc6).rg, texture2DRect(depthMap, tc7).rg)); - -    depth1 = min(depth1, depth2); -    depth1 = min(depth1, depth3); -    depth1 = min(depth1, depth4); - -    vec2 depth = min(depth1.xy, depth1.zw); - -    int side = sqrt(gl_VerticesIn); - -    for (int j = 0; j < side; j++) -    { -        for (int k = 0; k < side; ++k) -        { -            vec3 pos = gl_PositionIn[(j * side) + k].xyz; -            vec4 v = shadowMatrix[i] * vec4(pos, 1.0); -            gl_Position = v; -            to_vec = pos - light_position.xyz * depth; -            EmitVertex(); -        } - -        EndPrimitive(); -    } - -    vec3 norms[3]; // Normals -    vec3 lightdir3]; // Directions toward light - -    vec4 v[4]; // Temporary vertices - -    vec4 or_pos[3] = -    {  // Triangle oriented toward light source -        gl_PositionIn[0], -        gl_PositionIn[2], -        gl_PositionIn[4] -    }; - -    // Compute normal at each vertex. -    cross_products(n, 0, 2, 4); - -    // Compute direction from vertices to light. -    lightdir[0] = getLightDirection(lightpos, gl_PositionIn[0].xyz); -    lightdir[1] = getLightDirection(lightpos, gl_PositionIn[2].xyz); -    lightdir[2] = getLightDirection(lightpos, gl_PositionIn[4].xyz); - -    // Check if the main triangle faces the light. -    bool faces_light = true; -    if (!(dot(ns[0],d[0]) > 0 -         |dot(ns[1],d[1]) > 0 -         |dot(ns[2],d[2]) > 0)) -    { -        // Flip vertex winding order in or_pos. -        or_pos[1] = gl_PositionIn[4]; -        or_pos[2] = gl_PositionIn[2]; -        faces_light = false; -    } - -    // Near cap: simply render triangle. -    emitTri(or_pos); - -    // Far cap: extrude positions to infinity. -    v[0] =vec4(lightpos.w * or_pos[0].xyz - lightpos.xyz,0); -    v[1] =vec4(lightpos.w * or_pos[2].xyz - lightpos.xyz,0); -    v[2] =vec4(lightpos.w * or_pos[1].xyz - lightpos.xyz,0); - -    emitTri(v); - -    // Loop over all edges and extrude if needed. -    for ( int i=0; i<3; i++ )  -    { -       // Compute indices of neighbor triangle. -       int v0 = i*2; -       int nb = (i*2+1); -       int v1 = (i*2+2) % 6; -       cross_products(n, v0, nb, v1); - -       // Compute direction to light, again as above. -       d[0] =lightpos.xyz-lightpos.w*gl_PositionIn[v0].xyz; -       d[1] =lightpos.xyz-lightpos.w*gl_PositionIn[nb].xyz; -       d[2] =lightpos.xyz-lightpos.w*gl_PositionIn[v1].xyz; - -       bool is_parallel = gl_PositionIn[nb].w < 1e-5; - -       // Extrude the edge if it does not have a -       // neighbor, or if it's a possible silhouette. -       if (is_parallel || -          ( faces_light != (dot(ns[0],d[0])>0 || -                            dot(ns[1],d[1])>0 || -                            dot(ns[2],d[2])>0) )) -       { -           // Make sure sides are oriented correctly. -           int i0 = faces_light ? v0 : v1; -           int i1 = faces_light ? v1 : v0; - -           v[0] = gl_PositionIn[i0]; -           v[1] = vec4(lightpos.w*gl_PositionIn[i0].xyz - lightpos.xyz, 0); -           v[2] = gl_PositionIn[i1]; -           v[3] = vec4(lightpos.w*gl_PositionIn[i1].xyz - lightpos.xyz, 0); - -           emitQuad(v); -       } -    } -} - -void main() -{ -    // Output -    emitPrimitives(0); -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl new file mode 100644 index 0000000000..a04f611440 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -0,0 +1,122 @@ +/**  + * @file fullbrightShinyF.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$ + */ +  +/*[EXTRA_CODE_HERE]*/ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +#ifndef HAS_DIFFUSE_LOOKUP +uniform sampler2D diffuseMap; +#endif + + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_texcoord1; +VARYING vec3 vary_position; + +uniform samplerCube environmentMap; + +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass() +uniform int no_atmo; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClip(vec3 light); + +void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); + +vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); + +#ifdef HAS_REFLECTION_PROBES +// reflection probe interface +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,  +        vec3 pos, vec3 norm, float glossiness, float envIntensity); +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm); +void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); +#endif + +// See: +//   class1\deferred\fullbrightShinyF.glsl +//   class1\lighting\lightFullbrightShinyF.glsl +void main() +{ +#ifdef HAS_DIFFUSE_LOOKUP +	vec4 color = diffuseLookup(vary_texcoord0.xy); +#else +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy); +#endif +	 +	color.rgb *= vertex_color.rgb; + +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 0) +	{ +        vec3 sunlit; +        vec3 amblit; +        vec3 additive; +        vec3 atten; +        vec3 pos = vary_position; +        calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false); + +        float env_intensity = vertex_color.a; +#ifndef HAS_REFLECTION_PROBES +        vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	 +        color.rgb = mix(color.rgb, envColor.rgb, env_intensity); +#else +        vec3 ambenv; +        vec3 glossenv; +        vec3 legacyenv; +        vec3 norm = normalize(vary_texcoord1.xyz); +        vec4 spec = vec4(0,0,0,0); +        sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, env_intensity); +        legacyenv *= 1.5; // fudge brighter +        applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity); +#endif +        color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten); +        color.rgb = fullbrightScaleSoftClip(color.rgb); +	} + +/* +	// NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects. +	else +	{ +		vec3  envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb; +		float env_intensity = vertex_color.a; +		color.rgb = mix(color.rgb, envColor.rgb, env_intensity); +	} +*/ + +	color.a = 1.0; +	//color.rgb = linear_to_srgb(color.rgb); + +	frag_color = color; +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl deleted file mode 100644 index 34d26cddea..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl +++ /dev/null @@ -1,70 +0,0 @@ -/**  - * @file class3/deferred/gatherSkyShF.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$ - */ -  -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -VARYING vec2 vary_frag; - -uniform vec2 screen_res; -uniform sampler2D sh_input_r; -uniform sampler2D sh_input_g; -uniform sampler2D sh_input_b; - -void main() -{ -    vec2 offset	  = vec2(2.0) / screen_res; - -    vec4 r = vec4(0); -    vec4 g = vec4(0); -    vec4 b = vec4(0); - -    vec2 tc = vary_frag * 2.0; - -	r += texture2D(sh_input_r, tc + vec2(0,        0)); -	r += texture2D(sh_input_r, tc + vec2(offset.x, 0)); -	r += texture2D(sh_input_r, tc + vec2(0,        offset.y)); -	r += texture2D(sh_input_r, tc + vec2(offset.x, offset.y)); -    r /= 4.0f; - -	g += texture2D(sh_input_g, tc + vec2(0,        0)); -	g += texture2D(sh_input_g, tc + vec2(offset.x, 0)); -	g += texture2D(sh_input_g, tc + vec2(0,        offset.y)); -	g += texture2D(sh_input_g, tc + vec2(offset.x, offset.y)); -    g /= 4.0f; - -	b += texture2D(sh_input_b, tc + vec2(0,        0)); -	b += texture2D(sh_input_b, tc + vec2(offset.x, 0)); -	b += texture2D(sh_input_b, tc + vec2(0,        offset.y)); -	b += texture2D(sh_input_b, tc + vec2(offset.x, offset.y)); -    b /= 4.0f; - -    frag_data[0] = r; -    frag_data[1] = g; -    frag_data[2] = b; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl deleted file mode 100644 index 337c8a50fe..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl +++ /dev/null @@ -1,40 +0,0 @@ -/**  - * @file gatherSkyShV.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$ - */ -  -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; - -VARYING vec2 vary_frag; -uniform vec2 screen_res; - -void main() -{ -    // pass through untransformed fullscreen pos -    float oo_divisor = screen_res.x / 64.0; -    vec3 pos = (position.xyz * oo_divisor) + vec3(oo_divisor - 1, oo_divisor - 1, 0); -	gl_Position = vec4(pos.xyz, 1.0); -    vary_frag = texcoord0 * oo_divisor; -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl deleted file mode 100644 index d5d91c88f0..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl +++ /dev/null @@ -1,111 +0,0 @@ -/**  - * @file class3/deferred/genSkyShF.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$ - */ -  -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -VARYING vec2 vary_frag; - -uniform vec3 sun_dir; - -uniform sampler2D transmittance_texture; -uniform sampler3D scattering_texture; -uniform sampler3D single_mie_scattering_texture; -uniform sampler2D irradiance_texture; - -vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance); - -vec3 calcDirection(vec2 tc) -{ -     float phi = tc.y * 2.0 * 3.14159265; -     float cosTheta = sqrt(1.0 - tc.x); -     float sinTheta = sqrt(1.0 - cosTheta * cosTheta); -     return vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta); -} - -// reverse mapping above to convert a hemisphere direction into phi/theta values -void getPhiAndThetaFromDirection(vec3 dir, out float phi, out float theta) -{ -     float sin_theta; -     float cos_theta; -     cos_theta = dir.z; -     theta     = acos(cos_theta); -     sin_theta = sin(theta); -     phi       = abs(sin_theta) > 0.0001 ? acos(dir.x / sin_theta) : 1.0; -} - -// reverse mapping above to convert a hemisphere direction into an SH texture sample pos -vec2 calcShUvFromDirection(vec3 dir) -{ -    vec2 uv; -    float phi; -    float theta; -    getPhiAndThetaFromDirection(dir, phi, theta); -    uv.y = phi   / 2.0 * 3.14159265; -    uv.x = theta / 2.0 * 3.14159265; -    return uv; -} - -void projectToL1(vec3 n, vec3 c, vec4 basis, out vec4 coeffs[3]) -{ -    coeffs[0] = vec4(basis.x, n * basis.yzw * c.r); -    coeffs[1] = vec4(basis.x, n * basis.yzw * c.g); -    coeffs[2] = vec4(basis.x, n * basis.yzw * c.b); -} - -void main() -{ -    float Y00 = sqrt(1.0 / 3.14159265) * 0.5; -    float Y1x = sqrt(3.0 / 3.14159265) * 0.5; -    float Y1y = Y1x; -    float Y1z = Y1x; - -    vec4 L1 = vec4(Y00, Y1x, Y1y, Y1z); - -    vec3 view_direction = calcDirection(vary_frag); -    vec3 sun_direction  = normalize(sun_dir); -    vec3 cam_pos        = vec3(0, 0, 6360); - -    vec3 transmittance; -    vec3 radiance = GetSkyLuminance(cam_pos, view_direction, 0.0f, sun_direction, transmittance); - -    vec3 color = vec3(1.0) - exp(-radiance * 0.0001); - -    color = pow(color, vec3(1.0/2.2)); - -    vec4 coeffs[3]; -    coeffs[0] = vec4(0); -    coeffs[1] = vec4(0); -    coeffs[2] = vec4(0); - -    projectToL1(view_direction, color.rgb, L1, coeffs); - -    frag_data[0] = coeffs[0]; -    frag_data[1] = coeffs[1]; -    frag_data[2] = coeffs[2]; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl deleted file mode 100644 index b466883dc7..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl +++ /dev/null @@ -1,37 +0,0 @@ -/**  - * @file genSkyShV.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$ - */ -  -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; - -VARYING vec2 vary_frag; - -void main() -{ -    // pass through untransformed fullscreen pos -	gl_Position = vec4(position.xyz, 1.0); -    vary_frag = texcoord0; -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl deleted file mode 100644 index 33c5667cae..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl +++ /dev/null @@ -1,44 +0,0 @@ -/**  - * @file class3/deferred/indirect.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]*/ - -uniform sampler2D sh_input_r; -uniform sampler2D sh_input_g; -uniform sampler2D sh_input_b; - -vec3 GetIndirect(vec3 norm) -{ -    vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); -    vec4 l1r = texture2D(sh_input_r, vec2(0,0)); -    vec4 l1g = texture2D(sh_input_g, vec2(0,0)); -    vec4 l1b = texture2D(sh_input_b, vec2(0,0)); -    vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)), -                         dot(l1g, l1tap * vec4(1, norm.xyz)), -                         dot(l1b, l1tap * vec4(1, norm.xyz))); -    indirect = clamp(indirect, vec3(0), vec3(1.0)); -    return indirect; -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl new file mode 100644 index 0000000000..c5b1937cfb --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -0,0 +1,455 @@ +/** +* @file materialF.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$ +*/ + +/*[EXTRA_CODE_HERE]*/ + +//class1/deferred/materialF.glsl + +// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass. + +#define DIFFUSE_ALPHA_MODE_NONE     0 +#define DIFFUSE_ALPHA_MODE_BLEND    1 +#define DIFFUSE_ALPHA_MODE_MASK     2 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3 + +uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise +uniform int sun_up_factor; + +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); +#endif + +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); + +vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClip(vec3 light); + +void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); + +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cs); + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +#ifdef HAS_SUN_SHADOW +float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); +#endif + +#ifdef HAS_REFLECTION_PROBES +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,  +        vec3 pos, vec3 norm, float glossiness, float envIntensity); +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm); +void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); +#endif + +uniform samplerCube environmentMap; +uniform sampler2D     lightFunc; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +uniform mat3 env_mat; + +uniform vec3 sun_dir; +uniform vec3 moon_dir; +VARYING vec2 vary_fragcoord; + +VARYING vec3 vary_position; + +uniform mat4 proj_mat; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec4 light_attenuation[8]; +uniform vec3 light_diffuse[8]; + +float getAmbientClamp(); + +vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance) +{ +    // SL-14895 inverted attenuation work-around +    // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct +    // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights() +    // to recover the `adjusted_radius` value previously being sent as la. +    float falloff_factor = (12.0 * fa) - 9.0; +    float inverted_la = falloff_factor / la; +    // Yes, it makes me want to cry as well. DJH +     +    vec3 col = vec3(0); + +    //get light vector +    vec3 lv = lp.xyz - v; + +    //get distance +    float dist = length(lv); +    float da = 1.0; + +    dist /= inverted_la; + +    if (dist > 0.0 && inverted_la > 0.0) +    { +        //normalize light vector +        lv = normalize(lv); + +        //distance attenuation +        float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0); +        dist_atten *= dist_atten; +        dist_atten *= 2.0f; + +        if (dist_atten <= 0.0) +        { +            return col; +        } + +        // spotlight coefficient. +        float spot = max(dot(-ln, lv), is_pointlight); +        da *= spot*spot; // GL_SPOT_EXPONENT=2 + +        //angular attenuation +        da *= dot(n, lv); + +        float lit = 0.0f; + +        float amb_da = ambiance; +        if (da >= 0) +        { +            lit = max(da * dist_atten, 0.0); +            col = lit * light_col * diffuse; +            amb_da += (da*0.5 + 0.5) * ambiance; +        } +        amb_da += (da*da*0.5 + 0.5) * ambiance; +        amb_da *= dist_atten; +        amb_da = min(amb_da, 1.0f - lit); + +        // SL-10969 need to see why these are blown out +        //col.rgb += amb_da * light_col * diffuse; + +        if (spec.a > 0.0) +        { +            //vec3 ref = dot(pos+lv, norm); +            vec3 h = normalize(lv + npos); +            float nh = dot(n, h); +            float nv = dot(n, npos); +            float vh = dot(npos, h); +            float sa = nh; +            float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; + +            float gtdenom = 2 * nh; +            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + +            if (nh > 0.0) +            { +                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da); +                vec3 speccol = lit*scol*light_col.rgb*spec.rgb; +                speccol = clamp(speccol, vec3(0), vec3(1)); +                col += speccol; + +                float cur_glare = max(speccol.r, speccol.g); +                cur_glare = max(cur_glare, speccol.b); +                glare = max(glare, speccol.r); +                glare += max(cur_glare, 0.0); +            } +        } +    } + +    return max(col, vec3(0.0, 0.0, 0.0)); +} + +#else +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif +#endif + +uniform sampler2D diffuseMap;  //always in sRGB space + +#ifdef HAS_NORMAL_MAP +uniform sampler2D bumpMap; +#endif + +#ifdef HAS_SPECULAR_MAP +uniform sampler2D specularMap; + +VARYING vec2 vary_texcoord2; +#endif + +uniform float env_intensity; +uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +uniform float minimum_alpha; +#endif + +#ifdef HAS_NORMAL_MAP +VARYING vec3 vary_mat0; +VARYING vec3 vary_mat1; +VARYING vec3 vary_mat2; +VARYING vec2 vary_texcoord1; +#else +VARYING vec3 vary_normal; +#endif + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +vec2 encode_normal(vec3 n); + +void main() +{ +    vec2 pos_screen = vary_texcoord0.xy; + +    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); +	diffcol.rgb *= vertex_color.rgb; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) + +    // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points +    float bias = 0.001953125; // 1/512, or half an 8-bit quantization +    if (diffcol.a < minimum_alpha-bias) +    { +        discard; +    } +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +	vec3 gamma_diff = diffcol.rgb; +	diffcol.rgb = srgb_to_linear(diffcol.rgb); +#endif + +#ifdef HAS_SPECULAR_MAP +    vec4 spec = texture2D(specularMap, vary_texcoord2.xy); +    spec.rgb *= specular_color.rgb; +#else +    vec4 spec = vec4(specular_color.rgb, 1.0); +#endif + +#ifdef HAS_NORMAL_MAP +	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); + +	norm.xyz = norm.xyz * 2 - 1; + +	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), +			  dot(norm.xyz,vary_mat1), +			  dot(norm.xyz,vary_mat2)); +#else +	vec4 norm = vec4(0,0,0,1.0); +	vec3 tnorm = vary_normal; +#endif + +    norm.xyz = normalize(tnorm.xyz); + +    vec2 abnormal = encode_normal(norm.xyz); + +    vec4 final_color = diffcol; + +#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) +	final_color.a = emissive_brightness; +#else +	final_color.a = max(final_color.a, emissive_brightness); +#endif + +    vec4 final_specular = spec; +     +#ifdef HAS_SPECULAR_MAP +    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0); +	final_specular.a = specular_color.a * norm.a; +#else +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); +	final_specular.a = specular_color.a; +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +    //forward rendering, output just lit sRGBA +    vec3 pos = vary_position; + +    float shadow = 1.0f; + +#ifdef HAS_SUN_SHADOW +    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen); +#endif + +    spec = final_specular; +    vec4 diffuse = final_color; +    float envIntensity = final_normal.z; + +    vec3 color = vec3(0,0,0); + +    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; + +    float bloom = 0.0; +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; + +    calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false); +     +        // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020) +        // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level +        // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage +        //color = fullbrightScaleSoftClip(color); + +    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + +    //we're in sRGB space, so gamma correct this dot product so  +    // lighting from the sun stays sharp +    float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0); +    da = pow(da, 1.0 / 1.3); +    vec3 sun_contrib = min(da, shadow) * sunlit; + +#ifdef HAS_REFLECTION_PROBES +    vec3 ambenv; +    vec3 glossenv; +    vec3 legacyenv; +    sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); +    amblit = max(ambenv, amblit); +    color.rgb = amblit; +#else + +    color = amblit; + +    //darken ambient for normals perpendicular to light vector so surfaces in shadow  +    // and facing away from light still have some definition to them. +    // do NOT gamma correct this dot product so ambient lighting stays soft +    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +    ambient *= 0.5; +    ambient *= ambient; +    ambient = (1.0 - ambient); + +    color *= ambient; +#endif + +    color += sun_contrib; + +    color *= gamma_diff.rgb; + +    float glare = 0.0; + +    if (spec.a > 0.0)  // specular reflection +    { +        float sa        = dot(refnormpersp, sun_dir.xyz); +        vec3  dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r); + +        // add the two types of shiny together +        vec3 spec_contrib = dumbshiny * spec.rgb; +        bloom             = dot(spec_contrib, spec_contrib) / 6; + +        glare = max(spec_contrib.r, spec_contrib.g); +        glare = max(glare, spec_contrib.b); + +        color += spec_contrib; + +#ifdef HAS_REFLECTION_PROBES +        applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); +#endif +    } + + +    color = mix(color.rgb, diffcol.rgb, diffuse.a); + +#ifdef HAS_REFLECTION_PROBES +    if (envIntensity > 0.0) +    {  // add environmentmap +        //fudge darker +        legacyenv *= 0.5*diffuse.a+0.5; +         +        applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); +    } +#else +    if (envIntensity > 0.0) +    { +        //add environmentmap +        vec3 env_vec = env_mat * refnormpersp; + +        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; + +        color = mix(color, reflected_color, envIntensity); + +        float cur_glare = max(reflected_color.r, reflected_color.g); +        cur_glare = max(cur_glare, reflected_color.b); +        cur_glare *= envIntensity*4.0; +        glare += cur_glare; +    } +#endif + +    color = atmosFragLighting(color, additive, atten); +    color = scaleSoftClipFrag(color); + +    //convert to linear before adding local lights +    color = srgb_to_linear(color); + +    vec3 npos = normalize(-pos.xyz); + +    vec3 light = vec3(0, 0, 0); +     +    final_specular.rgb = srgb_to_linear(final_specular.rgb); // SL-14035 + +#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w ); + +    LIGHT_LOOP(1) +        LIGHT_LOOP(2) +        LIGHT_LOOP(3) +        LIGHT_LOOP(4) +        LIGHT_LOOP(5) +        LIGHT_LOOP(6) +        LIGHT_LOOP(7) + +    color += light; + +    glare = min(glare, 1.0); +    float al = max(diffcol.a, glare)*vertex_color.a; + +    //convert to srgb as this color is being written post gamma correction +    color = linear_to_srgb(color); + +#ifdef WATER_FOG +    vec4 temp = applyWaterFogView(pos, vec4(color, al)); +    color = temp.rgb; +    al = temp.a; +#endif + +    frag_color = vec4(color, al); + +#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer  + +    // deferred path +    frag_data[0] = final_color; //gbuffer is sRGB +    frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent. +    frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity. +#endif +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl deleted file mode 100644 index 9d62b9d180..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl +++ /dev/null @@ -1,291 +0,0 @@ -/**  - * @file multiSpotLightF.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$ - */ -  -#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 - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform sampler2D projectionMap; -uniform sampler2D lightFunc; - -uniform mat4 proj_mat; //screen space to light space -uniform float proj_near; //near clip for projection -uniform vec3 proj_p; //plane projection is emitting from (in screen space) -uniform vec3 proj_n; -uniform float proj_focus; //distance from plane to begin blurring -uniform float proj_lod;  //(number of mips in proj map) -uniform float proj_range; //range between near clip and far clip plane of projection -uniform float proj_ambient_lod; -uniform float proj_ambiance; -uniform float near_clip; -uniform float far_clip; - -uniform vec3 proj_origin; //origin of projection to be used for angular attenuation -uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; - -uniform vec3 center; -uniform float size; -uniform vec3 color; -uniform float falloff; - -VARYING vec4 vary_fragcoord; -uniform vec2 screen_res; - -uniform mat4 inv_proj; - -vec3 getNorm(vec2 pos_screen); - -vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) -{ -    vec4 ret = texture2DLod(projectionMap, tc, lod); -     -    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -     -    float det = min(lod/(proj_lod*0.5), 1.0); -     -    float d = min(dist.x, dist.y); -     -    d *= min(1, d * (proj_lod - lod)); -     -    float edge = 0.25*det; -     -    ret *= clamp(d/edge, 0.0, 1.0); -     -    return ret; -} - -vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) -{ -    vec4 ret = texture2DLod(projectionMap, tc, lod); - -    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -     -    float det = min(lod/(proj_lod*0.5), 1.0); -     -    float d = min(dist.x, dist.y); -     -    float edge = 0.25*det; -         -    ret *= clamp(d/edge, 0.0, 1.0); -     -    return ret; -} - -vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) -{ -    vec4 ret = texture2DLod(projectionMap, tc, lod); - -    vec2 dist = tc-vec2(0.5); -     -    float d = dot(dist,dist); -         -    ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); -     -    return ret; -} - - -vec4 getPosition(vec2 pos_screen); - -void main()  -{ -    vec4 frag = vary_fragcoord; -    frag.xyz /= frag.w; -    frag.xyz = frag.xyz*0.5+0.5; -    frag.xy *= screen_res; -     -    vec3 pos = getPosition(frag.xy).xyz; -    vec3 lv = center.xyz-pos.xyz; -    float dist = length(lv); -    dist /= size; -    if (dist > 1.0) -    { -        discard; -    } -     -    float shadow = 1.0; -     -    if (proj_shadow_idx >= 0) -    { -        vec4 shd = texture2DRect(lightMap, frag.xy); -        shadow = (proj_shadow_idx == 0) ? shd.b : shd.a; -        shadow += shadow_fade; -        shadow = clamp(shadow, 0.0, 1.0);         -    } -     -    vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -     -    float envIntensity = norm.z; - -    norm = getNorm(frag.xy); -     -    norm = normalize(norm); -    float l_dist = -dot(lv, proj_n); -     -    vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); -    if (proj_tc.z < 0.0) -    { -        discard; -    } -     -    proj_tc.xyz /= proj_tc.w; -     -    float fa = (falloff*0.5)+1.0; -    float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0); -    dist_atten *= dist_atten; -    dist_atten *= 2.0; -    if (dist_atten <= 0.0) -    { -        discard; -    } -     -    lv = proj_origin-pos.xyz; -    lv = normalize(lv); -    float da = dot(norm, lv); - -    vec3 col = vec3(0,0,0); -         -    vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb); -     -    vec4 spec = texture2DRect(specularRect, frag.xy); - -    vec3 dlit = vec3(0, 0, 0); - -    float noise = texture2D(noiseMap, frag.xy/128.0).b; -    if (proj_tc.z > 0.0 && -        proj_tc.x < 1.0 && -        proj_tc.y < 1.0 && -        proj_tc.x > 0.0 && -        proj_tc.y > 0.0) -    { -        float amb_da = proj_ambiance; -        float lit = 0.0; - -        if (da > 0.0) -        { -            lit = da * dist_atten * noise; - -            float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); -            float lod = diff * proj_lod; -             -            vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -         -            dlit = color.rgb * plcol.rgb * plcol.a; -             -            col = dlit*lit*diff_tex*shadow; -            amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; -        } -         -        //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -        vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); -                             -        amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance; -                 -        amb_da *= dist_atten * noise; -             -        amb_da = min(amb_da, 1.0-lit); -             -        col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; -    } -     - -    if (spec.a > 0.0) -    { -        vec3 npos = -normalize(pos); -        dlit *= min(da*6.0, 1.0) * dist_atten; - -        //vec3 ref = dot(pos+lv, norm); -        vec3 h = normalize(lv+npos); -        float nh = dot(norm, h); -        float nv = dot(norm, npos); -        float vh = dot(npos, h); -        float sa = nh; -        float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; - -        float gtdenom = 2 * nh; -        float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); -                                 -        if (nh > 0.0) -        { -            float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); -            col += dlit*scol*spec.rgb*shadow; -            //col += spec.rgb; -        } -    }    - -    if (envIntensity > 0.0) -    { -        vec3 ref = reflect(normalize(pos), norm); -         -        //project from point pos in direction ref to plane proj_p, proj_n -        vec3 pdelta = proj_p-pos; -        float ds = dot(ref, proj_n); -         -        if (ds < 0.0) -        { -            vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; -             -            vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - -            if (stc.z > 0.0) -            { -                stc /= stc.w; -                                 -                if (stc.x < 1.0 && -                    stc.y < 1.0 && -                    stc.x > 0.0 && -                    stc.y > 0.0) -                { -                    col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; -                } -            } -        } -    } - -    //not sure why, but this line prevents MATBUG-194 -    col = max(col, vec3(0.0)); - -    col = scaleDownLight(col); - -    //output linear space color as gamma correction happens down stream -    frag_color.rgb = col;    -    frag_color.a = 0.0; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl deleted file mode 100644 index ca9ce3a2e1..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl +++ /dev/null @@ -1,37 +0,0 @@ -/**  - * @file pointShadowBlur.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$ - */ - -uniform samplerCube cube_map;  - -in vec3 to_vec; - -out vec4 fragColor; - -void main()  -{ -	vec4 vcol = texture(cube_map, to_vec); -	fragColor = vec4(vcol.rgb, 1.0); -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl new file mode 100644 index 0000000000..8c1323ba1a --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -0,0 +1,476 @@ +/** + * @file class2/deferred/reflectionProbeF.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ + +#extension GL_ARB_shader_texture_lod : enable + +#define FLT_MAX 3.402823466e+38 + +#define REFMAP_COUNT 256 +#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider + +uniform samplerCubeArray   reflectionProbes; + +layout (std140, binding = 1) uniform ReflectionProbes +{ +    // list of OBBs for user override probes +    // box is a set of 3 planes outward facing planes and the depth of the box along that plane +    // for each box refBox[i]... +    /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation +    //  box[3][0..2] - plane thickness +    mat4 refBox[REFMAP_COUNT]; +    // list of bounding spheres for reflection probes sorted by distance to camera (closest first) +    vec4 refSphere[REFMAP_COUNT]; +    // index  of cube map in reflectionProbes for a corresponding reflection probe +    // e.g. cube map channel of refSphere[2] is stored in refIndex[2] +    // refIndex.x - cubemap channel in reflectionProbes +    // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index) +    // refIndex.z - number of neighbors +    // refIndex.w - priority, if negative, this probe has a box influence +    ivec4 refIndex[REFMAP_COUNT]; + +    // neighbor list data (refSphere indices, not cubemap array layer) +    ivec4 refNeighbor[1024]; + +    // number of reflection probes present in refSphere +    int refmapCount; + +    // intensity of ambient light from reflection probes +    float reflectionAmbiance; +}; + +// Inputs +uniform mat3 env_mat; + +// list of probeIndexes shader will actually use after "getRefIndex" is called +// (stores refIndex/refSphere indices, NOT rerflectionProbes layer) +int probeIndex[REF_SAMPLE_COUNT]; + +// number of probes stored in probeIndex +int probeInfluences = 0; + +bool isAbove(vec3 pos, vec4 plane) +{ +    return (dot(plane.xyz, pos) + plane.w) > 0; +} + +// return true if probe at index i influences position pos +bool shouldSampleProbe(int i, vec3 pos) +{ +    if (refIndex[i].w < 0) +    { +        vec4 v = refBox[i] * vec4(pos, 1.0); +        if (abs(v.x) > 1 ||  +            abs(v.y) > 1 || +            abs(v.z) > 1) +        { +            return false; +        } +    } +    else +    { +        vec3 delta = pos.xyz - refSphere[i].xyz; +        float d = dot(delta, delta); +        float r2 = refSphere[i].w; +        r2 *= r2; + +        if (d > r2) +        { //outside bounding sphere +            return false; +        } +    } + +    return true; +} + +// call before sampleRef +// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT +// overall algorithm --  +void preProbeSample(vec3 pos) +{ +    // TODO: make some sort of structure that reduces the number of distance checks + +    for (int i = 0; i < refmapCount; ++i) +    { +        // found an influencing probe +        if (shouldSampleProbe(i, pos)) +        { +            probeIndex[probeInfluences] = i; +            ++probeInfluences; + +            int neighborIdx = refIndex[i].y; +            if (neighborIdx != -1) +            { +                int neighborCount = min(refIndex[i].z, REF_SAMPLE_COUNT-1); + +                int count = 0; +                while (count < neighborCount) +                { +                    // check up to REF_SAMPLE_COUNT-1 neighbors (neighborIdx is ivec4 index) + +                    int idx = refNeighbor[neighborIdx].x; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    idx = refNeighbor[neighborIdx].y; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    idx = refNeighbor[neighborIdx].z; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    idx = refNeighbor[neighborIdx].w; +                    if (shouldSampleProbe(idx, pos)) +                    { +                        probeIndex[probeInfluences++] = idx; +                        if (probeInfluences == REF_SAMPLE_COUNT) +                        { +                            return; +                        } +                    } +                    count++; +                    if (count == neighborCount) +                    { +                        return; +                    } + +                    ++neighborIdx; +                } + +                return; +            } +        } +    } +} + +// from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection + +// original reference implementation: +/* +bool intersect(const Ray &ray) const  +{  +        float t0, t1; // solutions for t if the ray intersects  +#if 0  +        // geometric solution +        Vec3f L = center - orig;  +        float tca = L.dotProduct(dir);  +        // if (tca < 0) return false; +        float d2 = L.dotProduct(L) - tca * tca;  +        if (d2 > radius2) return false;  +        float thc = sqrt(radius2 - d2);  +        t0 = tca - thc;  +        t1 = tca + thc;  +#else  +        // analytic solution +        Vec3f L = orig - center;  +        float a = dir.dotProduct(dir);  +        float b = 2 * dir.dotProduct(L);  +        float c = L.dotProduct(L) - radius2;  +        if (!solveQuadratic(a, b, c, t0, t1)) return false;  +#endif  +        if (t0 > t1) std::swap(t0, t1);  +  +        if (t0 < 0) {  +            t0 = t1; // if t0 is negative, let's use t1 instead  +            if (t0 < 0) return false; // both t0 and t1 are negative  +        }  +  +        t = t0;  +  +        return true;  +} */ + +// adapted -- assume that origin is inside sphere, return distance from origin to edge of sphere +vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2) +{  +        float t0, t1; // solutions for t if the ray intersects  + +        vec3 L = center - origin;  +        float tca = dot(L,dir); + +        float d2 = dot(L,L) - tca * tca;  + +        float thc = sqrt(radius2 - d2);  +        t0 = tca - thc;  +        t1 = tca + thc;  +  +        vec3 v = origin + dir * t1; +        return v;  +}  + +// from https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +/* +vec3 DirectionWS = normalize(PositionWS - CameraWS); +vec3 ReflDirectionWS = reflect(DirectionWS, NormalWS); + +// Intersection with OBB convertto unit box space +// Transform in local unit parallax cube space (scaled and rotated) +vec3 RayLS = MulMatrix( float(3x3)WorldToLocal, ReflDirectionWS); +vec3 PositionLS = MulMatrix( WorldToLocal, PositionWS); + +vec3 Unitary = vec3(1.0f, 1.0f, 1.0f); +vec3 FirstPlaneIntersect  = (Unitary - PositionLS) / RayLS; +vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; +vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); +float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z)); + +// Use Distance in WS directly to recover intersection +vec3 IntersectPositionWS = PositionWS + ReflDirectionWS * Distance; +vec3 ReflDirectionWS = IntersectPositionWS - CubemapPositionWS; + +return texCUBE(envMap, ReflDirectionWS); +*/ + +// get point of intersection with given probe's box influence volume +// origin - ray origin in clip space +// dir - ray direction in clip space +// i - probe index in refBox/refSphere +vec3 boxIntersect(vec3 origin, vec3 dir, int i) +{ +    // Intersection with OBB convertto unit box space +    // Transform in local unit parallax cube space (scaled and rotated) +    mat4 clipToLocal = refBox[i]; + +    vec3 RayLS = mat3(clipToLocal) * dir; +    vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; + +    vec3 Unitary = vec3(1.0f, 1.0f, 1.0f); +    vec3 FirstPlaneIntersect  = (Unitary - PositionLS) / RayLS; +    vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; +    vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); +    float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z)); + +    // Use Distance in CS directly to recover intersection +    vec3 IntersectPositionCS = origin + dir * Distance; + +    return IntersectPositionCS; +} + + + +// Tap a sphere based reflection probe +// pos - position of pixel +// dir - pixel normal +// lod - which mip to bias towards (lower is higher res, sharper reflections) +// c - center of probe +// r2 - radius of probe squared +// i - index of probe  +// vi - point at which reflection vector struck the influence volume, in clip space +vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i) +{ +    //lod = max(lod, 1); +    // parallax adjustment + +    vec3 v; +    if (refIndex[i].w < 0) +    { +        v = boxIntersect(pos, dir, i); +    } +    else +    { +        v = sphereIntersect(pos, dir, c, r2); +    } + +    v -= c; +    v = env_mat * v; +    { +        float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res +        return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb; +        //return texture(reflectionProbes, vec4(v.xyz, refIndex[i].x)).rgb; +    } +} + +vec3 sampleProbes(vec3 pos, vec3 dir, float lod) +{ +    float wsum = 0.0; +    vec3 col = vec3(0,0,0); +    float vd2 = dot(pos,pos); // view distance squared + +    for (int idx = 0; idx < probeInfluences; ++idx) +    { +        int i = probeIndex[idx]; +        float r = refSphere[i].w; // radius of sphere volume +        float p = float(abs(refIndex[i].w)); // priority +        float rr = r*r; // radius squred +        float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down) +        vec3 delta = pos.xyz-refSphere[i].xyz; +        float d2 = dot(delta,delta); +        float r2 = r1*r1;  +         +        { +            vec3 refcol = tapRefMap(pos, dir, lod, refSphere[i].xyz, rr, i); +             +            float w = 1.0/d2; + +            float atten = 1.0-max(d2-r2, 0.0)/(rr-r2); +            w *= atten; +            w *= p; // boost weight based on priority +            col += refcol*w; +             +            wsum += w; +        } +    } + +    if (probeInfluences <= 1) +    { //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera  +        for (int idx = 0; idx < 8; ++idx) +        { +            if (refIndex[idx].w < 0) +            { // don't fallback to box probes, they are *very* specific +                continue; +            } +            int i = idx; +            vec3 delta = pos.xyz-refSphere[i].xyz; +            float d2 = dot(delta,delta); +             +            { +                vec3 refcol = tapRefMap(pos, dir, lod, refSphere[i].xyz, d2, i); +                 +                float w = 1.0/d2; +                w *= w; +                col += refcol*w; +                wsum += w; +            } +        } +    } + +    if (wsum > 0.0) +    { +        col *= 1.0/wsum; +    } +     +    return col; +} + +vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod) +{ +    vec3 col = sampleProbes(pos, dir, lod); + +    //desaturate +    vec3 hcol = col *0.5; +     +    col *= 2.0; +    col = vec3( +        col.r + hcol.g + hcol.b, +        col.g + hcol.r + hcol.b, +        col.b + hcol.r + hcol.g +    ); +     +    col *= 0.333333; + +    return col*reflectionAmbiance; + +} + +// brighten a color so that at least one component is 1 +vec3 brighten(vec3 c) +{ +    float m = max(max(c.r, c.g), c.b); + +    if (m == 0) +    { +        return vec3(1,1,1); +    } + +    return c * 1.0/m; +} + + +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,  +        vec3 pos, vec3 norm, float glossiness, float envIntensity) +{ +    // TODO - don't hard code lods +    float reflection_lods = 8; +    preProbeSample(pos); + +    vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + +    ambenv = sampleProbeAmbient(pos, norm, reflection_lods-1); + +    if (glossiness > 0.0) +    { +        float lod = (1.0-glossiness)*reflection_lods; +        glossenv = sampleProbes(pos, normalize(refnormpersp), lod); +    } + +    if (envIntensity > 0.0) +    { +        legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0); +    } +} + +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm) +{ +    glossenv *= 0.35; // fudge darker +    float fresnel = 1.0+dot(normalize(pos.xyz), norm.xyz); +    float minf = spec.a * 0.1; +    fresnel = fresnel * (1.0-minf) + minf; +    glossenv *= spec.rgb*min(fresnel, 1.0); +    color.rgb += glossenv; +} + + void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity) + { +    vec3 reflected_color = legacyenv; //*0.5; //fudge darker +    vec3 lookAt = normalize(pos); +    float fresnel = 1.0+dot(lookAt, norm.xyz); +    fresnel *= fresnel; +    fresnel = min(fresnel+envIntensity, 1.0); +    reflected_color *= (envIntensity*fresnel)*brighten(spec.rgb); +    color = mix(color.rgb, reflected_color, envIntensity); + }
\ No newline at end of file diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl deleted file mode 100644 index c8991f7a18..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl +++ /dev/null @@ -1,73 +0,0 @@ -/**  - * @file class3/deferred/shVisF.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$ - */ - -#ifdef DEFINE_GL_FRAGCOLOR -    out vec4 frag_color; -#else -    #define frag_color gl_FragColor -#endif - -///////////////////////////////////////////////////////////////////////// -// Fragment shader for L1 SH debug rendering -///////////////////////////////////////////////////////////////////////// - -uniform sampler2D sh_input_r; -uniform sampler2D sh_input_g; -uniform sampler2D sh_input_b; - -uniform mat3 inv_modelviewprojection; - -VARYING vec4 vary_pos; - -void main(void)  -{ -    vec2 coord = vary_pos.xy + vec2(0.5,0.5); - -    coord.x *= (1.6/0.9); - -    if (dot(coord, coord) > 0.25) -    { -        discard; -    } - -    vec4 n = vec4(coord*2.0, 0.0, 1); -    //n.y = -n.y; -    n.z = sqrt(max(1.0-n.x*n.x-n.y*n.y, 0.0)); -    //n.xyz = inv_modelviewprojection * n.xyz; - -    vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); -    vec4 l1r = texture2D(sh_input_r, vec2(0,0)); -    vec4 l1g = texture2D(sh_input_g, vec2(0,0)); -    vec4 l1b = texture2D(sh_input_b, vec2(0,0)); -    vec3 indirect = vec3( -                      dot(l1r, l1tap * n), -                      dot(l1g, l1tap * n), -                      dot(l1b, l1tap * n)); - -    //indirect = pow(indirect, vec3(0.45)); -    indirect *= 3.0; - -	frag_color = vec4(indirect, 1.0); -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl deleted file mode 100644 index 8f32dfde79..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl +++ /dev/null @@ -1,33 +0,0 @@ -/**  - * @file class3/deferred/shVisV.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$ - */ -ATTRIBUTE vec3 position; -VARYING vec4 vary_pos; - -void main() -{ -    // Output -    vary_pos = vec4(position, 1); -    gl_Position = vary_pos; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl deleted file mode 100644 index af1461c297..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl +++ /dev/null @@ -1,66 +0,0 @@ -/**  - * @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 !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING float target_pos_x; -VARYING vec4 pos; -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 !defined(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/class3/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl deleted file mode 100644 index 50f1ffd626..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl +++ /dev/null @@ -1,74 +0,0 @@ -/**  - * @file class3/deferred/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 !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING float pos_w; - -VARYING float target_pos_x; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -vec4 getPosition(vec2 screen_coord); -vec4 computeMoments(float depth, float a); - -void main()  -{ -    vec4 pos = getPosition(vary_texcoord0.xy); - -    float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; - -    if (alpha < 0.05) // treat as totally transparent -    { -        discard; -    } - -    if (alpha < 0.88) // treat as semi-transparent -    { -        if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) -        { -            discard; -        } -    } - -    frag_color = computeMoments(length(pos.xyz), alpha); -     -#if !defined(DEPTH_CLAMP) -    gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); -#endif - -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl deleted file mode 100644 index 6a646f5e9e..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl +++ /dev/null @@ -1,67 +0,0 @@ -/**  - * @file class3/deferred/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 !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING vec4 pos; -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); - -	pos = modelview_projection_matrix * pre_pos; - -	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; - -#if !defined(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/class3/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl deleted file mode 100644 index db8c75fb8a..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl +++ /dev/null @@ -1,50 +0,0 @@ -/**  - * @file class3/deferred/shadowCubeV.glsl - * - * $LicenseInfo:firstyear=2011&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$ - */ - -uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; - -#if !defined(DEPTH_CLAMP) -VARYING vec4 post_pos; -#endif - -uniform vec3 box_center; -uniform vec3 box_size; - -void main() -{ -	//transform vertex -	vec3 p = position*box_size+box_center; -	vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0); - -#if !defined(DEPTH_CLAMP) -	post_pos = pos; - -	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); -#else -	gl_Position = pos; -#endif -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl deleted file mode 100644 index 3350267130..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl +++ /dev/null @@ -1,49 +0,0 @@ -/**  - * @file class3/deferred/shadowF.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 !defined(DEPTH_CLAMP) -VARYING float pos_zd2; -#endif - -VARYING vec4 pos; -VARYING float target_pos_x; - -vec4 computeMoments(float depth, float a); - -void main()  -{ -    frag_color = computeMoments(length(pos), 1.0); -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl deleted file mode 100644 index 2f69a353e8..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl +++ /dev/null @@ -1,157 +0,0 @@ -/**  - * @file class3/deferred/shadowUtil.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$ - */ - -uniform sampler2D       shadowMap0; -uniform sampler2D       shadowMap1; -uniform sampler2D       shadowMap2; -uniform sampler2D       shadowMap3; -uniform sampler2D       shadowMap4; -uniform sampler2D       shadowMap5; - -uniform vec3 sun_dir; -uniform vec3 moon_dir; -uniform vec2 shadow_res; -uniform vec2 proj_shadow_res; -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform float shadow_bias; - -uniform float spot_shadow_bias; -uniform float spot_shadow_offset; - -float getDepth(vec2 screenpos); -vec3 getNorm(vec2 screenpos); -vec4 getPosition(vec2 pos_screen); - -float ReduceLightBleeding(float p_max, float Amount) -{ -    return smoothstep(Amount, 1, p_max); -} - -float ChebyshevUpperBound(vec2 m, float t, float min_v, float Amount) -{ -    float p = (t <= m.x) ? 1.0 : 0.0; - -    float v = m.y - (m.x*m.x); -    v = max(v, min_v); - -    float d = t - m.x; - -    float p_max = v / (v + d*d); - -    p_max = ReduceLightBleeding(p_max, Amount); - -    return max(p, p_max); -} - -vec4 computeMoments(float depth, float a) -{ -    float m1 = depth; -    float dx = dFdx(depth); -    float dy = dFdy(depth); -    float m2 = m1*m1 + 0.25 * a * (dx*dx + dy*dy); -    return vec4(m1, m2, a, max(dx, dy)); -} - -float vsmDirectionalSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix) -{ -    vec4 lpos = shadowMatrix * stc; -    vec4 moments = texture2D(shadowMap, lpos.xy); -    return ChebyshevUpperBound(moments.rg, depth - shadow_bias * 256.0f, 0.125, 0.9); -} - -float vsmSpotSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix) -{ -    vec4 lpos = shadowMatrix * stc; -    vec4 moments = texture2D(shadowMap, lpos.xy); -    lpos.xyz /= lpos.w; -    lpos.xy *= 0.5; -    lpos.xy += 0.5; -    return ChebyshevUpperBound(moments.rg, depth - spot_shadow_bias * 16.0f, 0.125, 0.9); -} - -#if VSM_POINT_SHADOWS -float vsmPointSample(float lightDistance, vec3 lightDirection, samplerCube shadow_cube_map) -{ -    vec4 moments = textureCube(shadow_cube_map, light_direction); -    return ChebyshevUpperBound(moments.rg, light_distance, 0.01, 0.25); -} -#endif - -float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen) -{ -	if (pos.z < -shadow_clip.w) -    { -        discard; -    } - -    float depth = getDepth(pos_screen); - -    vec4 spos       = vec4(pos,1.0); -    vec4 near_split = shadow_clip*-0.75; -    vec4 far_split  = shadow_clip*-1.25; - -    float shadow = 0.0f; -    float weight = 1.0; - -    if (spos.z < near_split.z) -    { -        shadow += vsmDirectionalSample(spos, depth, shadowMap3, shadow_matrix[3]); -        weight += 1.0f; -    } -    if (spos.z < near_split.y) -    { -        shadow += vsmDirectionalSample(spos, depth, shadowMap2, shadow_matrix[2]); -        weight += 1.0f; -    } -    if (spos.z < near_split.x) -    { -        shadow += vsmDirectionalSample(spos, depth, shadowMap1, shadow_matrix[1]); -        weight += 1.0f; -    } -    if (spos.z > far_split.x) -    { -        shadow += vsmDirectionalSample(spos, depth, shadowMap0, shadow_matrix[0]); -        weight += 1.0f; -    } - -    shadow /= weight; - -    return shadow; -} - -float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen) -{ -	if (pos.z < -shadow_clip.w) -    { -        discard; -    } - -    float depth = getDepth(pos_screen); - -    pos += norm * spot_shadow_offset; -    return vsmSpotSample(vec4(pos, 1.0), depth, (index == 0) ? shadowMap4 : shadowMap5, shadow_matrix[4 + index]); -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl deleted file mode 100644 index a0b082ed7c..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl +++ /dev/null @@ -1,126 +0,0 @@ -/**  - * @file class3/deferred/skyF.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$ - */ -  -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -VARYING vec2 vary_frag; - -uniform vec3 camPosLocal; -uniform vec3 sun_dir; -uniform float sun_size; -uniform float far_z; -uniform mat4 inv_proj; -uniform mat4 inv_modelview; - -uniform sampler2D transmittance_texture; -uniform sampler3D scattering_texture; -uniform sampler3D single_mie_scattering_texture; -uniform sampler2D irradiance_texture; -uniform sampler2D rainbow_map; -uniform sampler2D halo_map; - -uniform float moisture_level; -uniform float droplet_radius; -uniform float ice_level; - -vec3 GetSolarLuminance(); -vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance); -vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance); - -vec3 ColorFromRadiance(vec3 radiance); -vec3 rainbow(float d) -{ -    // d is the dot product of view and sun directions, so ranging -1.0..1.0 -    // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec -    // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175. - -    // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted. -    // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the -    // interesting range, but in reversed order:  i.e. d = (1 - d) - 1.575 -    d = clamp(-0.575 - d, 0.0, 1.0); - -    // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible. -    // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate -    // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857 -    float interior_coord = max(0.0, d - 0.25) * 4.2857; -    d = clamp(d, 0.0, 0.25) + interior_coord; - -    float rad = (droplet_radius - 5.0f) / 1024.0f; -    return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level; -} - -vec3 halo22(float d) -{ -   float v = sqrt(max(0, 1 - (d*d))); -   return texture2D(halo_map, vec2(0, v)).rgb * ice_level; -} - -void main() -{ -    vec3 pos      = vec3((vary_frag * 2.0) - vec2(1.0, 1.0f), 1.0); -    vec4 view_pos = (inv_proj * vec4(pos, 1.0f)); - -    view_pos /= view_pos.w; - -    vec3 view_ray = (inv_modelview * vec4(view_pos.xyz, 0.0f)).xyz + camPosLocal; - -    vec3 view_direction = normalize(view_ray); -    vec3 sun_direction  = normalize(sun_dir); -    vec3 earth_center   = vec3(0, 0, -6360.0f); -    vec3 camPos = (camPosLocal / 1000.0f) - earth_center; - -    vec3 transmittance; -    vec3 radiance_sun  = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance); -    vec3 solar_luminance = GetSolarLuminance(); - -    // If the view ray intersects the Sun, add the Sun radiance. -    float s = dot(view_direction, sun_direction); - -    // cheesy solar disc... -    if (s >= (sun_size * 0.999)) -    { -        radiance_sun += pow(smoothstep(0.0, 1.3, (s - (sun_size * 0.9))), 2.0) * solar_luminance * transmittance; -    } -    s = smoothstep(0.9, 1.0, s) * 16.0f; - -    vec3 color = ColorFromRadiance(radiance_sun); - -    float optic_d = dot(view_direction, sun_direction); -    vec3 halo_22 = halo22(optic_d); - -    color.rgb += rainbow(optic_d) * optic_d; -    color.rgb += halo_22; - -    color = pow(color, vec3(1.0/2.2)); - -    frag_data[0] = vec4(color, 1.0 + s); -    frag_data[1] = vec4(0.0); -    frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0); -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl deleted file mode 100644 index 2eb222ada4..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl +++ /dev/null @@ -1,37 +0,0 @@ -/**  - * @file class3/deferred/skyV.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$ - */ -  -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; - -VARYING vec2 vary_frag; - -void main() -{ -    // pass through untransformed fullscreen pos at back of frustum for proper sky depth testing -	gl_Position = vec4(position.xy, 1.0f, 1.0); -    vary_frag = texcoord0; -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 7ed9e7b4fc..61757882bb 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -1,31 +1,35 @@ -/**  - * @file class3/deferred/softenLightF.glsl +/** + * @file class2/deferred/softenLightF.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$   */ -  +  #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable -/*[EXTRA_CODE_HERE]*/ +#define FLT_MAX 3.402823466e+38 + +#define REFMAP_COUNT 256 +#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color; @@ -36,142 +40,153 @@ out vec4 frag_color;  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect normalMap; + +#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)  uniform sampler2DRect lightMap; +#endif +  uniform sampler2DRect depthMap;  uniform sampler2D     lightFunc; -uniform samplerCube environmentMap;  uniform float blur_size;  uniform float blur_fidelity;  // Inputs -uniform vec4 morphFactor; -uniform vec3 camPosLocal; -uniform float cloud_shadow; -uniform float max_y; -uniform vec4 glow;  uniform mat3 env_mat; -uniform vec4 shadow_clip;  uniform vec3 sun_dir; +uniform vec3 moon_dir; +uniform int  sun_up_factor;  VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj; -uniform mat4 inv_modelview; -  uniform vec2 screen_res; -uniform sampler2D transmittance_texture; -uniform sampler3D scattering_texture; -uniform sampler3D single_mie_scattering_texture; -uniform sampler2D irradiance_texture; +vec3 getNorm(vec2 pos_screen); +vec4 getPositionWithDepth(vec2 pos_screen, float depth); -uniform sampler2D sh_input_r; -uniform sampler2D sh_input_g; -uniform sampler2D sh_input_b; +void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); +float getAmbientClamp(); +vec3  atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3  scaleSoftClipFrag(vec3 l); +vec3  fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3  fullbrightScaleSoftClip(vec3 light); -vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance); -vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance); -vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance); +// reflection probe interface +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,  +        vec3 pos, vec3 norm, float glossiness, float envIntensity); +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm); +void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); -vec3 ColorFromRadiance(vec3 radiance); -vec4 getPositionWithDepth(vec2 pos_screen, float depth); -vec4 getPosition(vec2 pos_screen); -vec3 getNorm(vec2 pos_screen); +vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c);  #ifdef WATER_FOG  vec4 applyWaterFogView(vec3 pos, vec4 color);  #endif -void main()  +void main()  { -    vec2 tc = vary_fragcoord.xy; -    float depth = texture2DRect(depthMap, tc.xy).r; -    vec3 pos = getPositionWithDepth(tc, depth).xyz; -    vec4 norm = texture2DRect(normalMap, tc); +    vec2  tc           = vary_fragcoord.xy; +    float depth        = texture2DRect(depthMap, tc.xy).r; +    vec4  pos          = getPositionWithDepth(tc, depth); +    vec4  norm         = texture2DRect(normalMap, tc);      float envIntensity = norm.z; -    norm.xyz = getNorm(tc); +    norm.xyz           = getNorm(tc); + +    vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir; +    float da          = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); +    float light_gamma = 1.0 / 1.3; +    da                = pow(da, light_gamma); -    float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); +    vec4 diffuse     = texture2DRect(diffuseRect, tc); +         diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025 +    vec4 spec        = texture2DRect(specularRect, vary_fragcoord.xy); -    vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB -    diffuse.rgb = srgb_to_linear(diffuse.rgb); -    vec3 col; +#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) +    vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; +    scol_ambocc      = pow(scol_ambocc, vec2(light_gamma)); +    float scol       = max(scol_ambocc.r, diffuse.a); +    float ambocc     = scol_ambocc.g; +#else +    float scol = 1.0; +    float ambocc = 1.0; +#endif + +    vec3  color = vec3(0);      float bloom = 0.0; + +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; + +    calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); + +    //vec3 amb_vec = env_mat * norm.xyz; + +    vec3 ambenv; +    vec3 glossenv; +    vec3 legacyenv; +    sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); + +    amblit = max(ambenv, amblit); +    color.rgb = amblit*ambocc; + +    //float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +    //ambient *= 0.5; +    //ambient *= ambient; +    //ambient = (1.0 - ambient); +    //color.rgb *= ambient; + +    vec3 sun_contrib = min(da, scol) * sunlit; +    color.rgb += sun_contrib; +    color.rgb = min(color.rgb, vec3(1,1,1)); +    color.rgb *= diffuse.rgb; + +    vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + +    if (spec.a > 0.0)  // specular reflection      { -        vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f); - -        vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); -         -        vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; - -        float scol = max(scol_ambocc.r, diffuse.a);  - -        float ambocc = scol_ambocc.g; - -        vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); -        vec4 l1r = texture2D(sh_input_r, vec2(0,0)); -        vec4 l1g = texture2D(sh_input_g, vec2(0,0)); -        vec4 l1b = texture2D(sh_input_b, vec2(0,0)); - -        vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)), -                             dot(l1g, l1tap * vec4(1, norm.xyz)), -                             dot(l1b, l1tap * vec4(1, norm.xyz))); - -        indirect = clamp(indirect, vec3(0), vec3(1.0)); - -        vec3 transmittance; -        vec3 sky_irradiance; -        vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance); -        vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance); - -        vec3 radiance   = scol * (sun_irradiance + sky_irradiance) + inscatter; -        vec3 atmo_color = ColorFromRadiance(radiance); - -        col = atmo_color + indirect; -        col *= transmittance; -        col *= diffuse.rgb; - -        vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); - -        if (spec.a > 0.0) // specular reflection -        { -            // the old infinite-sky shiny reflection -            // -            float sa = dot(refnormpersp, sun_dir.xyz); -            vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color; -             -            // add the two types of shiny together -            vec3 spec_contrib = dumbshiny * spec.rgb * 0.25; -            bloom = dot(spec_contrib, spec_contrib); -            col += spec_contrib; -        } - -        col = mix(col, diffuse.rgb, diffuse.a); - -        if (envIntensity > 0.0) -        { //add environmentmap -            vec3 env_vec = env_mat * refnormpersp; -            vec3 sun_direction  = (inv_modelview * vec4(sun_dir, 1.0)).xyz; -            vec3 radiance_sun  = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance); -            vec3 refcol = ColorFromRadiance(radiance_sun); -            col = mix(col.rgb, refcol, envIntensity); -        } -                         -        /*if (norm.w < 0.5) -        { -            col = scaleSoftClipFrag(col); -        }*/ - -        #ifdef WATER_FOG -            vec4 fogged = applyWaterFogView(pos,vec4(col, bloom)); -            col = fogged.rgb; -            bloom = fogged.a; -        #endif +        float sa        = dot(normalize(refnormpersp), light_dir.xyz); +        vec3  dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r); + +        // add the two types of shiny together +        vec3 spec_contrib = dumbshiny * spec.rgb; +        bloom             = dot(spec_contrib, spec_contrib) / 6; +        color.rgb += spec_contrib; + +        // add reflection map - EXPERIMENTAL WORK IN PROGRESS +        applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);      } -    //output linear since gamma correction happens down stream -    frag_color.rgb = col; +    color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); + +    if (envIntensity > 0.0) +    {  // add environmentmap +        //fudge darker +        legacyenv *= 0.5*diffuse.a+0.5;; +        applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); +    } + +    if (norm.w < 0.5) +    { +        color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); +        color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); +    } + +#ifdef WATER_FOG +    vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); +    color       = fogged.rgb; +    bloom       = fogged.a; +#endif + +    // convert to linear as fullscreen lights need to sum in linear colorspace +    // and will be gamma (re)corrected downstream... +    //color = vec3(ambocc); +    //color = ambenv; +    //color.b = diffuse.a; +    frag_color.rgb = srgb_to_linear(color.rgb);      frag_color.a = bloom;  } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl deleted file mode 100644 index 9d872b8df8..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl +++ /dev/null @@ -1,38 +0,0 @@ -/**  - * @file class3/deferred/softenLightV.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$ - */ -ATTRIBUTE vec3 position; - -VARYING vec2 vary_fragcoord; - -uniform mat4 modelview_projection_matrix; -uniform vec2 screen_res; - -void main() -{ -	//transform vertex -	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); -	gl_Position = pos;  -	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl deleted file mode 100644 index 56b0f4e5ce..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ /dev/null @@ -1,287 +0,0 @@ -/**  - * @file spotLightF.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$ - */ -  -#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 - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform sampler2D projectionMap; -uniform sampler2D lightFunc; - -uniform mat4 proj_mat; //screen space to light space -uniform float proj_near; //near clip for projection -uniform vec3 proj_p; //plane projection is emitting from (in screen space) -uniform vec3 proj_n; -uniform float proj_focus; //distance from plane to begin blurring -uniform float proj_lod;  //(number of mips in proj map) -uniform float proj_range; //range between near clip and far clip plane of projection -uniform float proj_ambient_lod; -uniform float proj_ambiance; -uniform float near_clip; -uniform float far_clip; - -uniform vec3 proj_origin; //origin of projection to be used for angular attenuation -uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; - -uniform float size; -uniform vec3 color; -uniform float falloff; - -VARYING vec3 trans_center; -VARYING vec4 vary_fragcoord; -uniform vec2 screen_res; - -uniform mat4 inv_proj; - -vec3 getNorm(vec2 pos_screen); - -vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) -{ -    vec4 ret = texture2DLod(projectionMap, tc, lod); -     -    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -     -    float det = min(lod/(proj_lod*0.5), 1.0); -     -    float d = min(dist.x, dist.y); -     -    d *= min(1, d * (proj_lod - lod)); -     -    float edge = 0.25*det; -     -    ret *= clamp(d/edge, 0.0, 1.0); -     -    return ret; -} - -vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) -{ -    vec4 ret = texture2DLod(projectionMap, tc, lod); -     -    vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -     -    float det = min(lod/(proj_lod*0.5), 1.0); -     -    float d = min(dist.x, dist.y); -     -    float edge = 0.25*det; -         -    ret *= clamp(d/edge, 0.0, 1.0); -     -    return ret; -} - -vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) -{ -    vec4 ret = texture2DLod(projectionMap, tc, lod); -     -    vec2 dist = tc-vec2(0.5); -     -    float d = dot(dist,dist); -         -    ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); -     -    return ret; -} - - -vec4 getPosition(vec2 pos_screen); - -void main()  -{ -    vec4 frag = vary_fragcoord; -    frag.xyz /= frag.w; -    frag.xyz = frag.xyz*0.5+0.5; -    frag.xy *= screen_res; -     -    vec3 pos = getPosition(frag.xy).xyz; -    vec3 lv = trans_center.xyz-pos.xyz; -    float dist = length(lv); -    dist /= size; -    if (dist > 1.0) -    { -        discard; -    } -     -    float shadow = 1.0; -     -    if (proj_shadow_idx >= 0) -    { -        vec4 shd = texture2DRect(lightMap, frag.xy); -        shadow = (proj_shadow_idx == 0) ? shd.b : shd.a; -        shadow += shadow_fade; -        shadow = clamp(shadow, 0.0, 1.0); -    } -     -    vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -    float envIntensity = norm.z; -    norm = getNorm(frag.xy); -     -    norm = normalize(norm); -    float l_dist = -dot(lv, proj_n); -     -    vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); -    if (proj_tc.z < 0.0) -    { -        discard; -    } -     -    proj_tc.xyz /= proj_tc.w; -     -    float fa = (falloff*0.5) + 1.0; -    float dist_atten = min(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 1.0); -    dist_atten *= dist_atten; -    dist_atten *= 2.0; - -    if (dist_atten <= 0.0) -    { -        discard; -    } -     -    lv = proj_origin-pos.xyz; -    lv = normalize(lv); -    float da = dot(norm, lv); -         -    vec3 col = vec3(0,0,0); -         -    vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb); -         -    vec4 spec = texture2DRect(specularRect, frag.xy); - -    vec3 dlit = vec3(0, 0, 0); - -    float noise = texture2D(noiseMap, frag.xy/128.0).b; -    if (proj_tc.z > 0.0 && -        proj_tc.x < 1.0 && -        proj_tc.y < 1.0 && -        proj_tc.x > 0.0 && -        proj_tc.y > 0.0) -    { -        float amb_da = proj_ambiance; -        float lit = 0.0; -         -        if (da > 0.0) -        { -            lit = da * dist_atten * noise; - -            float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); -            float lod = diff * proj_lod; -             -            vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -         -            dlit = color.rgb * plcol.rgb * plcol.a; -             -            col = dlit*lit*diff_tex*shadow; -            amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; -        } -         -        //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -        vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); -                             -        amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance; -                 -        amb_da *= dist_atten * noise; -             -        amb_da = min(amb_da, 1.0-lit); -             -        col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; -    } -     - -    if (spec.a > 0.0) -    { -        dlit *= min(da*6.0, 1.0) * dist_atten; -        vec3 npos = -normalize(pos); - -        //vec3 ref = dot(pos+lv, norm); -        vec3 h = normalize(lv+npos); -        float nh = dot(norm, h); -        float nv = dot(norm, npos); -        float vh = dot(npos, h); -        float sa = nh; -        float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; - -        float gtdenom = 2 * nh; -        float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); -                                 -        if (nh > 0.0) -        { -            float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); -            col += dlit*scol*spec.rgb*shadow; -        } -    }    -     - -    if (envIntensity > 0.0) -    { -        vec3 ref = reflect(normalize(pos), norm); -         -        //project from point pos in direction ref to plane proj_p, proj_n -        vec3 pdelta = proj_p-pos; -        float ds = dot(ref, proj_n); -         -        if (ds < 0.0) -        { -            vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; -             -            vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - -            if (stc.z > 0.0) -            { -                stc /= stc.w; -                                 -                if (stc.x < 1.0 && -                    stc.y < 1.0 && -                    stc.x > 0.0 && -                    stc.y > 0.0) -                { -                    col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; -                } -            } -        } -    } -     -    //not sure why, but this line prevents MATBUG-194 -    col = max(col, vec3(0.0)); - -    frag_color.rgb = col;    -    frag_color.a = 0.0; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl deleted file mode 100644 index 112b498c90..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl +++ /dev/null @@ -1,57 +0,0 @@ -/**  - * @file class3\deferred\sunLightF.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$ - */ - -#extension GL_ARB_texture_rectangle : enable - -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -//class 2, shadows, no SSAO - -// Inputs -VARYING vec2 vary_fragcoord; - -vec4 getPosition(vec2 pos_screen); -vec3 getNorm(vec2 pos_screen); - -float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);  -float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);  - -void main()  -{ -	vec2 pos_screen = vary_fragcoord.xy; -	vec4 pos = getPosition(pos_screen); -	vec3 norm = getNorm(pos_screen); - -	frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen); -	frag_color.g = 1.0f; -    frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen); -    frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen); -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl deleted file mode 100644 index 342a2ff3ed..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl +++ /dev/null @@ -1,61 +0,0 @@ -/**  - * @file class3\deferred\sunLightSSAOF.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$ - */ -  -#extension GL_ARB_texture_rectangle : enable - -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -//class 2 -- shadows and SSAO - -// Inputs -VARYING vec2 vary_fragcoord; - -uniform vec3 sun_dir; - -vec4 getPosition(vec2 pos_screen); -vec3 getNorm(vec2 pos_screen); - -float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); -float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen); - -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen); - -void main()  -{ -	vec2 pos_screen = vary_fragcoord.xy; -	vec4 pos        = getPosition(pos_screen); -	vec3 norm       = getNorm(pos_screen); - -	frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen); -    frag_color.b = calcAmbientOcclusion(pos, norm, pos_screen); -    frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen); -    frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen); -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl deleted file mode 100644 index bc5eb5181d..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl +++ /dev/null @@ -1,41 +0,0 @@ -/**  - * @file sunLightV.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$ - */ - -uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; - -VARYING vec2 vary_fragcoord; - -uniform vec2 screen_res; - -void main() -{ -	//transform vertex -	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); -	gl_Position = pos;  -	 -	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	 -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl deleted file mode 100644 index 41673d1669..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl +++ /dev/null @@ -1,59 +0,0 @@ -/**  - * @file treeShadowF.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$ - */ - -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform float minimum_alpha; - -uniform sampler2D diffuseMap; - -VARYING vec4 pos; -VARYING vec2 vary_texcoord0; - -vec4 computeMoments(float d, float a); - -void main()  -{ -	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a; - -	if (alpha < minimum_alpha) -	{ -		discard; -	} - -    frag_color = computeMoments(length(pos), 1.0); - -#if !defined(DEPTH_CLAMP) -	gl_FragDepth = max(pos.z/pos.w*0.5+0.5, 0.0); -#endif - -} - diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl deleted file mode 100644 index 15e769ac10..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl +++ /dev/null @@ -1,43 +0,0 @@ -/**  - * @file treeShadowV.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$ - */ - -uniform mat4 texture_matrix0; -uniform mat4 modelview_projection_matrix; -  -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; - -VARYING vec4 pos; -VARYING vec2 vary_texcoord0; - -void main() -{ -	//transform vertex -	pos = modelview_projection_matrix*vec4(position.xyz, 1.0); - -	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); -	 -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl deleted file mode 100644 index 540226e672..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file underWaterF.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$ - */ -  -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -uniform sampler2D diffuseMap; -uniform sampler2D bumpMap;    -uniform sampler2D screenTex; -uniform sampler2D refTex; -uniform sampler2D screenDepth; - -uniform vec4 fogCol; -uniform vec3 lightDir; -uniform vec3 specular; -uniform float lightExp; -uniform vec2 fbScale; -uniform float refScale; -uniform float znear; -uniform float zfar; -uniform float kd; -uniform vec4 waterPlane; -uniform vec3 eyeVec; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; -uniform vec2 screenRes; - -//bigWave is (refCoord.w, view.w); -VARYING vec4 refCoord; -VARYING vec4 littleWave; -VARYING vec4 view; - -vec2 encode_normal(vec3 n); - -vec4 applyWaterFog(vec4 color, vec3 viewVec) -{ -	//normalize view vector -	vec3 view = normalize(viewVec); -	float es = -view.z; - -	//find intersection point with water plane and eye vector -	 -	//get eye depth -	float e0 = max(-waterPlane.w, 0.0); -	 -	//get object depth -	float depth = length(viewVec); -		 -	//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); -	return color * D + kc * L; -} - -void main()  -{ -	vec4 color; -	     -	//get detail normals -	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; -	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; -	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;     -	vec3 wavef = normalize(wave1+wave2+wave3); -	 -	//figure out distortion vector (ripply)    -	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -	distort = distort+wavef.xy*refScale; -		 -	vec4 fb = texture2D(screenTex, distort); - -	frag_data[0] = vec4(fb.rgb, 1.0); // diffuse -	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec -	frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl deleted file mode 100644 index c65cf48c67..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl +++ /dev/null @@ -1,174 +0,0 @@ -/**  - * @file waterF.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$ - */ -  -#extension GL_ARB_texture_rectangle : enable - -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -uniform sampler2D bumpMap;    -uniform sampler2D bumpMap2; -uniform float blend_factor; -uniform sampler2D screenTex; -uniform sampler2D refTex; - -uniform float sunAngle; -uniform float sunAngle2; -uniform vec3 lightDir; -uniform vec3 specular; -uniform float lightExp; -uniform float refScale; -uniform float kd; -uniform vec2 screenRes; -uniform vec3 normScale; -uniform float fresnelScale; -uniform float fresnelOffset; -uniform float blurMultiplier; -uniform vec2 screen_res; -uniform mat4 norm_mat; //region space to screen space - -//bigWave is (refCoord.w, view.w); -VARYING vec4 refCoord; -VARYING vec4 littleWave; -VARYING vec4 view; -VARYING vec4 vary_position; - -vec3 scaleSoftClip(vec3 c); -vec2 encode_normal(vec3 n); - -vec3 BlendNormal(vec3 bump1, vec3 bump2) -{ -    //vec3 normal   = bump1.xyz * vec3( 2.0,  2.0, 2.0) - vec3(1.0, 1.0,  0.0); -    //vec3 normal2  = bump2.xyz * vec3(-2.0, -2.0, 2.0) + vec3(1.0, 1.0, -1.0); -    //vec3 n        = normalize(normal * dot(normal, normal2) - (normal2 * normal.z)); -    vec3 n = normalize(mix(bump1, bump2, blend_factor)); -    return n; -} - -void main()  -{ -	vec4 color; -	float dist = length(view.xy); -	 -	//normalize view vector -	vec3 viewVec = normalize(view.xyz); -	 -	//get wave normals -	vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; -	vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; -	vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; - - -	vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0; -	vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0; -	vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0; - -    vec3 wave1 = BlendNormal(wave1_a, wave1_b); -    vec3 wave2 = BlendNormal(wave2_a, wave2_b); -    vec3 wave3 = BlendNormal(wave3_a, wave3_b); - -	//get base fresnel components	 -	 -	vec3 df = vec3( -					dot(viewVec, wave1), -					dot(viewVec, (wave2 + wave3) * 0.5), -					dot(viewVec, wave3) -				 ) * fresnelScale + fresnelOffset; -	df *= df; -		     -	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -	 -	float dist2 = dist; -	dist = max(dist, 5.0); -	 -	float dmod = sqrt(dist); -	 -	vec2 dmod_scale = vec2(dmod*dmod, dmod); -	 -	//get reflected color -	vec2 refdistort1 = wave1.xy*normScale.x; -	vec2 refvec1 = distort+refdistort1/dmod_scale; -	vec4 refcol1 = texture2D(refTex, refvec1); -	 -	vec2 refdistort2 = wave2.xy*normScale.y; -	vec2 refvec2 = distort+refdistort2/dmod_scale; -	vec4 refcol2 = texture2D(refTex, refvec2); -	 -	vec2 refdistort3 = wave3.xy*normScale.z; -	vec2 refvec3 = distort+refdistort3/dmod_scale; -	vec4 refcol3 = texture2D(refTex, refvec3); - -	vec4 refcol = refcol1 + refcol2 + refcol3; -	float df1 = df.x + df.y + df.z; -	refcol *= df1 * 0.333; -	 -	vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; -	wavef.z *= max(-viewVec.z, 0.1); -	wavef = normalize(wavef); -	 -	float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; -	 -	vec2 refdistort4 = wavef.xy*0.125; -	refdistort4.y -= abs(refdistort4.y); -	vec2 refvec4 = distort+refdistort4/dmod; -	float dweight = min(dist2*blurMultiplier, 1.0); -	vec4 baseCol = texture2D(refTex, refvec4); - -	refcol = mix(baseCol*df2, refcol, dweight); - -	//get specular component -	float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); -		 -	//harden specular -	spec = pow(spec, 128.0); - -	//figure out distortion vector (ripply)    -	vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); -		 -	vec4 fb = texture2D(screenTex, distort2); -	 -	//mix with reflection -	// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug -	color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); - -    color.rgb *= 2.0f; -    color.rgb = scaleSoftClip(color.rgb); -	 -	vec4 pos = vary_position; -	 -	color.rgb += spec * specular; -	color.a    = spec * sunAngle2; -     -	vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz); -	 -	frag_data[0] = vec4(color.rgb, color); // diffuse -	frag_data[1] = vec4(spec * specular, spec);		// speccolor, spec -	frag_data[2] = vec4(encode_normal(wavef.xyz), 0.05, 0);// normalxy, 0, 0 -} diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl deleted file mode 100644 index 02000d90ca..0000000000 --- a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl +++ /dev/null @@ -1,95 +0,0 @@ -/**  - * @file waterV.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$ - */ - -uniform mat4 modelview_matrix; -uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; - - -uniform vec2 d1; -uniform vec2 d2; -uniform float time; -uniform vec3 eyeVec; -uniform float waterHeight; - -VARYING vec4 refCoord; -VARYING vec4 littleWave; -VARYING vec4 view; - -VARYING vec4 vary_position; - -float wave(vec2 v, float t, float f, vec2 d, float s)  -{ -   return (dot(d, v)*f + t*s)*f; -} - -void main() -{ -	//transform vertex -	vec4 pos = vec4(position.xyz, 1.0); -	mat4 modelViewProj = modelview_projection_matrix; -	 -	vec4 oPosition; -		     -	//get view vector -	vec3 oEyeVec; -	oEyeVec.xyz = pos.xyz-eyeVec; -		 -	float d = length(oEyeVec.xy); -	float ld = min(d, 2560.0); -	 -	pos.xy = eyeVec.xy + oEyeVec.xy/d*ld; -	view.xyz = oEyeVec; -		 -	d = clamp(ld/1536.0-0.5, 0.0, 1.0);	 -	d *= d; -		 -	oPosition = vec4(position, 1.0); -	oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); -	vary_position = modelview_matrix * oPosition; -	oPosition = modelViewProj * oPosition; -	 -	refCoord.xyz = oPosition.xyz + vec3(0,0,0.2); -	 -	//get wave position parameter (create sweeping horizontal waves) -	vec3 v = pos.xyz; -	v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0; -	     -	//push position for further horizon effect. -	pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z); -	pos.w = 1.0; -	pos = modelview_matrix*pos; -	 -	//pass wave parameters to pixel shader -	vec2 bigWave =  (v.xy) * vec2(0.04,0.04)  + d1 * time * 0.055; -	//get two normal map (detail map) texture coordinates -	littleWave.xy = (v.xy) * vec2(0.45, 0.9)   + d2 * time * 0.13; -	littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1; -	view.w = bigWave.y; -	refCoord.w = bigWave.x; -	 -	gl_Position = oPosition; -} diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 84a41113be..8d02bec53e 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1188,12 +1188,18 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)  static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera"); +extern BOOL gCubeSnapshot; +  //-----------------------------------------------------------------------------  // updateCamera()  //-----------------------------------------------------------------------------  void LLAgentCamera::updateCamera()  {  	LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA); +    if (gCubeSnapshot) +    { +        return; +    }  	// - changed camera_skyward to the new global "mCameraUpVector"  	mCameraUpVector = LLVector3::z_axis; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3bcd4f9a49..c60f2d0fcc 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1506,22 +1506,23 @@ bool LLAppViewer::doFrame()  			// Render scene.  			// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18 -			if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) -			{ -				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Display" ) -				pingMainloopTimeout("Main:Display"); -				gGLActive = TRUE; +            if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display"); +                pingMainloopTimeout("Main:Display"); +                gGLActive = TRUE; -				display(); +                display(); -				{ -					LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) -				pingMainloopTimeout("Main:Snapshot"); -				LLFloaterSnapshot::update(); // take snapshots -					LLFloaterOutfitSnapshot::update(); -				gGLActive = FALSE; -			} -		} +                { +                    LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot"); +                    pingMainloopTimeout("Main:Snapshot"); +                    gPipeline.mReflectionMapManager.update(); +                    LLFloaterSnapshot::update(); // take snapshots +                    LLFloaterOutfitSnapshot::update(); +                    gGLActive = FALSE; +                } +            }  		}  		{ diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index a3837fe10c..1e548141c8 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -37,6 +37,7 @@  #include "lldrawpoolbump.h"  #include "lldrawpoolmaterials.h"  #include "lldrawpoolground.h" +#include "lldrawpoolpbropaque.h"  #include "lldrawpoolsimple.h"  #include "lldrawpoolsky.h"  #include "lldrawpooltree.h" @@ -117,6 +118,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  	case POOL_WL_SKY:  		poolp = new LLDrawPoolWLSky();  		break; +	case POOL_PBR_OPAQUE: +		poolp = new LLDrawPoolPBROpaque(); +		break;  	default:  		LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;  		return NULL; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index fd1b022e5b..b73ae94bbb 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -67,6 +67,7 @@ public:  		POOL_WATER,  		POOL_GLOW,  		POOL_ALPHA, +		POOL_PBR_OPAQUE,  		NUM_POOL_TYPES,  		// * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them  		// - and the LLDrawPool types enum controls what order things are rendered in diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index e674707c01..89b8ec1ba2 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -129,6 +129,8 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d      }  } +extern BOOL gCubeSnapshot; +  void LLDrawPoolAlpha::renderPostDeferred(S32 pass)   {       LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; @@ -155,13 +157,13 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)      forwardRender();      // final pass, render to depth for depth of field effects -    if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField")) +    if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot)      {           //update depth buffer sampler -        gPipeline.mScreen.flush(); -        gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), -            0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); -        gPipeline.mDeferredDepth.bindTarget(); +        gPipeline.mRT->screen.flush(); +        gPipeline.mRT->deferredDepth.copyContents(gPipeline.mRT->deferredScreen, 0, 0, gPipeline.mRT->deferredScreen.getWidth(), gPipeline.mRT->deferredScreen.getHeight(), +            0, 0, gPipeline.mRT->deferredDepth.getWidth(), gPipeline.mRT->deferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); +        gPipeline.mRT->deferredDepth.bindTarget();          simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;          simple_shader->bind(); @@ -175,8 +177,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)          renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,               true); // <--- discard mostly transparent faces -        gPipeline.mDeferredDepth.flush(); -        gPipeline.mScreen.bindTarget(); +        gPipeline.mRT->deferredDepth.flush(); +        gPipeline.mRT->screen.bindTarget();          gGL.setColorMask(true, false);      } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 8db6a10e26..288ba8f536 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -465,6 +465,11 @@ void LLDrawPoolBump::beginFullbrightShiny()  		shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);          cube_map->setMatrix(1); +        if (shader->mFeatures.hasReflectionProbes) +        { +            gPipeline.bindReflectionProbes(*shader); +        } +  		// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for   		// the cube map in the one pass shiny shaders  		gGL.getTexUnit(1)->disable(); @@ -526,6 +531,10 @@ void LLDrawPoolBump::endFullbrightShiny()  	{  		cube_map->disable();          cube_map->restoreMatrix(); +        if (shader->mFeatures.hasReflectionProbes) +        { +            gPipeline.unbindReflectionProbes(*shader); +        }  		shader->unbind();  	} @@ -741,6 +750,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  void LLDrawPoolBump::renderPostDeferred(S32 pass)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL      for (int i = 0; i < 2; ++i)      { // two passes -- static and rigged          mRigged = (i == 1); diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp new file mode 100644 index 0000000000..2478aa0cff --- /dev/null +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -0,0 +1,92 @@ +/**  + * @file lldrawpoolpbropaque.cpp + * @brief LLDrawPoolPBROpaque class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "lldrawpool.h" +#include "lldrawpoolpbropaque.h" +#include "llviewershadermgr.h" +#include "pipeline.h" + +LLDrawPoolPBROpaque::LLDrawPoolPBROpaque() : +    LLRenderPass(POOL_PBR_OPAQUE) +{ +} + +void LLDrawPoolPBROpaque::prerender() +{ +    mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  +} + +// Forward +void LLDrawPoolPBROpaque::beginRenderPass(S32 pass) +{ +} + +void LLDrawPoolPBROpaque::endRenderPass( S32 pass ) +{ +} + +void LLDrawPoolPBROpaque::render(S32 pass) +{ +} + +// Deferred +void LLDrawPoolPBROpaque::beginDeferredPass(S32 pass) +{ +    gDeferredPBROpaqueProgram.bind(); +} + +void LLDrawPoolPBROpaque::endDeferredPass(S32 pass) +{ +    gDeferredPBROpaqueProgram.unbind(); +    LLRenderPass::endRenderPass(pass); +} + +void LLDrawPoolPBROpaque::renderDeferred(S32 pass) +{ +    if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_MATERIALS)) +    { +         return; +    } + +    gGL.flush(); + +    LLGLDisable blend(GL_BLEND); +    LLGLDisable alpha_test(GL_ALPHA_TEST); + +    // TODO: handle HUDs? +    //if (LLPipeline::sRenderingHUDs) +    //    mShader->uniform1i(LLShaderMgr::NO_ATMO, 1); +    //else +    //    mShader->uniform1i(LLShaderMgr::NO_ATMO, 0); + +    // TODO: handle under water? +    // if (LLPipeline::sUnderWaterRender) +    // PASS_SIMPLE or PASS_MATERIAL +    //pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +} + diff --git a/indra/newview/lldrawpoolpbropaque.h b/indra/newview/lldrawpoolpbropaque.h new file mode 100644 index 0000000000..ada806a3bf --- /dev/null +++ b/indra/newview/lldrawpoolpbropaque.h @@ -0,0 +1,61 @@ +/**  + * @file lldrawpoolpbropaque.h + * @brief LLDrawPoolPBrOpaque class definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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_LLDRAWPOOLPBROPAQUE_H +#define LL_LLDRAWPOOLPBROPAQUE_H + +#include "lldrawpool.h" + +class LLDrawPoolPBROpaque : public LLRenderPass +{ +public: +    enum +    { +       VERTEX_DATA_MASK = 0 +                        | LLVertexBuffer::MAP_VERTEX +                        | LLVertexBuffer::MAP_NORMAL +                        | LLVertexBuffer::MAP_TEXCOORD0 +                        | LLVertexBuffer::MAP_COLOR +    }; +    virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +    LLDrawPoolPBROpaque(); + +    /*virtual*/ S32 getNumDeferredPasses() { return 1; } +    /*virtual*/ void beginDeferredPass(S32 pass); +    /*virtual*/ void endDeferredPass(S32 pass); +    /*virtual*/ void renderDeferred(S32 pass); + +    // Non ALM isn't supported +    /*virtual*/ void beginRenderPass(S32 pass); +    /*virtual*/ void endRenderPass(S32 pass); +    /*virtual*/ S32  getNumPasses() { return 0; } +    /*virtual*/ void render(S32 pass = 0); +    /*virtual*/ void prerender(); + +}; + +#endif // LL_LLDRAWPOOLPBROPAQUE_H diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index d0c26bc43b..a2d9c0ba2b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -587,7 +587,6 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)  						glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);  					}  					gGL.syncMatrices(); -					LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 );  					glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);  					glDisableClientState(GL_TEXTURE_COORD_ARRAY);  				} diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index fe5120376c..7279e1ad6d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -330,8 +330,8 @@ void LLFloaterModelPreview::initModelPreview()  	S32 tex_width = 512;  	S32 tex_height = 512; -	S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenWidth); -	S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenHeight); +	S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->width); +	S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->height);  	while ((tex_width << 1) < max_width)  	{ diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 8d19aa36bb..045bc4a6b8 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1182,6 +1182,7 @@ void LLFloaterPreference::refreshEnabledState()  {  	LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");  	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); +    LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");  	// if vertex shaders off, disable all shader related products  	if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")) @@ -1205,6 +1206,11 @@ void LLFloaterPreference::refreshEnabledState()  	ctrl_deferred->setEnabled(enabled); +    //PBR +    BOOL deferred = gSavedSettings.getBOOL("RenderDeferred"); +    // TODO: add "RenderPBR" to LLFeatureManager +    ctrl_pbr->setEnabled(deferred); +  	// Cannot have floater active until caps have been received  	getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 71657239a6..ad3742157f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -123,6 +123,7 @@ F32		LLPanelFace::getCurrentShinyScaleU()		{ return getChild<LLUICtrl>("shinySca  F32		LLPanelFace::getCurrentShinyScaleV()		{ return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal();					}  F32		LLPanelFace::getCurrentShinyOffsetU()		{ return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal();					}  F32		LLPanelFace::getCurrentShinyOffsetV()		{ return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal();					} +LLUUID	LLPanelFace::getCurrentMaterialID()			{ return getChild<LLUICtrl>("materialID")->getValue().asUUID(); 					}  //  // Methods @@ -154,9 +155,11 @@ BOOL	LLPanelFace::postBuild()  	childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);  	childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);  	childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); +	childSetCommitCallback("materialID", &LLPanelFace::onCommitMaterialID, this);  	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);  	childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); +	childSetAction("button save material", &LLPanelFace::onSaveMaterial, this);  	LLTextureCtrl*	mTextureCtrl;  	LLTextureCtrl*	mShinyTextureCtrl; @@ -298,7 +301,7 @@ BOOL	LLPanelFace::postBuild()  	{  		mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);  	} -	 +  	clearCtrls(); @@ -1409,7 +1412,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  			LLMaterialPtr material;  			LLSelectedTEMaterial::getCurrent(material, identical); -			if (material && editable) +            // enable this UI box if a single face is selected. +            BOOL is_single_face = !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected(); +            childSetEnabled("button save material", static_cast<bool>(is_single_face)); +            childSetEnabled("materialID", static_cast<bool>(is_single_face));   // doesn't work - why? + +            // TODO: 2022-04 conflicts with media button placement. hide the button if applying media +            // i.e.  childSetVisible("button save material", !applying_media); + +            if (material && editable)  			{  				LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL; @@ -1518,6 +1529,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  		calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal());  		calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal());  		calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal()); + +		getChildView("materialID")->setEnabled(editable);  	}  	else  	{ @@ -2302,6 +2315,17 @@ void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata)  	LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff());  } +//static +void LLPanelFace::onCommitMaterialID(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = static_cast<LLPanelFace*>(userdata); +    LLUUID matID = self->getCurrentMaterialID(); +	LLSelectedTEMaterial::setMaterialID(self, matID); + +    // Temporary demo hack - replace the TE entries with those from the Material's LLSD +    applyMaterialUUID(matID, userdata); +} +  // static  void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )  { @@ -2538,6 +2562,207 @@ void LLPanelFace::onAlignTexture(void* userdata)      self->alignTestureLayer();  } +#include "llagent.h" +#include "llfilesystem.h" +#include "llviewerassetupload.h" +#include "llviewermenufile.h" +#include "llsd.h" +#include "llsdutil.h" +#include "llsdserialize.h" +#include "llinventorymodel.h" + +void LLPanelFace::onSaveMaterial(void* userdata) +{ +    // DRTVWR-559, Q&D material picker - save to inventory goes here +    LL_DEBUGS("Material") << "saving render material to inventory" << LL_ENDL; + +    std::string name = "New Material"; + +	LLSD material_data = llsd::map( +		"version", "1", +		"material", LLSD::emptyMap() +	); + +    // gen a new uuid for this asset +    LLTransactionID tid; +    tid.generate();     // timestamp-based randomization + uniquification +    LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + +    material_data["material"] = renderMaterialToLLSD(new_asset_id, userdata); +    std::stringstream output; +    LLSDSerialize::toNotation(material_data, output); + +    //S32 expected_upload_cost = 0;// LLAgentBenefitsMgr::current().getTextureUploadCost(); +     +    std::string res_name = name; +    std::string res_desc = "Saved Material"; +    //LLFolderType::EType folder_type = LLFolderType::FT_MATERIAL; +    //LLInventoryType::EType inv_type = LLInventoryType::IT_MATERIAL; +    U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); + +    LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); +    const U8 subtype = NO_INV_SUBTYPE;  // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? + +    create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, res_name, res_desc, +        LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, +        new LLBoostFuncInventoryCallback([output=output.str()](LLUUID const & inv_item_id){ +            // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() +            LLResourceUploadInfo::ptr_t uploadInfo = +                std::make_shared<LLBufferedAssetUploadInfo>( +                    inv_item_id, +                    LLAssetType::AT_SETTINGS, // TODO switch to AT_MATERIAL +                    output, +                    [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { +                        LL_INFOS("Material") << "inventory item uploaded.  item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; +                        LLSD params = llsd::map("ASSET_ID", new_asset_id); +                        LLNotificationsUtil::add("MaterialCreated", params); +                    }); + +            const LLViewerRegion* region = gAgent.getRegion(); +            if (region) +            { +                 std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); +                 if (agent_url.empty()) +                 { +                     LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; +                 } +                 LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); +            } +        }) +    ); + +} + +// Fill an LLSD with data describing the current face's texture settings +// TODO 2022-05 FUBAR there are both colliding and different data in LLPanelFace vs the TE.  Also, neither one has the diffuse tex settings. +//               +LLSD LLPanelFace::renderMaterialToLLSD(LLUUID uuid, void* userdata) +{ +    llassert(userdata != nullptr); + +    LLSD sd; + +    sd.insert("RenderMaterialUUID",    LLSD(uuid)); + +    // now pull same data from the selected TE (same but different. W T F?)  +    LLMaterialPtr mat = nullptr; +    bool ident; // ? +    LLSelectedTEMaterial::getCurrent(mat, ident); + +    if (mat) +    { +        sd.insert("teMaterialID", LLSD(mat->getMaterialID())); + +        sd.insert("teNormalMap", LLSD(mat->getNormalID())); +        sd.insert("teNormalOffsetX", LLSD(mat->getNormalOffsetX())); +        sd.insert("teNormalOffsetY", LLSD(mat->getNormalOffsetY())); +        sd.insert("teNormalRepeatX", LLSD(mat->getNormalRepeatX())); +        sd.insert("teNormalRepeatY", LLSD(mat->getNormalRepeatY())); +        sd.insert("teNormalRotation", LLSD(mat->getNormalRotation())); + +        sd.insert("teSpecularMap", LLSD(mat->getSpecularID())); +        LLColor4U color = mat->getSpecularLightColor(); + +        sd.insert("teSpecularColorR", LLSD(static_cast<S32>(color.mV[0]))); +        sd.insert("teSpecularColorG", LLSD(static_cast<S32>(color.mV[1]))); +        sd.insert("teSpecularColorB", LLSD(static_cast<S32>(color.mV[2]))); +        sd.insert("teSpecularColorA", LLSD(static_cast<S32>(color.mV[3]))); +        sd.insert("teSpecularExponent", LLSD(static_cast<S32>(mat->getSpecularLightExponent()))); +        sd.insert("teSpecularOffsetX", LLSD(mat->getSpecularOffsetX())); +        sd.insert("teSpecularOffsetY", LLSD(mat->getSpecularOffsetY())); +        sd.insert("teSpecularRepeatX", LLSD(mat->getSpecularRepeatX())); +        sd.insert("teSpecularRepeatY", LLSD(mat->getSpecularRepeatY())); +        sd.insert("teSpecularRotation", LLSD(mat->getSpecularRotation())); + +        sd.insert("teAlphaMode", LLSD(static_cast<S32>(mat->getDiffuseAlphaMode()))); +        sd.insert("teAlphaCutoff", LLSD(static_cast<S32>(mat->getAlphaMaskCutoff()))); +        sd.insert("teEnvIntensity", LLSD(static_cast<S32>(mat->getEnvironmentIntensity()))); +        sd.insert("teShaderMask", LLSD(static_cast<S32>(mat->getShaderMask()))); +    } +    else +    { +        // pull data from the LLPanelFace +        LLPanelFace* instance = static_cast<LLPanelFace*>(userdata); +        sd.insert("pfNormalMap",         LLSD(instance->getCurrentNormalMap())); +        sd.insert("pfSpecularMap",       LLSD(instance->getCurrentSpecularMap())); +        sd.insert("pfShininess",         LLSD(static_cast<S32>(instance->getCurrentShininess()))); +        sd.insert("pfBumpiness",         LLSD(static_cast<S32>(instance->getCurrentBumpiness()))); +        sd.insert("pfAlphaMode",         LLSD(static_cast<S32>(instance->getCurrentDiffuseAlphaMode()))); +        sd.insert("pfAlphaCutoff",       LLSD(static_cast<S32>(instance->getCurrentAlphaMaskCutoff()))); +        sd.insert("pfEnvIntensity",      LLSD(static_cast<S32>(instance->getCurrentEnvIntensity()))); +        sd.insert("pfGlossiness",        LLSD(static_cast<S32>(instance->getCurrentGlossiness()))); +        sd.insert("pfNormalRotation",    LLSD(instance->getCurrentBumpyRot())); +        sd.insert("pfNormalScaleU",      LLSD(instance->getCurrentBumpyScaleU())); +        sd.insert("pfNormalScaleV",      LLSD(instance->getCurrentBumpyScaleV())); +        sd.insert("pfNormalOffsetU",     LLSD(instance->getCurrentBumpyOffsetU())); +        sd.insert("pfNormalOffsetV",     LLSD(instance->getCurrentBumpyOffsetV())); +        sd.insert("pfSpecularRotation",  LLSD(instance->getCurrentShinyRot())); +        sd.insert("pfSpecularScaleU",    LLSD(instance->getCurrentShinyScaleU())); +        sd.insert("pfSpecularScaleV",    LLSD(instance->getCurrentShinyScaleV())); +        sd.insert("pfSpecularOffsetU",   LLSD(instance->getCurrentShinyOffsetU())); +        sd.insert("pfSpecularOffsetV",   LLSD(instance->getCurrentShinyOffsetV())); +        sd.insert("pfMaterialID",        LLSD(instance->getCurrentMaterialID())); +    } + +    return sd; +} + +// Take the individual texture settings from the material and apply to current face & TE +void LLPanelFace::applyMaterialUUID(LLUUID uuid, void* userdata) +{ +    llassert(userdata != nullptr); +    //LLPanelFace* instance = static_cast<LLPanelFace*>(userdata); +     +    LLFileSystem material_file(uuid, LLAssetType::AT_MATERIAL, LLFileSystem::READ); +    S32 bufsize = material_file.getSize(); +    llassert(bufsize > 0); +    std::vector<U8> buffer(bufsize); +    material_file.read(&buffer[0], bufsize); +    std::istringstream input(std::string(buffer.begin(), buffer.end()));  // TODO - extend LLFileSystem to expose iostream interface +    LLSD matSD; + +    LLSDSerialize::fromNotation(matSD, input, bufsize); + +    LL_INFOS() << "dump matSD: " << matSD << LL_ENDL; + +    // strip off the versioning wrapper for now +    matSD = matSD["material"]; + +    // wrong, oops. llassert(uuid == matSD.get("RenderMaterialUUID").asUUID());      // if not, whoo boy + +    LLMaterialPtr mat = nullptr; +    bool ident; // ? +    LLSelectedTEMaterial::getCurrent(mat, ident); + +    mat->setMaterialID(matSD.get("teMaterialID").asUUID()); + +    mat->setNormalID(matSD.get("teNormalMap").asUUID()); +    mat->setNormalOffsetX(matSD.get("teNormalOffsetX").asReal()); +    mat->setNormalOffsetY(matSD.get("teNormalOffsetY").asReal()); +    mat->setNormalRepeatX(matSD.get("teNormalRepeatX").asReal()); +    mat->setNormalRepeatY(matSD.get("teNormalRepeatY").asReal()); +    mat->setNormalRotation(matSD.get("teNormalRotation").asReal()); + +    mat->setSpecularID(matSD.get("teSpecularMap").asUUID()); +    LLColor4U color; +    color.mV[0] = static_cast<U8>(matSD.get("teSecularColorR").asInteger()); +    color.mV[1] = static_cast<U8>(matSD.get("teSecularColorG").asInteger()); +    color.mV[2] = static_cast<U8>(matSD.get("teSecularColorB").asInteger()); +    color.mV[3] = static_cast<U8>(matSD.get("teSecularColorA").asInteger()); +    mat->setSpecularLightColor(color); +    mat->setSpecularLightExponent(static_cast<U8>(matSD.get("teSpecularExponent").asInteger())); +    mat->setSpecularOffsetX(matSD.get("teSpecularOffsetX").asReal()); +    mat->setSpecularOffsetY(matSD.get("teSpecularOffsetY").asReal()); +    mat->setSpecularRepeatX(matSD.get("teSpecularRepeatX").asReal()); +    mat->setSpecularRepeatY(matSD.get("teSpecularRepeatY").asReal()); +    mat->setSpecularRotation(matSD.get("teSpecularRotation").asReal()); + +    mat->setDiffuseAlphaMode(static_cast<U8>(matSD.get("teAlphaMode").asInteger())); +    mat->setAlphaMaskCutoff(static_cast<U8>(matSD.get("teAlphaCutoff").asInteger())); +    mat->setEnvironmentIntensity(static_cast<U8>(matSD.get("teEnvIntensity").asInteger())); +    //mat->setShaderMask(static_cast<U32>(matSD.get(teShaderMask").asInteger()); +} +  // TODO: I don't know who put these in or what these are for???  void LLPanelFace::setMediaURL(const std::string& url) diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 2d57d89a44..a8ecf8fdf2 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -191,6 +191,7 @@ protected:  	static void		onCommitMaterialGloss(			LLUICtrl* ctrl, void* userdata);  	static void		onCommitMaterialEnv(				LLUICtrl* ctrl, void* userdata);  	static void		onCommitMaterialMaskCutoff(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialID( LLUICtrl* ctrl, void* userdata);  	static void		onCommitMaterialsMedia(	LLUICtrl* ctrl, void* userdata);  	static void		onCommitMaterialType(	LLUICtrl* ctrl, void* userdata); @@ -205,6 +206,10 @@ protected:  	static void		onClickAutoFix(void*);      static void		onAlignTexture(void*); +    static void		onSaveMaterial(void*); +    static LLSD     renderMaterialToLLSD(LLUUID uuid, void* userdata); +    static void     applyMaterialUUID(LLUUID uuid, void*); +  	static F32     valueGlow(LLViewerObject* object, S32 face); @@ -233,6 +238,7 @@ private:  	F32		getCurrentShinyScaleV();  	F32		getCurrentShinyOffsetU();  	F32		getCurrentShinyOffsetV(); +	LLUUID	getCurrentMaterialID();  	// Update visibility of controls to match current UI mode  	// (e.g. materials vs media editing) @@ -497,6 +503,7 @@ public:  		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);  		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);  		DEF_EDIT_MAT_STATE(LLColor4U,	const LLColor4U&,setSpecularLightColor); +		DEF_EDIT_MAT_STATE(LLUUID, const LLUUID&, setMaterialID);  	};  	class LLSelectedTE diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp new file mode 100644 index 0000000000..54a627efd4 --- /dev/null +++ b/indra/newview/llreflectionmap.cpp @@ -0,0 +1,269 @@ +/** + * @file llreflectionmap.cpp + * @brief LLReflectionMap class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "llreflectionmap.h" +#include "pipeline.h" +#include "llviewerwindow.h" +#include "llviewerregion.h" + +extern F32SecondsImplicit gFrameTimeSeconds; + +LLReflectionMap::LLReflectionMap() +{ +    mLastUpdateTime = gFrameTimeSeconds; +} + +void LLReflectionMap::update(U32 resolution, U32 face) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    mLastUpdateTime = gFrameTimeSeconds; +    llassert(mCubeArray.notNull()); +    llassert(mCubeIndex != -1); +    llassert(LLPipeline::sRenderDeferred); +     +    // make sure we don't walk off the edge of the render target +    while (resolution > gPipeline.mRT->deferredScreen.getWidth() || +        resolution > gPipeline.mRT->deferredScreen.getHeight()) +    { +        resolution /= 2; +    } +    gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face); +} + +bool LLReflectionMap::shouldUpdate() +{ +    const F32 TIMEOUT_INTERVAL = 30.f; // update no less than this often +    const F32 RENDER_TIMEOUT = 1.f; // don't update if hasn't been used for rendering for this long +     +    if (mLastBindTime > gFrameTimeSeconds - RENDER_TIMEOUT) +    {    +        if (mLastUpdateTime < gFrameTimeSeconds - TIMEOUT_INTERVAL) +        { +            return true; +        } +    } + +    return false; +} + +void LLReflectionMap::dirty() +{ +    mDirty = true; +    mLastUpdateTime = gFrameTimeSeconds; +} + +void LLReflectionMap::autoAdjustOrigin() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + +    if (mGroup) +    { +        const LLVector4a* bounds = mGroup->getBounds(); +        auto* node = mGroup->getOctreeNode(); + +        if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN) +        { +            // for terrain, make probes float a couple meters above the highest point in the surface patch +            mOrigin = bounds[0]; +            mOrigin.getF32ptr()[2] += bounds[1].getF32ptr()[2] + 3.f; + +            // update radius to encompass bounding box +            LLVector4a d; +            d.setAdd(bounds[0], bounds[1]); +            d.sub(mOrigin); +            mRadius = d.getLength3().getF32(); +        } +        else if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) +        { +            mPriority = 8; +            // cast a ray towards 8 corners of bounding box +            // nudge origin towards center of empty space + +            if (node->isLeaf() || node->getChildCount() > 1 || node->getData().size() > 0) +            { // use center of object bounding box for leaf nodes or nodes with multiple child nodes +                mOrigin = bounds[0]; + +                LLVector4a start; +                LLVector4a end; + +                LLVector4a size = bounds[1]; + +                LLVector4a corners[] = +                { +                    { 1, 1, 1 }, +                    { -1, 1, 1 }, +                    { 1, -1, 1 }, +                    { -1, -1, 1 }, +                    { 1, 1, -1 }, +                    { -1, 1, -1 }, +                    { 1, -1, -1 }, +                    { -1, -1, -1 } +                }; + +                for (int i = 0; i < 8; ++i) +                { +                    corners[i].mul(size); +                    corners[i].add(bounds[0]); +                } + +                LLVector4a extents[2]; +                extents[0].setAdd(bounds[0], bounds[1]); +                extents[1].setSub(bounds[0], bounds[1]); + +                bool hit = false; +                for (int i = 0; i < 8; ++i) +                { +                    int face = -1; +                    LLVector4a intersection; +                    LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], true, false, &face, &intersection); +                    if (drawable != nullptr) +                    { +                        hit = true; +                        update_min_max(extents[0], extents[1], intersection); +                    } +                    else +                    { +                        update_min_max(extents[0], extents[1], corners[i]); +                    } +                } + +                if (hit) +                { +                    mOrigin.setAdd(extents[0], extents[1]); +                    mOrigin.mul(0.5f); +                } + +                // make sure radius encompasses all objects +                LLSimdScalar r2 = 0.0; +                for (int i = 0; i < 8; ++i) +                { +                    LLVector4a v; +                    v.setSub(corners[i], mOrigin); + +                    LLSimdScalar d = v.dot3(v); + +                    if (d > r2) +                    { +                        r2 = d; +                    } +                } + +                mRadius = llmax(sqrtf(r2.getF32()), 8.f); +            } +            else +            { +                // user placed probe +                mPriority = 64; + +                // use center of octree node volume for nodes that are just branches without data +                mOrigin = node->getCenter(); + +                // update radius to encompass entire octree node volume +                mRadius = node->getSize().getLength3().getF32(); + +                //mOrigin = bounds[0]; +                //mRadius = bounds[1].getLength3().getF32(); + +            } +        } +    } +    else if (mViewerObject) +    { +        mPriority = 64; +        mOrigin.load3(mViewerObject->getPositionAgent().mV); +        mRadius = mViewerObject->getScale().mV[0]*0.5f; +    } +} + +bool LLReflectionMap::intersects(LLReflectionMap* other) +{ +    // TODO: incorporate getBox +    LLVector4a delta; +    delta.setSub(other->mOrigin, mOrigin); + +    F32 dist = delta.dot3(delta).getF32(); + +    F32 r2 = mRadius + other->mRadius; + +    r2 *= r2; + +    return dist < r2; +} + +bool LLReflectionMap::getBox(LLMatrix4& box) +{  +    if (mViewerObject) +    { +        LLVolume* volume = mViewerObject->getVolume(); +        if (volume) +        { +            LLVOVolume* vobjp = (LLVOVolume*)mViewerObject; + +            U8 profile = volume->getProfileType(); +            U8 path = volume->getPathType(); + +            if (profile == LL_PCODE_PROFILE_SQUARE && +                path == LL_PCODE_PATH_LINE) +            { +                // nope +                /*box = vobjp->getRelativeXform(); +                box *= vobjp->mDrawable->getRenderMatrix(); +                LLMatrix4 modelview(gGLModelView); +                box *= modelview; +                box.invert();*/ + +                // nope +                /*box = LLMatrix4(gGLModelView); +                box *= vobjp->mDrawable->getRenderMatrix(); +                box *= vobjp->getRelativeXform(); +                box.invert();*/ + +                glh::matrix4f mv(gGLModelView); +                glh::matrix4f scale; +                LLVector3 s = vobjp->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); +                mRadius = s.magVec(); +                scale.set_scale(glh::vec3f(s.mV)); +                if (vobjp->mDrawable != nullptr) +                { +                    glh::matrix4f rm((F32*)vobjp->mDrawable->getWorldMatrix().mMatrix); + +                    glh::matrix4f rt((F32*)vobjp->getRelativeXform().mMatrix); + +                    mv = mv * rm * scale; // *rt; +                    mv = mv.inverse(); + +                    box = LLMatrix4(mv.m); + +                    return true; +                } +            } +        } +    } + +    return false; +} diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h new file mode 100644 index 0000000000..4f0f124118 --- /dev/null +++ b/indra/newview/llreflectionmap.h @@ -0,0 +1,101 @@ +/** + * @file llreflectionmap.h + * @brief LLReflectionMap class declaration + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ + +#pragma once + +#include "llcubemaparray.h" +#include "llmemory.h" + +class LLSpatialGroup; +class LLViewerObject; + +class alignas(16) LLReflectionMap : public LLRefCount +{ +    LL_ALIGN_NEW +public: +    // allocate an environment map of the given resolution  +    LLReflectionMap(); + +    // update this environment map +    // resolution - size of cube map to generate +    void update(U32 resolution, U32 face); + +    // return true if this probe should update *now* +    bool shouldUpdate(); + +    // Mark this reflection map as needing an update (resets last update time, so spamming this call will cause a cube map to never update) +    void dirty(); + +    // for volume partition probes, try to place this probe in the best spot +    void autoAdjustOrigin(); + +    // return true if given Reflection Map's influence volume intersect's with this one's +    bool intersects(LLReflectionMap* other); + +    // get the encoded bounding box of this probe's influence volume +    // will only return a box if this probe has a volume with a square +    // profile and a linear path +    // return false if no bounding box (treat as sphere influence volume) +    bool getBox(LLMatrix4& box); + +    // point at which environment map was last generated from (in agent space) +    LLVector4a mOrigin; +     +    // distance from viewer camera +    F32 mDistance; + +    // radius of this probe's affected area +    F32 mRadius = 16.f; + +    // last time this probe was updated (or when its update timer got reset) +    F32 mLastUpdateTime = 0.f; + +    // last time this probe was bound for rendering +    F32 mLastBindTime = 0.f; + +    // cube map used to sample this environment map +    LLPointer<LLCubeMapArray> mCubeArray; +    S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array + +    // index into array packed by LLReflectionMapManager::getReflectionMaps +    // WARNING -- only valid immediately after call to getReflectionMaps +    S32 mProbeIndex = -1; + +    // set of any LLReflectionMaps that intersect this map (maintained by LLReflectionMapManager +    std::vector<LLReflectionMap*> mNeighbors; + +    // spatial group this probe is tracking (if any) +    LLSpatialGroup* mGroup = nullptr; + +    // viewer object this probe is tracking (if any) +    LLViewerObject* mViewerObject = nullptr; + +    // what priority should this probe have (higher is higher priority) +    U32 mPriority = 1; + +    bool mDirty = true; +}; + diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp new file mode 100644 index 0000000000..34055653d4 --- /dev/null +++ b/indra/newview/llreflectionmapmanager.cpp @@ -0,0 +1,720 @@ +/** + * @file llreflectionmapmanager.cpp + * @brief LLReflectionMapManager class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "llreflectionmapmanager.h" +#include "llviewercamera.h" +#include "llspatialpartition.h" +#include "llviewerregion.h" +#include "pipeline.h" +#include "llviewershadermgr.h" +#include "llviewercontrol.h" + +extern BOOL gCubeSnapshot; +extern BOOL gTeleportDisplay; + +//#pragma optimize("", off) + +// experimental pipeline render target override, if this works, do something less hacky +LLPipeline::RenderTargetPack gProbeRT; + +LLReflectionMapManager::LLReflectionMapManager() +{ +    for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) +    { +        mCubeFree[i] = true; +    } +} + +struct CompareReflectionMapDistance +{ + +}; + + +struct CompareProbeDistance +{ +    bool operator()(const LLPointer<LLReflectionMap>& lhs, const LLPointer<LLReflectionMap>& rhs) +    { +        return lhs->mDistance < rhs->mDistance; +    } +}; + +// helper class to seed octree with probes +void LLReflectionMapManager::update() +{ +    if (!LLPipeline::sRenderPBR || gTeleportDisplay) +    { +        return; +    } + +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    llassert(!gCubeSnapshot); // assert a snapshot is not in progress +    if (LLAppViewer::instance()->logoutRequestSent()) +    { +        return; +    } + +    // =============== TODO -- move to an init function  ================= + +    if (mTexture.isNull()) +    { +        mTexture = new LLCubeMapArray(); +        mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT); +    } + +    if (!mRenderTarget.isComplete()) +    { +        U32 color_fmt = GL_RGBA; +        const bool use_depth_buffer = true; +        const bool use_stencil_buffer = true; +        U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample +        mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE); + +        // hack to allocate render targets using gPipeline code +        auto* old_rt = gPipeline.mRT; +        gPipeline.mRT = &gProbeRT; +        gPipeline.allocateScreenBuffer(targetRes, targetRes); +        gPipeline.allocateShadowBuffer(targetRes, targetRes); +        gPipeline.mRT = old_rt; +    } + +    if (mMipChain.empty()) +    { +        U32 res = LL_REFLECTION_PROBE_RESOLUTION; +        U32 count = log2((F32)res) + 0.5f; +         +        mMipChain.resize(count); +        for (int i = 0; i < count; ++i) +        { +            mMipChain[i].allocate(res, res, GL_RGB, false, false, LLTexUnit::TT_RECT_TEXTURE); +            res /= 2; +        } +    } + +    // =============== TODO -- move to an init function  ================= + +    // naively drop probes every 16m as we move the camera around for now +    // later, use LLSpatialPartition to manage probes +    const F32 PROBE_SPACING = 16.f; +    const U32 MAX_PROBES = 8; + +    LLVector4a camera_pos; +    camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); + +    // process kill list +    for (int i = 0; i < mProbes.size(); ) +    { +        auto& iter = std::find(mKillList.begin(), mKillList.end(), mProbes[i]); +        if (iter != mKillList.end()) +        { +            deleteProbe(i); +            mProbes.erase(mProbes.begin() + i); +            mKillList.erase(iter); +        } +        else +        { +            ++i; +        } +    } + +    mKillList.clear(); +     +    // process create list +    for (auto& probe : mCreateList) +    { +        mProbes.push_back(probe); +    } + +    mCreateList.clear(); + +    if (mProbes.empty()) +    { +        return; +    } +    const F32 UPDATE_INTERVAL = 5.f;  //update no more than once every 5 seconds + +    bool did_update = false; + +    LLReflectionMap* oldestProbe = nullptr; + +    if (mUpdatingProbe != nullptr) +    { +        did_update = true; +        doProbeUpdate(); +    } + +    for (int i = 0; i < mProbes.size(); ++i) +    { +        LLReflectionMap* probe = mProbes[i]; +        if (probe->getNumRefs() == 1) +        { // no references held outside manager, delete this probe +            deleteProbe(i); +            --i; +            continue; +        } +         +        probe->mProbeIndex = i; + +        LLVector4a d; +         +        if (!did_update &&  +            i < LL_REFLECTION_PROBE_COUNT && +            (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) +        { +            oldestProbe = probe; +        } + +        d.setSub(camera_pos, probe->mOrigin); +        probe->mDistance = d.getLength3().getF32()-probe->mRadius; +    } + +#if 1 +    if (!did_update && oldestProbe != nullptr) +    { +        LLReflectionMap* probe = oldestProbe; +        if (probe->mCubeIndex == -1) +        { +            probe->mCubeArray = mTexture; +            probe->mCubeIndex = allocateCubeIndex(); +        } + +        probe->autoAdjustOrigin(); + +        mUpdatingProbe = probe; +        doProbeUpdate(); +        probe->mDirty = false; +    } +#endif + +    // update distance to camera for all probes +    std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance()); +} + +LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) +{ +    LLReflectionMap* probe = new LLReflectionMap(); +    probe->mGroup = group; +    probe->mOrigin = group->getOctreeNode()->getCenter(); +    probe->mDirty = true; + +    if (gCubeSnapshot) +    { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update +        mCreateList.push_back(probe); +    } +    else +    { +        mProbes.push_back(probe); +    } + +    return probe; +} + +void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& maps) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + +    U32 count = 0; +    U32 lastIdx = 0; +    for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i) +    { +        mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested +        if (mProbes[i]->mCubeIndex != -1) +        { +            mProbes[i]->mProbeIndex = count; +            maps[count++] = mProbes[i]; +        } +        else +        { +            mProbes[i]->mProbeIndex = -1; +        } +        lastIdx = i; +    } + +    // set remaining probe indices to -1 +    for (U32 i = lastIdx+1; i < mProbes.size(); ++i) +    { +        mProbes[i]->mProbeIndex = -1; +    } + +    // null terminate list +    if (count < maps.size()) +    { +        maps[count] = nullptr; +    } +} + +LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group) +{ +#if 1 +    if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) +    { +        OctreeNode* node = group->getOctreeNode(); +        F32 size = node->getSize().getF32ptr()[0]; +        if (size >= 7.f && size <= 17.f) +        { +            return addProbe(group); +        } +    } +     +    if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN) +    { +        OctreeNode* node = group->getOctreeNode(); +        F32 size = node->getSize().getF32ptr()[0]; +        if (size >= 15.f && size <= 17.f) +        { +            return addProbe(group); +        } +    } +#endif +    return nullptr; +} + +LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj) +{ +    llassert(vobj != nullptr); + +    LLReflectionMap* probe = new LLReflectionMap(); +    probe->mViewerObject = vobj; +    probe->mOrigin.load3(vobj->getPositionAgent().mV); +    probe->mDirty = true; + +    if (gCubeSnapshot) +    { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update +        mCreateList.push_back(probe); +    } +    else +    { +        mProbes.push_back(probe); +    } + +    return probe; +} + + +S32 LLReflectionMapManager::allocateCubeIndex() +{ +    for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) +    { +        if (mCubeFree[i]) +        { +            mCubeFree[i] = false; +            return i; +        } +    } + +    // no cubemaps free, steal one from the back of the probe list +    for (int i = mProbes.size() - 1; i >= LL_REFLECTION_PROBE_COUNT; --i) +    { +        if (mProbes[i]->mCubeIndex != -1) +        { +            S32 ret = mProbes[i]->mCubeIndex; +            mProbes[i]->mCubeIndex = -1; +            return ret; +        } +    } + +    llassert(false); // should never fail to allocate, something is probably wrong with mCubeFree +    return -1; +} + +void LLReflectionMapManager::deleteProbe(U32 i) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    LLReflectionMap* probe = mProbes[i]; + +    if (probe->mCubeIndex != -1) +    { // mark the cube index used by this probe as being free +        mCubeFree[probe->mCubeIndex] = true; +    } +    if (mUpdatingProbe == probe) +    { +        mUpdatingProbe = nullptr; +        mUpdatingFace = 0; +    } + +    // remove from any Neighbors lists +    for (auto& other : probe->mNeighbors) +    { +        auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); +        llassert(iter != other->mNeighbors.end()); +        other->mNeighbors.erase(iter); +    } + +    mProbes.erase(mProbes.begin() + i); +} + + +void LLReflectionMapManager::doProbeUpdate() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    llassert(mUpdatingProbe != nullptr); + +    mRenderTarget.bindTarget(); +    auto* old_rt = gPipeline.mRT; +    gPipeline.mRT = &gProbeRT; +    mUpdatingProbe->update(mRenderTarget.getWidth(), mUpdatingFace); +    gPipeline.mRT = old_rt; +    mRenderTarget.flush(); + +    // generate mipmaps +    { +        LLGLDepthTest depth(GL_FALSE, GL_FALSE); +        LLGLDisable cull(GL_CULL_FACE); + +        gReflectionMipProgram.bind(); +        gGL.matrixMode(gGL.MM_MODELVIEW); +        gGL.pushMatrix(); +        gGL.loadIdentity(); + +        gGL.matrixMode(gGL.MM_PROJECTION); +        gGL.pushMatrix(); +        gGL.loadIdentity(); + +        gGL.flush(); +        U32 res = LL_REFLECTION_PROBE_RESOLUTION*2; + +        S32 mips = log2((F32) LL_REFLECTION_PROBE_RESOLUTION)+0.5f; + +        for (int i = 0; i < mMipChain.size(); ++i) +        { +            LL_PROFILE_GPU_ZONE("probe mip"); +            mMipChain[i].bindTarget(); + +            if (i == 0) +            { +                gGL.getTexUnit(0)->bind(&mRenderTarget); +            } +            else +            { +                gGL.getTexUnit(0)->bind(&(mMipChain[i - 1])); +            } + +            gGL.begin(gGL.QUADS); +             +            gGL.texCoord2f(0, 0); +            gGL.vertex2f(-1, -1); +             +            gGL.texCoord2f(res, 0); +            gGL.vertex2f(1, -1); + +            gGL.texCoord2f(res, res); +            gGL.vertex2f(1, 1); + +            gGL.texCoord2f(0, res); +            gGL.vertex2f(-1, 1); +            gGL.end(); +            gGL.flush(); + +            res /= 2; + +            S32 mip = i - (mMipChain.size() - mips); + +            if (mip >= 0) +            { +                mTexture->bind(0); +                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, mUpdatingProbe->mCubeIndex * 6 + mUpdatingFace, 0, 0, res, res); +                mTexture->unbind(); +            } +            mMipChain[i].flush(); +        } + +        gGL.popMatrix(); +        gGL.matrixMode(gGL.MM_MODELVIEW); +        gGL.popMatrix(); + +        gReflectionMipProgram.unbind(); +    } +     +    if (++mUpdatingFace == 6) +    { +        updateNeighbors(mUpdatingProbe); +        mUpdatingProbe = nullptr; +        mUpdatingFace = 0; +    } +} + +void LLReflectionMapManager::rebuild() +{ +    for (auto& probe : mProbes) +    { +        probe->mLastUpdateTime = 0.f; +    } +} + +void LLReflectionMapManager::shift(const LLVector4a& offset) +{ +    for (auto& probe : mProbes) +    { +        probe->mOrigin.add(offset); +    } +} + +void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + +    //remove from existing neighbors +    { +        LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear"); +     +        for (auto& other : probe->mNeighbors) +        { +            auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); +            llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly +            other->mNeighbors.erase(iter); +        } + +        probe->mNeighbors.clear(); +    } + +    // search for new neighbors +    { +        LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search"); +        for (auto& other : mProbes) +        { +            if (other != probe) +            { +                if (probe->intersects(other)) +                { +                    probe->mNeighbors.push_back(other); +                    other->mNeighbors.push_back(probe); +                } +            } +        } +    } +} + +void LLReflectionMapManager::updateUniforms() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + +    // structure for packing uniform buffer object +    // see class2/deferred/softenLightF.glsl +    struct ReflectionProbeData +    { +        LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed +        LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space +        GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; +        GLint refNeighbor[4096]; +        GLint refmapCount; +        GLfloat reflectionAmbiance; +    }; + +    mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); +    getReflectionMaps(mReflectionMaps); + +    ReflectionProbeData rpd; + +    static LLCachedControl<F32> ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f); +    rpd.reflectionAmbiance = ambiance; + +    // load modelview matrix into matrix 4a +    LLMatrix4a modelview; +    modelview.loadu(gGLModelView); +    LLVector4a oa; // scratch space for transformed origin + +    S32 count = 0; +    U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors + +    for (auto* refmap : mReflectionMaps) +    { +        if (refmap == nullptr) +        { +            break; +        } + +        llassert(refmap->mProbeIndex == count); +        llassert(mReflectionMaps[refmap->mProbeIndex] == refmap); + +        llassert(refmap->mCubeIndex >= 0); // should always be  true, if not, getReflectionMaps is bugged + +        { +            //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere"); + +            modelview.affineTransform(refmap->mOrigin, oa); +            rpd.refSphere[count].set(oa.getF32ptr()); +            rpd.refSphere[count].mV[3] = refmap->mRadius; +        } + +        rpd.refIndex[count][0] = refmap->mCubeIndex; +        llassert(nc % 4 == 0); +        rpd.refIndex[count][1] = nc / 4; +        rpd.refIndex[count][3] = refmap->mPriority; + +        // for objects that are reflection probes, use the volume as the influence volume of the probe +        // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres +        if (refmap->getBox(rpd.refBox[count])) +        { // negate priority to indicate this probe has a box influence volume +            rpd.refIndex[count][3] = -rpd.refIndex[count][3]; +        } + +        S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors +        { +            //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); +            //pack neghbor list +            for (auto& neighbor : refmap->mNeighbors) +            { +                if (ni >= 4096) +                { // out of space +                    break; +                } + +                GLint idx = neighbor->mProbeIndex; +                if (idx == -1) +                { +                    continue; +                } + +                // this neighbor may be sampled +                rpd.refNeighbor[ni++] = idx; +            } +        } + +        if (nc == ni) +        { +            //no neighbors, tag as empty +            rpd.refIndex[count][1] = -1; +        } +        else +        { +            rpd.refIndex[count][2] = ni - nc; + +            // move the cursor forward +            nc = ni; +            if (nc % 4 != 0) +            { // jump to next power of 4 for compatibility with ivec4 +                nc += 4 - (nc % 4); +            } +        } + + +        count++; +    } + +    rpd.refmapCount = count; + +    //copy rpd into uniform buffer object +    if (mUBO == 0) +    { +        glGenBuffersARB(1, &mUBO); +    } + +    { +        LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); +        glBindBufferARB(GL_UNIFORM_BUFFER, mUBO); +        glBufferDataARB(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); +        glBindBufferARB(GL_UNIFORM_BUFFER, 0); +    } +} + +void LLReflectionMapManager::setUniforms() +{ +    llassert(LLPipeline::sRenderPBR); +    if (mUBO == 0) +    {  +        updateUniforms(); +    } +    glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); +} + + +void renderReflectionProbe(LLReflectionMap* probe) +{ +    F32* po = probe->mOrigin.getF32ptr(); + +    //draw orange line from probe to neighbors +    gGL.flush(); +    gGL.diffuseColor4f(1, 0.5f, 0, 1); +    gGL.begin(gGL.LINES); +    for (auto& neighbor : probe->mNeighbors) +    { +        gGL.vertex3fv(po); +        gGL.vertex3fv(neighbor->mOrigin.getF32ptr()); +    } +    gGL.end(); +    gGL.flush(); + +#if 0 +    LLSpatialGroup* group = probe->mGroup; +    if (group) +    { // draw lines from corners of object aabb to reflection probe + +        const LLVector4a* bounds = group->getBounds(); +        LLVector4a o = bounds[0]; + +        gGL.flush(); +        gGL.diffuseColor4f(0, 0, 1, 1); +        F32* c = o.getF32ptr(); + +        const F32* bc = bounds[0].getF32ptr(); +        const F32* bs = bounds[1].getF32ptr(); + +        // daaw blue lines from corners to center of node +        gGL.begin(gGL.LINES); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]); + +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]); +        gGL.vertex3fv(c); +        gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]); +        gGL.end(); + +        //draw yellow line from center of node to reflection probe origin +        gGL.flush(); +        gGL.diffuseColor4f(1, 1, 0, 1); +        gGL.begin(gGL.LINES); +        gGL.vertex3fv(c); +        gGL.vertex3fv(po); +        gGL.end(); +        gGL.flush(); +    } +#endif +} + +void LLReflectionMapManager::renderDebug() +{ +    gDebugProgram.bind(); + +    for (auto& probe : mProbes) +    { +        renderReflectionProbe(probe); +    } + +    gDebugProgram.unbind(); +} diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h new file mode 100644 index 0000000000..bf963f3486 --- /dev/null +++ b/indra/newview/llreflectionmapmanager.h @@ -0,0 +1,138 @@ +/** + * @file llreflectionmapmanager.h + * @brief LLReflectionMapManager class declaration + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ + +#pragma once + +#include "llreflectionmap.h" +#include "llrendertarget.h" +#include "llcubemaparray.h" + +class LLSpatialGroup; +class LLViewerObject; + +// number of reflection probes to keep in vram +#define LL_REFLECTION_PROBE_COUNT 256 + +// reflection probe resolution +#define LL_REFLECTION_PROBE_RESOLUTION 256 + +// reflection probe mininum scale +#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; + +class alignas(16) LLReflectionMapManager +{ +    LL_ALIGN_NEW +public: +    // allocate an environment map of the given resolution  +    LLReflectionMapManager(); + +    // maintain reflection probes +    void update(); + +    // add a probe for the given spatial group +    LLReflectionMap* addProbe(LLSpatialGroup* group); +     +    // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size() +    // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr. +    //  maps -- presized array of Reflection Map pointers +    void getReflectionMaps(std::vector<LLReflectionMap*>& maps); + +    // called by LLSpatialGroup constructor +    // If spatial group should receive a Reflection Probe, will create one for the specified spatial group +    LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group); + +    // presently hacked into LLViewerObject::setTE +    // Used by LLViewerObjects that are Reflection Probes +    // Guaranteed to not return null +    LLReflectionMap* registerViewerObject(LLViewerObject* vobj); + +    // force an update of all probes +    void rebuild(); + +    // called on region crossing to "shift" probes into new coordinate frame +    void shift(const LLVector4a& offset); + +    // debug display, called from llspatialpartition if reflection +    // probe debug display is active +    void renderDebug(); + +private: +    friend class LLPipeline; + +    // delete the probe with the given index in mProbes +    void deleteProbe(U32 i); + +    // get a free cube index +    // if no cube indices are free, free one starting from the back of the probe list +    S32 allocateCubeIndex(); + +    // update the neighbors of the given probe  +    void updateNeighbors(LLReflectionMap* probe); + +    // update UBO used for rendering (call only once per render pipe flush) +    void updateUniforms(); + +    // bind UBO used for rendering +    void setUniforms(); + +    // render target for cube snapshots +    // used to generate mipmaps without doing a copy-to-texture +    LLRenderTarget mRenderTarget; + +    std::vector<LLRenderTarget> mMipChain; + +    // storage for reflection probes +    LLPointer<LLCubeMapArray> mTexture; + +    // array indicating if a particular cubemap is free +    bool mCubeFree[LL_REFLECTION_PROBE_COUNT]; + +    // start tracking the given spatial group +    void trackGroup(LLSpatialGroup* group); +     +    // perform an update on the currently updating Probe +    void doProbeUpdate(); +     +    // list of active reflection maps +    std::vector<LLPointer<LLReflectionMap> > mProbes; + +    // list of reflection maps to kill +    std::vector<LLPointer<LLReflectionMap> > mKillList; + +    // list of reflection maps to create +    std::vector<LLPointer<LLReflectionMap> > mCreateList; + +    // handle to UBO +    U32 mUBO = 0; + +    // list of maps being used for rendering +    std::vector<LLReflectionMap*> mReflectionMaps; + +    LLReflectionMap* mUpdatingProbe = nullptr; +    U32 mUpdatingFace = 0; + +}; + diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 0d53950889..39bb46e6fa 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -554,9 +554,12 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO  	sg_assert(mOctreeNode->getListenerCount() == 0);  	setState(SG_INITIAL_STATE_MASK);  	gPipeline.markRebuild(this, TRUE); +     +    // let the reflection map manager know about this spatial group +    mReflectionProbe = gPipeline.mReflectionMapManager.registerSpatialGroup(this); -	mRadius = 1; -	mPixelArea = 1024.f; +    mRadius = 1; +    mPixelArea = 1024.f;  }  void LLSpatialGroup::updateDistance(LLCamera &camera) @@ -735,8 +738,17 @@ BOOL LLSpatialGroup::changeLOD()  	return FALSE;  } +void LLSpatialGroup::dirtyReflectionProbe() +{ +    if (mReflectionProbe != nullptr) +    { +        mReflectionProbe->dirty(); +    } +} +  void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry)  { +    dirtyReflectionProbe();  	addObject((LLDrawable*)entry->getDrawable());  	unbound();  	setState(OBJECT_DIRTY); @@ -744,6 +756,7 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry*  void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry)  { +    dirtyReflectionProbe();  	removeObject((LLDrawable*)entry->getDrawable(), TRUE);  	LLViewerOctreeGroup::handleRemoval(node, entry);  } @@ -780,6 +793,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c  {  	LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL +    dirtyReflectionProbe(); +  	if (child->getListenerCount() == 0)  	{  		new LLSpatialGroup(child, getSpatialPartition()); @@ -794,6 +809,11 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c  	assert_states_valid(this);  } +void LLSpatialGroup::handleChildRemoval(const oct_node* parent, const oct_node* child) +{ +    dirtyReflectionProbe(); +} +  void LLSpatialGroup::destroyGL(bool keep_occlusion)   {  	setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1399,7 +1419,9 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result  	return 0;  	} -	 + +extern BOOL gCubeSnapshot; +  S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; @@ -1418,7 +1440,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)          LLOctreeCullShadow culler(&camera);          culler.traverse(mOctree);      } -    else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) +    else if (mInfiniteFarClip || (!LLPipeline::sUseFarClip && !gCubeSnapshot))      {          LLOctreeCullNoFarClip culler(&camera);          culler.traverse(mOctree); @@ -1738,7 +1760,7 @@ void renderOctree(LLSpatialGroup* group)  			}  		}*/  	} -	 +  //	LLSpatialGroup::OctreeNode* node = group->mOctreeNode;  //	gGL.diffuseColor4f(0,1,0,1);  //	drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize())); @@ -2610,14 +2632,12 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)  			gGL.diffuseColor4fv(line_color.mV);  			gGL.syncMatrices();  			{ -				LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 )  				glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);  			}  			gGL.diffuseColor4fv(color.mV);  			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  			{ -				LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 )  				glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);  			}  		} @@ -3156,7 +3176,6 @@ void renderRaycast(LLDrawable* drawablep)  						gGL.diffuseColor4f(0,1,1,0.5f);  						glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);  						gGL.syncMatrices(); -						LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 );  						glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);  					} @@ -3704,7 +3723,7 @@ void LLSpatialPartition::renderDebug()  									  //LLPipeline::RENDER_DEBUG_BUILD_QUEUE |  									  LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |  									  LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY | -									  LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))  +									  LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))  	{  		return;  	} @@ -3738,7 +3757,6 @@ void LLSpatialPartition::renderDebug()  	LLOctreeRenderNonOccluded render_debug(camera);  	render_debug.traverse(mOctree); -  	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))  	{  		{ @@ -3948,6 +3966,23 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co  	return drawable;  } +LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, +    BOOL pick_transparent, +    BOOL pick_rigged, +    S32* face_hit,                   // return the face hit +    LLVector4a* intersection,         // return the intersection point +    LLVector2* tex_coord,            // return the texture coordinates of the intersection point +    LLVector4a* normal,               // return the surface normal at the intersection point +    LLVector4a* tangent			// return the surface tangent at the intersection point +) + +{ +    LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, face_hit, intersection, tex_coord, normal, tangent); +    LLDrawable* drawable = intersect.check(getOctreeNode()); + +    return drawable; +} +  LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,   					   LLViewerTexture* texture, LLVertexBuffer* buffer,  					   bool selected, diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 6d3ef33801..e9d84ecf06 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -53,6 +53,7 @@ class LLSpatialPartition;  class LLSpatialBridge;  class LLSpatialGroup;  class LLViewerRegion; +class LLReflectionMap;  void pushVerts(LLFace* face, U32 mask); @@ -313,6 +314,17 @@ public:  	void drawObjectBox(LLColor4 col); +    LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, +        BOOL pick_transparent, +        BOOL pick_rigged, +        S32* face_hit,                          // return the face hit +        LLVector4a* intersection = NULL,         // return the intersection point +        LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point +        LLVector4a* normal = NULL,               // return the surface normal at the intersection point +        LLVector4a* tangent = NULL             // return the surface tangent at the intersection point +    ); + +  	LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}  	 //LISTENER FUNCTIONS @@ -320,6 +332,7 @@ public:  	virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);  	virtual void handleDestruction(const TreeNode* node);  	virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); +    virtual void handleChildRemoval(const oct_node* parent, const oct_node* child);  public:  	LL_ALIGN_16(LLVector4a mViewAngle); @@ -327,6 +340,8 @@ public:  	F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() +    void dirtyReflectionProbe(); +  protected:  	virtual ~LLSpatialGroup(); @@ -355,6 +370,9 @@ public:      //used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior      LLVOAvatar* mAvatarp = nullptr;      U32 mRenderOrder = 0;  +    // Reflection Probe associated with this node (if any) +    LLPointer<LLReflectionMap> mReflectionProbe = nullptr; +  } LL_ALIGN_POSTFIX(64);  class LLGeometryManager diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 4804ef6ddc..481086f760 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -88,6 +88,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()  	addEntry(LLViewerAssetType::AT_NONE, 				new ViewerAssetEntry(DAD_NONE));      addEntry(LLViewerAssetType::AT_SETTINGS,            new ViewerAssetEntry(DAD_SETTINGS)); +    addEntry(LLViewerAssetType::AT_MATERIAL,            new ViewerAssetEntry(DAD_MATERIAL));  };  EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4618871630..1e8ad12b2a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -440,9 +440,10 @@ static bool handleRenderLocalLightsChanged(const LLSD& newvalue)  	return true;  } +// NOTE: may be triggered by RenderDeferred OR RenderPBR changing, don't trust "newvalue"  static bool handleRenderDeferredChanged(const LLSD& newvalue)  { -	LLRenderTarget::sUseFBO = newvalue.asBoolean(); +    LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");  	if (gPipeline.isInit())  	{  		LLPipeline::refreshCachedSettings(); @@ -694,6 +695,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));  	gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));  	gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2)); +    gSavedSettings.getControl("RenderPBR")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));  	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6a2b06d9b5..1b8e53e667 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -97,6 +97,7 @@ BOOL gResizeScreenTexture = FALSE;  BOOL gResizeShadowTexture = FALSE;  BOOL gWindowResized = FALSE;  BOOL gSnapshot = FALSE; +BOOL gCubeSnapshot = FALSE;  BOOL gShaderProfileFrame = FALSE;  // This is how long the sim will try to teleport you before giving up. @@ -193,15 +194,23 @@ void display_update_camera()  	// Cut draw distance in half when customizing avatar,  	// but on the viewer only.  	F32 final_far = gAgentCamera.mDrawDistance; -	if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) +    if (gCubeSnapshot) +    { +        final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance"); +    } +    else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) +          	{  		final_far *= 0.5f;  	}  	LLViewerCamera::getInstance()->setFar(final_far);  	gViewerWindow->setup3DRender(); -	// Update land visibility too -	LLWorld::getInstance()->setLandFarClip(final_far); +    if (!gCubeSnapshot) +    { +        // Update land visibility too +        LLWorld::getInstance()->setLandFarClip(final_far); +    }  }  // Write some stats to LL_INFOS() @@ -907,19 +916,19 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)          if (LLPipeline::sRenderDeferred)          { -            gPipeline.mDeferredScreen.bindTarget(); +            gPipeline.mRT->deferredScreen.bindTarget();              glClearColor(1, 0, 1, 1); -            gPipeline.mDeferredScreen.clear(); +            gPipeline.mRT->deferredScreen.clear();          }          else          { -            gPipeline.mScreen.bindTarget(); +            gPipeline.mRT->screen.bindTarget();              if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())              {                  const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();                  glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);              } -            gPipeline.mScreen.clear(); +            gPipeline.mRT->screen.clear();          }          gGL.setColorMask(true, false); @@ -989,7 +998,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); -        LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen); +        LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);          rt.flush();          if (rt.sUseFBO) @@ -1001,7 +1010,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)          if (LLPipeline::sRenderDeferred)          { -			gPipeline.renderDeferredLighting(&gPipeline.mScreen); +			gPipeline.renderDeferredLighting(&gPipeline.mRT->screen);  		}  		LLPipeline::sUnderWaterRender = FALSE; @@ -1048,6 +1057,114 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	}  } +// WIP simplified copy of display() that does minimal work +void display_cube_face() +{ +    LL_RECORD_BLOCK_TIME(FTM_RENDER); +    LL_PROFILE_GPU_ZONE("display cube face"); + +    llassert(!gSnapshot); +    llassert(!gTeleportDisplay); +    llassert(LLPipeline::sRenderDeferred); +    llassert(LLStartUp::getStartupState() >= STATE_PRECACHE); +    llassert(!LLAppViewer::instance()->logoutRequestSent()); +    llassert(!gRestoreGL); +    llassert(!gUseWireframe); + +    bool rebuild = false; + +    LLGLSDefault gls_default; +    LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); + +    LLVertexBuffer::unbind(); + +    gPipeline.disableLights(); + +    gPipeline.mBackfaceCull = TRUE; + +    LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); +    gViewerWindow->setup3DViewport(); + +    if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) +    { //don't draw hud objects in this frame +        gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); +    } + +    if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES)) +    { //don't draw hud particles in this frame +        gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); +    } + +    display_update_camera(); + +    LLSpatialGroup::sNoDelete = TRUE; +         +    S32 occlusion = LLPipeline::sUseOcclusion; +    LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots +    //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data + +    static LLCullResult result; +    LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; +    LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater(); +    gPipeline.updateCull(*LLViewerCamera::getInstance(), result); + +    gGL.setColorMask(true, true); +    glClearColor(0, 0, 0, 0); +    gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); +         +    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + +    { +        LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; +        gPipeline.stateSort(*LLViewerCamera::getInstance(), result); + +        if (rebuild) +        { +            ////////////////////////////////////// +            // +            // rebuildPools +            // +            // +            gPipeline.rebuildPools(); +            stop_glerror(); +        } +    } +     +    LLPipeline::sUseOcclusion = occlusion; + +    LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); + +    LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; + +    gGL.setColorMask(true, true); + +    gPipeline.mRT->deferredScreen.bindTarget(); +    glClearColor(1, 0, 1, 1); +    gPipeline.mRT->deferredScreen.clear(); +         +    gGL.setColorMask(true, false); + +    LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + +    gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); + +    gGL.setColorMask(true, true); + +    gPipeline.mRT->deferredScreen.flush(); +        +    gPipeline.renderDeferredLighting(&gPipeline.mRT->screen); + +    LLPipeline::sUnderWaterRender = FALSE; + +    // Finalize scene +    gPipeline.renderFinalize(); + +    LLSpatialGroup::sNoDelete = FALSE; +    gPipeline.clearReferences(); + +    gPipeline.rebuildGroups(); +} +  void render_hud_attachments()  {  	gGL.matrixMode(LLRender::MM_PROJECTION); @@ -1242,7 +1359,7 @@ bool setup_hud_matrices(const LLRect& screen_region)  void render_ui(F32 zoom_factor, int subfield)  {  	LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); - +    LL_PROFILE_GPU_ZONE("ui");  	LLGLState::checkStates();  	glh::matrix4f saved_view = get_current_modelview(); @@ -1325,7 +1442,7 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");  void swap()  {  	LL_RECORD_BLOCK_TIME(FTM_SWAP); - +    LL_PROFILE_GPU_ZONE("swap");  	if (gDisplaySwapBuffers)  	{  		gViewerWindow->getWindow()->swapBuffers(); @@ -1487,7 +1604,7 @@ void render_ui_2d()              LLView::sIsRectDirty = false;  			LLRect t_rect; -			gPipeline.mUIScreen.bindTarget(); +			gPipeline.mRT->uiScreen.bindTarget();  			gGL.setColorMask(true, true);  			{  				static const S32 pad = 8; @@ -1519,7 +1636,7 @@ void render_ui_2d()  				gViewerWindow->draw();  			} -			gPipeline.mUIScreen.flush(); +			gPipeline.mRT->uiScreen.flush();  			gGL.setColorMask(true, false);              LLView::sDirtyRect = t_rect; @@ -1529,7 +1646,7 @@ void render_ui_2d()  		LLGLDisable blend(GL_BLEND);  		S32 width = gViewerWindow->getWindowWidthScaled();  		S32 height = gViewerWindow->getWindowHeightScaled(); -		gGL.getTexUnit(0)->bind(&gPipeline.mUIScreen); +		gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen);  		gGL.begin(LLRender::TRIANGLE_STRIP);  		gGL.color4f(1,1,1,1);  		gGL.texCoord2f(0, 0);			gGL.vertex2i(0, 0); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e3de4267dc..8732bde35c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1081,6 +1081,10 @@ U64 info_display_from_string(std::string info_display)  	{  		return LLPipeline::RENDER_DEBUG_IMPOSTORS;  	} +    else if ("reflection probes" == info_display) +    { +    return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES; +    }  	else  	{  		LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL; @@ -8304,6 +8308,12 @@ void handle_cache_clear_immediately()  	LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);  } +void handle_rebuild_reflection_probes() +{ +    gPipeline.mReflectionMapManager.rebuild(); +} + +  void handle_web_content_test(const LLSD& param)  {  	std::string url = param.asString(); @@ -9402,6 +9412,8 @@ void initialize_menus()  	view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");  	//Develop (clear cache immediately)  	commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) ); +    //Develop (override environment map) +    commit.add("Develop.RebuildReflectionProbes", boost::bind(&handle_rebuild_reflection_probes));  	// Admin >Object  	view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index a95636ff23..6ecf9dd0c4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -343,6 +343,13 @@ LLViewerObject::~LLViewerObject()  {  	deleteTEImages(); +    // unhook from reflection probe manager +    if (mReflectionProbe.notNull()) +    { +        mReflectionProbe->mViewerObject = nullptr; +        mReflectionProbe = nullptr; +    } +  	if(mInventory)  	{  		mInventory->clear();  // will deref and delete entries @@ -4862,7 +4869,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)  	LLPrimitive::setTE(te, texture_entry); -		const LLUUID& image_id = getTE(te)->getID(); +	const LLUUID& image_id = getTE(te)->getID();  	LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);  	mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); @@ -6017,6 +6024,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para  		  new_block = new LLExtendedMeshParams();  		  break;        } +      case LLNetworkData::PARAMS_RENDER_MATERIAL: +      { +          new_block = new LLRenderMaterialParams(); +          break; +      }  	  default:  	  {  		  LL_INFOS() << "Unknown param type." << LL_ENDL; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bef8e3e7e3..5b6d24887c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -43,6 +43,7 @@  #include "llvertexbuffer.h"  #include "llbbox.h"  #include "llrigginginfo.h" +#include "llreflectionmap.h"  class LLAgent;			// TODO: Get rid of this.  class LLAudioSource; @@ -845,7 +846,7 @@ protected:  	F32 mLinksetCost;  	F32 mPhysicsCost;  	F32 mLinksetPhysicsCost; - +      	bool mCostStale;  	mutable bool mPhysicsShapeUnknown; @@ -904,6 +905,11 @@ private:  	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.  	EObjectUpdateType	mLastUpdateType;  	BOOL	mLastUpdateCached; + +public: +    // reflection probe state +    bool mIsReflectionProbe = false;  // if true, this object should register itself with LLReflectionProbeManager +    LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object.  If not null, should be deregistered when this object is destroyed  };  /////////////////// diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 086b433c72..d4ee754d5c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -49,6 +49,8 @@  #include "lljoint.h"  #include "llskinningutil.h" +//#pragma optimize("", off) +  static LLStaticHashedString sTexture0("texture0");  static LLStaticHashedString sTexture1("texture1");  static LLStaticHashedString sTex0("tex0"); @@ -82,6 +84,7 @@ LLGLSLShader	gOcclusionCubeProgram;  LLGLSLShader	gCustomAlphaProgram;  LLGLSLShader	gGlowCombineProgram;  LLGLSLShader	gSplatTextureRectProgram; +LLGLSLShader	gReflectionMipProgram;  LLGLSLShader	gGlowCombineFXAAProgram;  LLGLSLShader	gTwoTextureAddProgram;  LLGLSLShader	gTwoTextureCompareProgram; @@ -258,6 +261,7 @@ LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];  LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader			gDeferredPBROpaqueProgram;  //helper for making a rigged variant of a given shader  bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -489,6 +493,7 @@ void LLViewerShaderMgr::setShaders()      bool canRenderDeferred       = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");      bool hasWindLightShaders     = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");      S32 shadow_detail            = gSavedSettings.getS32("RenderShadowDetail"); +    bool pbr = gSavedSettings.getBOOL("RenderPBR");      bool doingWindLight          = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders");      bool useRenderDeferred       = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred"); @@ -528,6 +533,11 @@ void LLViewerShaderMgr::setShaders()          }      } +    if (deferred_class > 0 && pbr) +    { +        deferred_class = 3; +    } +      if (doingWindLight)      {          // user has disabled WindLight in their settings, downgrade @@ -641,7 +651,6 @@ void LLViewerShaderMgr::setShaders()      }      if (loaded) -      {          loaded = loadTransformShaders();          if (loaded) @@ -660,8 +669,8 @@ void LLViewerShaderMgr::setShaders()          // Load max avatar shaders to set the max level          mShaderLevel[SHADER_AVATAR] = 3;          mMaxAvatarShaderLevel = 3; -                 -            if (loadShadersObject()) + +        if (loadShadersObject())          { //hardware skinning is enabled and rigged attachment shaders loaded correctly              BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); @@ -752,6 +761,7 @@ void LLViewerShaderMgr::unloadShaders()  	gCustomAlphaProgram.unload();  	gGlowCombineProgram.unload();  	gSplatTextureRectProgram.unload(); +    gReflectionMipProgram.unload();  	gGlowCombineFXAAProgram.unload();  	gTwoTextureAddProgram.unload();  	gTwoTextureCompareProgram.unload(); @@ -975,6 +985,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/deferredUtil.glsl",                    1) );  	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/shadowUtil.glsl",                      1) );  	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/aoUtil.glsl",                          1) ); +    index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl",                llmax(mShaderLevel[SHADER_DEFERRED], 1)) );  	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",                    mShaderLevel[SHADER_LIGHTING] ) );  	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl",                   mShaderLevel[SHADER_LIGHTING] ) );  	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl",          mShaderLevel[SHADER_LIGHTING] ) ); @@ -1218,7 +1229,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  BOOL LLViewerShaderMgr::loadShadersDeferred()  { -    bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1; +    bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&  +        gSavedSettings.getS32("RenderShadowDetail") > 0;      BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");  	BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable"); @@ -1307,6 +1319,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			gDeferredMaterialProgram[i].unload();  			gDeferredMaterialWaterProgram[i].unload();  		} + +        gDeferredPBROpaqueProgram.unload(); +  		return TRUE;  	} @@ -1498,6 +1513,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()              gDeferredMaterialProgram[i].mFeatures.hasGamma = true;              gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow; +            if (mShaderLevel[SHADER_DEFERRED] > 2) +            { +                gDeferredMaterialProgram[i].mFeatures.hasReflectionProbes = true; +                gDeferredMaterialProgram[i].addPermutation("HAS_REFLECTION_PROBES", "1"); +            } +              if (has_skin)              {                  gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1"); @@ -1591,6 +1612,22 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()              success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);              llassert(success);  		} + +        if (success) +        { +            gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader"; +            gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true; +            gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true; + +            gDeferredPBROpaqueProgram.mShaderFiles.clear(); +            gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER_ARB)); +            gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER_ARB)); +            gDeferredPBROpaqueProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +            gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +            //gDeferredPBROpaqueProgram.addPermutation("HAS_NORMAL_MAP", "1"); +            success = gDeferredPBROpaqueProgram.createShader(NULL, NULL); +            llassert(success); +        }  	}  	gDeferredMaterialProgram[1].mFeatures.hasLighting = true; @@ -2181,6 +2218,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        if (gDeferredFullbrightShinyProgram.mShaderLevel > 2) +        { +            gDeferredFullbrightShinyProgram.addPermutation("HAS_REFLECTION_PROBES", "1"); +            gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true; +        }          success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);  		success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);  		llassert(success); @@ -2253,6 +2295,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenProgram.mFeatures.hasGamma = true;  		gDeferredSoftenProgram.mFeatures.isDeferred = true;  		gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow; +        gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;          gDeferredSoftenProgram.clearPermutations();  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2260,6 +2303,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        if (use_sun_shadow) +        { +            gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1"); +        } +          if (ambient_kill)          {              gDeferredSoftenProgram.addPermutation("AMBIENT_KILL", "1"); @@ -2278,6 +2326,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ //if using SSAO, take screen space light map into account as if shadows are enabled  			gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); +            gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");  		}  		success = gDeferredSoftenProgram.createShader(NULL, NULL); @@ -2303,6 +2352,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;          gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;          gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow; +        gDeferredSoftenWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2; + +        if (use_sun_shadow) +        { +            gDeferredSoftenWaterProgram.addPermutation("HAS_SUN_SHADOW", "1"); +        }          if (ambient_kill)          { @@ -2317,6 +2372,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          if (local_light_kill)          {              gDeferredSoftenWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); +            gDeferredSoftenWaterProgram.addPermutation("HAS_SSAO", "1");          }  		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) @@ -3574,7 +3630,6 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		}  	} -  	if (success)  	{  		gTwoTextureAddProgram.mName = "Two Texture Add Shader"; @@ -3750,6 +3805,22 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		success = gAlphaMaskProgram.createShader(NULL, NULL);  	} +    if (success) +    { +        gReflectionMipProgram.mName = "Reflection Mip Shader"; +        gReflectionMipProgram.mShaderFiles.clear(); +        gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB)); +        gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; +        success = gReflectionMipProgram.createShader(NULL, NULL); +        if (success) +        { +            gReflectionMipProgram.bind(); +            gReflectionMipProgram.uniform1i(sScreenMap, 0); +            gReflectionMipProgram.unbind(); +        } +    } +  	if( !success )  	{  		mShaderLevel[SHADER_INTERFACE] = 0; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 93bb29a355..f0187db302 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -161,6 +161,7 @@ extern LLGLSLShader			gOcclusionCubeProgram;  extern LLGLSLShader			gCustomAlphaProgram;  extern LLGLSLShader			gGlowCombineProgram;  extern LLGLSLShader			gSplatTextureRectProgram; +extern LLGLSLShader			gReflectionMipProgram;  extern LLGLSLShader			gGlowCombineFXAAProgram;  extern LLGLSLShader			gDebugProgram;  extern LLGLSLShader			gClipProgram; @@ -313,4 +314,6 @@ extern LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];  extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; + +extern LLGLSLShader			gDeferredPBROpaqueProgram;  #endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8e565bbdca..a6597e3233 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -228,6 +228,7 @@ extern BOOL gDebugClicks;  extern BOOL gDisplaySwapBuffers;  extern BOOL gDepthDirty;  extern BOOL gResizeScreenTexture; +extern BOOL gCubeSnapshot;  LLViewerWindow	*gViewerWindow = NULL; @@ -4926,8 +4927,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  			U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;  			if (scratch_space.allocate(image_width, image_height, color_fmt, true, true))  			{ -				original_width = gPipeline.mDeferredScreen.getWidth(); -				original_height = gPipeline.mDeferredScreen.getHeight(); +				original_width = gPipeline.mRT->deferredScreen.getWidth(); +				original_height = gPipeline.mRT->deferredScreen.getHeight();  				if (gPipeline.allocateScreenBuffer(image_width, image_height))  				{ @@ -5170,6 +5171,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;      gDisplaySwapBuffers = FALSE;      glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -5184,8 +5186,8 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_      LLPipeline::sShowHUDAttachments = FALSE;      LLRect window_rect = getWorldViewRectRaw(); -    S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw(); -    S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw(); +    S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw(); +    S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();      LLRenderTarget scratch_space;      U32 color_fmt = GL_RGBA; @@ -5266,6 +5268,125 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_      return true;  } +void display_cube_face(); + +BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face) +{ +    // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot +    LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; +    LL_PROFILE_GPU_ZONE("cubeSnapshot"); +    llassert(LLPipeline::sRenderDeferred); +    llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress +     +    U32 res = LLRenderTarget::sCurResX; + +    llassert(res <= gPipeline.mRT->deferredScreen.getWidth()); +    llassert(res <= gPipeline.mRT->deferredScreen.getHeight()); + +    // save current view/camera settings so we can restore them afterwards +    S32 old_occlusion = LLPipeline::sUseOcclusion; + +    // set new parameters specific to the 360 requirements +    LLPipeline::sUseOcclusion = 0; +    LLViewerCamera* camera = LLViewerCamera::getInstance(); +     +    LLViewerCamera saved_camera = LLViewerCamera::instance(); +    glh::matrix4f saved_proj = get_current_projection(); +    glh::matrix4f saved_mod = get_current_modelview(); + +    // camera constants for the square, cube map capture image +    camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV +    camera->setView(F_PI_BY_TWO); +    camera->yaw(0.0); +    camera->setOrigin(origin); + +    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +     +    BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE; +    if (prev_draw_ui != false) +    { +        LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); +    } +    BOOL prev_draw_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); +    if (prev_draw_particles) +    { +        gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); +    } +    LLPipeline::sShowHUDAttachments = FALSE; +    LLRect window_rect = getWorldViewRectRaw(); + +    mWorldViewRectRaw.set(0, res, res, 0); + +    // these are the 6 directions we will point the camera, see LLCubeMapArray::sTargets +    LLVector3 look_dirs[6] = { +        LLVector3(1, 0, 0), +        LLVector3(-1, 0, 0), +        LLVector3(0, 1, 0), +        LLVector3(0, -1, 0), +        LLVector3(0, 0, 1), +        LLVector3(0, 0, -1) +    }; + +    LLVector3 look_upvecs[6] = { +        LLVector3(0, -1, 0), +        LLVector3(0, -1, 0), +        LLVector3(0, 0, 1), +        LLVector3(0, 0, -1), +        LLVector3(0, -1, 0), +        LLVector3(0, -1, 0) +    }; + +    // for each of six sides of cubemap +    //for (int i = 0; i < 6; ++i) +    int i = face; +    { +        // set up camera to look in each direction +        camera->lookDir(look_dirs[i], look_upvecs[i]); + +        // turning this flag off here prohibits the screen swap +        // to present the new page to the viewer - this stops +        // the black flash in between captures when the number +        // of render passes is more than 1. We need to also +        // set it here because code in LLViewerDisplay resets +        // it to TRUE each time. +        gDisplaySwapBuffers = FALSE; + +        // actually render the scene +        gCubeSnapshot = TRUE; +        display_cube_face(); +        gCubeSnapshot = FALSE; +    } + +    gDisplaySwapBuffers = TRUE; + +    if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) +    { +        if (prev_draw_ui != false) +        { +            LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); +        } +    } + +    if (prev_draw_particles) +    { +        gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); +    } + +    LLPipeline::sShowHUDAttachments = TRUE; + +    gPipeline.resetDrawOrders(); +    mWorldViewRectRaw = window_rect; +     +    // restore original view/camera/avatar settings settings +    *camera = saved_camera; +    set_current_modelview(saved_mod); +    set_current_projection(saved_proj); +    LLPipeline::sUseOcclusion = old_occlusion; + +    // ==================================================== +    return true; +} +  void LLViewerWindow::destroyWindow()  {  	if (mWindow) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 979a560508..ac7f8b2e39 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -68,6 +68,8 @@ class LLWindowListener;  class LLViewerWindowListener;  class LLVOPartGroup;  class LLPopupView; +class LLCubeMap; +class LLCubeMapArray;  #define PICK_HALF_WIDTH 5  #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1) @@ -360,6 +362,18 @@ public:      BOOL			simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes); +     +     +    // take a cubemap snapshot +    // origin - vantage point to take the snapshot from +    // cubearray - cubemap array for storing the results +    // index - cube index in the array to use (cube index, not face-layer) +    BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face); + +     +    // special implementation of simpleSnapshot for reflection maps +    BOOL			reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes); +      BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);  	BOOL			isSnapshotLocSet() const;  	void			resetSnapshotLoc() const; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 068e8a131d..04e9a4f179 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -756,6 +756,7 @@ LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :  void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)  {      LL_PROFILE_ZONE_SCOPED; +    LL_PROFILE_GPU_ZONE("particle vbo");  	if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))  	{  		return; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 126a25115d..784c0350fc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -106,6 +106,7 @@ LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;  LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;  extern BOOL gGLDebugLoggingEnabled; +extern BOOL gCubeSnapshot;  // Implementation class of LLMediaDataClientObject.  See llmediadataclient.h  class LLMediaDataClientObjectImpl : public LLMediaDataClientObject @@ -718,7 +719,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;  	// Update the pixel area of all faces -    if (mDrawable.isNull()) +    if (mDrawable.isNull() || gCubeSnapshot)      {          return;      } @@ -2156,7 +2157,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes)  	return ;  } -//virtual      +//virtual  void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)  {  	BOOL changed = (mTEImages[index] != imagep); @@ -3388,6 +3389,11 @@ F32 LLVOVolume::getSpotLightPriority() const  void LLVOVolume::updateSpotLightPriority()  { +    if (gCubeSnapshot) +    { +        return; +    } +      F32 r = getLightRadius();  	LLVector3 pos = mDrawable->getPositionAgent(); @@ -5497,6 +5503,8 @@ static inline void add_face(T*** list, U32* count, T* face)  void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; +    llassert(!gCubeSnapshot); +  	if (group->changeLOD())  	{  		group->mLastUpdateDistance = group->mDistance; @@ -5674,6 +5682,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					continue;  				} +#if LL_RELEASE_WITH_DEBUG_INFO +                const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); +                const LLUUID obj_id( vobj->getID() ); +                bool is_pbr = (obj_id == pbr_id); +#else +                bool is_pbr = false; +#endif + +                // HACK - make this object a Reflection Probe if a certain UUID is detected +                static LLCachedControl<std::string> reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); +                if (facep->getTextureEntry()->getID() == LLUUID(reflection_probe_id)) +                { +                    if (!vobj->mIsReflectionProbe) +                    { +                        vobj->mIsReflectionProbe = true; +                        vobj->mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(vobj); +                    } +                } +                else +                { +                    // not a refleciton probe any more +                    vobj->mIsReflectionProbe = false; +                    vobj->mReflectionProbe = nullptr; +                } +                // END HACK +  				//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render  				// batch, it will recover its vertex buffer reference from the spatial group  				facep->setVertexBuffer(NULL); @@ -5739,6 +5773,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);  					U32 type = gPipeline.getPoolTypeFromTE(te, tex); + +                    if (is_pbr) +                    { +                        type = LLDrawPool::POOL_PBR_OPAQUE; +                    } +                    else  					if (type != LLDrawPool::POOL_ALPHA && force_simple)  					{  						type = LLDrawPool::POOL_SIMPLE; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8abb49fba8..8837038d02 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -820,7 +820,7 @@ void LLWorld::updateNetStats()  void LLWorld::printPacketsLost()  { -	LL_INFOS() << "Simulators:" << LL_ENDL; +	LL_INFOS() << "Simulators:" << LL_ENDL;   	LL_INFOS() << "----------" << LL_ENDL;  	LLCircuitData *cdp = NULL; @@ -855,6 +855,7 @@ F32 LLWorld::getLandFarClip() const  void LLWorld::setLandFarClip(const F32 far_clip)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT;  	static S32 const rwidth = (S32)REGION_WIDTH_U32;  	S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;  	S32 const n2 = (llceil(far_clip) - 1) / rwidth; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index da16c8209f..3332185bfd 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -227,6 +227,7 @@ extern S32 gBoxFrame;  //extern BOOL gHideSelectedObjects;  extern BOOL gDisplaySwapBuffers;  extern BOOL gDebugGL; +extern BOOL gCubeSnapshot;  bool	gAvatarBacklight = false; @@ -350,6 +351,7 @@ bool	LLPipeline::sRenderFrameTest = false;  bool	LLPipeline::sRenderAttachedLights = true;  bool	LLPipeline::sRenderAttachedParticles = true;  bool	LLPipeline::sRenderDeferred = false; +bool    LLPipeline::sRenderPBR = false;  S32		LLPipeline::sVisibleLightCount = 0;  bool	LLPipeline::sRenderingHUDs;  F32     LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; @@ -405,9 +407,7 @@ LLPipeline::LLPipeline() :  	mWLSkyPool(NULL),  	mLightMask(0),  	mLightMovingMask(0), -	mLightingDetail(0), -	mScreenWidth(0), -	mScreenHeight(0) +	mLightingDetail(0)  {  	mNoiseMap = 0;  	mTrueNoiseMap = 0; @@ -436,6 +436,8 @@ void LLPipeline::init()  {  	refreshCachedSettings(); +    mRT = new RenderTargetPack(); +  	gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");  	gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");  	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); @@ -462,6 +464,7 @@ void LLPipeline::init()  	getPool(LLDrawPool::POOL_BUMP);  	getPool(LLDrawPool::POOL_MATERIALS);  	getPool(LLDrawPool::POOL_GLOW); +	getPool(LLDrawPool::POOL_PBR_OPAQUE);  	resetFrameStats(); @@ -539,6 +542,7 @@ void LLPipeline::init()  	connectRefreshCachedSettingsSafe("UseOcclusion");  	connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");  	connectRefreshCachedSettingsSafe("RenderDeferred"); +    connectRefreshCachedSettingsSafe("RenderPBR");  	connectRefreshCachedSettingsSafe("RenderDeferredSunWash");  	connectRefreshCachedSettingsSafe("RenderFSAASamples");  	connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); @@ -692,6 +696,9 @@ void LLPipeline::cleanup()  	mDeferredVB = NULL;  	mCubeVB = NULL; + +    delete mRT; +    mRT = nullptr;  }  //============================================================================ @@ -733,7 +740,7 @@ void LLPipeline::requestResizeShadowTexture()  void LLPipeline::resizeShadowTexture()  {      releaseShadowTargets(); -    allocateShadowBuffer(mScreenWidth, mScreenHeight); +    allocateShadowBuffer(mRT->width, mRT->height);      gResizeShadowTexture = FALSE;  } @@ -744,7 +751,7 @@ void LLPipeline::resizeScreenTexture()  		GLuint resX = gViewerWindow->getWorldViewWidthRaw();  		GLuint resY = gViewerWindow->getWorldViewHeightRaw(); -		if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) +		if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))  		{  			releaseScreenBuffers();              releaseShadowTargets(); @@ -767,42 +774,16 @@ void LLPipeline::allocatePhysicsBuffer()  bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  { -	refreshCachedSettings(); -	 -	bool save_settings = sRenderDeferred; -	if (save_settings) -	{ -		// Set this flag in case we crash while resizing window or allocating space for deferred rendering targets -		gSavedSettings.setBOOL("RenderInitError", TRUE); -		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); -	} - +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;  	eFBOStatus ret = doAllocateScreenBuffer(resX, resY); -	if (save_settings) -	{ -		// don't disable shaders on next session -		gSavedSettings.setBOOL("RenderInitError", FALSE); -		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); -	} -	 -	if (ret == FBO_FAILURE) -	{ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled -		//NOTE: if the session closes successfully after this call, deferred rendering will be  -		// disabled on future sessions -		if (LLPipeline::sRenderDeferred) -		{ -			gSavedSettings.setBOOL("RenderDeferred", FALSE); -			LLPipeline::refreshCachedSettings(); -		} -	} -  	return ret == FBO_SUCCESS_FULLRES;  }  LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;  	// try to allocate screen buffers at requested resolution and samples  	// - on failure, shrink number of samples and try again  	// - if not multisampled, shrink resolution and try again (favor X resolution over Y) @@ -856,11 +837,10 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)  bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  { -	refreshCachedSettings(); - +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;  	// remember these dimensions -	mScreenWidth = resX; -	mScreenHeight = resY; +	mRT->width = resX; +	mRT->height = resY;  	U32 res_mod = RenderResolutionDivisor; @@ -872,7 +852,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  	if (RenderUIBuffer)  	{ -		if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) +		if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))  		{  			return false;  		} @@ -886,10 +866,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		const U32 occlusion_divisor = 3;  		//allocate deferred rendering color buffers -		if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; -		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; -		if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; -		if (!addDeferredAttachments(mDeferredScreen)) return false; +		if (!mRT->deferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!addDeferredAttachments(mRT->deferredScreen)) return false;  		GLuint screenFormat = GL_RGBA16;  		if (gGLManager.mIsAMD) @@ -902,23 +882,23 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  			screenFormat = GL_RGBA16F_ARB;  		} -		if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (samples > 0)  		{ -			if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; +			if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;  		}  		else  		{ -			mFXAABuffer.release(); +			mRT->fxaaBuffer.release();  		}  		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) -		{ //only need mDeferredLight for shadows OR ssao OR dof OR fxaa -			if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; +		{ //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa +			if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;  		}  		else  		{ -			mDeferredLight.release(); +			mRT->deferredLight.release();  		}          allocateShadowBuffer(resX, resY); @@ -931,22 +911,22 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)      }      else      { -        mDeferredLight.release(); +        mRT->deferredLight.release();          releaseShadowTargets(); -		mFXAABuffer.release(); -		mScreen.release(); -		mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first -		mDeferredDepth.release(); -		mOcclusionDepth.release(); +		mRT->fxaaBuffer.release(); +		mRT->screen.release(); +		mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first +		mRT->deferredDepth.release(); +		mRT->occlusionDepth.release(); -		if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		 +		if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		  	}  	if (LLPipeline::sRenderDeferred)  	{ //share depth buffer between deferred targets -		mDeferredScreen.shareDepthBuffer(mScreen); +		mRT->deferredScreen.shareDepthBuffer(mRT->screen);  	}  	gGL.getTexUnit(0)->disable(); @@ -961,8 +941,7 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0  bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)  { -	refreshCachedSettings(); -	 +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;  	if (LLPipeline::sRenderDeferred)  	{  		S32 shadow_detail = RenderShadowDetail; @@ -977,12 +956,12 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)  		{ //allocate 4 sun shadow maps  			for (U32 i = 0; i < 4; i++)  			{ -				if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) +				if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))                  {                      return false;                  } -                if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) +                if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))                  {                      return false;                  } @@ -1005,11 +984,11 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)              U32 spot_shadow_map_height = height;  			for (U32 i = 4; i < 6; i++)  			{ -                if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) +                if (!mRT->shadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))  		{                      return false;  			} -                if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE)) +                if (!mRT->shadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE))  		{  			return false;  		} @@ -1048,11 +1027,13 @@ void LLPipeline::updateRenderDeferred()                        LLPipeline::sRenderBump &&                        WindLightUseAtmosShaders &&                        (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); +    sRenderPBR = sRenderDeferred && gSavedSettings.getBOOL("RenderPBR");  }  // static  void LLPipeline::refreshCachedSettings()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;  	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");  	LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");  	LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); @@ -1199,21 +1180,21 @@ void LLPipeline::releaseShadowBuffers()  void LLPipeline::releaseScreenBuffers()  { -	mUIScreen.release(); -	mScreen.release(); -	mFXAABuffer.release(); +	mRT->uiScreen.release(); +	mRT->screen.release(); +	mRT->fxaaBuffer.release();  	mPhysicsDisplay.release(); -	mDeferredScreen.release(); -	mDeferredDepth.release(); -	mDeferredLight.release(); -	mOcclusionDepth.release(); +	mRT->deferredScreen.release(); +	mRT->deferredDepth.release(); +	mRT->deferredLight.release(); +	mRT->occlusionDepth.release();  }  void LLPipeline::releaseShadowTarget(U32 index)  { -    mShadow[index].release(); -    mShadowOcclusion[index].release(); +    mRT->shadow[index].release(); +    mRT->shadowOcclusion[index].release();  }  void LLPipeline::releaseShadowTargets() @@ -1256,8 +1237,8 @@ void LLPipeline::createGLBuffers()      }      allocateScreenBuffer(resX, resY); -    mScreenWidth = 0; -    mScreenHeight = 0; +    mRT->width = 0; +    mRT->height = 0;      if (sRenderDeferred)      { @@ -1597,6 +1578,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  		poolp = mWLSkyPool;  		break; +	case LLDrawPool::POOL_PBR_OPAQUE: +		poolp = mPBROpaquePool; +		break; +  	default:  		llassert(0);  		LL_ERRS() << "Invalid Pool Type in  LLPipeline::findPool() type=" << type << LL_ENDL; @@ -2028,6 +2013,7 @@ void LLPipeline::updateMove()  //static  F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)  { +    llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots  	LLVector3 lookAt = center - camera.getOrigin();  	F32 dist = lookAt.length(); @@ -2353,11 +2339,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla  	{  		if (LLPipeline::sRenderDeferred && can_use_occlusion)  		{ -			mOcclusionDepth.bindTarget(); +			mRT->occlusionDepth.bindTarget();  		}  		else  		{ -			mScreen.bindTarget(); +			mRT->screen.bindTarget();  		}  	} @@ -2479,11 +2465,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla  	{  		if (LLPipeline::sRenderDeferred && can_use_occlusion)  		{ -			mOcclusionDepth.flush(); +			mRT->occlusionDepth.flush();  		}  		else  		{ -			mScreen.flush(); +			mRT->screen.flush();  		}  	}  } @@ -2497,7 +2483,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)  	group->setVisible(); -	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) +	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)  	{  		group->updateDistance(camera);  	} @@ -2603,6 +2589,8 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d  void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    llassert(!gCubeSnapshot);  	downsampleDepthBuffer(source, dest, scratch_space);  	dest.bindTarget();  	doOcclusion(camera); @@ -2612,6 +2600,7 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT  void LLPipeline::doOcclusion(LLCamera& camera)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +    LL_PROFILE_GPU_ZONE("doOcclusion");      if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&  		(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))  	{ @@ -2845,7 +2834,7 @@ void LLPipeline::rebuildPriorityGroups()  void LLPipeline::rebuildGroups()  { -	if (mGroupQ2.empty()) +	if (mGroupQ2.empty() || gCubeSnapshot)  	{  		return;  	} @@ -2895,6 +2884,10 @@ void LLPipeline::updateGeom(F32 max_dtime)  	LLPointer<LLDrawable> drawablep;  	LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); +    if (gCubeSnapshot) +    { +        return; +    }  	assertInitialized(); @@ -3134,6 +3127,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)  		}  	} +    mReflectionMapManager.shift(offseta); +  	LLHUDText::shiftAll(offset);  	LLHUDNameTag::shiftAll(offset); @@ -3314,7 +3309,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  		}  	} -	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) +	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)  	{  		LLSpatialGroup* last_group = NULL;  		BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); @@ -3396,7 +3391,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)  			stateSort(drawablep, camera);  		} -		if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) +		if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)  		{ //avoid redundant stateSort calls  			group->mLastUpdateDistance = group->mDistance;  		} @@ -3465,7 +3460,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)  		}  	} -	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) +	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)  	{  		//if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here  		{ @@ -3743,21 +3738,26 @@ void LLPipeline::postSort(LLCamera& camera)  	assertInitialized();  	LL_PUSH_CALLSTACKS(); -	//rebuild drawable geometry -	for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) -	{ -		LLSpatialGroup* group = *i; -		if (!sUseOcclusion ||  -			!group->isOcclusionState(LLSpatialGroup::OCCLUDED)) -		{ -			group->rebuildGeom(); -		} -	} -	LL_PUSH_CALLSTACKS(); -	//rebuild groups -	sCull->assertDrawMapsEmpty(); -	rebuildPriorityGroups(); +    if (!gCubeSnapshot) +    { +        //rebuild drawable geometry +        for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) +        { +            LLSpatialGroup* group = *i; +            if (!sUseOcclusion || +                !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) +            { +                group->rebuildGeom(); +            } +        } +        LL_PUSH_CALLSTACKS(); +        //rebuild groups +        sCull->assertDrawMapsEmpty(); + +        rebuildPriorityGroups(); +    } +  	LL_PUSH_CALLSTACKS(); @@ -3773,7 +3773,7 @@ void LLPipeline::postSort(LLCamera& camera)  			continue;  		} -		if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY)) +		if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY) && !gCubeSnapshot)  		{ //no way this group is going to be drawable without a rebuild  			group->rebuildGeom();  		} @@ -3791,7 +3791,7 @@ void LLPipeline::postSort(LLCamera& camera)                  LLDrawInfo* info = *k;  				sCull->pushDrawInfo(j->first, info); -                if (!sShadowRender && !sReflectionRender) +                if (!sShadowRender && !sReflectionRender && !gCubeSnapshot)                  {                      touchTextures(info);                      addTrianglesDrawn(info->mCount, info->mDrawMode); @@ -3806,7 +3806,7 @@ void LLPipeline::postSort(LLCamera& camera)  			if (alpha != group->mDrawMap.end())  			{ //store alpha groups for sorting  				LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); -				if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) +				if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)  				{  					if (bridge)  					{ @@ -4262,7 +4262,7 @@ U32 LLPipeline::sCurRenderPoolType = 0 ;  void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)  {  	LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - +    LL_PROFILE_GPU_ZONE("renderGeom");  	assertInitialized();  	F32 saved_modelview[16]; @@ -4437,7 +4437,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)  		gGL.loadMatrix(gGLModelView);  		if (occlude) -		{ +		{ // catch uncommon condition where pools at drawpool grass and later are disabled  			occlude = false;  			gGLLastMatrix = NULL;  			gGL.loadMatrix(gGLModelView); @@ -4512,14 +4512,10 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)  void LLPipeline::renderGeomDeferred(LLCamera& camera)  {  	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); -  	LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); +    LL_PROFILE_GPU_ZONE("renderGeomDeferred"); +  	{ -		// SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. -		// Solutions are: -		// 1. Use a new scope -		// 2. Use named zones -		// 3. Use transient zones  		LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);  		LLGLEnable cull(GL_CULL_FACE); @@ -4540,6 +4536,12 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  		LLGLState::checkStates();  		LLGLState::checkTextureChannels(); +        if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1) +        { +            //update reflection probe uniform +            mReflectionMapManager.updateUniforms(); +        } +  		U32 cur_type = 0;  		gGL.setColorMask(true, true); @@ -4611,6 +4613,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)  {  	LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS); +    LL_PROFILE_GPU_ZONE("renderGeomPostDeferred"); +  	U32 cur_type = 0;  	LLGLEnable cull(GL_CULL_FACE); @@ -4633,11 +4637,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)  		if (occlude && cur_type >= LLDrawPool::POOL_GRASS)  		{ +            llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots  			occlude = false;  			gGLLastMatrix = NULL;  			gGL.loadMatrix(gGLModelView);  			LLGLSLShader::bindNoShader(); -			doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth); +			doOcclusion(camera, mRT->screen, mRT->occlusionDepth, &mRT->deferredDepth);  			gGL.setColorMask(true, false);  		} @@ -4706,6 +4711,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)  void LLPipeline::renderGeomShadow(LLCamera& camera)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +    LL_PROFILE_GPU_ZONE("renderGeomShadow");      U32 cur_type = 0;  	LLGLEnable cull(GL_CULL_FACE); @@ -5160,7 +5166,6 @@ void LLPipeline::renderDebug()  		glPointSize(1.f);  	} -  	// Debug stuff.  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5214,6 +5219,12 @@ void LLPipeline::renderDebug()  	visible_selected_groups.clear(); +    //draw reflection probes and links between them +    if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only) +    { +        mReflectionMapManager.renderDebug(); +    } +  	gUIProgram.bind();  	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) @@ -5702,6 +5713,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  		}  		break; +    case LLDrawPool::POOL_PBR_OPAQUE: +        if( mPBROpaquePool ) +        { +            llassert(0); +            LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL; +        } +        else +        { +            mPBROpaquePool = new_poolp; +        } +        break; +  	default:  		llassert(0);  		LL_WARNS() << "Invalid Pool Type in  LLPipeline::addPool()" << LL_ENDL; @@ -5818,6 +5841,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )  		mGroundPool = NULL;  		break; +    case LLDrawPool::POOL_PBR_OPAQUE: +        llassert( poolp == mPBROpaquePool ); +        mPBROpaquePool = NULL; +        break; +  	default:  		llassert(0);  		LL_WARNS() << "Invalid Pool Type in  LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; @@ -5934,6 +5962,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)  static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;  	F32 inten = light->getLightIntensity();  	if (inten < .001f)  	{ @@ -5957,9 +5986,10 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_  void LLPipeline::calcNearbyLights(LLCamera& camera)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;  	assertInitialized(); -	if (LLPipeline::sReflectionRender) +	if (LLPipeline::sReflectionRender || gCubeSnapshot)  	{  		return;  	} @@ -6142,6 +6172,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)  void LLPipeline::setupHWLights(LLDrawPool* pool)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;  	assertInitialized();      LLEnvironment& environment = LLEnvironment::instance(); @@ -7464,9 +7495,11 @@ void LLPipeline::renderFinalize()      }      LLVector2 tc1(0, 0); -    LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2); +    LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2);      LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); +    LL_PROFILE_GPU_ZONE("renderFinalize"); +      gGL.color4f(1, 1, 1, 1);      LLGLDepthTest depth(GL_FALSE);      LLGLDisable blend(GL_BLEND); @@ -7488,6 +7521,7 @@ void LLPipeline::renderFinalize()      if (sRenderGlow)      { +        LL_PROFILE_GPU_ZONE("glow");          mGlow[2].bindTarget();          mGlow[2].clear(); @@ -7512,7 +7546,7 @@ void LLPipeline::renderFinalize()              gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -            mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); +            mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT);              gGL.color4f(1, 1, 1, 1);              gPipeline.enableLightsFullbright(); @@ -7528,7 +7562,7 @@ void LLPipeline::renderFinalize()              gGL.end(); -            gGL.getTexUnit(0)->unbind(mScreen.getUsage()); +            gGL.getTexUnit(0)->unbind(mRT->screen.getUsage());              mGlow[2].flush(); @@ -7606,7 +7640,7 @@ void LLPipeline::renderFinalize()      gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();      glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -    tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight()); +    tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight());      gGL.flush(); @@ -7614,17 +7648,18 @@ void LLPipeline::renderFinalize()      if (LLPipeline::sRenderDeferred)      { -          bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&                             (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && -                           RenderDepthOfField; +                           RenderDepthOfField && +                            !gCubeSnapshot; -        bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); +        bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();          gViewerWindow->setup3DViewport();          if (dof_enabled)          { +            LL_PROFILE_GPU_ZONE("dof");              LLGLSLShader *shader = &gDeferredPostProgram;              LLGLDisable blend(GL_BLEND); @@ -7709,7 +7744,7 @@ void LLPipeline::renderFinalize()              const F32 default_fov = CameraFieldOfView * F_PI / 180.f; -            // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); +            // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();              F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); @@ -7729,15 +7764,15 @@ void LLPipeline::renderFinalize()              F32 magnification = focal_length / (subject_distance - focal_length);              { // build diffuse+bloom+CoF -                mDeferredLight.bindTarget(); +                mRT->deferredLight.bindTarget();                  shader = &gDeferredCoFProgram;                  bindDeferredShader(*shader); -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());                  if (channel > -1)                  { -                    mScreen.bindTexture(0, channel); +                    mRT->screen.bindTexture(0, channel);                  }                  shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); @@ -7760,23 +7795,23 @@ void LLPipeline::renderFinalize()                  gGL.end();                  unbindDeferredShader(*shader); -                mDeferredLight.flush(); +                mRT->deferredLight.flush();              } -            U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale); -            U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale); +            U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); +            U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);              { // perform DoF sampling at half-res (preserve alpha channel) -                mScreen.bindTarget(); +                mRT->screen.bindTarget();                  glViewport(0, 0, dof_width, dof_height);                  gGL.setColorMask(true, false);                  shader = &gDeferredPostProgram;                  bindDeferredShader(*shader); -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());                  if (channel > -1)                  { -                    mDeferredLight.bindTexture(0, channel); +                    mRT->deferredLight.bindTexture(0, channel);                  }                  shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7795,15 +7830,15 @@ void LLPipeline::renderFinalize()                  gGL.end();                  unbindDeferredShader(*shader); -                mScreen.flush(); +                mRT->screen.flush();                  gGL.setColorMask(true, true);              }              { // combine result based on alpha                  if (multisample)                  { -                    mDeferredLight.bindTarget(); -                    glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); +                    mRT->deferredLight.bindTarget(); +                    glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());                  }                  else                  { @@ -7817,10 +7852,10 @@ void LLPipeline::renderFinalize()                  shader = &gDeferredDoFCombineProgram;                  bindDeferredShader(*shader); -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());                  if (channel > -1)                  { -                    mScreen.bindTexture(0, channel); +                    mRT->screen.bindTexture(0, channel);                  }                  shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7844,24 +7879,25 @@ void LLPipeline::renderFinalize()                  if (multisample)                  { -                    mDeferredLight.flush(); +                    mRT->deferredLight.flush();                  }              }          }          else          { +            LL_PROFILE_GPU_ZONE("no dof");              if (multisample)              { -                mDeferredLight.bindTarget(); +                mRT->deferredLight.bindTarget();              }              LLGLSLShader *shader = &gDeferredPostNoDoFProgram;              bindDeferredShader(*shader); -            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());              if (channel > -1)              { -                mScreen.bindTexture(0, channel); +                mRT->screen.bindTexture(0, channel);              }              gGL.begin(LLRender::TRIANGLE_STRIP); @@ -7880,17 +7916,18 @@ void LLPipeline::renderFinalize()              if (multisample)              { -                mDeferredLight.flush(); +                mRT->deferredLight.flush();              }          }          if (multisample)          { +            LL_PROFILE_GPU_ZONE("aa");              // bake out texture2D with RGBL for FXAA shader -            mFXAABuffer.bindTarget(); +            mRT->fxaaBuffer.bindTarget(); -            S32 width = mScreen.getWidth(); -            S32 height = mScreen.getHeight(); +            S32 width = mRT->screen.getWidth(); +            S32 height = mRT->screen.getHeight();              glViewport(0, 0, width, height);              LLGLSLShader *shader = &gGlowCombineFXAAProgram; @@ -7898,10 +7935,10 @@ void LLPipeline::renderFinalize()              shader->bind();              shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); -            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());              if (channel > -1)              { -                mDeferredLight.bindTexture(0, channel); +                mRT->deferredLight.bindTexture(0, channel);              }              gGL.begin(LLRender::TRIANGLE_STRIP); @@ -7912,18 +7949,18 @@ void LLPipeline::renderFinalize()              gGL.flush(); -            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());              shader->unbind(); -            mFXAABuffer.flush(); +            mRT->fxaaBuffer.flush();              shader = &gFXAAProgram;              shader->bind(); -            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); +            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());              if (channel > -1)              { -                mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); +                mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);              }              gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; @@ -7932,8 +7969,8 @@ void LLPipeline::renderFinalize()              gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();              glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -            F32 scale_x = (F32) width / mFXAABuffer.getWidth(); -            F32 scale_y = (F32) height / mFXAABuffer.getHeight(); +            F32 scale_x = (F32) width / mRT->fxaaBuffer.getWidth(); +            F32 scale_y = (F32) height / mRT->fxaaBuffer.getHeight();              shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);              shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);              shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, @@ -7984,7 +8021,7 @@ void LLPipeline::renderFinalize()          gGlowCombineProgram.bind();          gGL.getTexUnit(0)->bind(&mGlow[1]); -        gGL.getTexUnit(1)->bind(&mScreen); +        gGL.getTexUnit(1)->bind(&mRT->screen);          LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); @@ -8027,10 +8064,10 @@ void LLPipeline::renderFinalize()          gSplatTextureRectProgram.unbind();      } -    if (LLRenderTarget::sUseFBO) -    { // copy depth buffer from mScreen to framebuffer -        LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0, -                                                  mScreen.getWidth(), mScreen.getHeight(), +    if (LLRenderTarget::sUseFBO && !gCubeSnapshot) +    { // copy depth buffer from mRT->screen to framebuffer +        LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0, +                                                  mRT->screen.getWidth(), mRT->screen.getHeight(),                                                    GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);      } @@ -8048,10 +8085,10 @@ void LLPipeline::renderFinalize()  void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - -    LLRenderTarget* deferred_target       = &mDeferredScreen; -    LLRenderTarget* deferred_depth_target = &mDeferredDepth; -    LLRenderTarget* deferred_light_target = &mDeferredLight; +    LL_PROFILE_GPU_ZONE("bindDeferredShader"); +    LLRenderTarget* deferred_target       = &mRT->deferredScreen; +    LLRenderTarget* deferred_depth_target = &mRT->deferredDepth; +    LLRenderTarget* deferred_light_target = &mRT->deferredLight;  	shader.bind();  	S32 channel = 0; @@ -8200,16 +8237,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_  		{  			cube_map->enable(channel);  			cube_map->bind(); -			F32* m = gGLModelView; -						 -			F32 mat[] = { m[0], m[1], m[2], -						  m[4], m[5], m[6], -						  m[8], m[9], m[10] }; -		 -			shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);  		} + +        F32* m = gGLModelView; + +        F32 mat[] = { m[0], m[1], m[2], +                      m[4], m[5], m[6], +                      m[8], m[9], m[10] }; + +        shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);  	} +    bindReflectionProbes(shader); +          if (gAtmosphere)      {          // bind precomputed textures necessary for calculating sun and sky luminance @@ -8238,7 +8278,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_          }      } -	shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); +    /*if (gCubeSnapshot) +    { // we only really care about the first two values, but the shader needs increasing separation between clip planes +        shader.uniform4f(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1.f, 64.f, 128.f, 256.f); +    } +    else*/ +    { +        shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); +    }  	shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);  	shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);  	shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize); @@ -8273,8 +8320,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_  	shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);      shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV); -	shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight()); -	shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight()); +	shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight()); +	shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mRT->shadow[4].getWidth(), mRT->shadow[4].getHeight());  	shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);  	shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); @@ -8310,14 +8357,15 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f)  void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +    LL_PROFILE_GPU_ZONE("renderDeferredLighting");      if (!sCull)      {          return;      } -    LLRenderTarget *deferred_target       = &mDeferredScreen; -    LLRenderTarget *deferred_depth_target = &mDeferredDepth; -    LLRenderTarget *deferred_light_target = &mDeferredLight; +    LLRenderTarget *deferred_target       = &mRT->deferredScreen; +    LLRenderTarget *deferred_depth_target = &mRT->deferredDepth; +    LLRenderTarget *deferred_light_target = &mRT->deferredLight;      {          LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); @@ -8384,6 +8432,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)          if (RenderDeferredSSAO || RenderShadowDetail > 0)          { +            LL_PROFILE_GPU_ZONE("sun program");              deferred_light_target->bindTarget();              {  // paint shadow/SSAO light map (direct lighting lightmap)                  LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow"); @@ -8431,66 +8480,79 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)          }          if (RenderDeferredSSAO) -        {  // soften direct lighting lightmap -            LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow"); -            // blur lightmap -            screen_target->bindTarget(); -            glClearColor(1, 1, 1, 1); -            screen_target->clear(GL_COLOR_BUFFER_BIT); -            glClearColor(0, 0, 0, 0); - -            bindDeferredShader(gDeferredBlurLightProgram); -            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -            LLVector3 go          = RenderShadowGaussian; -            const U32 kern_length = 4; -            F32       blur_size   = RenderShadowBlurSize; -            F32       dist_factor = RenderShadowBlurDistFactor; - -            // sample symmetrically with the middle sample falling exactly on 0.0 -            F32 x = 0.f; - -            LLVector3 gauss[32];  // xweight, yweight, offset - -            for (U32 i = 0; i < kern_length; i++) -            { -                gauss[i].mV[0] = llgaussian(x, go.mV[0]); -                gauss[i].mV[1] = llgaussian(x, go.mV[1]); -                gauss[i].mV[2] = x; -                x += 1.f; +        { +            /*if (gCubeSnapshot) +            { // SSAO and shadows disabled in reflection maps +                deferred_light_target->bindTarget(); +                glClearColor(1, 1, 1, 1); +                deferred_light_target->clear(); +                glClearColor(0, 0, 0, 0); +                deferred_light_target->flush();              } +            else*/ +            { +                // soften direct lighting lightmap +                LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow"); +                LL_PROFILE_GPU_ZONE("soften shadow"); +                // blur lightmap +                screen_target->bindTarget(); +                glClearColor(1, 1, 1, 1); +                screen_target->clear(GL_COLOR_BUFFER_BIT); +                glClearColor(0, 0, 0, 0); -            gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); -            gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); -            gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); -            gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f)); +                bindDeferredShader(gDeferredBlurLightProgram); +                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                LLVector3 go = RenderShadowGaussian; +                const U32 kern_length = 4; +                F32       blur_size = RenderShadowBlurSize; +                F32       dist_factor = RenderShadowBlurDistFactor; -            { -                LLGLDisable   blend(GL_BLEND); -                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -                stop_glerror(); -                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -                stop_glerror(); -            } +                // sample symmetrically with the middle sample falling exactly on 0.0 +                F32 x = 0.f; -            screen_target->flush(); -            unbindDeferredShader(gDeferredBlurLightProgram); +                LLVector3 gauss[32];  // xweight, yweight, offset -            bindDeferredShader(gDeferredBlurLightProgram, screen_target); +                for (U32 i = 0; i < kern_length; i++) +                { +                    gauss[i].mV[0] = llgaussian(x, go.mV[0]); +                    gauss[i].mV[1] = llgaussian(x, go.mV[1]); +                    gauss[i].mV[2] = x; +                    x += 1.f; +                } -            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -            deferred_light_target->bindTarget(); +                gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); +                gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); +                gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); +                gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f)); -            gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); +                { +                    LLGLDisable   blend(GL_BLEND); +                    LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +                    stop_glerror(); +                    mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                    stop_glerror(); +                } -            { -                LLGLDisable   blend(GL_BLEND); -                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -                stop_glerror(); -                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -                stop_glerror(); +                screen_target->flush(); +                unbindDeferredShader(gDeferredBlurLightProgram); + +                bindDeferredShader(gDeferredBlurLightProgram, screen_target); + +                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                deferred_light_target->bindTarget(); + +                gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); + +                { +                    LLGLDisable   blend(GL_BLEND); +                    LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +                    stop_glerror(); +                    mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                    stop_glerror(); +                } +                deferred_light_target->flush(); +                unbindDeferredShader(gDeferredBlurLightProgram);              } -            deferred_light_target->flush(); -            unbindDeferredShader(gDeferredBlurLightProgram);          }          stop_glerror(); @@ -8511,6 +8573,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)              LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;              LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics"); +            LL_PROFILE_GPU_ZONE("atmospherics");              bindDeferredShader(soften_shader);              LLEnvironment &environment = LLEnvironment::instance(); @@ -8557,7 +8620,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)              gPipeline.popRenderTypeMask();          } -        bool render_local = RenderLocalLights; +        bool render_local = RenderLocalLights; // && !gCubeSnapshot;          if (render_local)          { @@ -8566,9 +8629,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)              LLDrawable::drawable_list_t spot_lights;              LLDrawable::drawable_list_t fullscreen_spot_lights; -            for (U32 i = 0; i < 2; i++) +            if (!gCubeSnapshot)              { -                mTargetShadowSpotLight[i] = NULL; +                for (U32 i = 0; i < 2; i++) +                { +                    mTargetShadowSpotLight[i] = NULL; +                }              }              std::list<LLVector4> light_colors; @@ -8577,6 +8643,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)              {                  LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - local lights"); +                LL_PROFILE_GPU_ZONE("local lights");                  bindDeferredShader(gDeferredLightProgram);                  if (mCubeVB.isNull()) @@ -8683,6 +8750,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)              if (!spot_lights.empty())              {                  LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - projectors"); +                LL_PROFILE_GPU_ZONE("projectors");                  LLGLDepthTest depth(GL_TRUE, GL_FALSE);                  bindDeferredShader(gDeferredSpotLightProgram); @@ -8729,7 +8797,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)              {                  LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights");                  LLGLDepthTest depth(GL_FALSE); - +                LL_PROFILE_GPU_ZONE("fullscreen lights");                  // full screen blit                  gGL.pushMatrix();                  gGL.loadIdentity(); @@ -8825,6 +8893,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)      gGL.loadIdentity();      { +        LL_PROFILE_GPU_ZONE("gamma correct");          LLGLDepthTest depth(GL_FALSE, GL_FALSE);          LLVector2 tc1(0, 0); @@ -8904,6 +8973,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)          popRenderTypeMask();      } +    if (!gCubeSnapshot)      {          // render highlights, etc.          renderHighlights(); @@ -9015,6 +9085,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  		shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);  	} +    if (!gCubeSnapshot)  	{  		LLDrawable* potential = drawablep;  		//determine if this is a good light for casting shadows @@ -9066,9 +9137,9 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  { -    LLRenderTarget* deferred_target       = &mDeferredScreen; -    LLRenderTarget* deferred_depth_target = &mDeferredDepth; -    LLRenderTarget* deferred_light_target = &mDeferredLight; +    LLRenderTarget* deferred_target       = &mRT->deferredScreen; +    LLRenderTarget* deferred_depth_target = &mRT->deferredDepth; +    LLRenderTarget* deferred_light_target = &mRT->deferredLight;  	stop_glerror();      shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); @@ -9107,11 +9178,47 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  			cube_map->disable();  		}  	} + +    unbindReflectionProbes(shader); +  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.getTexUnit(0)->activate();  	shader.unbind();  } +void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) +{ +    S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); +    if (channel > -1 && mReflectionMapManager.mTexture.notNull()) +    { +        // see comments in class2/deferred/softenLightF.glsl for what these uniforms mean +        mReflectionMapManager.mTexture->bind(channel); +        mReflectionMapManager.setUniforms(); + +        F32* m = gGLModelView; + +        F32 mat[] = { m[0], m[1], m[2], +                      m[4], m[5], m[6], +                      m[8], m[9], m[10] }; + +        shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); +    } +} + +void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader) +{ +    S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP); +    if (channel > -1 && mReflectionMapManager.mTexture.notNull()) +    { +        mReflectionMapManager.mTexture->unbind(); +        if (channel == 0) +        { +            gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE); +        } +    } +} + +  inline float sgn(float a)  {      if (a > 0.0F) return (1.0F); @@ -9122,8 +9229,9 @@ inline float sgn(float a)  void LLPipeline::generateWaterReflection(LLCamera& camera_in)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +    LL_PROFILE_GPU_ZONE("generateWaterReflection"); -    if (!assertInitialized()) +    if (!assertInitialized() || gCubeSnapshot)      {          return;      } @@ -9533,7 +9641,7 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbri  void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); - +    LL_PROFILE_GPU_ZONE("renderShadow");      //disable occlusion culling for shadow passes (save setting to restore later)      S32 occlude = LLPipeline::sUseOcclusion;      if (!use_occlusion) @@ -9568,7 +9676,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera          gDeferredShadowCubeProgram.bind();      } -    LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1]; +    LLRenderTarget& occlusion_target = mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - 1];      occlusion_target.bindTarget();      updateCull(shadow_cam, result); @@ -9620,7 +9728,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera          }          LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); - +        LL_PROFILE_GPU_ZONE("shadow simple");          gGL.getTexUnit(0)->disable();          for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i)          { @@ -9653,7 +9761,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera      {          LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); - +        LL_PROFILE_GPU_ZONE("shadow alpha");          for (int i = 0; i < 2; ++i)          {              bool rigged = i == 1; @@ -9712,9 +9820,12 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera      gGLLastMatrix = NULL;      gGL.loadMatrix(gGLModelView); -    LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1]; +    LLRenderTarget& occlusion_source = mRT->shadow[LLViewerCamera::sCurCameraID - 1]; -    doOcclusion(shadow_cam, occlusion_source, occlusion_target); +    if (occlude > 1) +    { +        doOcclusion(shadow_cam, occlusion_source, occlusion_target); +    }      if (use_shader)      { @@ -9935,7 +10046,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)  	{  		mHighlightSet.insert(HighlightItem(mHighlightObject));  	} -	 +    llassert(!gCubeSnapshot); +  	if (!mHighlightSet.empty())  	{  		F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime; @@ -9985,7 +10097,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)  LLRenderTarget* LLPipeline::getShadowTarget(U32 i)  { -    return &mShadow[i]; +    return &mRT->shadow[i];  }  static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); @@ -9999,6 +10111,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	}  	LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); +    LL_PROFILE_GPU_ZONE("generateSunShadow");  	bool skip_avatar_update = false;  	if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) @@ -10110,6 +10223,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	clip = RenderShadowOrthoClipPlanes;  	mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); +    //if (gCubeSnapshot) +    { //always do a single 64m shadow in reflection maps +        mSunClipPlanes.set(64.f, 128.f, 256.f); +        mSunOrthoClipPlanes.set(64.f, 128.f, 256.f); +    } +  	//currently used for amount to extrude frusta corners for constructing shadow frusta  	//LLVector3 n = RenderShadowNearDist;  	//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; @@ -10226,21 +10345,34 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	// convenience array of 4 near clip plane distances  	F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; -  	if (mSunDiffuse == LLColor4::black) -	{ //sun diffuse is totally black, shadows don't matter +	{ //sun diffuse is totally shadows don't matter  		LLGLDepthTest depth(GL_TRUE);  		for (S32 j = 0; j < 4; j++)  		{ -			mShadow[j].bindTarget(); -			mShadow[j].clear(); -			mShadow[j].flush(); +			mRT->shadow[j].bindTarget(); +			mRT->shadow[j].clear(); +			mRT->shadow[j].flush();  		}  	}  	else  	{ -		for (S32 j = 0; j < 4; j++) +        /*if (gCubeSnapshot) +        { +            // do one shadow split for cube snapshots, clear the rest +            mSunClipPlanes.set(64.f, 64.f, 64.f); +            dist[1] = dist[2] = dist[3] = dist[4] = 64.f; +            for (S32 j = 1; j < 4; j++) +            { +                mRT->shadow[j].bindTarget(); +                mRT->shadow[j].clear(); +                mRT->shadow[j].flush(); +            } +        }*/ + +		//for (S32 j = 0; j < (gCubeSnapshot ? 1 : 4); j++) +        for (S32 j = 0; j < 4; j++)  		{  			if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))  			{ @@ -10301,12 +10433,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  					mShadowCamera[j+4] = shadow_cam;  				} -				mShadow[j].bindTarget(); +				mRT->shadow[j].bindTarget();  				{  					LLGLDepthTest depth(GL_TRUE); -					mShadow[j].clear(); +					mRT->shadow[j].clear();  				} -				mShadow[j].flush(); +				mRT->shadow[j].flush();  				mShadowError.mV[j] = 0.f;  				mShadowFOV.mV[j] = 0.f; @@ -10593,18 +10725,18 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			stop_glerror(); -			mShadow[j].bindTarget(); -			mShadow[j].getViewport(gGLViewport); -			mShadow[j].clear(); +			mRT->shadow[j].bindTarget(); +			mRT->shadow[j].getViewport(gGLViewport); +			mRT->shadow[j].clear(); -			U32 target_width = mShadow[j].getWidth(); +			U32 target_width = mRT->shadow[j].getWidth();  			{  				static LLCullResult result[4];  				renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width);  			} -			mShadow[j].flush(); +			mRT->shadow[j].flush();  			if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))  			{ @@ -10619,142 +10751,145 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	if (gen_shadow)  	{ -		LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); -		F32 fade_amt = gFrameIntervalSeconds.value()  -			* llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); - -		//update shadow targets -		for (U32 i = 0; i < 2; i++) -		{ //for each current shadow -			LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); - -			if (mShadowSpotLight[i].notNull() &&  -				(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || -				mShadowSpotLight[i] == mTargetShadowSpotLight[1])) -			{ //keep this spotlight -				mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); -			} -			else -			{ //fade out this light -				mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); +        if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates +        { +		    LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); +		    F32 fade_amt = gFrameIntervalSeconds.value()  +			    * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); + +		    //update shadow targets +		    for (U32 i = 0; i < 2; i++) +		    { //for each current shadow +			    LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); + +			    if (mShadowSpotLight[i].notNull() &&  +				    (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || +				    mShadowSpotLight[i] == mTargetShadowSpotLight[1])) +			    { //keep this spotlight +				    mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); +			    } +			    else +			    { //fade out this light +				    mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); -				if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) -				{ //faded out, grab one of the pending spots (whichever one isn't already taken) -					if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) -					{ -						mShadowSpotLight[i] = mTargetShadowSpotLight[0]; -					} -					else -					{ -						mShadowSpotLight[i] = mTargetShadowSpotLight[1]; -					} -				} -			} -		} +				    if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) +				    { //faded out, grab one of the pending spots (whichever one isn't already taken) +					    if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) +					    { +						    mShadowSpotLight[i] = mTargetShadowSpotLight[0]; +					    } +					    else +					    { +						    mShadowSpotLight[i] = mTargetShadowSpotLight[1]; +					    } +				    } +			    } +		    } + +            for (S32 i = 0; i < 2; i++) +            { +                set_current_modelview(saved_view); +                set_current_projection(saved_proj); -		for (S32 i = 0; i < 2; i++) -		{ -			set_current_modelview(saved_view); -			set_current_projection(saved_proj); +                if (mShadowSpotLight[i].isNull()) +                { +                    continue; +                } -			if (mShadowSpotLight[i].isNull()) -			{ -				continue; -			} +                LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); -			LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); +                if (!volume) +                { +                    mShadowSpotLight[i] = NULL; +                    continue; +                } -			if (!volume) -			{ -				mShadowSpotLight[i] = NULL; -				continue; -			} +                LLDrawable* drawable = mShadowSpotLight[i]; -			LLDrawable* drawable = mShadowSpotLight[i]; +                LLVector3 params = volume->getSpotLightParams(); +                F32 fov = params.mV[0]; -			LLVector3 params = volume->getSpotLightParams(); -			F32 fov = params.mV[0]; +                //get agent->light space matrix (modelview) +                LLVector3 center = drawable->getPositionAgent(); +                LLQuaternion quat = volume->getRenderRotation(); -			//get agent->light space matrix (modelview) -			LLVector3 center = drawable->getPositionAgent(); -			LLQuaternion quat = volume->getRenderRotation(); +                //get near clip plane +                LLVector3 scale = volume->getScale(); +                LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f); +                at_axis *= quat; -			//get near clip plane -			LLVector3 scale = volume->getScale(); -			LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); -			at_axis *= quat; +                LLVector3 np = center + at_axis; +                at_axis.normVec(); -			LLVector3 np = center+at_axis; -			at_axis.normVec(); +                //get origin that has given fov for plane np, at_axis, and given scale +                F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f); -			//get origin that has given fov for plane np, at_axis, and given scale -			F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); +                LLVector3 origin = np - at_axis * dist; -			LLVector3 origin = np - at_axis*dist; +                LLMatrix4 mat(quat, LLVector4(origin, 1.f)); -			LLMatrix4 mat(quat, LLVector4(origin, 1.f)); +                view[i + 4] = glh::matrix4f((F32*)mat.mMatrix); -			view[i+4] = glh::matrix4f((F32*) mat.mMatrix); +                view[i + 4] = view[i + 4].inverse(); -			view[i+4] = view[i+4].inverse(); +                //get perspective matrix +                F32 near_clip = dist + 0.01f; +                F32 width = scale.mV[VX]; +                F32 height = scale.mV[VY]; +                F32 far_clip = dist + volume->getLightRadius() * 1.5f; -			//get perspective matrix -			F32 near_clip = dist+0.01f; -			F32 width = scale.mV[VX]; -			F32 height = scale.mV[VY]; -			F32 far_clip = dist+volume->getLightRadius()*1.5f; +                F32 fovy = fov * RAD_TO_DEG; +                F32 aspect = width / height; -			F32 fovy = fov * RAD_TO_DEG; -			F32 aspect = width/height; -			 -			proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); +                proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip); -			//translate and scale to from [-1, 1] to [0, 1] -			glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, -							0.f, 0.5f, 0.f, 0.5f, -							0.f, 0.f, 0.5f, 0.5f, -							0.f, 0.f, 0.f, 1.f); +                //translate and scale to from [-1, 1] to [0, 1] +                glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, +                    0.f, 0.5f, 0.f, 0.5f, +                    0.f, 0.f, 0.5f, 0.5f, +                    0.f, 0.f, 0.f, 1.f); -			set_current_modelview(view[i+4]); -			set_current_projection(proj[i+4]); +                set_current_modelview(view[i + 4]); +                set_current_projection(proj[i + 4]); -			mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; -			 -			for (U32 j = 0; j < 16; j++) -			{ -				gGLLastModelView[j] = mShadowModelview[i+4].m[j]; -				gGLLastProjection[j] = mShadowProjection[i+4].m[j]; -			} +                mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view; + +                for (U32 j = 0; j < 16; j++) +                { +                    gGLLastModelView[j] = mShadowModelview[i + 4].m[j]; +                    gGLLastProjection[j] = mShadowProjection[i + 4].m[j]; +                } -			mShadowModelview[i+4] = view[i+4]; -			mShadowProjection[i+4] = proj[i+4]; +                mShadowModelview[i + 4] = view[i + 4]; +                mShadowProjection[i + 4] = proj[i + 4]; -			LLCamera shadow_cam = camera; -			shadow_cam.setFar(far_clip); -			shadow_cam.setOrigin(origin); +                LLCamera shadow_cam = camera; +                shadow_cam.setFar(far_clip); +                shadow_cam.setOrigin(origin); -			LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); +                LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); -			stop_glerror(); +                stop_glerror(); -			mShadow[i+4].bindTarget(); -			mShadow[i+4].getViewport(gGLViewport); -			mShadow[i+4].clear(); +                mRT->shadow[i + 4].bindTarget(); +                mRT->shadow[i + 4].getViewport(gGLViewport); +                mRT->shadow[i + 4].clear(); -			U32 target_width = mShadow[i+4].getWidth(); +                U32 target_width = mRT->shadow[i + 4].getWidth(); -			static LLCullResult result[2]; +                static LLCullResult result[2]; -			LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); +                LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); -            RenderSpotLight = drawable;             +                RenderSpotLight = drawable; -			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); +                renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], FALSE, FALSE, target_width); -            RenderSpotLight = nullptr; +                RenderSpotLight = nullptr; -			mShadow[i+4].flush(); - 		} +                mRT->shadow[i + 4].flush(); +            } +        }  	}  	else  	{ //no spotlight shadows @@ -10827,6 +10962,7 @@ static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");  void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)  {      LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR); +    LL_PROFILE_GPU_ZONE("generateImpostor");  	LLGLState::checkStates();  	LLGLState::checkTextureChannels(); @@ -11070,7 +11206,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)  		if (LLPipeline::sRenderDeferred)  		{  			GLuint buff = GL_COLOR_ATTACHMENT0; -			LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF );  			glDrawBuffersARB(1, &buff);  		} @@ -11471,3 +11606,9 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )  	}  } +void LLPipeline::overrideEnvironmentMap() +{ +    //mReflectionMapManager.mProbes.clear(); +    //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin()); +} + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 62d3ae7a39..bb2e1d65ae 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -38,6 +38,7 @@  #include "llgl.h"  #include "lldrawable.h"  #include "llrendertarget.h" +#include "llreflectionmapmanager.h"  #include <stack> @@ -293,6 +294,10 @@ public:  	void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);  	void unbindDeferredShader(LLGLSLShader& shader); + +    void bindReflectionProbes(LLGLSLShader& shader); +    void unbindReflectionProbes(LLGLSLShader& shader); +  	void renderDeferredLighting(LLRenderTarget* light_target);  	void postDeferredGammaCorrect(LLRenderTarget* screen_target); @@ -426,6 +431,9 @@ public:  	void hideObject( const LLUUID& id );  	void restoreHiddenObject( const LLUUID& id ); +    LLReflectionMapManager mReflectionMapManager; +    void overrideEnvironmentMap(); +  private:  	void unloadShaders();  	void addToQuickLookup( LLDrawPool* new_poolp ); @@ -574,7 +582,8 @@ public:  		RENDER_DEBUG_ATTACHMENT_BYTES	=  0x20000000, // not used  		RENDER_DEBUG_TEXEL_DENSITY		=  0x40000000,  		RENDER_DEBUG_TRIANGLE_COUNT		=  0x80000000, -		RENDER_DEBUG_IMPOSTORS			= 0x100000000 +		RENDER_DEBUG_IMPOSTORS			= 0x100000000, +        RENDER_DEBUG_REFLECTION_PROBES  = 0x200000000  	};  public: @@ -626,26 +635,38 @@ public:  	static bool				sRenderAttachedLights;  	static bool				sRenderAttachedParticles;  	static bool				sRenderDeferred; +    static bool				sRenderPBR;  	static S32				sVisibleLightCount;  	static bool				sRenderingHUDs;      static F32              sDistortionWaterClipPlaneMargin;  	static LLTrace::EventStatHandle<S64> sStatBatchSize; -	//screen texture -	U32 					mScreenWidth; -	U32 					mScreenHeight; -	 -	LLRenderTarget			mScreen; -	LLRenderTarget			mUIScreen; -	LLRenderTarget			mDeferredScreen; -	LLRenderTarget			mFXAABuffer; -	LLRenderTarget			mEdgeMap; -	LLRenderTarget			mDeferredDepth; -	LLRenderTarget			mOcclusionDepth; -	LLRenderTarget			mDeferredLight; -	LLRenderTarget			mHighlight; -	LLRenderTarget			mPhysicsDisplay; +    class RenderTargetPack +    { +    public: +        U32 					width = 0; +        U32 					height = 0; + +        //screen texture +        LLRenderTarget			screen; +        LLRenderTarget			uiScreen; +        LLRenderTarget			deferredScreen; +        LLRenderTarget			fxaaBuffer; +        LLRenderTarget			edgeMap; +        LLRenderTarget			deferredDepth; +        LLRenderTarget			occlusionDepth; +        LLRenderTarget			deferredLight; + +        //sun shadow map +        LLRenderTarget			shadow[6]; +        LLRenderTarget			shadowOcclusion[6]; +    }; + +    RenderTargetPack* mRT; + +    LLRenderTarget			mHighlight; +    LLRenderTarget			mPhysicsDisplay;      LLCullResult            mSky;      LLCullResult            mReflectedObjects; @@ -657,9 +678,9 @@ public:  	//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]  	LLPointer<LLVertexBuffer> mCubeVB; -	//sun shadow map -	LLRenderTarget			mShadow[6]; -	LLRenderTarget			mShadowOcclusion[6]; +    //list of currently bound reflection maps +    std::vector<LLReflectionMap*> mReflectionMaps; +  	std::vector<LLVector3>	mShadowFrustPoints[4];  	LLVector4				mShadowError;  	LLVector4				mShadowFOV; @@ -860,6 +881,7 @@ protected:  	LLDrawPool*					mBumpPool;  	LLDrawPool*					mMaterialsPool;  	LLDrawPool*					mWLSkyPool; +	LLDrawPool*					mPBROpaquePool;  	// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar  public: diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 0abee2ff80..44bdcd86f9 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2,7 +2,7 @@  <floater   positioning="cascading"   legacy_header_height="18" - height="600" + height="640"   layout="topleft"   bg_opaque_image="Window_NoTitle_Foreground"   bg_alpha_image="Window_NoTitle_Background" @@ -820,7 +820,7 @@      width="282"/>      <tab_container       follows="left|top" -     height="410" +     height="460"       halign="center"       left="0"       name="Object Info Tabs" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8d7cfe1116..0b0f8e17bc 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2912,6 +2912,16 @@ function="World.EnvPreset"             parameter="lights" />          </menu_item_check>          <menu_item_check +         label="Reflection Probes" +         name="Reflection Probes"> +          <menu_item_check.on_check +           function="Advanced.CheckInfoDisplay" +           parameter="reflection probes" /> +          <menu_item_check.on_click +           function="Advanced.ToggleInfoDisplay" +           parameter="reflection probes" /> +        </menu_item_check> +        <menu_item_check           label="Particles"           name="Particles">            <menu_item_check.on_check @@ -3250,6 +3260,13 @@ function="World.EnvPreset"                   function="ToggleControl"                   parameter="RenderHoverGlowEnable" />              </menu_item_check> +            <menu_item_call +              enabled="true" +              label="Rebuild Reflection Probes" +              name="Rebuild Reflection Probes"> +              <menu_item_call.on_click +               function="Develop.RebuildReflectionProbes" /> +            </menu_item_call>            <menu_item_separator />            <menu_item_call diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index aa93601669..786cf32e7a 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -11819,4 +11819,10 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB      </form>    </notification> +<notification + icon="notifytip.tga" + name="MaterialCreated" + type="notifytip"> +Material successfully created.  Asset ID: [ASSET_ID] +</notification>  </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 5aff7a5127..90bb45d1bc 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -258,7 +258,21 @@      <check_box.commit_callback        function="Pref.RenderOptionUpdate" />    </check_box> -   + +  <check_box +    control_name="RenderPBR" +    height="16" +    initial_value="true" +    label="Physically Based Rendering" +    layout="topleft" +    left="30" +    name="UsePBRShaders" +    top_delta="24" +    width="256"> +    <check_box.commit_callback +      function="Pref.RenderOptionUpdate" /> +  </check_box> +    <slider      control_name="IndirectMaxComplexity"      tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll" @@ -274,7 +288,7 @@      max_val="101"      name="IndirectMaxComplexity"      show_text="false" -    top_delta="60" +    top_delta="36"      width="300">      <slider.commit_callback        function="Pref.UpdateIndirectMaxComplexity" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 90f32ae452..85ee736176 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -2,7 +2,7 @@  <panel           border="false"           follows="all" -         height="420" +         height="500"           label="Texture"           layout="topleft"           left="0" @@ -772,7 +772,7 @@               width="260" />  			<button  			 left="10" -			 top="222" +			 top="257"  			 height="20"  			 label="Align"  			 label_selected="Align current texture layers" @@ -793,4 +793,29 @@               height="4"               start_url="about:blank"               decouple_texture_size="true" /> -	   </panel> +      <button +       left="90" +       top="222" +       height="20" +       label="Save as Material" +       label_selected="Save current face as a Material" +       layout="topleft" +       name="button save material" +       top_delta="0" +       tool_tip="Save material to inventory" +       width="110" /> + +            <line_editor +             enabled="true" +             follows="top|left" +             height="16" +             layout="topleft" +             left="7" +             label="Material UUID" +             name="materialID" +             select_on_focus="true" +             top="380" +             width="200" +             tool_tip="UUID for a material asset" +             /> +</panel>  | 
