12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265 |
- #if defined(BUMP) || !defined(NORMAL) || defined(FORCENORMALFORWARD) || defined(SPECULARAA) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)
- #extension GL_OES_standard_derivatives : enable
- #endif
- #ifdef LODBASEDMICROSFURACE
- #extension GL_EXT_shader_texture_lod : enable
- #endif
- #define CUSTOM_FRAGMENT_BEGIN
- #ifdef LOGARITHMICDEPTH
- #extension GL_EXT_frag_depth : enable
- #endif
- precision highp float;
- // Forces linear space for image processing
- #ifndef FROMLINEARSPACE
- #define FROMLINEARSPACE
- #endif
- // Declaration
- #include<__decl__pbrFragment>
- #include<pbrFragmentExtraDeclaration>
- #include<__decl__lightFragment>[0..maxSimultaneousLights]
- #include<pbrFragmentSamplersDeclaration>
- #include<imageProcessingDeclaration>
- #include<clipPlaneFragmentDeclaration>
- #include<logDepthDeclaration>
- #include<fogFragmentDeclaration>
- // Helper Functions
- #include<helperFunctions>
- #include<pbrHelperFunctions>
- #include<imageProcessingFunctions>
- #include<shadowsFragmentFunctions>
- #include<harmonicsFunctions>
- #include<pbrDirectLightingSetupFunctions>
- #include<pbrDirectLightingFalloffFunctions>
- #include<pbrBRDFFunctions>
- #include<pbrDirectLightingFunctions>
- #include<pbrIBLFunctions>
- #include<bumpFragmentFunctions>
- #ifdef REFLECTION
- #include<reflectionFunction>
- #endif
- #define CUSTOM_FRAGMENT_DEFINITIONS
- // _____________________________ MAIN FUNCTION ____________________________
- void main(void) {
- #define CUSTOM_FRAGMENT_MAIN_BEGIN
- #include<clipPlaneFragment>
- // _____________________________ Geometry Information ____________________________
- vec3 viewDirectionW = normalize(vEyePosition.xyz - vPositionW);
- #ifdef NORMAL
- vec3 normalW = normalize(vNormalW);
- #else
- vec3 normalW = normalize(cross(dFdx(vPositionW), dFdy(vPositionW))) * vEyePosition.w;
- #endif
- #ifdef CLEARCOAT
- // Needs to use the geometric normal before bump for this.
- vec3 clearCoatNormalW = normalW;
- #endif
- #include<bumpFragment>
- #if defined(FORCENORMALFORWARD) && defined(NORMAL)
- vec3 faceNormal = normalize(cross(dFdx(vPositionW), dFdy(vPositionW))) * vEyePosition.w;
- #if defined(TWOSIDEDLIGHTING)
- faceNormal = gl_FrontFacing ? faceNormal : -faceNormal;
- #endif
- normalW *= sign(dot(normalW, faceNormal));
- #endif
- #if defined(TWOSIDEDLIGHTING) && defined(NORMAL)
- normalW = gl_FrontFacing ? normalW : -normalW;
- #endif
- // _____________________________ Albedo Information ______________________________
- // Albedo
- vec3 surfaceAlbedo = vAlbedoColor.rgb;
- // Alpha
- float alpha = vAlbedoColor.a;
- #ifdef ALBEDO
- vec4 albedoTexture = texture2D(albedoSampler, vAlbedoUV + uvOffset);
- #if defined(ALPHAFROMALBEDO) || defined(ALPHATEST)
- alpha *= albedoTexture.a;
- #endif
- #ifdef GAMMAALBEDO
- surfaceAlbedo *= toLinearSpace(albedoTexture.rgb);
- #else
- surfaceAlbedo *= albedoTexture.rgb;
- #endif
- surfaceAlbedo *= vAlbedoInfos.y;
- #endif
- #ifdef VERTEXCOLOR
- surfaceAlbedo *= vColor.rgb;
- #endif
- #define CUSTOM_FRAGMENT_UPDATE_ALBEDO
- // _____________________________ Alpha Information _______________________________
- #ifdef OPACITY
- vec4 opacityMap = texture2D(opacitySampler, vOpacityUV + uvOffset);
- #ifdef OPACITYRGB
- alpha = getLuminance(opacityMap.rgb);
- #else
- alpha *= opacityMap.a;
- #endif
- alpha *= vOpacityInfos.y;
- #endif
- #ifdef VERTEXALPHA
- alpha *= vColor.a;
- #endif
- #if !defined(SS_LINKREFRACTIONTOTRANSPARENCY) && !defined(ALPHAFRESNEL)
- #ifdef ALPHATEST
- if (alpha < ALPHATESTVALUE)
- discard;
- #ifndef ALPHABLEND
- // Prevent to blend with the canvas.
- alpha = 1.0;
- #endif
- #endif
- #endif
- #define CUSTOM_FRAGMENT_UPDATE_ALPHA
- #include<depthPrePass>
- #define CUSTOM_FRAGMENT_BEFORE_LIGHTS
- // _____________________________ AO Information _______________________________
- vec3 ambientOcclusionColor = vec3(1., 1., 1.);
- #ifdef AMBIENT
- vec3 ambientOcclusionColorMap = texture2D(ambientSampler, vAmbientUV + uvOffset).rgb * vAmbientInfos.y;
- #ifdef AMBIENTINGRAYSCALE
- ambientOcclusionColorMap = vec3(ambientOcclusionColorMap.r, ambientOcclusionColorMap.r, ambientOcclusionColorMap.r);
- #endif
- ambientOcclusionColor = mix(ambientOcclusionColor, ambientOcclusionColorMap, vAmbientInfos.z);
- #endif
- #ifdef UNLIT
- vec3 diffuseBase = vec3(1., 1., 1.);
- #else
- // _____________________________ Reflectivity Info _______________________________
- float microSurface = vReflectivityColor.a;
- vec3 surfaceReflectivityColor = vReflectivityColor.rgb;
- #ifdef METALLICWORKFLOW
- vec2 metallicRoughness = surfaceReflectivityColor.rg;
- #ifdef REFLECTIVITY
- vec4 surfaceMetallicColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
- #ifdef AOSTOREINMETALMAPRED
- vec3 aoStoreInMetalMap = vec3(surfaceMetallicColorMap.r, surfaceMetallicColorMap.r, surfaceMetallicColorMap.r);
- ambientOcclusionColor = mix(ambientOcclusionColor, aoStoreInMetalMap, vReflectivityInfos.z);
- #endif
- #ifdef METALLNESSSTOREINMETALMAPBLUE
- metallicRoughness.r *= surfaceMetallicColorMap.b;
- #else
- metallicRoughness.r *= surfaceMetallicColorMap.r;
- #endif
- #ifdef ROUGHNESSSTOREINMETALMAPALPHA
- metallicRoughness.g *= surfaceMetallicColorMap.a;
- #else
- #ifdef ROUGHNESSSTOREINMETALMAPGREEN
- metallicRoughness.g *= surfaceMetallicColorMap.g;
- #endif
- #endif
- #endif
- #ifdef MICROSURFACEMAP
- vec4 microSurfaceTexel = texture2D(microSurfaceSampler, vMicroSurfaceSamplerUV + uvOffset) * vMicroSurfaceSamplerInfos.y;
- metallicRoughness.g *= microSurfaceTexel.r;
- #endif
- #define CUSTOM_FRAGMENT_UPDATE_METALLICROUGHNESS
-
- // Compute microsurface from roughness.
- microSurface = 1.0 - metallicRoughness.g;
- // Diffuse is used as the base of the reflectivity.
- vec3 baseColor = surfaceAlbedo;
- #ifdef REFLECTANCE
- // Following Frostbite Remapping,
- // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf page 115
- // vec3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + baseColor * metallic;
- // where 0.16 * reflectance * reflectance remaps the reflectance to allow storage in 8 bit texture
- // Compute the converted diffuse.
- surfaceAlbedo = baseColor.rgb * (1.0 - metallicRoughness.r);
- // Compute the converted reflectivity.
- surfaceReflectivityColor = mix(0.16 * reflectance * reflectance, baseColor, metallicRoughness.r);
- #else
- vec3 metallicF0 = vec3(vReflectivityColor.a, vReflectivityColor.a, vReflectivityColor.a);
- #ifdef METALLICF0FACTORFROMMETALLICMAP
- #ifdef REFLECTIVITY
- metallicF0 *= surfaceMetallicColorMap.a;
- #endif
- #endif
- // Compute the converted diffuse.
- surfaceAlbedo = mix(baseColor.rgb * (1.0 - metallicF0.r), vec3(0., 0., 0.), metallicRoughness.r);
- // Compute the converted reflectivity.
- surfaceReflectivityColor = mix(metallicF0, baseColor, metallicRoughness.r);
- #endif
- #else
- #ifdef REFLECTIVITY
- vec4 surfaceReflectivityColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
- surfaceReflectivityColor *= toLinearSpace(surfaceReflectivityColorMap.rgb);
- surfaceReflectivityColor *= vReflectivityInfos.y;
- #ifdef MICROSURFACEFROMREFLECTIVITYMAP
- microSurface *= surfaceReflectivityColorMap.a;
- microSurface *= vReflectivityInfos.z;
- #else
- #ifdef MICROSURFACEAUTOMATIC
- microSurface *= computeDefaultMicroSurface(microSurface, surfaceReflectivityColor);
- #endif
- #ifdef MICROSURFACEMAP
- vec4 microSurfaceTexel = texture2D(microSurfaceSampler, vMicroSurfaceSamplerUV + uvOffset) * vMicroSurfaceSamplerInfos.y;
- microSurface *= microSurfaceTexel.r;
- #endif
-
- #define CUSTOM_FRAGMENT_UPDATE_MICROSURFACE
-
- #endif
- #endif
- #endif
-
- // Adapt microSurface.
- microSurface = saturate(microSurface);
- // Compute roughness.
- float roughness = 1. - microSurface;
- // _____________________________ Alpha Fresnel ___________________________________
- #ifdef ALPHAFRESNEL
- #if defined(ALPHATEST) || defined(ALPHABLEND)
- // Convert approximate perceptual opacity (gamma-encoded opacity) to linear opacity (absorptance, or inverse transmission)
- // for use with the linear HDR render target. The final composition will be converted back to gamma encoded values for eventual display.
- // Uses power 2.0 rather than 2.2 for simplicity/efficiency, and because the mapping does not need to map the gamma applied to RGB.
- float opacityPerceptual = alpha;
- #ifdef LINEARALPHAFRESNEL
- float opacity0 = opacityPerceptual;
- #else
- float opacity0 = opacityPerceptual * opacityPerceptual;
- #endif
- float opacity90 = fresnelGrazingReflectance(opacity0);
- vec3 normalForward = faceforward(normalW, -viewDirectionW, normalW);
- // Calculate the appropriate linear opacity for the current viewing angle (formally, this quantity is the "directional absorptance").
- alpha = getReflectanceFromAnalyticalBRDFLookup_Jones(saturate(dot(viewDirectionW, normalForward)), vec3(opacity0), vec3(opacity90), sqrt(microSurface)).x;
- #ifdef ALPHATEST
- if (alpha < ALPHATESTVALUE)
- discard;
- #ifndef ALPHABLEND
- // Prevent to blend with the canvas.
- alpha = 1.0;
- #endif
- #endif
- #endif
- #endif
- // _____________________________ Compute Geometry info _________________________________
- float NdotVUnclamped = dot(normalW, viewDirectionW);
- // The order 1886 page 3.
- float NdotV = absEps(NdotVUnclamped);
- float alphaG = convertRoughnessToAverageSlope(roughness);
- vec2 AARoughnessFactors = getAARoughnessFactors(normalW.xyz);
- #ifdef SPECULARAA
- // Adapt linear roughness (alphaG) to geometric curvature of the current pixel.
- alphaG += AARoughnessFactors.y;
- #endif
- #ifdef ANISOTROPIC
- float anisotropy = vAnisotropy.b;
- vec3 anisotropyDirection = vec3(vAnisotropy.xy, 0.);
- #ifdef ANISOTROPIC_TEXTURE
- vec3 anisotropyMapData = texture2D(anisotropySampler, vAnisotropyUV + uvOffset).rgb * vAnisotropyInfos.y;
- anisotropy *= anisotropyMapData.b;
- anisotropyDirection.rg *= anisotropyMapData.rg * 2.0 - 1.0;
- #endif
- mat3 anisoTBN = mat3(normalize(TBN[0]), normalize(TBN[1]), normalize(TBN[2]));
- vec3 anisotropicTangent = normalize(anisoTBN * anisotropyDirection);
- vec3 anisotropicBitangent = normalize(cross(anisoTBN[2], anisotropicTangent));
-
- vec3 anisotropicNormal = getAnisotropicBentNormals(anisotropicTangent, anisotropicBitangent, normalW, viewDirectionW, anisotropy);
- #endif
- // _____________________________ Refraction Info _______________________________________
- #ifdef SS_REFRACTION
- vec4 environmentRefraction = vec4(0., 0., 0., 0.);
- #ifdef ANISOTROPIC
- vec3 refractionVector = refract(-viewDirectionW, anisotropicNormal, vRefractionInfos.y);
- #else
- vec3 refractionVector = refract(-viewDirectionW, normalW, vRefractionInfos.y);
- #endif
- #ifdef SS_REFRACTIONMAP_OPPOSITEZ
- refractionVector.z *= -1.0;
- #endif
- // _____________________________ 2D vs 3D Maps ________________________________
- #ifdef SS_REFRACTIONMAP_3D
- refractionVector.y = refractionVector.y * vRefractionInfos.w;
- vec3 refractionCoords = refractionVector;
- refractionCoords = vec3(refractionMatrix * vec4(refractionCoords, 0));
- #else
- vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
- vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
- refractionCoords.y = 1.0 - refractionCoords.y;
- #endif
- #ifdef SS_LODINREFRACTIONALPHA
- float refractionLOD = getLodFromAlphaG(vRefractionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
- #elif defined(SS_LINEARSPECULARREFRACTION)
- float refractionLOD = getLinearLodFromRoughness(vRefractionMicrosurfaceInfos.x, roughness);
- #else
- float refractionLOD = getLodFromAlphaG(vRefractionMicrosurfaceInfos.x, alphaG);
- #endif
- #ifdef LODBASEDMICROSFURACE
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- refractionLOD = refractionLOD * vRefractionMicrosurfaceInfos.y + vRefractionMicrosurfaceInfos.z;
- #ifdef SS_LODINREFRACTIONALPHA
- // Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
- // is constrained to appropriate LOD levels in order to prevent aliasing.
- // The environment map is first sampled without custom LOD selection to determine
- // the hardware-selected LOD, and this is then used to constrain the final LOD selection
- // so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
- // where the normal is varying rapidly).
- // Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
- // manual calculation via derivatives is also possible, but for simplicity we use the
- // hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
- float automaticRefractionLOD = UNPACK_LOD(sampleRefraction(refractionSampler, refractionCoords).a);
- float requestedRefractionLOD = max(automaticRefractionLOD, refractionLOD);
- #else
- float requestedRefractionLOD = refractionLOD;
- #endif
- environmentRefraction = sampleRefractionLod(refractionSampler, refractionCoords, requestedRefractionLOD);
- #else
- float lodRefractionNormalized = saturate(refractionLOD / log2(vRefractionMicrosurfaceInfos.x));
- float lodRefractionNormalizedDoubled = lodRefractionNormalized * 2.0;
- vec4 environmentRefractionMid = sampleRefraction(refractionSampler, refractionCoords);
- if(lodRefractionNormalizedDoubled < 1.0){
- environmentRefraction = mix(
- sampleRefraction(refractionSamplerHigh, refractionCoords),
- environmentRefractionMid,
- lodRefractionNormalizedDoubled
- );
- }else{
- environmentRefraction = mix(
- environmentRefractionMid,
- sampleRefraction(refractionSamplerLow, refractionCoords),
- lodRefractionNormalizedDoubled - 1.0
- );
- }
- #endif
- #ifdef SS_RGBDREFRACTION
- environmentRefraction.rgb = fromRGBD(environmentRefraction);
- #endif
- #ifdef SS_GAMMAREFRACTION
- environmentRefraction.rgb = toLinearSpace(environmentRefraction.rgb);
- #endif
- // _____________________________ Levels _____________________________________
- environmentRefraction.rgb *= vRefractionInfos.x;
- #endif
- // _____________________________ Reflection Info _______________________________________
- #ifdef REFLECTION
- vec4 environmentRadiance = vec4(0., 0., 0., 0.);
- vec3 environmentIrradiance = vec3(0., 0., 0.);
- #ifdef ANISOTROPIC
- vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), anisotropicNormal);
- #else
- vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
- #endif
- #ifdef REFLECTIONMAP_OPPOSITEZ
- reflectionVector.z *= -1.0;
- #endif
- // _____________________________ 2D vs 3D Maps ________________________________
- #ifdef REFLECTIONMAP_3D
- vec3 reflectionCoords = reflectionVector;
- #else
- vec2 reflectionCoords = reflectionVector.xy;
- #ifdef REFLECTIONMAP_PROJECTION
- reflectionCoords /= reflectionVector.z;
- #endif
- reflectionCoords.y = 1.0 - reflectionCoords.y;
- #endif
- #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
- float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
- #elif defined(LINEARSPECULARREFLECTION)
- float reflectionLOD = getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x, roughness);
- #else
- float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG);
- #endif
- #ifdef LODBASEDMICROSFURACE
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
- #ifdef LODINREFLECTIONALPHA
- // Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
- // is constrained to appropriate LOD levels in order to prevent aliasing.
- // The environment map is first sampled without custom LOD selection to determine
- // the hardware-selected LOD, and this is then used to constrain the final LOD selection
- // so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
- // where the normal is varying rapidly).
- // Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
- // manual calculation via derivatives is also possible, but for simplicity we use the
- // hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
- float automaticReflectionLOD = UNPACK_LOD(sampleReflection(reflectionSampler, reflectionCoords).a);
- float requestedReflectionLOD = max(automaticReflectionLOD, reflectionLOD);
- #else
- float requestedReflectionLOD = reflectionLOD;
- #endif
- environmentRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, requestedReflectionLOD);
- #else
- float lodReflectionNormalized = saturate(reflectionLOD / log2(vReflectionMicrosurfaceInfos.x));
- float lodReflectionNormalizedDoubled = lodReflectionNormalized * 2.0;
- vec4 environmentSpecularMid = sampleReflection(reflectionSampler, reflectionCoords);
- if(lodReflectionNormalizedDoubled < 1.0){
- environmentRadiance = mix(
- sampleReflection(reflectionSamplerHigh, reflectionCoords),
- environmentSpecularMid,
- lodReflectionNormalizedDoubled
- );
- }else{
- environmentRadiance = mix(
- environmentSpecularMid,
- sampleReflection(reflectionSamplerLow, reflectionCoords),
- lodReflectionNormalizedDoubled - 1.0
- );
- }
- #endif
- #ifdef RGBDREFLECTION
- environmentRadiance.rgb = fromRGBD(environmentRadiance);
- #endif
- #ifdef GAMMAREFLECTION
- environmentRadiance.rgb = toLinearSpace(environmentRadiance.rgb);
- #endif
- // _____________________________ Irradiance ________________________________
- #ifdef USESPHERICALFROMREFLECTIONMAP
- #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
- environmentIrradiance = vEnvironmentIrradiance;
- #else
- #ifdef ANISOTROPIC
- vec3 irradianceVector = vec3(reflectionMatrix * vec4(anisotropicNormal, 0)).xyz;
- #else
- vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
- #endif
- #ifdef REFLECTIONMAP_OPPOSITEZ
- irradianceVector.z *= -1.0;
- #endif
- environmentIrradiance = computeEnvironmentIrradiance(irradianceVector);
- #endif
- #elif defined(USEIRRADIANCEMAP)
- environmentIrradiance = sampleReflection(irradianceSampler, reflectionCoords).rgb;
- #ifdef RGBDREFLECTION
- environmentIrradiance.rgb = fromRGBD(environmentIrradiance);
- #endif
- #ifdef GAMMAREFLECTION
- environmentIrradiance.rgb = toLinearSpace(environmentIrradiance.rgb);
- #endif
- #endif
- // _____________________________ Levels _____________________________________
- environmentRadiance.rgb *= vReflectionInfos.x;
- environmentRadiance.rgb *= vReflectionColor.rgb;
- environmentIrradiance *= vReflectionColor.rgb;
- #endif
- // ___________________ Compute Reflectance aka R0 F0 info _________________________
- float reflectance = max(max(surfaceReflectivityColor.r, surfaceReflectivityColor.g), surfaceReflectivityColor.b);
- float reflectance90 = fresnelGrazingReflectance(reflectance);
- vec3 specularEnvironmentR0 = surfaceReflectivityColor.rgb;
- vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
- // ________________________________ Sheen Information ______________________________
- #ifdef SHEEN
- float sheenIntensity = vSheenColor.a;
- #ifdef SHEEN_TEXTURE
- vec4 sheenMapData = texture2D(sheenSampler, vSheenUV + uvOffset) * vSheenInfos.y;
- sheenIntensity *= sheenMapData.a;
- #endif
- #ifdef SHEEN_LINKWITHALBEDO
- float sheenFactor = pow5(1.0-sheenIntensity);
- vec3 sheenColor = baseColor.rgb*(1.0-sheenFactor);
- float sheenRoughness = sheenIntensity;
- // remap albedo.
- surfaceAlbedo.rgb *= sheenFactor;
- #else
- vec3 sheenColor = vSheenColor.rgb;
- #ifdef SHEEN_TEXTURE
- sheenColor.rgb *= toLinearSpace(sheenMapData.rgb);
- #endif
- float sheenRoughness = roughness;
- // Sheen Lobe Layering.
- sheenIntensity *= (1. - reflectance);
- // Remap F0 and sheen.
- sheenColor *= sheenIntensity;
- #endif
- // Sheen Reflection
- #if defined(REFLECTION)
- float sheenAlphaG = convertRoughnessToAverageSlope(sheenRoughness);
- #ifdef SPECULARAA
- // Adapt linear roughness (alphaG) to geometric curvature of the current pixel.
- sheenAlphaG += AARoughnessFactors.y;
- #endif
- vec4 environmentSheenRadiance = vec4(0., 0., 0., 0.);
- // _____________________________ 2D vs 3D Maps ________________________________
- #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
- float sheenReflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, sheenAlphaG, NdotVUnclamped);
- #elif defined(LINEARSPECULARREFLECTION)
- float sheenReflectionLOD = getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x, sheenRoughness);
- #else
- float sheenReflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, sheenAlphaG);
- #endif
- #ifdef LODBASEDMICROSFURACE
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- sheenReflectionLOD = sheenReflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
- environmentSheenRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, sheenReflectionLOD);
- #else
- float lodSheenReflectionNormalized = saturate(sheenReflectionLOD / log2(vReflectionMicrosurfaceInfos.x));
- float lodSheenReflectionNormalizedDoubled = lodSheenReflectionNormalized * 2.0;
- vec4 environmentSheenMid = sampleReflection(reflectionSampler, reflectionCoords);
- if(lodSheenReflectionNormalizedDoubled < 1.0){
- environmentSheenRadiance = mix(
- sampleReflection(reflectionSamplerHigh, reflectionCoords),
- environmentSheenMid,
- lodSheenReflectionNormalizedDoubled
- );
- }else{
- environmentSheenRadiance = mix(
- environmentSheenMid,
- sampleReflection(reflectionSamplerLow, reflectionCoords),
- lodSheenReflectionNormalizedDoubled - 1.0
- );
- }
- #endif
- #ifdef RGBDREFLECTION
- environmentSheenRadiance.rgb = fromRGBD(environmentSheenRadiance);
- #endif
- #ifdef GAMMAREFLECTION
- environmentSheenRadiance.rgb = toLinearSpace(environmentSheenRadiance.rgb);
- #endif
- // _____________________________ Levels _____________________________________
- environmentSheenRadiance.rgb *= vReflectionInfos.x;
- environmentSheenRadiance.rgb *= vReflectionColor.rgb;
- #endif
- #endif
- // _____________________________ Clear Coat Information ____________________________
- #ifdef CLEARCOAT
- // Clear COAT parameters.
- float clearCoatIntensity = vClearCoatParams.x;
- float clearCoatRoughness = vClearCoatParams.y;
- #ifdef CLEARCOAT_TEXTURE
- vec2 clearCoatMapData = texture2D(clearCoatSampler, vClearCoatUV + uvOffset).rg * vClearCoatInfos.y;
- clearCoatIntensity *= clearCoatMapData.x;
- clearCoatRoughness *= clearCoatMapData.y;
- #endif
- #ifdef CLEARCOAT_TINT
- vec3 clearCoatColor = vClearCoatTintParams.rgb;
- float clearCoatThickness = vClearCoatTintParams.a;
- #ifdef CLEARCOAT_TINT_TEXTURE
- vec4 clearCoatTintMapData = texture2D(clearCoatTintSampler, vClearCoatTintUV + uvOffset);
- clearCoatColor *= toLinearSpace(clearCoatTintMapData.rgb);
- clearCoatThickness *= clearCoatTintMapData.a;
- #endif
- clearCoatColor = computeColorAtDistanceInMedia(clearCoatColor, clearCoatColorAtDistance);
- #endif
- // remapping and linearization of clear coat roughness
- // Let s see how it ends up in gltf
- // clearCoatRoughness = mix(0.089, 0.6, clearCoatRoughness);
- // Remap F0 to account for the change of interface within the material.
- vec3 specularEnvironmentR0Updated = getR0RemappedForClearCoat(specularEnvironmentR0);
- specularEnvironmentR0 = mix(specularEnvironmentR0, specularEnvironmentR0Updated, clearCoatIntensity);
- #ifdef CLEARCOAT_BUMP
- #ifdef NORMALXYSCALE
- float clearCoatNormalScale = 1.0;
- #else
- float clearCoatNormalScale = vClearCoatBumpInfos.y;
- #endif
- #if defined(TANGENT) && defined(NORMAL)
- mat3 TBNClearCoat = vTBN;
- #else
- mat3 TBNClearCoat = cotangent_frame(clearCoatNormalW * clearCoatNormalScale, vPositionW, vClearCoatBumpUV, vClearCoatTangentSpaceParams);
- #endif
- #ifdef OBJECTSPACE_NORMALMAP
- clearCoatNormalW = normalize(texture2D(clearCoatBumpSampler, vClearCoatBumpUV + uvOffset).xyz * 2.0 - 1.0);
- clearCoatNormalW = normalize(mat3(normalMatrix) * clearCoatNormalW);
- #else
- clearCoatNormalW = perturbNormal(TBNClearCoat, texture2D(clearCoatBumpSampler, vClearCoatBumpUV + uvOffset).xyz, vClearCoatBumpInfos.y);
- #endif
- #endif
- #if defined(FORCENORMALFORWARD) && defined(NORMAL)
- clearCoatNormalW *= sign(dot(clearCoatNormalW, faceNormal));
- #endif
- #if defined(TWOSIDEDLIGHTING) && defined(NORMAL)
- clearCoatNormalW = gl_FrontFacing ? clearCoatNormalW : -clearCoatNormalW;
- #endif
- // Clear Coat AA
- vec2 clearCoatAARoughnessFactors = getAARoughnessFactors(clearCoatNormalW.xyz);
- // Compute N dot V.
- float clearCoatNdotVUnclamped = dot(clearCoatNormalW, viewDirectionW);
- // The order 1886 page 3.
- float clearCoatNdotV = absEps(clearCoatNdotVUnclamped);
- #ifdef CLEARCOAT_TINT
- // Used later on in the light fragment and ibl.
- vec3 clearCoatVRefract = -refract(vPositionW, clearCoatNormalW, vClearCoatRefractionParams.y);
- // The order 1886 page 3.
- float clearCoatNdotVRefract = absEps(dot(clearCoatNormalW, clearCoatVRefract));
- vec3 absorption = vec3(0.);
- #endif
- // Clear Coat Reflection
- #if defined(REFLECTION)
- float clearCoatAlphaG = convertRoughnessToAverageSlope(clearCoatRoughness);
- #ifdef SPECULARAA
- // Adapt linear roughness (alphaG) to geometric curvature of the current pixel.
- clearCoatAlphaG += clearCoatAARoughnessFactors.y;
- #endif
- vec4 environmentClearCoatRadiance = vec4(0., 0., 0., 0.);
- vec3 clearCoatReflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), clearCoatNormalW);
- #ifdef REFLECTIONMAP_OPPOSITEZ
- clearCoatReflectionVector.z *= -1.0;
- #endif
- // _____________________________ 2D vs 3D Maps ________________________________
- #ifdef REFLECTIONMAP_3D
- vec3 clearCoatReflectionCoords = clearCoatReflectionVector;
- #else
- vec2 clearCoatReflectionCoords = clearCoatReflectionVector.xy;
- #ifdef REFLECTIONMAP_PROJECTION
- clearCoatReflectionCoords /= clearCoatReflectionVector.z;
- #endif
- clearCoatReflectionCoords.y = 1.0 - clearCoatReflectionCoords.y;
- #endif
- #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
- float clearCoatReflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, clearCoatAlphaG, clearCoatNdotVUnclamped);
- #elif defined(LINEARSPECULARREFLECTION)
- float sheenReflectionLOD = getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x, clearCoatRoughness);
- #else
- float clearCoatReflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, clearCoatAlphaG);
- #endif
- #ifdef LODBASEDMICROSFURACE
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- clearCoatReflectionLOD = clearCoatReflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
- float requestedClearCoatReflectionLOD = clearCoatReflectionLOD;
- environmentClearCoatRadiance = sampleReflectionLod(reflectionSampler, clearCoatReflectionCoords, requestedClearCoatReflectionLOD);
- #else
- float lodClearCoatReflectionNormalized = saturate(clearCoatReflectionLOD / log2(vReflectionMicrosurfaceInfos.x));
- float lodClearCoatReflectionNormalizedDoubled = lodClearCoatReflectionNormalized * 2.0;
- vec4 environmentClearCoatMid = sampleReflection(reflectionSampler, reflectionCoords);
- if(lodClearCoatReflectionNormalizedDoubled < 1.0){
- environmentClearCoatRadiance = mix(
- sampleReflection(reflectionSamplerHigh, clearCoatReflectionCoords),
- environmentClearCoatMid,
- lodClearCoatReflectionNormalizedDoubled
- );
- }else{
- environmentClearCoatRadiance = mix(
- environmentClearCoatMid,
- sampleReflection(reflectionSamplerLow, clearCoatReflectionCoords),
- lodClearCoatReflectionNormalizedDoubled - 1.0
- );
- }
- #endif
- #ifdef RGBDREFLECTION
- environmentClearCoatRadiance.rgb = fromRGBD(environmentClearCoatRadiance);
- #endif
- #ifdef GAMMAREFLECTION
- environmentClearCoatRadiance.rgb = toLinearSpace(environmentClearCoatRadiance.rgb);
- #endif
- // _____________________________ Levels _____________________________________
- environmentClearCoatRadiance.rgb *= vReflectionInfos.x;
- environmentClearCoatRadiance.rgb *= vReflectionColor.rgb;
- #endif
- #endif
- // _____________________________ IBL BRDF + Energy Cons ________________________________
- #if defined(ENVIRONMENTBRDF)
- // BRDF Lookup
- vec3 environmentBrdf = getBRDFLookup(NdotV, roughness);
- #ifdef MS_BRDF_ENERGY_CONSERVATION
- vec3 energyConservationFactor = getEnergyConservationFactor(specularEnvironmentR0, environmentBrdf);
- #endif
- #endif
- // ___________________________________ SubSurface ______________________________________
- #ifdef SUBSURFACE
- #ifdef SS_REFRACTION
- float refractionIntensity = vSubSurfaceIntensity.x;
- #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
- refractionIntensity *= (1.0 - alpha);
- // Put alpha back to 1;
- alpha = 1.0;
- #endif
- #endif
- #ifdef SS_TRANSLUCENCY
- float translucencyIntensity = vSubSurfaceIntensity.y;
- #endif
- #ifdef SS_SCATTERING
- float scatteringIntensity = vSubSurfaceIntensity.z;
- #endif
- #ifdef SS_THICKNESSANDMASK_TEXTURE
- vec4 thicknessMap = texture2D(thicknessSampler, vThicknessUV + uvOffset);
- float thickness = thicknessMap.r * vThicknessParam.y + vThicknessParam.x;
- #ifdef SS_MASK_FROM_THICKNESS_TEXTURE
- #ifdef SS_REFRACTION
- refractionIntensity *= thicknessMap.g;
- #endif
- #ifdef SS_TRANSLUCENCY
- translucencyIntensity *= thicknessMap.b;
- #endif
- #ifdef SS_SCATTERING
- scatteringIntensity *= thicknessMap.a;
- #endif
- #endif
- #else
- float thickness = vThicknessParam.y;
- #endif
- #ifdef SS_TRANSLUCENCY
- thickness = maxEps(thickness);
- vec3 transmittance = transmittanceBRDF_Burley(vTintColor.rgb, vDiffusionDistance, thickness);
- transmittance *= translucencyIntensity;
- #endif
- #endif
- // ____________________________________________________________________________________
- // _____________________________ Direct Lighting Info __________________________________
- vec3 diffuseBase = vec3(0., 0., 0.);
- #ifdef SPECULARTERM
- vec3 specularBase = vec3(0., 0., 0.);
- #endif
- #ifdef CLEARCOAT
- vec3 clearCoatBase = vec3(0., 0., 0.);
- #endif
- #ifdef SHEEN
- vec3 sheenBase = vec3(0., 0., 0.);
- #endif
- #ifdef LIGHTMAP
- vec4 lightmapColor = texture2D(lightmapSampler, vLightmapUV + uvOffset);
- #ifdef RGBDLIGHTMAP
- lightmapColor.rgb = fromRGBD(lightmapColor);
- #endif
- #ifdef GAMMALIGHTMAP
- lightmapColor.rgb = toLinearSpace(lightmapColor.rgb);
- #endif
- lightmapColor.rgb *= vLightmapInfos.y;
- #endif
- // Direct Lighting Variables
- preLightingInfo preInfo;
- lightingInfo info;
- float shadow = 1.; // 1 - shadowLevel
- #include<lightFragment>[0..maxSimultaneousLights]
- // _________________________ Specular Environment Oclusion __________________________
- #if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)
- vec3 specularEnvironmentReflectance = getReflectanceFromBRDFLookup(specularEnvironmentR0, environmentBrdf);
- #ifdef RADIANCEOCCLUSION
- #ifdef AMBIENTINGRAYSCALE
- float ambientMonochrome = ambientOcclusionColor.r;
- #else
- float ambientMonochrome = getLuminance(ambientOcclusionColor);
- #endif
- float seo = environmentRadianceOcclusion(ambientMonochrome, NdotVUnclamped);
- specularEnvironmentReflectance *= seo;
- #endif
- #ifdef HORIZONOCCLUSION
- #ifdef BUMP
- #ifdef REFLECTIONMAP_3D
- float eho = environmentHorizonOcclusion(-viewDirectionW, normalW);
- specularEnvironmentReflectance *= eho;
- #endif
- #endif
- #endif
- #else
- // Jones implementation of a well balanced fast analytical solution.
- vec3 specularEnvironmentReflectance = getReflectanceFromAnalyticalBRDFLookup_Jones(NdotV, specularEnvironmentR0, specularEnvironmentR90, sqrt(microSurface));
- #endif
- // _____________________________ Sheen Environment Oclusion __________________________
- #if defined(SHEEN) && defined(REFLECTION)
- vec3 sheenEnvironmentReflectance = getSheenReflectanceFromBRDFLookup(sheenColor, environmentBrdf);
- #ifdef RADIANCEOCCLUSION
- sheenEnvironmentReflectance *= seo;
- #endif
- #ifdef HORIZONOCCLUSION
- #ifdef BUMP
- #ifdef REFLECTIONMAP_3D
- sheenEnvironmentReflectance *= eho;
- #endif
- #endif
- #endif
- #endif
- // _________________________ Clear Coat Environment Oclusion __________________________
- #ifdef CLEARCOAT
- #if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)
- // BRDF Lookup
- vec3 environmentClearCoatBrdf = getBRDFLookup(clearCoatNdotV, clearCoatRoughness);
- vec3 clearCoatEnvironmentReflectance = getReflectanceFromBRDFLookup(vec3(vClearCoatRefractionParams.x), environmentClearCoatBrdf);
- #ifdef RADIANCEOCCLUSION
- float clearCoatSeo = environmentRadianceOcclusion(ambientMonochrome, clearCoatNdotVUnclamped);
- clearCoatEnvironmentReflectance *= clearCoatSeo;
- #endif
- #ifdef HORIZONOCCLUSION
- #ifdef BUMP
- #ifdef REFLECTIONMAP_3D
- float clearCoatEho = environmentHorizonOcclusion(-viewDirectionW, clearCoatNormalW);
- clearCoatEnvironmentReflectance *= clearCoatEho;
- #endif
- #endif
- #endif
- #else
- // Jones implementation of a well balanced fast analytical solution.
- vec3 clearCoatEnvironmentReflectance = getReflectanceFromAnalyticalBRDFLookup_Jones(clearCoatNdotV, vec3(1.), vec3(1.), sqrt(1. - clearCoatRoughness));
- #endif
- clearCoatEnvironmentReflectance *= clearCoatIntensity;
- #if defined(CLEARCOAT_TINT)
- // NdotL = NdotV in IBL
- absorption = computeClearCoatAbsorption(clearCoatNdotVRefract, clearCoatNdotVRefract, clearCoatColor, clearCoatThickness, clearCoatIntensity);
- #ifdef REFLECTION
- environmentIrradiance *= absorption;
- #ifdef SHEEN
- sheenEnvironmentReflectance *= absorption;
- #endif
- #endif
- specularEnvironmentReflectance *= absorption;
- #endif
- // clear coat energy conservation
- float fresnelIBLClearCoat = fresnelSchlickGGX(clearCoatNdotV, vClearCoatRefractionParams.x, CLEARCOATREFLECTANCE90);
- fresnelIBLClearCoat *= clearCoatIntensity;
- float conservationFactor = (1. - fresnelIBLClearCoat);
- #ifdef REFLECTION
- environmentIrradiance *= conservationFactor;
- #ifdef SHEEN
- sheenEnvironmentReflectance *= conservationFactor;
- #endif
- #endif
- specularEnvironmentReflectance *= conservationFactor;
- #endif
- // _____________________________ Transmittance + Tint ________________________________
- #ifdef SS_REFRACTION
- vec3 refractionTransmittance = vec3(refractionIntensity);
- #ifdef SS_THICKNESSANDMASK_TEXTURE
- vec3 volumeAlbedo = computeColorAtDistanceInMedia(vTintColor.rgb, vTintColor.w);
- // // Simulate Flat Surface
- // thickness /= dot(refractionVector, -normalW);
- // // Simulate Curved Surface
- // float NdotRefract = dot(normalW, refractionVector);
- // thickness *= -NdotRefract;
- refractionTransmittance *= cocaLambert(volumeAlbedo, thickness);
- #elif defined(SS_LINKREFRACTIONTOTRANSPARENCY)
- // Tint the material with albedo.
- float maxChannel = max(max(surfaceAlbedo.r, surfaceAlbedo.g), surfaceAlbedo.b);
- vec3 volumeAlbedo = saturate(maxChannel * surfaceAlbedo);
- // Tint reflectance
- environmentRefraction.rgb *= volumeAlbedo;
- #else
- // Compute tint from min distance only.
- vec3 volumeAlbedo = computeColorAtDistanceInMedia(vTintColor.rgb, vTintColor.w);
- refractionTransmittance *= cocaLambert(volumeAlbedo, vThicknessParam.y);
- #endif
- // Decrease Albedo Contribution
- surfaceAlbedo *= (1. - refractionIntensity);
- #ifdef REFLECTION
- // Decrease irradiance Contribution
- environmentIrradiance *= (1. - refractionIntensity);
- #endif
- // Add Multiple internal bounces.
- vec3 bounceSpecularEnvironmentReflectance = (2.0 * specularEnvironmentReflectance) / (1.0 + specularEnvironmentReflectance);
- specularEnvironmentReflectance = mix(bounceSpecularEnvironmentReflectance, specularEnvironmentReflectance, refractionIntensity);
- // In theory T = 1 - R.
- refractionTransmittance *= 1.0 - specularEnvironmentReflectance;
- #endif
- // _______________________________ IBL Translucency ________________________________
- #if defined(REFLECTION) && defined(SS_TRANSLUCENCY)
- #if defined(USESPHERICALINVERTEX)
- vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
- #ifdef REFLECTIONMAP_OPPOSITEZ
- irradianceVector.z *= -1.0;
- #endif
- #endif
- #if defined(USESPHERICALFROMREFLECTIONMAP)
- vec3 refractionIrradiance = computeEnvironmentIrradiance(-irradianceVector);
- #elif defined(USEIRRADIANCEMAP)
- vec3 refractionIrradiance = sampleReflection(irradianceSampler, -irradianceVector).rgb;
- #ifdef RGBDREFLECTION
- refractionIrradiance.rgb = fromRGBD(refractionIrradiance);
- #endif
- #ifdef GAMMAREFLECTION
- refractionIrradiance.rgb = toLinearSpace(refractionIrradiance.rgb);
- #endif
- #else
- vec3 refractionIrradiance = vec3(0.);
- #endif
- refractionIrradiance *= transmittance;
- #endif
- // ______________________________________________________________________________
- // _____________________________ Energy Conservation ___________________________
- // Apply Energy Conservation.
- #ifndef METALLICWORKFLOW
- #ifdef SPECULAR_GLOSSINESS_ENERGY_CONSERVATION
- surfaceAlbedo.rgb = (1. - reflectance) * surfaceAlbedo.rgb;
- #endif
- #endif
- // _____________________________ Irradiance ______________________________________
- #ifdef REFLECTION
- vec3 finalIrradiance = environmentIrradiance;
- #if defined(SS_TRANSLUCENCY)
- finalIrradiance += refractionIrradiance;
- #endif
- finalIrradiance *= surfaceAlbedo.rgb;
- #endif
- // _____________________________ Specular ________________________________________
- #ifdef SPECULARTERM
- vec3 finalSpecular = specularBase;
- finalSpecular = max(finalSpecular, 0.0);
- // Full value needed for alpha.
- vec3 finalSpecularScaled = finalSpecular * vLightingIntensity.x * vLightingIntensity.w;
- #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
- finalSpecularScaled *= energyConservationFactor;
- #endif
- #endif
- // _____________________________ Radiance ________________________________________
- #ifdef REFLECTION
- vec3 finalRadiance = environmentRadiance.rgb;
- finalRadiance *= specularEnvironmentReflectance;
- // Full value needed for alpha.
- vec3 finalRadianceScaled = finalRadiance * vLightingIntensity.z;
- #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
- finalRadianceScaled *= energyConservationFactor;
- #endif
- #endif
- // _____________________________ Refraction ______________________________________
- #ifdef SS_REFRACTION
- vec3 finalRefraction = environmentRefraction.rgb;
- finalRefraction *= refractionTransmittance;
- #endif
- // _____________________________ Clear Coat _______________________________________
- #ifdef CLEARCOAT
- vec3 finalClearCoat = clearCoatBase;
- finalClearCoat = max(finalClearCoat, 0.0);
- // Full value needed for alpha.
- vec3 finalClearCoatScaled = finalClearCoat * vLightingIntensity.x * vLightingIntensity.w;
- #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
- finalClearCoatScaled *= energyConservationFactor;
- #endif
- // ____________________________ Clear Coat Radiance _______________________________
- #ifdef REFLECTION
- vec3 finalClearCoatRadiance = environmentClearCoatRadiance.rgb;
- finalClearCoatRadiance *= clearCoatEnvironmentReflectance;
- // Full value needed for alpha.
- vec3 finalClearCoatRadianceScaled = finalClearCoatRadiance * vLightingIntensity.z;
- #endif
- #ifdef SS_REFRACTION
- finalRefraction *= conservationFactor;
- #ifdef CLEARCOAT_TINT
- finalRefraction *= absorption;
- #endif
- #endif
- #endif
- // ________________________________ Sheen ________________________________________
- #ifdef SHEEN
- vec3 finalSheen = sheenBase * sheenColor;
- finalSheen = max(finalSheen, 0.0);
- vec3 finalSheenScaled = finalSheen * vLightingIntensity.x * vLightingIntensity.w;
- // #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
- // The sheen does not use the same BRDF so not energy conservation is possible
- // Should be less a problem as it is usually not metallic
- // finalSheenScaled *= energyConservationFactor;
- // #endif
-
- #ifdef REFLECTION
- vec3 finalSheenRadiance = environmentSheenRadiance.rgb;
- finalSheenRadiance *= sheenEnvironmentReflectance;
- // Full value needed for alpha.
- vec3 finalSheenRadianceScaled = finalSheenRadiance * vLightingIntensity.z;
- #endif
- #endif
- // _____________________________ Highlights on Alpha _____________________________
- #ifdef ALPHABLEND
- float luminanceOverAlpha = 0.0;
- #if defined(REFLECTION) && defined(RADIANCEOVERALPHA)
- luminanceOverAlpha += getLuminance(finalRadianceScaled);
- #if defined(CLEARCOAT)
- luminanceOverAlpha += getLuminance(finalClearCoatRadianceScaled);
- #endif
- #endif
- #if defined(SPECULARTERM) && defined(SPECULAROVERALPHA)
- luminanceOverAlpha += getLuminance(finalSpecularScaled);
- #endif
- #if defined(CLEARCOAT) && defined(CLEARCOATOVERALPHA)
- luminanceOverAlpha += getLuminance(finalClearCoatScaled);
- #endif
- #if defined(RADIANCEOVERALPHA) || defined(SPECULAROVERALPHA)
- alpha = saturate(alpha + luminanceOverAlpha * luminanceOverAlpha);
- #endif
- #endif
- #endif
- // _______________ Not done before as it is unlit only __________________________
- // _____________________________ Diffuse ________________________________________
- vec3 finalDiffuse = diffuseBase;
- finalDiffuse *= surfaceAlbedo.rgb;
- finalDiffuse = max(finalDiffuse, 0.0);
- // _____________________________ Ambient ________________________________________
- vec3 finalAmbient = vAmbientColor;
- finalAmbient *= surfaceAlbedo.rgb;
- // _____________________________ Emissive ________________________________________
- vec3 finalEmissive = vEmissiveColor;
- #ifdef EMISSIVE
- vec3 emissiveColorTex = texture2D(emissiveSampler, vEmissiveUV + uvOffset).rgb;
- finalEmissive *= toLinearSpace(emissiveColorTex.rgb);
- finalEmissive *= vEmissiveInfos.y;
- #endif
- // ______________________________ Ambient ________________________________________
- #ifdef AMBIENT
- vec3 ambientOcclusionForDirectDiffuse = mix(vec3(1.), ambientOcclusionColor, vAmbientInfos.w);
- #else
- vec3 ambientOcclusionForDirectDiffuse = ambientOcclusionColor;
- #endif
- // _______________________________________________________________________________
- // _____________________________ Composition _____________________________________
- // Reflection already includes the environment intensity.
- vec4 finalColor = vec4(
- finalAmbient * ambientOcclusionColor +
- finalDiffuse * ambientOcclusionForDirectDiffuse * vLightingIntensity.x +
- #ifndef UNLIT
- #ifdef REFLECTION
- finalIrradiance * ambientOcclusionColor * vLightingIntensity.z +
- #endif
- #ifdef SPECULARTERM
- // Computed in the previous step to help with alpha luminance.
- // finalSpecular * vLightingIntensity.x * vLightingIntensity.w +
- finalSpecularScaled +
- #endif
- #ifdef CLEARCOAT
- // Computed in the previous step to help with alpha luminance.
- // finalClearCoat * vLightingIntensity.x * vLightingIntensity.w +
- finalClearCoatScaled +
- #endif
- #ifdef SHEEN
- // Computed in the previous step to help with alpha luminance.
- // finalSheen * vLightingIntensity.x * vLightingIntensity.w +
- finalSheenScaled +
- #endif
- #ifdef REFLECTION
- // Comupted in the previous step to help with alpha luminance.
- // finalRadiance * vLightingIntensity.z +
- finalRadianceScaled +
- #ifdef CLEARCOAT
- // Comupted in the previous step to help with alpha luminance.
- // finalClearCoatRadiance * vLightingIntensity.z
- finalClearCoatRadianceScaled +
- #endif
- #ifdef SHEEN
- // Comupted in the previous step to help with alpha luminance.
- // finalSheenRadiance * vLightingIntensity.z
- finalSheenRadianceScaled +
- #endif
- #endif
- #ifdef SS_REFRACTION
- finalRefraction * vLightingIntensity.z +
- #endif
- #endif
- finalEmissive * vLightingIntensity.y,
- alpha);
- // _____________________________ LightMappping _____________________________________
- #ifdef LIGHTMAP
- #ifndef LIGHTMAPEXCLUDED
- #ifdef USELIGHTMAPASSHADOWMAP
- finalColor.rgb *= lightmapColor.rgb;
- #else
- finalColor.rgb += lightmapColor.rgb;
- #endif
- #endif
- #endif
- #define CUSTOM_FRAGMENT_BEFORE_FOG
- // _____________________________ Finally ___________________________________________
- finalColor = max(finalColor, 0.0);
- #include<logDepthFragment>
- #include<fogFragment>(color, finalColor)
- #ifdef IMAGEPROCESSINGPOSTPROCESS
- // Sanitize output incase invalid normals or tangents have caused div by 0 or undefined behavior
- // this also limits the brightness which helpfully reduces over-sparkling in bloom (native handles this in the bloom blur shader)
- finalColor.rgb = clamp(finalColor.rgb, 0., 30.0);
- #else
- // Alway run to ensure we are going back to gamma space.
- finalColor = applyImageProcessing(finalColor);
- #endif
- finalColor.a *= visibility;
- #ifdef PREMULTIPLYALPHA
- // Convert to associative (premultiplied) format if needed.
- finalColor.rgb *= finalColor.a;
- #endif
- #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
- gl_FragColor = finalColor;
- #include<pbrDebug>
- }
|