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

Add PBR Next properties API #4330

Merged
merged 4 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions packages/model-viewer/src/features/scene-graph/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,35 @@ export declare interface Material {
readonly clearcoatRoughnessTexture: TextureInfo|null;
readonly clearcoatNormalTexture: TextureInfo|null;
readonly clearcoatNormalScale: number;
readonly ior: number;
readonly sheenColorFactor: Readonly<RGB>;
readonly sheenColorTexture: TextureInfo|null;
readonly sheenRoughnessFactor: number;
readonly sheenRoughnessTexture: TextureInfo|null;
readonly transmissionFactor: number;
readonly transmissionTexture: TextureInfo|null;
readonly thicknessFactor: number;
readonly thicknessTexture: TextureInfo|null;
readonly attenuationDistance: number;
readonly attenuationColor: Readonly<RGB>;
readonly specularFactor: number;
readonly specularTexture: TextureInfo|null;
readonly specularColorFactor: Readonly<RGB>;
readonly specularColorTexture: TextureInfo|null;

setEmissiveStrength(emissiveStrength: number): void;
setClearcoatFactor(clearcoatFactor: number): void;
setClearcoatRoughnessFactor(clearcoatRoughnessFactor: number): void;
setClearcoatNormalScale(clearcoatNormalScale: number): void;
setIor(ior: number): void;
setSheenColorFactor(rgb: RGB|string): void;
setSheenRoughnessFactor(roughness: number): void;
setTransmissionFactor(transmission: number): void;
setThicknessFactor(thickness: number): void;
setAttenuationDistance(attenuationDistance: number): void;
setAttenuationColor(rgb: RGB|string): void;
setSpecularFactor(specularFactor: number): void;
setSpecularColorFactor(rgb: RGB|string): void;

/**
* The PBRMetallicRoughness configuration of the material.
Expand Down
269 changes: 217 additions & 52 deletions packages/model-viewer/src/features/scene-graph/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,7 @@ const $isActive = Symbol('isActive');
export const $variantSet = Symbol('variantSet');
const $modelVariants = Symbol('modelVariants');
const $name = Symbol('name');

/**
* PBR Next properties.
*/
const $clearcoatTexture = Symbol('clearcoatTexture');
const $clearcoatRoughnessTexture = Symbol('clearcoatRoughnessTexture');
const $clearcoatNormalTexture = Symbol('clearcoatNormalTexture');
const $pbrTextures = Symbol('pbrTextures');

/**
* Material facade implementation for Three.js materials
Expand All @@ -65,13 +59,7 @@ export class Material extends ThreeDOMElement implements MaterialInterface {
private[$variantSet] = new Set<number>();
private[$name]?: string;
readonly[$modelVariants]: Map<string, VariantData>;

/**
* PBR Next properties.
*/
private[$clearcoatTexture]!: TextureInfo;
private[$clearcoatRoughnessTexture]!: TextureInfo;
private[$clearcoatNormalTexture]!: TextureInfo;
private[$pbrTextures]!: Map<TextureUsage, TextureInfo>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can skip the ! by creating it right here, see $variantSet above.


get[$backingThreeMaterial](): MeshPhysicalMaterial {
return (this[$correlatedObjects] as Set<MeshPhysicalMaterial>)
Expand Down Expand Up @@ -134,26 +122,26 @@ export class Material extends ThreeDOMElement implements MaterialInterface {
correlatedMaterials,
);

this[$clearcoatTexture] = new TextureInfo(
onUpdate,
TextureUsage.Clearcoat,
null,
correlatedMaterials,
);

this[$clearcoatRoughnessTexture] = new TextureInfo(
onUpdate,
TextureUsage.ClearcoatRoughness,
null,
correlatedMaterials,
);

this[$clearcoatNormalTexture] = new TextureInfo(
onUpdate,
TextureUsage.ClearcoatNormal,
null,
correlatedMaterials,
);
const textureInfoFromUsage = (usage: TextureUsage) => {
this[$pbrTextures].set(
usage,
new TextureInfo(
onUpdate,
usage,
null,
correlatedMaterials,
));
};

textureInfoFromUsage(TextureUsage.Clearcoat);
textureInfoFromUsage(TextureUsage.ClearcoatRoughness);
textureInfoFromUsage(TextureUsage.ClearcoatNormal);
textureInfoFromUsage(TextureUsage.SheenColor);
textureInfoFromUsage(TextureUsage.SheenRoughness);
textureInfoFromUsage(TextureUsage.Transmission);
textureInfoFromUsage(TextureUsage.Thickness);
textureInfoFromUsage(TextureUsage.Specular);
textureInfoFromUsage(TextureUsage.SpecularColor);
Copy link
Collaborator

Choose a reason for hiding this comment

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

💯
nit: maybe createTextureInfo? FromUsage is already clear from the input type.

}

async[$getLoadedMaterial](): Promise<MeshPhysicalMaterial> {
Expand All @@ -173,6 +161,16 @@ export class Material extends ThreeDOMElement implements MaterialInterface {
return this[$correlatedObjects]!.values().next().value;
}

private colorFromRgb(rgb: RGB|string): Color {
const color = new Color();
if (rgb instanceof Array) {
color.fromArray(rgb);
} else {
color.set(rgb as ColorRepresentation);
}
return color;
}

[$ensureMaterialIsLoaded]() {
if (this[$lazyLoadGLTFInfo] == null) {
return;
Expand Down Expand Up @@ -250,12 +248,7 @@ export class Material extends ThreeDOMElement implements MaterialInterface {

setEmissiveFactor(rgb: RGB|string) {
this[$ensureMaterialIsLoaded]();
const color = new Color();
if (rgb instanceof Array) {
color.fromArray(rgb);
} else {
color.set(rgb as ColorRepresentation);
}
const color = this.colorFromRgb(rgb);
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.emissive.set(color);
Expand Down Expand Up @@ -356,11 +349,23 @@ export class Material extends ThreeDOMElement implements MaterialInterface {
/**
* PBR Next properties.
*/

// KHR_materials_emissive_strength
get emissiveStrength(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].emissiveIntensity;
}

setEmissiveStrength(emissiveStrength: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.emissiveIntensity = emissiveStrength;
}
this[$onUpdate]();
}

// KHR_materials_clearcoat
get clearcoatFactor(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].clearcoat;
Expand All @@ -373,33 +378,24 @@ export class Material extends ThreeDOMElement implements MaterialInterface {

get clearcoatTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$clearcoatTexture];
return this[$pbrTextures].get(TextureUsage.Clearcoat)!;
}

get clearcoatRoughnessTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$clearcoatRoughnessTexture];
return this[$pbrTextures].get(TextureUsage.ClearcoatRoughness)!;
}

get clearcoatNormalTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$clearcoatNormalTexture];
return this[$pbrTextures].get(TextureUsage.ClearcoatNormal)!;
}

get clearcoatNormalScale(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].clearcoatNormalScale.x;
}

setEmissiveStrength(emissiveStrength: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.emissiveIntensity = emissiveStrength;
}
this[$onUpdate]();
}

setClearcoatFactor(clearcoatFactor: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Expand Down Expand Up @@ -427,4 +423,173 @@ export class Material extends ThreeDOMElement implements MaterialInterface {
}
this[$onUpdate]();
}

// KHR_materials_ior
get ior(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].ior;
}

setIor(ior: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.ior = ior;
}
this[$onUpdate]();
}

// KHR_materials_sheen
get sheenColorFactor(): RGB {
this[$ensureMaterialIsLoaded]();
return (this[$backingThreeMaterial].sheenColor.toArray() as RGB);
}
get sheenColorTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$pbrTextures].get(TextureUsage.SheenColor)!;
}

get sheenRoughnessFactor(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].sheenRoughness;
}

get sheenRoughnessTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$pbrTextures].get(TextureUsage.SheenRoughness)!;
}

setSheenColorFactor(rgb: RGB|string) {
this[$ensureMaterialIsLoaded]();
const color = this.colorFromRgb(rgb);
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.sheenColor.set(color);
// Three.js GLTFExporter checks for internal sheen value.
material.sheen = 1;
}
this[$onUpdate]();
}

setSheenRoughnessFactor(roughness: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.sheenRoughness = roughness;
// Three.js GLTFExporter checks for internal sheen value.
material.sheen = 1;
}
this[$onUpdate]();
}

// KHR_materials_transmission
get transmissionFactor(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].transmission;
}

get transmissionTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$pbrTextures].get(TextureUsage.Transmission)!;
}

setTransmissionFactor(transmission: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.transmission = transmission;
}
this[$onUpdate]();
}

// KHR_materials_volume
get thicknessFactor(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].thickness;
}

get thicknessTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$pbrTextures].get(TextureUsage.Thickness)!;
}

get attenuationDistance(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].attenuationDistance;
}

get attenuationColor(): RGB {
this[$ensureMaterialIsLoaded]();
return (this[$backingThreeMaterial].attenuationColor.toArray() as RGB);
}

setThicknessFactor(thickness: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.thickness = thickness;
}
this[$onUpdate]();
}

setAttenuationDistance(attenuationDistance: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.attenuationDistance = attenuationDistance;
}
this[$onUpdate]();
}

setAttenuationColor(rgb: RGB|string) {
this[$ensureMaterialIsLoaded]();
const color = this.colorFromRgb(rgb);
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.attenuationColor.set(color);
}
this[$onUpdate]();
}

// KHR_materials_specular
get specularFactor(): number {
this[$ensureMaterialIsLoaded]();
return this[$backingThreeMaterial].specularIntensity;
}

get specularTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$pbrTextures].get(TextureUsage.Specular)!;
}

get specularColorFactor(): RGB {
this[$ensureMaterialIsLoaded]();
return (this[$backingThreeMaterial].specularColor.toArray() as RGB);
}

get specularColorTexture(): TextureInfo {
this[$ensureMaterialIsLoaded]();
return this[$pbrTextures].get(TextureUsage.SheenColor)!;
}

setSpecularFactor(specularFactor: number) {
this[$ensureMaterialIsLoaded]();
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.specularIntensity = specularFactor;
}
this[$onUpdate]();
}

setSpecularColorFactor(rgb: RGB|string) {
this[$ensureMaterialIsLoaded]();
const color = this.colorFromRgb(rgb);
for (const material of this[$correlatedObjects] as
Set<MeshPhysicalMaterial>) {
material.specularColor.set(color);
}
this[$onUpdate]();
}

// KHR_materials_iridescence
}
Loading
Loading