Skip to content

Commit

Permalink
AO Detail Map (#5270)
Browse files Browse the repository at this point in the history
* Add AO detail map properties to StandardMaterial

* Implement shader code for AO detail map

* Add validation of AO detail map properties to StandardMaterial tests

* Clarify default value in documentation for aoDetailMapChannel

* Remove aoDetailMapPS entry from chunkVersions table since it is brand new
  • Loading branch information
Mistale committed May 17, 2023
1 parent d608c67 commit f4523fc
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 8 deletions.
4 changes: 3 additions & 1 deletion src/scene/materials/standard-material-options-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,11 @@ class StandardMaterialOptionsBuilder {
options.specularEncoding = stdMat.specularEncoding || 'linear';
options.sheenEncoding = stdMat.sheenEncoding || 'linear';
options.aoMapUv = stdMat.aoUvSet; // backwards compatibility
options.aoDetail = !!stdMat.aoMap;
options.diffuseDetail = !!stdMat.diffuseMap;
options.normalDetail = !!stdMat.normalMap;
options.diffuseDetailMode = stdMat.diffuseDetailMode;
options.aoDetailMode = stdMat.aoDetailMode;
options.clearCoatTint = (stdMat.clearCoat !== 1.0) ? 1 : 0;
options.clearCoatGloss = !!stdMat.clearCoatGloss;
options.clearCoatGlossTint = (stdMat.clearCoatGloss !== 1.0) ? 1 : 0;
Expand All @@ -258,7 +260,7 @@ class StandardMaterialOptionsBuilder {
options.litOptions.useDiffuseMap = !!stdMat.diffuseMap;
options.litOptions.useAoMap = !!stdMat.aoMap;

options.litOptions.detailModes = !!options.diffuseDetail;
options.litOptions.detailModes = !!options.diffuseDetail || !!options.aoDetail;
options.litOptions.shadingModel = stdMat.shadingModel;
options.litOptions.ambientSH = !!stdMat.ambientSH;
options.litOptions.fastTbn = stdMat.fastTbn;
Expand Down
2 changes: 2 additions & 0 deletions src/scene/materials/standard-material-parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const standardMaterialParameterTypes = {
ambient: 'rgb',
ambientTint: 'boolean',
..._textureParameter('ao'),
..._textureParameter('aoDetail', true, false),
aoDetailMode: 'string',

diffuse: 'rgb',
diffuseTint: 'boolean',
Expand Down
39 changes: 33 additions & 6 deletions src/scene/materials/standard-material.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,18 +447,43 @@ let _params = new Set();
* @property {string} lightVertexColorChannel Vertex color channels to use for baked lighting. Can
* be "r", "g", "b", "a", "rgb" or any swizzled combination.
* @property {boolean} ambientTint Enables scene ambient multiplication by material ambient color.
* @property {import('../../platform/graphics/texture.js').Texture|null} aoMap Baked ambient
* @property {import('../../platform/graphics/texture.js').Texture|null} aoMap The main (primary) baked ambient
* occlusion (AO) map (default is null). Modulates ambient color.
* @property {number} aoMapUv AO map UV channel
* @property {string} aoMapChannel Color channel of the AO map to use. Can be "r", "g", "b" or "a".
* @property {Vec2} aoMapTiling Controls the 2D tiling of the AO map.
* @property {Vec2} aoMapOffset Controls the 2D offset of the AO map. Each component is between 0
* @property {number} aoMapUv Main (primary) AO map UV channel
* @property {string} aoMapChannel Color channel of the main (primary) AO map to use. Can be "r", "g", "b" or "a".
* @property {Vec2} aoMapTiling Controls the 2D tiling of the main (primary) AO map.
* @property {Vec2} aoMapOffset Controls the 2D offset of the main (primary) AO map. Each component is between 0
* and 1.
* @property {number} aoMapRotation Controls the 2D rotation (in degrees) of the AO map.
* @property {number} aoMapRotation Controls the 2D rotation (in degrees) of the main (primary) AO map.
* @property {boolean} aoVertexColor Use mesh vertex colors for AO. If aoMap is set, it'll be
* multiplied by vertex colors.
* @property {string} aoVertexColorChannel Vertex color channels to use for AO. Can be "r", "g",
* "b" or "a".
* @property {import('../../platform/graphics/texture.js').Texture|null} aoDetailMap The
* detail (secondary) baked ambient occlusion (AO) map of the material (default is null). Will only be used if main
* (primary) ao map is non-null.
* @property {number} aoDetailMapUv Detail (secondary) AO map UV channel.
* @property {Vec2} aoDetailMapTiling Controls the 2D tiling of the detail (secondary) AO
* map.
* @property {Vec2} aoDetailMapOffset Controls the 2D offset of the detail (secondary) AO
* map. Each component is between 0 and 1.
* @property {number} aoDetailMapRotation Controls the 2D rotation (in degrees) of the detail
* (secondary) AO map.
* @property {string} aoDetailMapChannel Color channels of the detail (secondary) AO map
* to use. Can be "r", "g", "b" or "a" (default is "g").
* @property {string} aoDetailMode Determines how the main (primary) and detail (secondary)
* AO maps are blended together. Can be:
*
* - {@link DETAILMODE_MUL}: Multiply together the primary and secondary colors.
* - {@link DETAILMODE_ADD}: Add together the primary and secondary colors.
* - {@link DETAILMODE_SCREEN}: Softer version of {@link DETAILMODE_ADD}.
* - {@link DETAILMODE_OVERLAY}: Multiplies or screens the colors, depending on the primary color.
* - {@link DETAILMODE_MIN}: Select whichever of the primary and secondary colors is darker,
* component-wise.
* - {@link DETAILMODE_MAX}: Select whichever of the primary and secondary colors is lighter,
* component-wise.
*
* Defaults to {@link DETAILMODE_MUL}.
* @property {number} occludeSpecular Uses ambient occlusion to darken specular/reflection. It's a
* hack, because real specular occlusion is view-dependent. However, it can be better than nothing.
*
Expand Down Expand Up @@ -1214,6 +1239,7 @@ function _defineMaterialProps() {
_defineTex2D('msdf', '');
_defineTex2D('diffuseDetail', 'rgb', false);
_defineTex2D('normalDetail', '');
_defineTex2D('aoDetail', 'g', false);
_defineTex2D('clearCoat', 'g');
_defineTex2D('clearCoatGloss', 'g');
_defineTex2D('clearCoatNormal', '');
Expand All @@ -1223,6 +1249,7 @@ function _defineMaterialProps() {
_defineTex2D('iridescenceThickness', 'g');

_defineFlag('diffuseDetailMode', DETAILMODE_MUL);
_defineFlag('aoDetailMode', DETAILMODE_MUL);

_defineObject('cubeMap');
_defineObject('sphereMap');
Expand Down
2 changes: 2 additions & 0 deletions src/scene/shader-lib/chunks/chunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ambientConstantPS from './lit/frag/ambientConstant.js';
import ambientEnvPS from './lit/frag/ambientEnv.js';
import ambientSHPS from './lit/frag/ambientSH.js';
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';
Expand Down Expand Up @@ -209,6 +210,7 @@ const shaderChunks = {
ambientEnvPS,
ambientSHPS,
aoPS,
aoDetailMapPS,
aoDiffuseOccPS,
aoSpecOccPS,
aoSpecOccConstPS,
Expand Down
3 changes: 2 additions & 1 deletion src/scene/shader-lib/chunks/standard/frag/ao.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ void getAO() {
dAo = 1.0;
#ifdef MAPTEXTURE
dAo *= texture2DBias($SAMPLER, $UV, textureBias).$CH;
float aoBase = texture2DBias($SAMPLER, $UV, textureBias).$CH;
dAo *= addAoDetail(aoBase);
#endif
#ifdef MAPVERTEX
Expand Down
10 changes: 10 additions & 0 deletions src/scene/shader-lib/chunks/standard/frag/aoDetailMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default /* glsl */`
float addAoDetail(float ao) {
#ifdef MAPTEXTURE
float aoDetail = texture2DBias($SAMPLER, $UV, textureBias).$CH;
return detailMode_$DETAILMODE(vec3(ao), vec3(aoDetail)).r;
#else
return ao;
#endif
}
`;
3 changes: 3 additions & 0 deletions src/scene/shader-lib/programs/standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,9 @@ const standard = {
}

// ao
if (options.aoDetail) {
code.append(this._addMap("aoDetail", "aoDetailMapPS", options, litShader.chunks, textureMapping));
}
if (options.aoMap || options.aoVertexColor) {
decl.append("float dAo;");
code.append(this._addMap("ao", "aoPS", options, litShader.chunks, textureMapping));
Expand Down
11 changes: 11 additions & 0 deletions test/scene/materials/standard-material.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ describe('StandardMaterial', function () {
expect(material.ambientTint).to.equal(false);
expect(material.anisotropy).to.equal(0);

expect(material.aoDetailMap).to.be.null;
expect(material.aoDetailMapChannel).to.equal('g');
expect(material.aoDetailMapOffset).to.be.an.instanceof(Vec2);
expect(material.aoDetailMapOffset.x).to.equal(0);
expect(material.aoDetailMapOffset.y).to.equal(0);
expect(material.aoDetailMapRotation).to.equal(0);
expect(material.aoDetailMapTiling).to.be.an.instanceof(Vec2);
expect(material.aoDetailMapTiling.x).to.equal(1);
expect(material.aoDetailMapTiling.y).to.equal(1);
expect(material.aoDetailMapUv).to.equal(0);
expect(material.aoDetailMode).to.equal(DETAILMODE_MUL);
expect(material.aoMap).to.be.null;
expect(material.aoMapChannel).to.equal('g');
expect(material.aoMapOffset).to.be.an.instanceof(Vec2);
Expand Down
7 changes: 7 additions & 0 deletions types-fixup.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,13 @@ const standardMaterialProps = [
['aoMapRotation', 'number'],
['aoMapTiling', 'Vec2'],
['aoMapUv', 'number'],
['aoDetailMap', 'Texture|null'],
['aoDetailMapChannel', 'string'],
['aoDetailMapOffset', 'Vec2'],
['aoDetailMapRotation', 'number'],
['aoDetailMapTiling', 'Vec2'],
['aoDetailMapUv', 'number'],
['aoDetailMode', 'string'],
['aoVertexColor', 'boolean'],
['aoVertexColorChannel', 'string'],
['bumpiness', 'number'],
Expand Down

0 comments on commit f4523fc

Please sign in to comment.