diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 41dc567f4b..4397901cdc 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -735,6 +735,24 @@ void LLLightState::setSunPrimary(bool v) } } +void LLLightState::setSize(F32 v) +{ + if (mSize != v) + { + ++gGL.mLightHash; + mSize = v; + } +} + +void LLLightState::setFalloff(F32 v) +{ + if (mFalloff != v) + { + ++gGL.mLightHash; + mFalloff = v; + } +} + void LLLightState::setAmbient(const LLColor4& ambient) { if (mAmbient != ambient) @@ -1002,6 +1020,7 @@ void LLRender::syncLightState() LLVector3 diffuse[LL_NUM_LIGHT_UNITS]; LLVector3 diffuse_b[LL_NUM_LIGHT_UNITS]; bool sun_primary[LL_NUM_LIGHT_UNITS]; + LLVector2 size[LL_NUM_LIGHT_UNITS]; for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; i++) { @@ -1013,11 +1032,13 @@ void LLRender::syncLightState() diffuse[i].set(light->mDiffuse.mV); diffuse_b[i].set(light->mDiffuseB.mV); sun_primary[i] = light->mSunIsPrimary; + size[i].set(light->mSize, light->mFalloff); } shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, LL_NUM_LIGHT_UNITS, position[0].mV); shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, LL_NUM_LIGHT_UNITS, direction[0].mV); shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, LL_NUM_LIGHT_UNITS, attenuation[0].mV); + shader->uniform2fv(LLShaderMgr::LIGHT_DEFERRED_ATTENUATION, LL_NUM_LIGHT_UNITS, size[0].mV); shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, LL_NUM_LIGHT_UNITS, diffuse[0].mV); shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV); shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_primary[0] ? 1 : 0); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 0559730192..5eaba86d18 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -256,6 +256,8 @@ public: void setSpotCutoff(const F32& cutoff); void setSpotDirection(const LLVector3& direction); void setSunPrimary(bool v); + void setSize(F32 size); + void setFalloff(F32 falloff); protected: friend class LLRender; @@ -276,6 +278,8 @@ protected: F32 mSpotExponent; F32 mSpotCutoff; + F32 mSize = 0.f; + F32 mFalloff = 0.f; }; class LLRender diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 5706275b47..ace0288521 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1186,6 +1186,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("light_position"); mReservedUniforms.push_back("light_direction"); mReservedUniforms.push_back("light_attenuation"); + mReservedUniforms.push_back("light_deferred_attenuation"); mReservedUniforms.push_back("light_diffuse"); mReservedUniforms.push_back("light_ambient"); mReservedUniforms.push_back("light_count"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index ad32cce295..23f10f462b 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -55,6 +55,7 @@ public: LIGHT_POSITION, // "light_position" LIGHT_DIRECTION, // "light_direction" LIGHT_ATTENUATION, // "light_attenuation" + LIGHT_DEFERRED_ATTENUATION, // "light_deferred_attenuation" LIGHT_DIFFUSE, // "light_diffuse" LIGHT_AMBIENT, // "light_ambient" MULTI_LIGHT_COUNT, // "light_count" diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 02b2daf0ac..fc1cee1f59 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -262,27 +262,15 @@ void main() vec3 sun_contrib = min(final_da, shadow) * sunlit; -#if !defined(AMBIENT_KILL) color.rgb = amblit; color.rgb *= ambient; -#endif // !defined(AMBIENT_KILL) -vec3 post_ambient = color.rgb; - -#if !defined(SUNLIGHT_KILL) color.rgb += sun_contrib; -#endif // !defined(SUNLIGHT_KILL) - -vec3 post_sunlight = color.rgb; color.rgb *= diffuse_srgb.rgb; -vec3 post_diffuse = color.rgb; - color.rgb = atmosFragLighting(color.rgb, additive, atten); -vec3 post_atmo = color.rgb; - vec4 light = vec4(0,0,0,0); color.rgb = scaleSoftClipFrag(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 449cbeaa28..652e609718 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -471,7 +471,7 @@ vec3 BRDFDiffuse(vec3 color) vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ) { - return (1.0 - specWeight * fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff); + return (1.0 - fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff); } vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float specWeight, float vh, float nl, float nv, float nh ) @@ -479,5 +479,64 @@ vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float spe vec3 fresnel = fresnelSchlick( reflect0, reflect90, vh ); // Fresnel float vis = V_GGX( nl, nv, alphaRough ); // Visibility float d = D_GGX( nh, alphaRough ); // Distribution - return specWeight * fresnel * vis * d; + return fresnel * vis * d; +} + +// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL +void pbrIbl(out vec3 colorDiffuse, // diffuse color output + out vec3 colorSpec, // specular color output, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, // normal dot view vector + float perceptualRough, // roughness factor + float gloss, // 1.0 - roughness factor + vec3 reflect0, // see also: initMaterial + vec3 c_diff) +{ + // Common to RadianceGGX and RadianceLambertian + vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1)); + vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 + vec3 fresnelR = max(vec3(gloss), reflect0) - reflect0; // roughness dependent fresnel + vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0); + + vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; + colorSpec = radiance * FssEssGGX; + + // Reference: getIBLRadianceLambertian fs + vec3 FssEssLambert = kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term + float Ems = 1.0 - (vScaleBias.x + vScaleBias.y); + vec3 avg = (reflect0 + (1.0 - reflect0) / 21.0); + vec3 AvgEms = avg * Ems; + vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); + vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms); + colorDiffuse = (FmsEms + kDiffuse) * irradiance; + + colorDiffuse *= ao; + colorSpec *= ao; +} + +void pbrDirectionalLight(inout vec3 colorDiffuse, + inout vec3 colorSpec, + vec3 sunlit, + float scol, + vec3 reflect0, + vec3 reflect90, + vec3 c_diff, + float alphaRough, + float vh, + float nl, + float nv, + float nh) +{ + float scale = 16.0; + vec3 sunColor = sunlit * scale; + + // scol = sun shadow + vec3 intensity = sunColor * nl * scol; + vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , 1.0, vh); + vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, 1.0, vh, nl, nv, nh); + + colorDiffuse += sunDiffuse; + colorSpec += sunSpec; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 6f087632a5..e87d90aa9e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -345,35 +345,6 @@ void main() if (spec.a > 0.0) // specular reflection { - /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020 - // Preserving the refactored version as a comment for potential reconsideration, - // overriding the general rule to avoid pollutiong the source with commented code. - // - // If you're reading this in 2021+, feel free to obliterate. - - vec3 npos = -normalize(pos.xyz); - - //vec3 ref = dot(pos+lv, norm); - vec3 h = normalize(light_dir.xyz + npos); - float nh = dot(norm.xyz, h); - float nv = dot(norm.xyz, 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 sp = sun_contrib*scol / 6.0f; - sp = clamp(sp, vec3(0), vec3(1)); - bloom = dot(sp, sp) / 4.0; - color += sp * spec.rgb; - } - */ - float sa = dot(refnormpersp, sun_dir.xyz); vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index bde015d109..bb0c07915b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -25,24 +25,11 @@ /*[EXTRA_CODE_HERE]*/ -#define PBR_USE_IBL 1 -#define PBR_USE_SUN 1 -#define PBR_USE_IRRADIANCE_HACK 1 - #define DIFFUSE_ALPHA_MODE_NONE 0 #define DIFFUSE_ALPHA_MODE_BLEND 1 #define DIFFUSE_ALPHA_MODE_MASK 2 #define DIFFUSE_ALPHA_MODE_EMISSIVE 3 -#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0 - -#define DEBUG_BASIC 0 -#define DEBUG_VERTEX 0 -#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse -#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse -#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse -#define DEBUG_POSITION 0 - uniform sampler2D diffuseMap; //always in sRGB space uniform sampler2D bumpMap; uniform sampler2D emissiveMap; @@ -56,8 +43,6 @@ uniform vec3 emissiveColor; uniform sampler2DRect lightMap; #endif -uniform samplerCube environmentMap; -uniform mat3 env_mat; uniform int sun_up_factor; uniform vec3 sun_dir; uniform vec3 moon_dir; @@ -107,8 +92,8 @@ 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 -vec2 encode_normal(vec3 n); vec3 srgb_to_linear(vec3 c); vec3 linear_to_srgb(vec3 c); @@ -116,6 +101,9 @@ vec3 linear_to_srgb(vec3 c); vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); 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 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); + 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); vec2 getGGX( vec2 brdfPoint ); @@ -125,35 +113,51 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv, vec3 pos, vec3 norm, float glossiness, float envIntensity); -vec3 hue_to_rgb(float hue); +void pbrDirectionalLight(inout vec3 colorDiffuse, + inout vec3 colorSpec, + vec3 sunlit, + float scol, + vec3 reflect0, + vec3 reflect90, + vec3 c_diff, + float alphaRough, + float vh, + float nl, + float nv, + float nh); + +void pbrIbl(out vec3 colorDiffuse, // diffuse color output + out vec3 colorSpec, // specular color output, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, + float perceptualRough, // roughness factor + float gloss, // 1.0 - roughness factor + vec3 reflect0, + vec3 c_diff); // lp = light position // la = linear attenuation, light radius // fa = falloff // See: LLRender::syncLightState() -vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 c_diff, - vec3 lightColor, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, - float la, float fa, float is_pointlight, float ambiance) +vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 reflect90, float alphaRough, vec3 c_diff, + vec3 lightColor, vec3 diffuse, vec3 p, vec3 v, vec3 n, vec4 lp, vec3 ln, + float lightSize, float lightFalloff, float is_pointlight, float ambiance) { vec3 intensity = vec3(0); - vec3 lv = lp.xyz - v; + vec3 lv = lp.xyz - p; vec3 h, l; float nh, nl, nv, vh, lightDist; calcHalfVectors(lv,n,v,h,l,nh,nl,nv,vh,lightDist); - if (lightDist > 0.0) + float dist = lightDist/lightSize; + + if (dist <= 1.0 && nl > 0.0) { - float falloff_factor = (12.0 * fa) - 9.0; - float inverted_la = falloff_factor / la; + float dist_atten = calcLegacyDistanceAttenuation(dist,lightFalloff); - float dist = lightDist / inverted_la; - - float dist_atten = calcLegacyDistanceAttenuation(dist,fa); - if (dist_atten <= 0.0) - return intensity; - - vec3 reflect90 = vec3(1); float specWeight = 1.0; lv = normalize(lv); @@ -161,7 +165,13 @@ vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 c_diff, nl *= spot * spot; if (nl > 0.0) - intensity = dist_atten * nl * lightColor * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh); + { + vec3 color = vec3(0); + intensity = dist_atten * nl * lightColor; + color += intensity * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh); + color += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); + return color; + } } return intensity; } @@ -192,26 +202,21 @@ void main() } #endif -// vec3 base = vertex_color.rgb * albedo.rgb * albedo.a; vec3 base = vertex_color.rgb * albedo.rgb; -#ifdef HAS_NORMAL_MAP vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); norm.xyz = normalize(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; - vec3 tnorm = vec3(0,0,1); -#endif tnorm = normalize(tnorm.xyz); + + tnorm *= gl_FrontFacing ? 1.0 : -1.0; norm.xyz = tnorm.xyz; -#if HAS_SHADOW +#ifdef HAS_SHADOW vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag); @@ -222,19 +227,15 @@ void main() // occlusion 1.0 // roughness 0.0 // metal 0.0 -#ifdef HAS_SPECULAR_MAP vec3 packedORM = texture2D(specularMap, vary_texcoord2.xy).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: lldrawpoolapha.cpp -#else - vec3 packedORM = vec3(1,0,0); -#endif packedORM.g *= roughnessFactor; packedORM.b *= metallicFactor; + // emissiveColor is the emissive color factor from GLTF and is already in linear space vec3 colorEmissive = emissiveColor; -#ifdef HAS_EMISSIVE_MAP - colorEmissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; -#endif + // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear + colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); vec3 colorDiffuse = vec3(0); vec3 colorSpec = vec3(0); @@ -246,9 +247,6 @@ void main() vec3 v = -normalize(vary_position.xyz); vec3 n = norm.xyz; - vec3 t = vec3(1,0,0); - vec3 b = normalize(cross(n,t)); - vec3 reflectVN = normalize(reflect(-v,n)); vec3 h, l; float nh, nl, nv, vh, lightDist; @@ -258,62 +256,40 @@ void main() float alphaRough, specWeight; initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - // Common to RadianceGGX and RadianceLambertian - vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1)); - vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 - vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel - vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0); - - vec3 legacyenv; - - vec3 irradiance = vec3(0); - vec3 specLight = vec3(0); float gloss = 1.0 - perceptualRough; - sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); -#if PBR_USE_IRRADIANCE_HACK - irradiance = max(amblit,irradiance) * ambocc; -#else -irradiance = vec3(amblit); -#endif - - vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; -#if PBR_USE_IBL - colorSpec += specWeight * specLight * FssEssGGX; -#endif - - vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term - float Ems = 1.0 - (vScaleBias.x + vScaleBias.y); - vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0); - vec3 AvgEms = avg * Ems; - vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); - vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms); -#if PBR_USE_IBL - colorDiffuse += (FmsEms + kDiffuse) * irradiance; -#endif - - colorDiffuse *= ao; - colorSpec *= ao; + vec3 irradiance = vec3(0); + vec3 radiance = vec3(0); + vec3 legacyenv = vec3(0); + sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); + irradiance = max(amblit,irradiance) * ambocc; + pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff); + // Sun/Moon Lighting if (nl > 0.0 || nv > 0.0) { - float scale = 4.9; - vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight + pbrDirectionalLight(colorDiffuse, colorSpec, srgb_to_linear(sunlit), scol, reflect0, reflect90, c_diff, alphaRough, vh, nl, nv, nh); + } - // scol = sun shadow - vec3 intensity = ambocc * sunColor * nl * scol; - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#if PBR_USE_SUN - colorDiffuse += sunDiffuse; - colorSpec += sunSpec; -#endif - } vec3 col = colorDiffuse + colorEmissive + colorSpec; + vec3 light = vec3(0); // Punctual lights -#define LIGHT_LOOP(i) light += srgb_to_linear(vec3(scol)) * calcPointLightOrSpotLight( reflect0, c_diff, srgb_to_linear(2.2*light_diffuse[i].rgb), albedo.rgb, pos.xyz, n, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w ); +#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight( \ + reflect0, \ + reflect90, \ + alphaRough, \ + c_diff, \ + light_diffuse[i].rgb, \ + base.rgb, \ + pos.xyz, \ + v, \ + n, \ + light_position[i], \ + light_direction[i].xyz, \ + light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, \ + light_attenuation[i].z, light_attenuation[i].w ); LIGHT_LOOP(1) LIGHT_LOOP(2) @@ -323,42 +299,12 @@ irradiance = vec3(amblit); LIGHT_LOOP(6) LIGHT_LOOP(7) -#if !defined(LOCAL_LIGHT_KILL) - col += light; -#endif // !defined(LOCAL_LIGHT_KILL) + col.rgb += light.rgb; -#if DEBUG_PBR_LIGHT_TYPE - col.rgb = vec3(0.75); - emissive = vec3(0); - spec.rgb = vec3(0); -#endif -#if DEBUG_BASIC - col.rgb = vec3( 1, 0, 1 ); -#endif -#if DEBUG_VERTEX - col.rgb = vertex_color.rgb; -#endif -#if DEBUG_NORMAL_MAP - col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; -#endif -#if DEBUG_NORMAL_OUT - col.rgb = vary_normal; -#endif -#if DEBUG_ORM - col.rgb = linear_to_srgb(spec); -#endif -#if DEBUG_POSITION - col.rgb = vary_position.xyz; -#endif + col.rgb = linear_to_srgb(col.rgb); + col *= atten.r; + col += 2.0*additive; + col = scaleSoftClipFrag(col); -// col.rgb = linear_to_srgb(col.rgb); -// frag_color = vec4(albedo.rgb,albedo.a); -// frag_color = vec4(base.rgb,albedo.a); -// frag_color = vec4(irradiance,albedo.a); -// frag_color = vec4(colorDiffuse,albedo.a); -// frag_color = vec4(colorEmissive,albedo.a); -// frag_color = vec4(sun_dir,albedo.a); -// frag_color = vec4(sunlit,albedo.a); - col = linear_to_srgb(col.rgb); - frag_color = vec4(col,albedo.a); + frag_color = vec4(col,albedo.a * vertex_color.a); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl index e0672f09e4..57a162ad51 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl @@ -94,7 +94,7 @@ void main() #endif gl_Position = vert; -#if HAS_SHADOW +#ifdef HAS_SHADOW vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip); #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index f0f5208f52..ea28cca0cb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -50,6 +50,7 @@ uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlpha vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); uniform mat3 normal_matrix; @@ -64,7 +65,7 @@ void main() discard; } - vec3 col = vertex_color.rgb * albedo.rgb; + vec3 col = vertex_color.rgb * srgb_to_linear(albedo.rgb); // from mikktspace.com vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; @@ -86,7 +87,7 @@ void main() spec.b *= metallicFactor; vec3 emissive = emissiveColor; - emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; + emissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); tnorm *= gl_FrontFacing ? 1.0 : -1.0; @@ -97,8 +98,8 @@ void main() //emissive = vNt * 0.5 + 0.5; //emissive = tnorm*0.5+0.5; // See: C++: addDeferredAttachments(), GLSL: softenLightF - frag_data[0] = vec4(col, 0.0); // Diffuse - frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive + frag_data[0] = vec4(linear_to_srgb(col), 0.0); // Diffuse + frag_data[1] = vec4(linear_to_srgb(emissive), vertex_color.a); // PBR sRGB Emissive frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags frag_data[3] = vec4(spec.rgb,0); // PBR linear packed Occlusion, Roughness, Metal. } diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index c7c241b76e..d8175aa260 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -27,11 +27,6 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_ANY_LIGHT_TYPE 0 // Output red light cone -#define DEBUG_PBR_LIGHT_TYPE 0 // Output PBR objects in red -#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in red -#define DEBUG_POINT_ZERO 0 // Output zero for point lights - #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else @@ -123,9 +118,6 @@ void main() } } - #if DEBUG_PBR_LIGHT_TYPE - colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0); - #endif final_color = colorDiffuse + colorSpec; } else @@ -174,18 +166,8 @@ void main() } } } - #if DEBUG_LEG_LIGHT_TYPE - final_color.rgb = vec3(0.5,0,0.0); - #endif } -#if DEBUG_POINT_ZERO - final_color = vec3(0); -#endif -#if DEBUG_ANY_LIGHT_TYPE - final_color = vec3(0.3333,0,0); -#endif - frag_color.rgb = final_color; frag_color.a = 0.0; #endif // LOCAL_LIGHT_KILL diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 6f39b0173b..509f9f6dd0 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -27,11 +27,6 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_ANY_LIGHT_TYPE 0 // Output magenta light cone -#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in green -#define DEBUG_PBR_LIGHT_TYPE 0 // Show PBR objects in blue -#define DEBUG_POINT_ZERO 0 // Output zero for point light - #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else @@ -119,9 +114,6 @@ void main() colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); } -#if DEBUG_PBR_LIGHT_TYPE - colorDiffuse = vec3(0,0,0.5); colorSpec = vec3(0); -#endif final_color = colorDiffuse + colorSpec; } else @@ -156,19 +148,8 @@ void main() { discard; } - -#if DEBUG_LEG_LIGHT_TYPE - final_color.rgb = vec3(0,0.25,0); -#endif } -#if DEBUG_POINT_ZERO - final_color = vec3(0); -#endif -#if DEBUG_ANY_LIGHT_TYPE - final_color = vec3(0.25,0,0.25); -#endif - frag_color.rgb = final_color; frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index d78c47a36a..1a7e11a1cd 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -23,106 +23,6 @@ * $/LicenseInfo$ */ -#define PBR_USE_ATMOS 1 -#define PBR_USE_IBL 1 -#define PBR_USE_SUN 1 - -#define PBR_USE_LINEAR_ALBEDO 1 -#define PBR_USE_DEFAULT_IRRADIANCE 0 // PBR: irradiance, skins/default/textures/default_irradiance.png -#define PBR_USE_IRRADIANCE_HACK 1 - -#define DEBUG_PBR_LIGHT_TYPE 0 // Output no global light to make it easier to see pointLight and spotLight -#define DEBUG_PBR_PACK_ORM0 0 // Rough=0, Metal=0 -#define DEBUG_PBR_PACK_ORM1 0 // Rough=1, Metal=1 -#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0 -#define DEBUG_PBR_VERT2CAM1 0 // vertex2camera = 0,0,1 -#define DEBUG_PBR_SPECLIGHT051 0 // Force specLigh to be 0,0.5,1 - -// Pass input through "as is" -#define DEBUG_PBR_DIFFUSE_MAP 0 // Output: use diffuse in G-Buffer -#define DEBUG_PBR_EMISSIVE 0 // Output: Emissive -#define DEBUG_PBR_METAL 0 // Output: grayscale Metal map -#define DEBUG_PBR_NORMAL_MAP 0 // Output: Normal -- also need to set DEBUG_NORMAL_MAP in pbropaqueF -#define DEBUG_PBR_OCCLUSION 0 // Output: grayscale Occlusion map -#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal -#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughness map -#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness - -#define DEBUG_PBR_TANGENT 0 // Output: Tangent -#define DEBUG_PBR_BITANGENT 0 // Output: Bitangent -#define DEBUG_PBR_DOT_BV 0 // Output: graysacle dot(Bitangent,Vertex2Camera) -#define DEBUG_PBR_DOT_TV 0 // Output: grayscale dot(Tangent ,Vertex2Camera) - -// IBL Spec -#define DEBUG_PBR_NORMAL 0 // Output: passed in normal -#define DEBUG_PBR_V2C_RAW 0 // Output: vertex2camera -#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal ,Vertex2Camera) -#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input) -#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output) -#define DEBUG_PBR_BRDF_SCALE_ONLY 0 // Output: grayscale BRDF Scale -#define DEBUG_PBR_BRDF_BIAS_ONLY 0 // Output: grayscale BRDER Bias -#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel -#define DEBUG_PBR_KSPEC 0 // Output: K spec -#define DEBUG_PBR_REFLECTION_DIR 0 // Output: reflection dir -#define DEBUG_PBR_SPEC_IBL 0 // Output: IBL specularity -#define DEBUG_PBR_SPEC_LEGACY 0 // Output: legacyenv -#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: environment reflection -#define DEBUG_PBR_FSS_ESS_GGX 0 // Output: FssEssGGX -#define DEBUG_PBR_SPEC 0 // Output: Final spec - -// IBL Diffuse -#define DEBUG_PBR_DIFFUSE_C 0 // Output: diffuse non metal mix -#define DEBUG_PBR_IRRADIANCE_RAW 0 // Output: Diffuse Irradiance pre-mix -#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance, NOTE: SSAO is factored in -#define DEBUG_PBR_FSS_ESS_LAMBERT 0 // Output: FssEssLambert -#define DEBUG_PBR_EMS 0 // Output: Ems = (1 - BRDF Scale + BRDF Bias) -#define DEBUG_PBR_EMS_AVG 0 // Output: Avg Ems -#define DEBUG_PBR_AVG 0 // Output: Avg -#define DEBUG_PBR_FMS_EMS 0 // Output: FmsEms -#define DEBUG_PBR_DIFFUSE_K 0 // Output: diffuse FssEssLambert + FmsEms -#define DEBUG_PBR_DIFFUSE_PRE_AO 0 // Output: diffuse pre AO -#define DEBUG_PBR_DIFFUSE 0 // Output: diffuse post AO - -// Atmospheric Lighting -#define DEBUG_PBR_AMBENV 0 // Output: ambient environment -#define DEBUG_PBR_AMBOCC 0 // Output: ambient occlusion -#define DEBUG_PBR_DA_RAW 0 // Output: da pre pow() -#define DEBUG_PBR_DA_POW 0 // Output: da post pow() -#define DEBUG_PBR_SUN_LIT 0 // Ouput: sunlit -#define DEBUG_PBR_SUN_CONTRIB 0 // Output: sun_contrib -#define DEBUG_PBR_SKY_ADDITIVE 0 // Output: additive -#define DEBUG_PBR_SKY_ATTEN 0 // Output: greyscale atten.r - -// Sun -#define DEBUG_PBR_SUN_FULL_BRIGHT 0 // Sunlit color = <1,1,1> -#define DEBUG_PBR_SUN_OUT_DIFFUSE 0 // Final sun diffuse : intensity * nl * diffuse -#define DEBUG_PBR_SUN_OUT_SPECULAR 0 // Final sun specular: intensity * nl * specular -#define DEBUG_PBR_SUN_LAMBERT 0 // BRDF Diffuse: Lambertian Diffuse color -#define DEBUG_PBR_SUN_LAMBERT_NL 0 // BRDF Diffuse: nl * Lambertian Diffuse color -#define DEBUG_PBR_SUN_H 0 // Half Vector -#define DEBUG_PBR_SUN_L 0 // Light Vector -#define DEBUG_PBR_SUN_V 0 // Surface to Light Vector -#define DEBUG_PBR_SUN_NH 0 // dot(n,h) -#define DEBUG_PBR_SUN_NL 0 // dot(n,l) -#define DEBUG_PBR_SUN_NV 0 // dot(n,v) -#define DEBUG_PBR_SUN_VH 0 // dot(v,h) -#define DEBUG_PBR_SUN_REFLECT0 0 // reflect0 only -#define DEBUG_PBR_SUN_SPEC_FRESNEL 0 // Fresnel -#define DEBUG_PBR_SUN_SPEC_D 0 // D(h) -#define DEBUG_PBR_SUN_SPEC_V 0 // V(l,v,h) -#define DEBUG_PBR_SUN_SPEC_DF 0 // D() * F() -#define DEBUG_PBR_SUN_SPEC_DV 0 // D() * V() -#define DEBUG_PBR_SUN_SPEC_FV 0 // F() * V() -#define DEBUG_PBR_SUN_SPEC_DFV 0 // D() * F() * V() -#define DEBUG_PBR_SUN_SPEC_NL_DFV 0 // nl * D() * F() * V() -#define DEBUG_PBR_SUN_FINAL 0 // LAMBERT_NL + BRDF() - -#define DEBUG_PBR_IOR 0 // Output: grayscale IOR -#define DEBUG_PBR_REFLECT0_BASE 0 // Output: black reflect0 default from ior -#define DEBUG_PBR_REFLECT0_MIX 0 // Output: diffuse reflect0 calculated from ior -#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance -- NOT USED -#define DEBUG_PBR_SPEC_WEIGHT 0 // Output: specWeight -#define DEBUG_PBR_V2C_REMAP 0 // Output: vertex2camera (remap [-1,1] -> [0,1]) #extension GL_ARB_texture_rectangle : enable #extension GL_ARB_shader_texture_lod : enable @@ -169,16 +69,7 @@ uniform vec2 screen_res; vec3 getNorm(vec2 pos_screen); vec4 getPositionWithDepth(vec2 pos_screen, float depth); -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); 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 calcF0(float ior); -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 getAmbientClamp(); -vec2 getGGX( vec2 brdfPoint ); -void initMaterial( vec3 diffuse, vec3 packedORM, - out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); vec3 scaleSoftClipFrag(vec3 l); vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); @@ -193,18 +84,39 @@ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); -// Debug Utils -vec3 BRDFDiffuse(vec3 color); -vec3 colorize_dot(float x); -vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh); -float D_GGX( float nh, float alphaRough ); -float V_GGX( float nl, float nv, float alphaRough ); - #ifdef WATER_FOG vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -uniform vec3 view_dir; // PBR +// PBR interface +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); +void initMaterial( vec3 diffuse, vec3 packedORM, + out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); +// perform PBR image based lighting according to GLTF spec +// all parameters are in linear space +void pbrIbl(out vec3 colorDiffuse, // diffuse color output + out vec3 colorSpec, // specular color output, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, + float perceptualRough, // roughness factor + float gloss, // 1.0 - roughness factor + vec3 reflect0, + vec3 c_diff); + +void pbrDirectionalLight(inout vec3 colorDiffuse, + inout vec3 colorSpec, + vec3 sunlit, + float scol, + vec3 reflect0, + vec3 reflect90, + vec3 c_diff, + float alphaRough, + float vh, + float nl, + float nv, + float nh); void main() { @@ -219,7 +131,7 @@ void main() float light_gamma = 1.0 / 1.3; vec4 diffuse = texture2DRect(diffuseRect, tc); - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR sRGB Emissive + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive #if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; @@ -241,8 +153,6 @@ void main() calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); - //vec3 amb_vec = env_mat * norm.xyz; - vec3 ambenv; vec3 glossenv; vec3 legacyenv; @@ -262,480 +172,111 @@ void main() vec3 colorDiffuse = vec3(0); vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl vec3 colorSpec = vec3(0); -// vec3 colorClearCoat = vec3(0); -// vec3 colorSheen = vec3(0); -// vec3 colorTransmission = vec3(0); vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl -#if DEBUG_PBR_PACK_ORM0 - packedORM = vec3(0,0,0); -#endif -#if DEBUG_PBR_PACK_ORM1 - packedORM = vec3(1,1,1); -#endif float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics) -#if DEBUG_PBR_REFLECT0_BASE - vec3 debug_reflect0 = vec3(calcF0(IOR)); -#endif float ao = packedORM.r; float metal = packedORM.b; vec3 v = -normalize(pos.xyz); -#if DEBUG_PBR_VERT2CAM1 - v = vec3(0,0,1); -#endif vec3 n = norm.xyz; -// vec3 t = texture2DRect(tangentMap, tc).rgb; -#if DEBUG_PBR_TANGENT1 - vec3 t = vec3(1,0,0); -#endif - vec3 b = cross( n,t); - vec3 reflectVN = normalize(reflect(-v,n)); vec3 h, l; float nh, nl, nv, vh, lightDist; calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist); - float tv = clamp(dot(t,v),0,1); - float bv = clamp(dot(b,v),0,1); - - // Reference: getMetallicRoughnessInfo -#if PBR_USE_LINEAR_ALBEDO - vec3 base = diffuse.rgb; -#else - vec3 base = linear_to_srgb(diffuse.rgb); -#endif float perceptualRough = packedORM.g; // NOTE: do NOT clamp here to be consistent with Blender, Blender is wrong and Substance is right + vec3 c_diff, reflect0, reflect90; float alphaRough, specWeight; - initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); -#if DEBUG_PBR_REFLECTANCE - float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b ); -#endif + initMaterial( diffuse.rgb, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - // Common to RadianceGGX and RadianceLambertian - vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1)); - vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 - vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel - vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0); - - // Reference: getIBLRadianceGGX - // https://forum.substance3d.com/index.php?topic=3243.0 - // Glossiness - // This map is the inverse of the roughness map. - vec3 irradiance = vec3(0); - vec3 specLight = vec3(0); float gloss = 1.0 - perceptualRough; - sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); -#if DEBUG_PBR_IRRADIANCE_RAW - vec3 debug_irradiance = irradiance; -#endif - -#if PBR_USE_DEFAULT_IRRADIANCE - vec2 iruv = vec2(0.5f + 0.5f * atan(reflectVN.z, reflectVN.x) / M_PI, 1.f - acos(reflectVN.y) / M_PI); - irradiance = texture2D(altDiffuseMap, iruv).rgb * ambocc; -#endif -#if PBR_USE_IRRADIANCE_HACK + vec3 irradiance = vec3(0); + vec3 radiance = vec3(0); + sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); irradiance = max(amblit,irradiance) * ambocc; -#endif -#if DEBUG_PBR_SPECLIGHT051 - specLight = vec3(0,0.5,1.0); - irradiance = specLight; -#endif - vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; -#if DEBUG_PBR_SPEC_IBL - vec3 debug_color_spec = specWeight * specLight * FssEssGGX; -#endif -#if PBR_USE_IBL - colorSpec += specWeight * specLight * FssEssGGX; -#endif - // Reference: getIBLRadianceLambertian - vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term - float Ems = 1.0 - (vScaleBias.x + vScaleBias.y); - vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0); - vec3 AvgEms = avg * Ems; - vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); - vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms); -#if PBR_USE_IBL - colorDiffuse += (FmsEms + kDiffuse) * irradiance; -#endif - #if DEBUG_PBR_DIFFUSE_PRE_AO - vec3 debug_diffuse = colorDiffuse; - #endif - - colorDiffuse *= ao; // Occlusion -- NOTE: pbropaque will need occlusion_strength pre-multiplied into spec.r - colorSpec *= ao; - - // Add in sun/moon reflection + pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff); + + // Add in sun/moon punctual light if (nl > 0.0 || nv > 0.0) { - float scale = 4.9; - vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight -#if DEBUG_PBR_SUN_FULL_BRIGHT - sunColor = vec3(1); -#endif - // scol = sun shadow - vec3 intensity = ambocc * sunColor * nl * scol; -#if PBR_USE_LINEAR_ALBEDO - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#else - vec3 sunDiffuse = base * intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#endif - // Disabling PBR bloom due to two reasons: - // 1. The glTF 2.0 Specification does not specify bloom, - // 2. As the camera moves there are lots of bloom shimmering. - //bloom = dot(sunSpec, sunSpec) / (scale * scale * scale); - - #if DEBUG_PBR_SUN_SPEC_FRESNEL - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_D - colorDiffuse = vec3(0); - colorSpec = vec3(D_GGX( nh, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_V - colorDiffuse = vec3(0); - colorSpec = vec3(V_GGX( nl, nv, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DF - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= D_GGX( nh, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DV - colorDiffuse = vec3(0); - colorSpec = vec3(D_GGX( nh, alphaRough )); - colorSpec *= vec3(V_GGX( nl, nv, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_FV - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= V_GGX( nl, nv, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DFV - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= D_GGX( nh, alphaRough ); - colorSpec *= V_GGX( nl, nv, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_NL_DFV - colorDiffuse = vec3(0); - colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - #endif - #if DEBUG_PBR_SUN_FINAL - colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - #endif - - #if DEBUG_PBR_SUN_OUT_DIFFUSE - colorDiffuse = linear_to_srgb(sunDiffuse); - colorSpec = vec3(0); - bloom = 0.0; - #endif - #if DEBUG_PBR_SUN_OUT_SPECULAR - colorDiffuse = linear_to_srgb(sunSpec); - colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_REFLECT0 - colorDiffuse = reflect0; - colorSpec = vec3(0); - #endif - -#if PBR_USE_SUN - colorDiffuse += sunDiffuse; - colorSpec += sunSpec; -#endif + pbrDirectionalLight(colorDiffuse, colorSpec, srgb_to_linear(sunlit), scol, reflect0, reflect90, c_diff, alphaRough, vh, nl, nv, nh); } -#if DEBUG_PBR_SUN_LAMBERT - colorDiffuse = BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = vec3(0); - bloom = 0; -#endif -#if DEBUG_PBR_SUN_LAMBERT_NL - colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = vec3(0); - bloom = 0; -#endif - - #if DEBUG_PBR_SUN_H - colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_L - colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_V - colorDiffuse = v*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NH - colorDiffuse = colorize_dot(nh); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NL - colorDiffuse = colorize_dot(nl); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NV - colorDiffuse = colorize_dot(nv); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_VH - colorDiffuse = colorize_dot(vh); colorSpec = vec3(0); - #endif - color.rgb = colorDiffuse + colorEmissive + colorSpec; -#if PBR_USE_ATMOS color = linear_to_srgb(color); color *= atten.r; color += 2.0*additive; color = scaleSoftClipFrag(color); color = srgb_to_linear(color); -#endif // PBR_USE_ATMOS - #if DEBUG_PBR_DIFFUSE - color.rgb = colorDiffuse; - #endif - #if DEBUG_PBR_EMISSIVE - color.rgb = colorEmissive; - #endif - #if DEBUG_PBR_METAL - color.rgb = vec3(metal); - #endif - #if DEBUG_PBR_NORMAL_MAP - color.rgb = diffuse.rgb; - #endif - #if DEBUG_PBR_OCCLUSION - color.rgb = vec3(ao); - #endif - #if DEBUG_PBR_ORM - color.rgb = packedORM; - #endif - #if DEBUG_PBR_ROUGH_PERCEPTUAL - color.rgb = vec3(perceptualRough); - #endif - #if DEBUG_PBR_ROUGH_ALPHA - color.rgb = vec3(alphaRough); - #endif - - #if DEBUG_PBR_NORMAL - color.rgb = norm.xyz*0.5 + vec3(0.5); - color.rgb = srgb_to_linear(color.rgb); - #endif - #if DEBUG_PBR_TANGENT - color.rgb = t; - #endif - #if DEBUG_PBR_BITANGENT - color.rgb = b; - #endif - #if DEBUG_PBR_DOT_NV - color.rgb = vec3(nv); - #endif - #if DEBUG_PBR_DOT_TV - color.rgb = vec3(tv); - #endif - #if DEBUG_PBR_DOT_BV - color.rgb = vec3(bv); - #endif - - #if DEBUG_PBR_AVG - color.rgb = avg; - #endif - #if DEBUG_PBR_BRDF_UV - color.rgb = vec3(brdfPoint,0.0); - color.rgb = linear_to_srgb(color.rgb); - #endif - #if DEBUG_PBR_BRDF_SCALE_BIAS - color.rgb = vec3(vScaleBias,0.0); - #endif - #if DEBUG_PBR_DIFFUSE_C - color.rgb = c_diff; - #endif - #if DEBUG_PBR_BRDF_SCALE_ONLY - color.rgb = vec3(vScaleBias.x); - #endif - #if DEBUG_PBR_BRDF_BIAS_ONLY - color.rgb = vec3(vScaleBias.y); - #endif - #if DEBUG_PBR_DIFFUSE_K - color.rgb = kDiffuse; - #endif - #if DEBUG_PBR_DIFFUSE_MAP - color.rgb = diffuse.rgb; - #endif - #if DEBUG_PBR_DIFFUSE_PRE_AO - color.rgb = debug_diffuse; - #endif - #if DEBUG_PBR_EMS - color.rgb = vec3(Ems); - #endif - #if DEBUG_PBR_EMS_AVG - color.rgb = AvgEms; - #endif - #if DEBUG_PBR_FMS_EMS - color.rgb = FmsEms; - #endif - #if DEBUG_PBR_FSS_ESS_GGX - color.rgb = FssEssGGX; // spec - #endif - #if DEBUG_PBR_FSS_ESS_LAMBERT - color.rgb = FssEssLambert; // diffuse - #endif - #if DEBUG_PBR_FRESNEL - color.rgb = fresnelR; - #endif - #if DEBUG_PBR_IOR - color.rgb = vec3(IOR); - #endif - #if DEBUG_PBR_IRRADIANCE_RAW - color.rgb = debug_irradiance; - bloom = 0; - #endif - #if DEBUG_PBR_IRRADIANCE - color.rgb = irradiance; - bloom = 0; - #endif - #if DEBUG_PBR_KSPEC - color.rgb = kSpec; - #endif - #if DEBUG_PBR_REFLECT0_BASE - color.rgb = vec3(debug_reflect0); - #endif - #if DEBUG_PBR_REFLECT0_MIX - color.rgb = vec3(reflect0); - #endif - #if DEBUG_PBR_REFLECTANCE - color.rgb = vec3(reflectance); - #endif - #if DEBUG_PBR_REFLECTION_DIR - color.rgb = reflect(-v, n); // NOTE: equivalent to normalize(reflect(pos.xyz, norm.xyz)); - #endif - #if DEBUG_PBR_SPEC - color.rgb = colorSpec; - #endif - #if DEBUG_PBR_SPEC_REFLECTION - color.rgb = specLight; - #endif - #if DEBUG_PBR_SPEC_WEIGHT - color.rgb = vec3(specWeight); - #endif - #if DEBUG_PBR_V2C_RAW - color.rgb = v; - #endif - #if DEBUG_PBR_V2C_REMAP - color.rgb = v*0.5 + vec3(0.5); - #endif - - #if DEBUG_PBR_DA_RAW - color.rgb = vec3(debug_da); - #endif - #if DEBUG_PBR_DA_POW - color.rgb = vec3(da); - #endif - #if DEBUG_PBR_SKY_ADDITIVE - color.rgb = additive; - #endif - #if DEBUG_PBR_SKY_ATTEN - color.rgb = vec3(atten.r); - #endif - #if DEBUG_PBR_SUN_LIT - color.rgb = sunlit; - #endif - #if DEBUG_PBR_SUN_CONTRIB - color.rgb = sun_contrib; - #endif - #if DEBUG_PBR_LIGHT_TYPE - color.rgb = vec3(0); - #endif - - frag_color.rgb = color.rgb; // PBR is done in linear + frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results } -else -{ - float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); -#if DEBUG_PBR_DA_RAW - float debug_da = da; -#endif - da = pow(da, light_gamma); - - diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 - - sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); - ambenv.rgb = linear_to_srgb(ambenv.rgb); - glossenv.rgb = linear_to_srgb(glossenv.rgb); - legacyenv.rgb = linear_to_srgb(legacyenv.rgb); - - 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 + else { - float sa = dot(normalize(refnormpersp), light_dir.xyz); - vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r); + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); + da = pow(da, light_gamma); - // add the two types of shiny together - vec3 spec_contrib = dumbshiny * spec.rgb; - bloom = dot(spec_contrib, spec_contrib) / 6; - color.rgb += spec_contrib; + diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 - // add reflection map - EXPERIMENTAL WORK IN PROGRESS - applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); - } + sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); + ambenv.rgb = linear_to_srgb(ambenv.rgb); + glossenv.rgb = linear_to_srgb(glossenv.rgb); + legacyenv.rgb = linear_to_srgb(legacyenv.rgb); - color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); + amblit = max(ambenv, amblit); + color.rgb = amblit*ambocc; - if (envIntensity > 0.0) - { // add environmentmap - //fudge darker - legacyenv *= 0.5*diffuse.a+0.5; - applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); - } + vec3 sun_contrib = min(da, scol) * sunlit; + color.rgb += sun_contrib; + color.rgb = min(color.rgb, vec3(1,1,1)); + color.rgb *= diffuse.rgb; - if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) - { - color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); - color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); - } + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); -#ifdef WATER_FOG - vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); - color = fogged.rgb; - bloom = fogged.a; -#endif - #if DEBUG_PBR_LIGHT_TYPE - color.rgb = vec3(0); + if (spec.a > 0.0) // specular reflection + { + 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); + } + + 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 (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) + { + 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 = ambenv; - //color.b = diffuse.a; - frag_color.rgb = srgb_to_linear(color.rgb); -} -#if DEBUG_PBR_AMBOCC - frag_color.rgb = vec3(ambocc); -#endif -#if DEBUG_PBR_AMBENV - frag_color.rgb = ambenv; -#endif + + // convert to linear as fullscreen lights need to sum in linear colorspace + // and will be gamma (re)corrected downstream... + //color = ambenv; + //color.b = diffuse.a; + frag_color.rgb = srgb_to_linear(color.rgb); + } + frag_color.a = bloom; } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 5bb43a0700..f001d2caee 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -663,9 +663,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; // Also see: LLPipeline::getPoolTypeFromTE() bool is_pbr = LLPipeline::sRenderPBR && gltf_mat; + LLGLDisable cull_face(is_pbr && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0); + if (is_pbr && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND) { - target_shader = &gDeferredPBRAlphaProgram[rigged]; + target_shader = &gDeferredPBRAlphaProgram; + if (params.mAvatar != nullptr) + { + target_shader = target_shader->mRiggedVariant; + } + if (current_shader != target_shader) { gPipeline.bindDeferredShader(*target_shader); @@ -710,9 +717,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) target_shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor); target_shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor); target_shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV); - - target_shader->mLightHash = 0; - gGL.syncLightState(); // Set light uniforms } else { diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 2a7ab84501..d9dd1e9381 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -82,6 +82,11 @@ void LLReflectionMap::autoAdjustOrigin() // cast a ray towards 8 corners of bounding box // nudge origin towards center of empty space + if (!node) + { + return; + } + 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]; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 8c414fb71d..51c6b2eea5 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -64,6 +64,7 @@ #include "llfloatertools.h" #include "llframetimer.h" #include "llfocusmgr.h" +#include "llgltfmateriallist.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llinventorymodel.h" @@ -1878,16 +1879,56 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) asset_id = mItem->getAssetUUID(); } + if (asset_id.notNull() && !objectp->hasRenderMaterialParams()) + { + // make sure param section exists + objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/); + } + if (te != -1) { - objectp->setRenderMaterialID(te, asset_id); + LLTextureEntry* tep = objectp->getTE(te); + if (asset_id.notNull()) + { + tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + } + else + { + tep->setGLTFMaterial(nullptr); + } + + objectp->faceMappingChanged(); + gPipeline.markTextured(objectp->mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(te, asset_id); + } } - else + else // Shouldn't happen? { S32 num_faces = objectp->getNumTEs(); for (S32 face = 0; face < num_faces; face++) { - objectp->setRenderMaterialID(face, asset_id); + LLTextureEntry* tep = objectp->getTE(face); + if (asset_id.notNull()) + { + tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + } + else + { + tep->setGLTFMaterial(nullptr); + } + + objectp->faceMappingChanged(); + gPipeline.markTextured(objectp->mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(face, asset_id); + } } } @@ -1895,26 +1936,43 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) } }; - if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + // TODO: once PBR starts supporting permissions, implement/figure this out + /*if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) { getSelection()->applyNoCopyTextureToTEs(item); } - else + else*/ { f setfunc(item, mat_id); getSelection()->applyToTEs(&setfunc); } - struct g : public LLSelectedObjectFunctor { LLViewerInventoryItem* mItem; g(LLViewerInventoryItem* item) : mItem(item) {} virtual bool apply(LLViewerObject* object) { + if (object && !object->permModify()) + { + return false; + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + if (param_block->isEmpty()) + { + object->setHasRenderMaterialParams(false); + } + else + { + object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } + if (!mItem) { - object->sendTEUpdate(); // 1 particle effect per object LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); effectp->setSourceObject(gAgentAvatarp); @@ -1922,6 +1980,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); } + + object->sendTEUpdate(); return true; } } sendfunc(item); @@ -2111,15 +2171,40 @@ void LLSelectMgr::selectionRevertGLTFMaterials() { LLObjectSelectionHandle mSelectedObjects; f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} - bool apply(LLViewerObject* object, S32 te) + bool apply(LLViewerObject* objectp, S32 te) { - if (object->permModify()) + if (objectp && !objectp->permModify()) { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size()) + return false; + } + + LLSelectNode* nodep = mSelectedObjects->findNode(objectp); + if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size()) + { + LLUUID asset_id = nodep->mSavedGLTFMaterials[te]; + LLTextureEntry* tep = objectp->getTE(te); + if (asset_id.notNull()) { - LLUUID id = nodep->mSavedGLTFMaterials[te]; - object->setRenderMaterialID(te, id); + tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + + if (!objectp->hasRenderMaterialParams()) + { + // make sure param section exists + objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an immediate update*/); + } + } + else + { + tep->setGLTFMaterial(nullptr); + } + + objectp->faceMappingChanged(); + gPipeline.markTextured(objectp->mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(te, asset_id); } } return true; @@ -2127,7 +2212,32 @@ void LLSelectMgr::selectionRevertGLTFMaterials() } setfunc(mSelectedObjects); getSelection()->applyToTEs(&setfunc); - LLSelectMgrSendFunctor sendfunc; + struct g : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object && !object->permModify()) + { + return false; + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + if (param_block->isEmpty()) + { + object->setHasRenderMaterialParams(false); + } + else + { + object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } + + object->sendTEUpdate(); + return true; + } + } sendfunc; getSelection()->applyToObjects(&sendfunc); } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 1e68c0c54a..8267e41ba5 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1834,56 +1834,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) if (op == TEXTURE_SELECT && mOnSelectCallback) { - // determine if the selected item in inventory is a material - // by finding the item in inventory and inspecting its (IT_) type - LLUUID item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE); - LLInventoryItem* item = gInventory.getItem(item_id); - if (item) - { - if (item->getInventoryType() == LLInventoryType::IT_MATERIAL) - { - // ask the selection manager for the list of selected objects - // to which the material will be applied. - LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstance()->getSelection(); - if (selectedObjectsHandle.notNull()) - { - LLObjectSelection* selectedObjects = selectedObjectsHandle.get(); - if (!selectedObjects->isEmpty()) - { - // we have a selection - iterate over it - for (LLObjectSelection::valid_iterator obj_iter = selectedObjects->valid_begin(); - obj_iter != selectedObjects->valid_end(); - ++obj_iter) - { - LLSelectNode* object = *obj_iter; - LLViewerObject* viewer_object = object->getObject(); - if (viewer_object) - { - // the asset ID of the material we want to apply - // the the selected objects - LLUUID asset_id = item->getAssetUUID(); - - // iterate over the faces in the object - // TODO: consider the case where user has - // selected only certain faces - S32 num_faces = viewer_object->getNumTEs(); - for (S32 face = 0; face < num_faces; face++) - { - viewer_object->setRenderMaterialID(face, asset_id); - dialog_refresh_all(); - } - viewer_object->sendTEUpdate(); - } - } - } - } - } - } - else - // original behavior for textures, not materials - { - mOnSelectCallback(this, LLSD()); - } + mOnSelectCallback(this, LLSD()); } else if (op == TEXTURE_CANCEL && mOnCancelCallback) { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index cfe4ff4b4e..bcc199ac39 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1123,6 +1123,11 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, for (S32 face = 0; face < num_faces; face++) { // update viewer side material in anticipation of update from simulator + + // TODO: fix this! + // Calling setRenderMaterialID multiple times sends material param + // updates multiple times and can create race condition. + // Send update only once! hit_obj->setRenderMaterialID(face, asset_id); dialog_refresh_all(); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8afc571e6d..e609f136d8 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7244,7 +7244,12 @@ void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id) if (id.notNull()) { getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); - setHasRenderMaterialParams(true); + + if (!hasRenderMaterialParams()) + { + // make sure param section exists + setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an immediate update*/); + } } else { diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 0c5d45c86c..c0cb7632ad 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -269,7 +269,8 @@ LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredPBROpaqueProgram; LLGLSLShader gDeferredSkinnedPBROpaqueProgram; -LLGLSLShader gDeferredPBRAlphaProgram[2]; // not skinned, skinned +LLGLSLShader gDeferredPBRAlphaProgram; +LLGLSLShader gDeferredSkinnedPBRAlphaProgram; //helper for making a rigged variant of a given shader bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -378,7 +379,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); - mShaderList.push_back(&gDeferredWLSunProgram); + mShaderList.push_back(&gDeferredWLSunProgram); + mShaderList.push_back(&gDeferredPBRAlphaProgram); + mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); + // [RLVa:KB] - @setsphere mShaderList.push_back(&gRlvSphereProgram); // [/RLVa:KB] @@ -1305,8 +1309,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBROpaqueProgram.unload(); gDeferredSkinnedPBROpaqueProgram.unload(); - gDeferredPBRAlphaProgram[0].unload(); - gDeferredPBRAlphaProgram[1].unload(); + gDeferredPBRAlphaProgram.unload(); + gDeferredSkinnedPBRAlphaProgram.unload(); return TRUE; } @@ -1643,76 +1647,70 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - for (int rigged = 0; rigged < 2 && success; ++rigged) + LLGLSLShader* shader = &gDeferredPBRAlphaProgram; + shader->mName = "Deferred PBR Alpha Shader"; + + shader->mFeatures.calculatesLighting = false; + shader->mFeatures.hasLighting = false; + shader->mFeatures.isAlphaLighting = true; + shader->mFeatures.hasSrgb = true; + shader->mFeatures.encodesNormal = true; + shader->mFeatures.calculatesAtmospherics = true; + shader->mFeatures.hasAtmospherics = true; + shader->mFeatures.hasGamma = true; + shader->mFeatures.hasTransport = true; + shader->mFeatures.hasShadows = use_sun_shadow; + shader->mFeatures.isDeferred = true; // include deferredUtils + shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; + + shader->mShaderFiles.clear(); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); + + shader->clearPermutations(); + + U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + shader->addPermutation("HAS_NORMAL_MAP", "1"); + shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness + shader->addPermutation("HAS_EMISSIVE_MAP", "1"); + shader->addPermutation("USE_VERTEX_COLOR", "1"); + + if (use_sun_shadow) { - LLGLSLShader* shader = &gDeferredPBRAlphaProgram[rigged]; - shader->mName = rigged - ? "Skinned Deferred PBR Alpha Shader" - : "Deferred PBR Alpha Shader"; - shader->mRiggedVariant = rigged - ? &gDeferredPBRAlphaProgram[1] - : nullptr; - shader->mFeatures.hasObjectSkinning = (bool)rigged; - shader->mFeatures.calculatesLighting = false; - shader->mFeatures.hasLighting = false; - shader->mFeatures.isAlphaLighting = true; - shader->mFeatures.hasSrgb = true; - shader->mFeatures.encodesNormal = true; - shader->mFeatures.calculatesAtmospherics = true; - shader->mFeatures.hasAtmospherics = true; - shader->mFeatures.hasGamma = true; - shader->mFeatures.hasTransport = true; - shader->mFeatures.hasShadows = use_sun_shadow; - shader->mFeatures.isDeferred = true; // include deferredUtils - shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; - - shader->mShaderFiles.clear(); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); - - shader->clearPermutations(); - - U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); - shader->addPermutation("HAS_NORMAL_MAP", "1"); - shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness - shader->addPermutation("HAS_EMISSIVE_MAP", "1"); - shader->addPermutation("USE_VERTEX_COLOR", "1"); - if (use_sun_shadow) - { - shader->addPermutation("HAS_SHADOW", "1"); - } - - if (ambient_kill) - { - shader->addPermutation("AMBIENT_KILL", "1"); - } - - if (sunlight_kill) - { - shader->addPermutation("SUNLIGHT_KILL", "1"); - } - - if (local_light_kill) - { - shader->addPermutation("LOCAL_LIGHT_KILL", "1"); - } - - if (rigged) - { - shader->addPermutation("HAS_SKIN", "1"); - } - - shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - success = shader->createShader(NULL, NULL); - llassert(success); - - // Alpha Shader Hack - // See: LLRender::syncMatrices() - shader->mFeatures.calculatesLighting = true; - shader->mFeatures.hasLighting = true; + shader->addPermutation("HAS_SHADOW", "1"); } + + if (ambient_kill) + { + shader->addPermutation("AMBIENT_KILL", "1"); + } + + if (sunlight_kill) + { + shader->addPermutation("SUNLIGHT_KILL", "1"); + } + + if (local_light_kill) + { + shader->addPermutation("LOCAL_LIGHT_KILL", "1"); + } + + shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram); + if (success) + { + success = shader->createShader(NULL, NULL); + } + llassert(success); + + // Alpha Shader Hack + // See: LLRender::syncMatrices() + shader->mFeatures.calculatesLighting = true; + shader->mFeatures.hasLighting = true; + + shader->mRiggedVariant->mFeatures.calculatesLighting = true; + shader->mRiggedVariant->mFeatures.hasLighting = true; } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index d02337fa46..76d57e876c 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -326,5 +326,5 @@ extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredPBROpaqueProgram; -extern LLGLSLShader gDeferredPBRAlphaProgram[2]; // not skinned, skinned +extern LLGLSLShader gDeferredPBRAlphaProgram; #endif diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8402c95404..0a6c002800 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6604,6 +6604,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setDiffuse(light_color); light_state->setAmbient(LLColor4::black); light_state->setConstantAttenuation(0.f); + light_state->setSize(light->getLightRadius() * 1.5f); + light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); + if (sRenderDeferred) { light_state->setLinearAttenuation(linatten);