Skip to content

Commit

Permalink
Refactor specular occlusions shader chunks (#7400)
Browse files Browse the repository at this point in the history
* Refactor specular occlusions shader chunks

* lint

* one additional improvement

* final update

* lint imports

---------

Co-authored-by: Martin Valigursky <[email protected]>
  • Loading branch information
mvaligursky and Martin Valigursky authored Mar 4, 2025
1 parent 77e2718 commit bf80c95
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 112 deletions.
6 changes: 6 additions & 0 deletions src/scene/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,12 @@ export const SPECOCC_AO = 1;
*/
export const SPECOCC_GLOSSDEPENDENT = 2;

export const specularOcclusionNames = {
[SPECOCC_NONE]: 'NONE',
[SPECOCC_AO]: 'AO',
[SPECOCC_GLOSSDEPENDENT]: 'GLOSSDEPENDENT'
};

// 16 bits for shader defs
export const SHADERDEF_NOSHADOW = 1;
export const SHADERDEF_SKIN = 2;
Expand Down
6 changes: 0 additions & 6 deletions src/scene/shader-lib/chunks-wgsl/chunks-wgsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
// import aoDetailMapPS from './standard/frag/aoDetailMap.js';
// import aoDiffuseOccPS from './lit/frag/aoDiffuseOcc.js';
// import aoSpecOccPS from './lit/frag/aoSpecOcc.js';
// import aoSpecOccConstPS from './lit/frag/aoSpecOccConst.js';
// import aoSpecOccConstSimplePS from './lit/frag/aoSpecOccConstSimple.js';
// import aoSpecOccSimplePS from './lit/frag/aoSpecOccSimple.js';
// import basePS from './lit/frag/base.js';
// import baseNineSlicedPS from './lit/frag/baseNineSliced.js';
// import baseNineSlicedTiledPS from './lit/frag/baseNineSlicedTiled.js';
Expand Down Expand Up @@ -209,9 +206,6 @@ const shaderChunksWGSL = {
// aoDetailMapPS,
// aoDiffuseOccPS,
// aoSpecOccPS,
// aoSpecOccConstPS,
// aoSpecOccConstSimplePS,
// aoSpecOccSimplePS,
// basePS,
// baseNineSlicedPS,
// baseNineSlicedTiledPS,
Expand Down
10 changes: 5 additions & 5 deletions src/scene/shader-lib/chunks/chunk-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ const chunkVersions = {
ambientEnvPS: CHUNKAPI_1_62,
ambientSHPS: CHUNKAPI_1_62,
aoDiffuseOccPS: CHUNKAPI_1_62,
aoSpecOccPS: CHUNKAPI_1_62,
aoSpecOccConstPS: CHUNKAPI_1_62,
aoSpecOccConstSimplePS: CHUNKAPI_1_62,
aoSpecOccSimplePS: CHUNKAPI_1_62,
aoSpecOccPS: CHUNKAPI_2_6,
clusteredLightPS: CHUNKAPI_1_62,
clusteredLightShadowPS: CHUNKAPI_1_62,
combinePS: CHUNKAPI_1_62,
Expand Down Expand Up @@ -126,7 +123,10 @@ const removedChunks = {
cubeMapProjectBoxPS: CHUNKAPI_2_6,
cubeMapProjectNonePS: CHUNKAPI_2_6,
envMultiplyPS: CHUNKAPI_2_6,
envConstPS: CHUNKAPI_2_6
envConstPS: CHUNKAPI_2_6,
aoSpecOccConstPS: CHUNKAPI_2_6,
aoSpecOccConstSimplePS: CHUNKAPI_2_6,
aoSpecOccSimplePS: CHUNKAPI_2_6
};

// compare two "major.minor" semantic version strings and return true if a is a smaller version than b.
Expand Down
6 changes: 0 additions & 6 deletions src/scene/shader-lib/chunks/chunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import aoPS from './standard/frag/ao.js';
import aoDetailMapPS from './standard/frag/aoDetailMap.js';
import aoDiffuseOccPS from './lit/frag/aoDiffuseOcc.js';
import aoSpecOccPS from './lit/frag/aoSpecOcc.js';
import aoSpecOccConstPS from './lit/frag/aoSpecOccConst.js';
import aoSpecOccConstSimplePS from './lit/frag/aoSpecOccConstSimple.js';
import aoSpecOccSimplePS from './lit/frag/aoSpecOccSimple.js';
import basePS from './lit/frag/base.js';
import baseNineSlicedPS from './lit/frag/baseNineSliced.js';
import baseNineSlicedTiledPS from './lit/frag/baseNineSlicedTiled.js';
Expand Down Expand Up @@ -209,9 +206,6 @@ const shaderChunks = {
aoDetailMapPS,
aoDiffuseOccPS,
aoSpecOccPS,
aoSpecOccConstPS,
aoSpecOccConstSimplePS,
aoSpecOccSimplePS,
basePS,
baseNineSlicedPS,
baseNineSlicedTiledPS,
Expand Down
50 changes: 36 additions & 14 deletions src/scene/shader-lib/chunks/lit/frag/aoSpecOcc.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
export default /* glsl */`
uniform float material_occludeSpecularIntensity;
void occludeSpecular(float gloss, float ao, vec3 worldNormal, vec3 viewDir) {
// approximated specular occlusion from AO
float specPow = exp2(gloss * 11.0);
// http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx
float specOcc = saturate(pow(dot(worldNormal, viewDir) + ao, 0.01*specPow) - 1.0 + ao);
specOcc = mix(1.0, specOcc, material_occludeSpecularIntensity);
dSpecularLight *= specOcc;
dReflection *= specOcc;
#ifdef LIT_SHEEN
sSpecularLight *= specOcc;
sReflection *= specOcc;
#if LIT_OCCLUDE_SPECULAR != NONE
#ifdef LIT_OCCLUDE_SPECULAR_FLOAT
uniform float material_occludeSpecularIntensity;
#endif
#endif
void occludeSpecular(float gloss, float ao, vec3 worldNormal, vec3 viewDir) {
#if LIT_OCCLUDE_SPECULAR == AO
#ifdef LIT_OCCLUDE_SPECULAR_FLOAT
float specOcc = mix(1.0, ao, material_occludeSpecularIntensity);
#else
float specOcc = ao;
#endif
#endif
#if LIT_OCCLUDE_SPECULAR == GLOSSDEPENDENT
// approximated specular occlusion from AO
// http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx
float specPow = exp2(gloss * 11.0);
float specOcc = saturate(pow(dot(worldNormal, viewDir) + ao, 0.01*specPow) - 1.0 + ao);
#ifdef LIT_OCCLUDE_SPECULAR_FLOAT
specOcc = mix(1.0, specOcc, material_occludeSpecularIntensity);
#endif
#endif
#if LIT_OCCLUDE_SPECULAR != NONE
dSpecularLight *= specOcc;
dReflection *= specOcc;
#ifdef LIT_SHEEN
sSpecularLight *= specOcc;
sReflection *= specOcc;
#endif
#endif
}
`;
16 changes: 0 additions & 16 deletions src/scene/shader-lib/chunks/lit/frag/aoSpecOccConst.js

This file was deleted.

11 changes: 0 additions & 11 deletions src/scene/shader-lib/chunks/lit/frag/aoSpecOccConstSimple.js

This file was deleted.

14 changes: 0 additions & 14 deletions src/scene/shader-lib/chunks/lit/frag/aoSpecOccSimple.js

This file was deleted.

70 changes: 30 additions & 40 deletions src/scene/shader-lib/programs/lit-shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_OMNI, LIGHTTYPE_SPOT,
SHADER_DEPTH, SHADER_PICK,
SHADOW_PCF1_32F, SHADOW_PCF3_32F, SHADOW_PCF5_32F, SHADOW_VSM_16F, SHADOW_VSM_32F, SHADOW_PCSS_32F,
SPECOCC_AO, SPECOCC_GLOSSDEPENDENT,
SPRITE_RENDERMODE_SLICED, SPRITE_RENDERMODE_TILED, shadowTypeInfo, SHADER_PREPASS,
SHADOW_PCF1_16F, SHADOW_PCF5_16F, SHADOW_PCF3_16F,
lightTypeNames, lightShapeNames, spriteRenderModeNames, fresnelNames, blendNames,
cubemaProjectionNames
cubemaProjectionNames,
specularOcclusionNames
} from '../../constants.js';
import { shaderChunks } from '../chunks/chunks.js';
import { ChunkUtils } from '../chunk-utils.js';
Expand Down Expand Up @@ -519,10 +519,13 @@ class LitShader {
this.fDefineSet(options.alphaToCoverage, 'LIT_ALPHA_TO_COVERAGE');
this.fDefineSet(options.useMsdf, 'LIT_MSDF');
this.fDefineSet(options.ssao, 'LIT_SSAO');
this.fDefineSet(options.useAo, 'LIT_AO');
this.fDefineSet(options.occludeDirect, 'LIT_OCCLUDE_DIRECT');
this.fDefineSet(options.msdfTextAttribute, 'LIT_MSDF_TEXT_ATTRIBUTE');
this.fDefineSet(true, 'LIT_NONE_SLICE_MODE', spriteRenderModeNames[options.nineSlicedMode]);
this.fDefineSet(true, 'LIT_BLEND_TYPE', blendNames[options.blendType]);
this.fDefineSet(true, 'LIT_CUBEMAP_PROJECTION', cubemaProjectionNames[options.cubeMapProjection]);
this.fDefineSet(true, 'LIT_OCCLUDE_SPECULAR', specularOcclusionNames[options.occludeSpecular]);

// injection defines
this.fDefineSet(true, '{lightingUv}', this.lightingUv ?? ''); // example: vUV0_1
Expand Down Expand Up @@ -646,31 +649,12 @@ class LitShader {
`);
}

if (options.useAo) {
func.append(chunks.aoDiffuseOccPS);
switch (options.occludeSpecular) {
case SPECOCC_AO:
func.append(`
#ifdef LIT_OCCLUDE_SPECULAR_FLOAT
#include "aoSpecOccSimplePS"
#else
#include "aoSpecOccConstSimplePS"
#endif
`);
break;
case SPECOCC_GLOSSDEPENDENT:
func.append(`
#ifdef LIT_OCCLUDE_SPECULAR_FLOAT
#include "aoSpecOccPS"
#else
#include "aoSpecOccConstPS"
#endif
`);
break;
default:
break;
}
}
func.append(`
#ifdef LIT_AO
#include "aoDiffuseOccPS"
#include "aoSpecOccPS"
#endif
`);

if (options.reflectionSource === 'envAtlasHQ') {
func.append(chunks.envAtlasPS);
Expand Down Expand Up @@ -920,11 +904,14 @@ class LitShader {
backend.append(' dDiffuseLight *= material_ambient;');
}

if (options.useAo && !options.occludeDirect) {
backend.append(' occludeDiffuse(litArgs_ao);');
}

backend.append(`
#ifdef LIT_AO
#ifndef LIT_OCCLUDE_DIRECT
occludeDiffuse(litArgs_ao);
#endif
#endif
#ifdef LIT_LIGHTMAP
addLightMap(
litArgs_lightmap,
Expand Down Expand Up @@ -1345,16 +1332,19 @@ class LitShader {
`);
}

if (options.useAo) {
if (options.occludeDirect) {
backend.append(' occludeDiffuse(litArgs_ao);');
}
if (options.occludeSpecular === SPECOCC_AO || options.occludeSpecular === SPECOCC_GLOSSDEPENDENT) {
backend.append(' occludeSpecular(litArgs_gloss, litArgs_ao, litArgs_worldNormal, dViewDirW);');
}
}

backend.append(`
// apply ambient occlusion
#ifdef LIT_AO
#ifdef LIT_OCCLUDE_DIRECT
occludeDiffuse(litArgs_ao);
#endif
#if LIT_OCCLUDE_SPECULAR != NONE
occludeSpecular(litArgs_gloss, litArgs_ao, litArgs_worldNormal, dViewDirW);
#endif
#endif
#ifdef LIT_SPECULARITY_FACTOR
dSpecularLight *= litArgs_specularityFactor;
#endif
Expand Down

0 comments on commit bf80c95

Please sign in to comment.