Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AO Detail Map #5270

Merged
merged 7 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should mention the default value is 'g'

Copy link
Contributor

@Maksims Maksims May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it common to use default value 'g' instead or 'r' in other similar properties?
We should avoid making assumptions of how artist should pack their channels, even as a default option while it is configurable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't seem to have that mentioned elsewhere in the docs, but we do set 'g' as the default channel in the material. It should be down to how textures are packed, surely, unless there is some bit depth favor for green channels (which would make sense perceptually) for certain file formats?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a clarification about the default value. I can't figure out why 'g' is the default for ao either, but I figured I'd just follow the same standard as aoMapChannel.
When packing ORM-textures for glTF, "r" is used for occlusion. But it may be related to inherent precision issues as @GSterbrant mentions.

* @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
1 change: 1 addition & 0 deletions src/scene/shader-lib/chunks/chunk-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { shaderChunks } from './chunks.js';
const chunkVersions = {
// frontend
aoPS: CHUNKAPI_1_57,
aoDetailMapPS: CHUNKAPI_1_62,
mvaligursky marked this conversation as resolved.
Show resolved Hide resolved
clearCoatPS: CHUNKAPI_1_57,
clearCoatGlossPS: CHUNKAPI_1_60,
clearCoatNormalPS: CHUNKAPI_1_57,
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 @@ -211,6 +212,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;
mvaligursky marked this conversation as resolved.
Show resolved Hide resolved
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