diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class1/gltf')
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessF.glsl | 185 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessV.glsl | 74 | 
2 files changed, 228 insertions, 31 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessF.glsl b/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessF.glsl index dbee58b76a..a59127ec77 100644 --- a/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessF.glsl +++ b/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessF.glsl @@ -1,24 +1,24 @@ -/**  +/**   * @file pbrmetallicroughnessF.glsl   *   * $LicenseInfo:firstyear=2024&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$   */ @@ -33,11 +33,82 @@ uniform sampler2D diffuseMap;  //always in sRGB space  uniform float metallicFactor;  uniform float roughnessFactor;  uniform vec3 emissiveColor; -uniform sampler2D bumpMap; +uniform sampler2D normalMap;  uniform sampler2D emissiveMap; -uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness +uniform sampler2D metallicRoughnessMap; +uniform sampler2D occlusionMap; + +#ifdef ALPHA_BLEND +out vec4 frag_color; + +in vec3 vary_fragcoord; + +#ifdef HAS_SUN_SHADOW +uniform sampler2D lightMap; +uniform vec2 screen_res; +#endif + +// Lights +// See: LLRender::syncLightState() +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; // spot direction +uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState() +uniform vec3 light_diffuse[8]; +uniform vec2 light_deferred_attenuation[8]; // light size and falloff + +uniform int sun_up_factor; +uniform vec3 sun_dir; +uniform vec3 moon_dir; +vec3 srgb_to_linear(vec3 c); +vec3 linear_to_srgb(vec3 c); + +void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); +vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color); + +void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); +float calcLegacyDistanceAttenuation(float distance, float falloff); +float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, +        vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); + +void mirrorClip(vec3 pos); +void waterClip(vec3 pos); + +void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor); + +vec3 pbrBaseLight(vec3 diffuseColor, +                  vec3 specularColor, +                  float metallic, +                  vec3 pos, +                  vec3 norm, +                  float perceptualRoughness, +                  vec3 light_dir, +                  vec3 sunlit, +                  float scol, +                  vec3 radiance, +                  vec3 irradiance, +                  vec3 colorEmissive, +                  float ao, +                  vec3 additive, +                  vec3 atten); + +vec3 pbrCalcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor, +                    float perceptualRoughness, +                    float metallic, +                    vec3 n, // normal +                    vec3 p, // pixel position +                    vec3 v, // view vector (negative normalized pixel position) +                    vec3 lp, // light position +                    vec3 ld, // light direction (for spotlights) +                    vec3 lightColor, +                    float lightSize, float falloff, float is_pointlight, float ambiance); + + +#else  out vec4 frag_data[4]; +#endif +  in vec3 vary_position;  in vec4 vertex_color; @@ -50,7 +121,7 @@ in vec2 normal_texcoord;  in vec2 metallic_roughness_texcoord;  in vec2 emissive_texcoord; -uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() +uniform float minimum_alpha;  vec3 linear_to_srgb(vec3 c);  vec3 srgb_to_linear(vec3 c); @@ -62,9 +133,11 @@ void mirrorClip(vec3 pos);  uniform mat3 normal_matrix; +  void main()  { -    mirrorClip(vary_position); +    vec3 pos = vary_position; +    mirrorClip(pos);      vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;      basecolor.rgb = srgb_to_linear(basecolor.rgb); @@ -79,39 +152,97 @@ void main()      vec3 col = basecolor.rgb;      // from mikktspace.com -    vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0; +    vec3 vNt = texture(normalMap, normal_texcoord.xy).xyz*2.0-1.0;      float sign = vary_sign;      vec3 vN = vary_normal;      vec3 vT = vary_tangent.xyz; -     +      vec3 vB = sign * cross(vN, vT); -    vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); +    vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );      // RGB = Occlusion, Roughness, Metal      // default values, see LLViewerTexture::sDefaultPBRORMImagep      //   occlusion 1.0      //   roughness 0.0      //   metal     0.0 -    vec3 spec = texture(specularMap, metallic_roughness_texcoord.xy).rgb; -     -    spec.g *= roughnessFactor; -    spec.b *= metallicFactor; +    vec3 orm = texture(metallicRoughnessMap, metallic_roughness_texcoord.xy).rgb; +    orm.r = texture(occlusionMap, metallic_roughness_texcoord.xy).r; +    orm.g *= roughnessFactor; +    orm.b *= metallicFactor;      vec3 emissive = emissiveColor;      emissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb); -    tnorm *= gl_FrontFacing ? 1.0 : -1.0; +    norm *= gl_FrontFacing ? 1.0 : -1.0; + +#ifdef ALPHA_BLEND +    vec3 color = vec3(0,0,0); + +    vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir; + +    float scol = 1.0; +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; +    calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten); + +    vec3 sunlit_linear = srgb_to_linear(sunlit); + +    vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + +#ifdef HAS_SUN_SHADOW +    scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag); +#endif + +    float perceptualRoughness = orm.g * roughnessFactor; +    float metallic = orm.b * metallicFactor; + +    // emissiveColor is the emissive color factor from GLTF and is already in linear space +    vec3 colorEmissive = emissiveColor; +    // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear +    colorEmissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb); + +    // PBR IBL +    float gloss      = 1.0 - perceptualRoughness; +    vec3  irradiance = vec3(0); +    vec3  radiance  = vec3(0); +    sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, pos.xyz, norm.xyz, gloss, true, amblit); + +    vec3 diffuseColor; +    vec3 specularColor; +    calcDiffuseSpecular(col.rgb, metallic, diffuseColor, specularColor); + +    vec3 v = -normalize(pos.xyz); + +    color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, orm.r, additive, atten); + +    vec3 light = vec3(0); + +    // Punctual lights +#define LIGHT_LOOP(i) light += pbrCalcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, 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.rgb += light.rgb; + +    color.rgb = applySkyAndWaterFog(pos.xyz, additive, atten, vec4(color, 1.0)).rgb; + +    float a = basecolor.a*vertex_color.a; -    //spec.rgb = vec3(1,1,0); -    //col = vec3(0,0,0); -    //emissive = vary_tangent.xyz*0.5+0.5; -    //emissive = vec3(sign*0.5+0.5); -    //emissive = vNt * 0.5 + 0.5; -    //emissive = tnorm*0.5+0.5; +    frag_color = max(vec4(color.rgb,a), vec4(0)); +#else      // See: C++: addDeferredAttachments(), GLSL: softenLightF -    frag_data[0] = max(vec4(col, 0.0), vec4(0));                                                   // Diffuse -    frag_data[1] = max(vec4(spec.rgb,0.0), vec4(0));                                    // PBR linear packed Occlusion, Roughness, Metal. -    frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags -    frag_data[3] = max(vec4(emissive,0), vec4(0));                                                // PBR sRGB Emissive +    frag_data[0] = max(vec4(col, 0.0), vec4(0)); +    frag_data[1] = max(vec4(orm.rgb,0.0), vec4(0)); +    frag_data[2] = vec4(norm, GBUFFER_FLAG_HAS_PBR); +    frag_data[3] = max(vec4(emissive,0), vec4(0)); +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessV.glsl b/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessV.glsl index 0add509002..403ca8b2db 100644 --- a/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessV.glsl +++ b/indra/newview/app_settings/shaders/class1/gltf/pbrmetallicroughnessV.glsl @@ -29,7 +29,6 @@ uniform mat4 modelview_matrix;  #ifdef HAS_SKIN  uniform mat4 projection_matrix; -mat4 getObjectSkinnedTransform();  #else  uniform mat3 normal_matrix;  uniform mat4 modelview_projection_matrix; @@ -62,21 +61,85 @@ out vec3 vary_position;  vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);  vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); + +#ifdef ALPHA_BLEND +out vec3 vary_fragcoord; +#endif + + +#ifdef HAS_SKIN +in vec4 weight4; + +layout (std140) uniform GLTFJoints +{ +    // list of OBBs for user override probes +    mat3x4 gltf_joints[MAX_JOINTS_PER_GLTF_OBJECT]; +}; + +mat4 getGLTFSkinTransform() +{ +    int i; + +    vec4 w = fract(weight4); +    vec4 index = floor(weight4); + +    index = min(index, vec4(MAX_JOINTS_PER_GLTF_OBJECT-1)); +    index = max(index, vec4( 0.0)); + +    w *= 1.0/(w.x+w.y+w.z+w.w); + +    int i1 = int(index.x); +    int i2 = int(index.y); +    int i3 = int(index.z); +    int i4 = int(index.w); + +    mat3 mat = mat3(gltf_joints[i1])*w.x; +         mat += mat3(gltf_joints[i2])*w.y; +         mat += mat3(gltf_joints[i3])*w.z; +         mat += mat3(gltf_joints[i4])*w.w; + +    vec3 trans = vec3(gltf_joints[i1][0].w,gltf_joints[i1][1].w,gltf_joints[i1][2].w)*w.x; +         trans += vec3(gltf_joints[i2][0].w,gltf_joints[i2][1].w,gltf_joints[i2][2].w)*w.y; +         trans += vec3(gltf_joints[i3][0].w,gltf_joints[i3][1].w,gltf_joints[i3][2].w)*w.z; +         trans += vec3(gltf_joints[i4][0].w,gltf_joints[i4][1].w,gltf_joints[i4][2].w)*w.w; + +    mat4 ret; + +    ret[0] = vec4(mat[0], 0); +    ret[1] = vec4(mat[1], 0); +    ret[2] = vec4(mat[2], 0); +    ret[3] = vec4(trans, 1.0); + +    return ret; + +#ifdef IS_AMD_CARD +   // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +   mat3x4 dummy1 = gltf_joints[0]; +   mat3x4 dummy2 = gltf_joints[MAX_JOINTS_PER_MESH_OBJECT-1]; +#endif + +} + +#endif +  void main()  {  #ifdef HAS_SKIN -    mat4 mat = getObjectSkinnedTransform(); +    mat4 mat = getGLTFSkinTransform();      mat = modelview_matrix * mat;      vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;      vary_position = pos; -    gl_Position = projection_matrix*vec4(pos,1.0); + +    vec4 vert = projection_matrix * vec4(pos, 1.0); +    gl_Position = vert;  #else      vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;      //transform vertex -    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    vec4 vert = modelview_projection_matrix * vec4(position.xyz, 1.0); +    gl_Position = vert;  #endif      base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); @@ -99,6 +162,9 @@ void main()      vary_normal = n;      vertex_color = diffuse_color; +#ifdef ALPHA_BLEND +    vary_fragcoord = vert.xyz; +#endif  } | 
