Skip to content

Commit 125c398

Browse files
authored
Merge pull request #6430 from AnalyticalGraphicsInc/pbr-lighting
Update PBR lighting
2 parents 2deae56 + b86b871 commit 125c398

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Change Log
3030
* Fixed bugs in `TimeIntervalCollection.removeInterval`. [#6418](https://github.com/AnalyticalGraphicsInc/cesium/pull/6418).
3131
* Fixed glTF support to handle meshes with and without tangent vectors, and with/without morph targets, sharing one material. [#6421](https://github.com/AnalyticalGraphicsInc/cesium/pull/6421)
3232
* Fixed glTF support to handle skinned meshes when no skin is supplied. [#6061](https://github.com/AnalyticalGraphicsInc/cesium/issues/6061)
33+
* Updated glTF 2.0 PBR shader to have brighter lighting. [#6430](https://github.com/AnalyticalGraphicsInc/cesium/pull/6430)
3334
* Allow loadWithXhr to work with string URLs in a web worker.
3435
* Updated to Draco 1.3.0 and implemented faster loading of Draco compressed glTF assets in browsers that support Web Assembly. [#6420](https://github.com/AnalyticalGraphicsInc/cesium/pull/6420)
3536
* `GroundPrimitive`s and `ClassificationPrimitive`s will become ready when `show` is `false`. [#6428](https://github.com/AnalyticalGraphicsInc/cesium/pull/6428)

Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js

+42-18
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,9 @@ define([
389389
// Fragment shader lighting
390390
fragmentShader += 'const float M_PI = 3.141592653589793;\n';
391391

392-
fragmentShader += 'vec3 lambertianDiffuse(vec3 baseColor) \n' +
392+
fragmentShader += 'vec3 lambertianDiffuse(vec3 diffuseColor) \n' +
393393
'{\n' +
394-
' return baseColor / M_PI;\n' +
394+
' return diffuseColor / M_PI;\n' +
395395
'}\n\n';
396396

397397
fragmentShader += 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' +
@@ -422,6 +422,22 @@ define([
422422
' return roughnessSquared / (M_PI * f * f);\n' +
423423
'}\n\n';
424424

425+
fragmentShader += 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' +
426+
'{\n' +
427+
' return pow(srgbIn, vec3(2.2));\n' +
428+
'}\n\n';
429+
430+
fragmentShader += 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' +
431+
'{\n' +
432+
' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' +
433+
' return vec4(linearOut, srgbIn.a);\n' +
434+
'}\n\n';
435+
436+
fragmentShader += 'vec3 LINEARtoSRGB(vec3 linearIn) \n' +
437+
'{\n' +
438+
' return pow(linearIn, vec3(1.0/2.2));\n' +
439+
'}\n\n';
440+
425441
fragmentShader += 'void main(void) \n{\n';
426442

427443
// Add normal mapping to fragment shader
@@ -470,7 +486,7 @@ define([
470486

471487
// Add base color to fragment shader
472488
if (defined(parameterValues.baseColorTexture)) {
473-
fragmentShader += ' vec4 baseColorWithAlpha = texture2D(u_baseColorTexture, ' + v_texcoord + ');\n';
489+
fragmentShader += ' vec4 baseColorWithAlpha = SRGBtoLINEAR4(texture2D(u_baseColorTexture, ' + v_texcoord + '));\n';
474490
if (defined(parameterValues.baseColorFactor)) {
475491
fragmentShader += ' baseColorWithAlpha *= u_baseColorFactor;\n';
476492
}
@@ -513,10 +529,12 @@ define([
513529
fragmentShader += ' vec3 v = -normalize(v_positionEC);\n';
514530

515531
// Generate fragment shader's lighting block
516-
fragmentShader += ' vec3 lightColor = vec3(1.0, 1.0, 1.0);\n';
517532
if (optimizeForCesium) {
533+
// The Sun is brighter than your average light source, and has a yellowish tint balanced by the Earth's ambient blue.
534+
fragmentShader += ' vec3 lightColor = vec3(1.5, 1.4, 1.2);\n';
518535
fragmentShader += ' vec3 l = normalize(czm_sunDirectionEC);\n';
519536
} else {
537+
fragmentShader += ' vec3 lightColor = vec3(1.0, 1.0, 1.0);\n';
520538
fragmentShader += ' vec3 l = vec3(0.0, 0.0, 1.0);\n';
521539
}
522540
fragmentShader += ' vec3 h = normalize(v + l);\n';
@@ -525,7 +543,7 @@ define([
525543
// Figure out if the reflection vector hits the ellipsoid
526544
fragmentShader += ' czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\n';
527545
fragmentShader += ' float vertexRadius = length(v_positionWC);\n';
528-
fragmentShader += ' float horizonDotNadir = 1.0 - ellipsoid.radii.x / vertexRadius;\n';
546+
fragmentShader += ' float horizonDotNadir = 1.0 - min(1.0, ellipsoid.radii.x / vertexRadius);\n';
529547
fragmentShader += ' float reflectionDotNadir = dot(r, normalize(v_positionWC));\n';
530548
// Flipping the X vector is a cheap way to get the inverse of czm_temeToPseudoFixed, since that's a rotation about Z.
531549
fragmentShader += ' r.x = -r.x;\n';
@@ -542,7 +560,7 @@ define([
542560

543561
fragmentShader += ' vec3 f0 = vec3(0.04);\n';
544562
fragmentShader += ' float alpha = roughness * roughness;\n';
545-
fragmentShader += ' vec3 diffuseColor = baseColor * (1.0 - metalness);\n';
563+
fragmentShader += ' vec3 diffuseColor = baseColor * (1.0 - metalness) * (1.0 - f0);\n';
546564
fragmentShader += ' vec3 specularColor = mix(f0, baseColor, metalness);\n';
547565
fragmentShader += ' float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n';
548566
fragmentShader += ' vec3 r90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));\n';
@@ -552,44 +570,49 @@ define([
552570
fragmentShader += ' float G = smithVisibilityGGX(alpha, NdotL, NdotV);\n';
553571
fragmentShader += ' float D = GGX(alpha, NdotH);\n';
554572

555-
fragmentShader += ' vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(baseColor);\n';
573+
fragmentShader += ' vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(diffuseColor);\n';
556574
fragmentShader += ' vec3 specularContribution = F * G * D / (4.0 * NdotL * NdotV);\n';
557575
fragmentShader += ' vec3 color = NdotL * lightColor * (diffuseContribution + specularContribution);\n';
558576

559577
if (optimizeForCesium) {
560-
fragmentShader += ' float inverseRoughness = 1.0 - roughness;\n';
578+
fragmentShader += ' float inverseRoughness = 1.04 - roughness;\n';
561579
fragmentShader += ' inverseRoughness *= inverseRoughness;\n';
562580
fragmentShader += ' vec3 sceneSkyBox = textureCube(czm_environmentMap, r).rgb * inverseRoughness;\n';
563581

564582
fragmentShader += ' float atmosphereHeight = 0.05;\n';
565583
fragmentShader += ' float blendRegionSize = 0.1 * ((1.0 - inverseRoughness) * 8.0 + 1.1 - horizonDotNadir);\n';
566-
fragmentShader += ' float farAboveHorizon = clamp(horizonDotNadir - blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n';
584+
fragmentShader += ' float blendRegionOffset = roughness * -1.0;\n';
585+
fragmentShader += ' float farAboveHorizon = clamp(horizonDotNadir - blendRegionSize * 0.5 + blendRegionOffset, 1.0e-10 - blendRegionSize, 0.99999);\n';
567586
fragmentShader += ' float aroundHorizon = clamp(horizonDotNadir + blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n';
568587
fragmentShader += ' float farBelowHorizon = clamp(horizonDotNadir + blendRegionSize * 1.5, 1.0e-10 - blendRegionSize, 0.99999);\n';
569588
fragmentShader += ' float smoothstepHeight = smoothstep(0.0, atmosphereHeight, horizonDotNadir);\n';
570-
fragmentShader += ' float lightScale = smoothstepHeight * 1.5 + 1.0;\n';
571589

572-
fragmentShader += ' vec3 diffuseIrradiance = mix(vec3(0.5), vec3(0.05), smoothstepHeight);\n';
573-
fragmentShader += ' vec3 belowHorizonColor = mix(vec3(0.1, 0.2, 0.4), vec3(0.2, 0.5, 0.7), smoothstepHeight);\n';
590+
fragmentShader += ' vec3 belowHorizonColor = mix(vec3(0.1, 0.15, 0.25), vec3(0.4, 0.7, 0.9), smoothstepHeight);\n';
574591
fragmentShader += ' vec3 nadirColor = belowHorizonColor * 0.5;\n';
575-
fragmentShader += ' vec3 aboveHorizonColor = vec3(0.8, 0.9, 0.95);\n';
576-
fragmentShader += ' vec3 blueSkyColor = mix(vec3(0.09, 0.13, 0.24), aboveHorizonColor, reflectionDotNadir * inverseRoughness * 0.5 + 0.5);\n';
592+
fragmentShader += ' vec3 aboveHorizonColor = mix(vec3(0.9, 1.0, 1.2), belowHorizonColor, roughness * 0.5);\n';
593+
fragmentShader += ' vec3 blueSkyColor = mix(vec3(0.18, 0.26, 0.48), aboveHorizonColor, reflectionDotNadir * inverseRoughness * 0.5 + 0.75);\n';
577594
fragmentShader += ' vec3 zenithColor = mix(blueSkyColor, sceneSkyBox, smoothstepHeight);\n';
578595

579-
fragmentShader += ' vec3 specularIrradiance = mix(zenithColor, aboveHorizonColor, smoothstep(farAboveHorizon, aroundHorizon, reflectionDotNadir) * inverseRoughness);\n';
596+
fragmentShader += ' vec3 blueSkyDiffuseColor = vec3(0.7, 0.85, 0.9);\n';
597+
fragmentShader += ' float diffuseIrradianceFromEarth = (1.0 - horizonDotNadir) * (reflectionDotNadir * 0.25 + 0.75) * smoothstepHeight;\n';
598+
fragmentShader += ' float diffuseIrradianceFromSky = (1.0 - smoothstepHeight) * (1.0 - (reflectionDotNadir * 0.25 + 0.25));\n';
599+
fragmentShader += ' vec3 diffuseIrradiance = blueSkyDiffuseColor * clamp(diffuseIrradianceFromEarth + diffuseIrradianceFromSky, 0.0, 1.0);\n';
600+
601+
fragmentShader += ' float notDistantRough = (1.0 - horizonDotNadir * roughness * 0.8);\n';
602+
fragmentShader += ' vec3 specularIrradiance = mix(zenithColor, aboveHorizonColor, smoothstep(farAboveHorizon, aroundHorizon, reflectionDotNadir) * notDistantRough);\n';
580603
fragmentShader += ' specularIrradiance = mix(specularIrradiance, belowHorizonColor, smoothstep(aroundHorizon, farBelowHorizon, reflectionDotNadir) * inverseRoughness);\n';
581604
fragmentShader += ' specularIrradiance = mix(specularIrradiance, nadirColor, smoothstep(farBelowHorizon, 1.0, reflectionDotNadir) * inverseRoughness);\n';
582605

583606
fragmentShader += ' vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n';
584-
fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * (specularColor * brdfLut.x + brdfLut.y));\n';
585-
fragmentShader += ' color = color * lightScale + IBLColor;\n';
607+
fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * SRGBtoLINEAR3(specularColor * brdfLut.x + brdfLut.y));\n';
608+
fragmentShader += ' color += IBLColor;\n';
586609
}
587610

588611
if (defined(parameterValues.occlusionTexture)) {
589612
fragmentShader += ' color *= texture2D(u_occlusionTexture, ' + v_texcoord + ').r;\n';
590613
}
591614
if (defined(parameterValues.emissiveTexture)) {
592-
fragmentShader += ' vec3 emissive = texture2D(u_emissiveTexture, ' + v_texcoord + ').rgb;\n';
615+
fragmentShader += ' vec3 emissive = SRGBtoLINEAR3(texture2D(u_emissiveTexture, ' + v_texcoord + ').rgb);\n';
593616
if (defined(parameterValues.emissiveFactor)) {
594617
fragmentShader += ' emissive *= u_emissiveFactor;\n';
595618
}
@@ -602,6 +625,7 @@ define([
602625
}
603626

604627
// Final color
628+
fragmentShader += ' color = LINEARtoSRGB(color);\n';
605629
var alphaMode = material.alphaMode;
606630
if (defined(alphaMode)) {
607631
if (alphaMode === 'MASK') {

0 commit comments

Comments
 (0)