diff --git a/docs/api/en/materials/MeshPhysicalMaterial.html b/docs/api/en/materials/MeshPhysicalMaterial.html
index e209528eb04051..625b6a41b580c1 100644
--- a/docs/api/en/materials/MeshPhysicalMaterial.html
+++ b/docs/api/en/materials/MeshPhysicalMaterial.html
@@ -133,10 +133,9 @@
[property:Float reflectivity]
This models the reflectivity of non-metallic materials. It has no effect when [page:MeshStandardMaterial.metalness metalness] is *1.0*
- [property:Color sheen]
+ [property:Color sheenTint]
- If a color is assigned to this property, the material will use a special sheen BRDF intended for rendering cloth materials such as velvet.
- The sheen color provides the ability to create two-tone specular materials. *null* by default.
+ Used for rendering materials such as velvet. It has no effect when set to black (0x000000). Default is black.
[property:Float transmission]
diff --git a/docs/api/en/math/Color.html b/docs/api/en/math/Color.html
index adfdf427f88a46..210e49b124aa39 100644
--- a/docs/api/en/math/Color.html
+++ b/docs/api/en/math/Color.html
@@ -208,6 +208,9 @@ [method:Object getHSL]( [param:Object target] )
[method:String getStyle]()
Returns the value of this color as a CSS style string. Example: 'rgb(255,0,0)'.
+ [method:Boolean isBlack]()
+ Returns true if the [page:.r r], [page:.g g] and [page:.b b] components are zero, false otherwise.
+
[method:Color lerp]( [param:Color color], [param:Float alpha] )
[page:Color color] - color to converge on.
diff --git a/examples/jsm/nodes/materials/StandardNodeMaterial.js b/examples/jsm/nodes/materials/StandardNodeMaterial.js
index 592cfe148b6228..16cb16f529e31e 100644
--- a/examples/jsm/nodes/materials/StandardNodeMaterial.js
+++ b/examples/jsm/nodes/materials/StandardNodeMaterial.js
@@ -34,7 +34,7 @@ NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [
'environment',
'mask',
'position',
- 'sheen'
+ 'sheenTint'
] );
export { StandardNodeMaterial };
diff --git a/examples/jsm/nodes/materials/nodes/StandardNode.js b/examples/jsm/nodes/materials/nodes/StandardNode.js
index 26b9fce2c336ad..1f4412db5ec89d 100644
--- a/examples/jsm/nodes/materials/nodes/StandardNode.js
+++ b/examples/jsm/nodes/materials/nodes/StandardNode.js
@@ -185,7 +185,7 @@ class StandardNode extends Node {
}
- if ( this.sheen ) this.sheen.analyze( builder );
+ if ( this.sheenTint ) this.sheenTint.analyze( builder );
// build code
@@ -230,7 +230,7 @@ class StandardNode extends Node {
const clearcoatEnv = useClearcoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearcoat', context: contextClearcoatEnvironment, slot: 'environment' } ) : undefined;
- const sheen = this.sheen ? this.sheen.flow( builder, 'c' ) : undefined;
+ const sheenTint = this.sheenTint ? this.sheenTint.flow( builder, 'c' ) : undefined;
builder.requires.transparent = alpha !== undefined;
@@ -368,9 +368,9 @@ class StandardNode extends Node {
}
- if ( sheen ) {
+ if ( sheenTint ) {
- output.push( 'material.sheenColor = ' + sheen.result + ';' );
+ output.push( 'material.sheenTint = ' + sheenTint.result + ';' );
}
@@ -547,7 +547,7 @@ class StandardNode extends Node {
if ( source.environment ) this.environment = source.environment;
- if ( source.sheen ) this.sheen = source.sheen;
+ if ( source.sheenTint ) this.sheenTint = source.sheenTint;
return this;
@@ -593,7 +593,7 @@ class StandardNode extends Node {
if ( this.environment ) data.environment = this.environment.toJSON( meta ).uuid;
- if ( this.sheen ) data.sheen = this.sheen.toJSON( meta ).uuid;
+ if ( this.sheenTint ) data.sheenTint = this.sheenTint.toJSON( meta ).uuid;
}
diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js
index 87ad254356c3a2..1a88bc44ed8e5b 100644
--- a/src/loaders/MaterialLoader.js
+++ b/src/loaders/MaterialLoader.js
@@ -74,7 +74,7 @@ class MaterialLoader extends Loader {
if ( json.color !== undefined && material.color !== undefined ) material.color.setHex( json.color );
if ( json.roughness !== undefined ) material.roughness = json.roughness;
if ( json.metalness !== undefined ) material.metalness = json.metalness;
- if ( json.sheen !== undefined ) material.sheen = new Color().setHex( json.sheen );
+ if ( json.sheenTint !== undefined ) material.sheenTint = new Color().setHex( json.sheenTint );
if ( json.emissive !== undefined && material.emissive !== undefined ) material.emissive.setHex( json.emissive );
if ( json.specular !== undefined && material.specular !== undefined ) material.specular.setHex( json.specular );
if ( json.specularIntensity !== undefined ) material.specularIntensity = json.specularIntensity;
diff --git a/src/materials/Material.js b/src/materials/Material.js
index 4b4c77155daf63..01ce2a792625fc 100644
--- a/src/materials/Material.js
+++ b/src/materials/Material.js
@@ -169,7 +169,7 @@ class Material extends EventDispatcher {
if ( this.roughness !== undefined ) data.roughness = this.roughness;
if ( this.metalness !== undefined ) data.metalness = this.metalness;
- if ( this.sheen && this.sheen.isColor ) data.sheen = this.sheen.getHex();
+ if ( this.sheenTint && this.sheenTint.isColor ) data.sheenTint = this.sheenTint.getHex();
if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
diff --git a/src/materials/MeshPhysicalMaterial.js b/src/materials/MeshPhysicalMaterial.js
index ee4922e40845a2..b59f0cac35fd46 100644
--- a/src/materials/MeshPhysicalMaterial.js
+++ b/src/materials/MeshPhysicalMaterial.js
@@ -15,7 +15,7 @@ import * as MathUtils from '../math/MathUtils.js';
* ior: ,
* reflectivity: ,
*
- * sheen: ,
+ * sheenTint: ,
*
* transmission: ,
* transmissionMap: new THREE.Texture( ),
@@ -69,7 +69,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
}
} );
- this.sheen = null; // null will disable sheen bsdf
+ this.sheenTint = new Color( 0x000000 );
this.transmission = 0.0;
this.transmissionMap = null;
@@ -108,15 +108,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
this.ior = source.ior;
- if ( source.sheen ) {
-
- this.sheen = ( this.sheen || new Color() ).copy( source.sheen );
-
- } else {
-
- this.sheen = null;
-
- }
+ this.sheenTint.copy( source.sheenTint );
this.transmission = source.transmission;
this.transmissionMap = source.transmissionMap;
diff --git a/src/math/Color.js b/src/math/Color.js
index 295c60e1a1766b..ef752607c49ddf 100644
--- a/src/math/Color.js
+++ b/src/math/Color.js
@@ -546,6 +546,12 @@ class Color {
}
+ isBlack() {
+
+ return ( this.r === 0 ) && ( this.g === 0 ) && ( this.b === 0 );
+
+ }
+
fromArray( array, offset = 0 ) {
this.r = array[ offset ];
diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js
index 5ec23b7e238809..73f52811399f6f 100644
--- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js
@@ -73,7 +73,7 @@ material.roughness = min( material.roughness, 1.0 );
#ifdef USE_SHEEN
- material.sheenColor = sheen;
+ material.sheenTint = sheenTint;
#endif
`;
diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js
index d14edd28942d10..c760a2e42997d7 100644
--- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js
@@ -11,7 +11,7 @@ struct PhysicalMaterial {
float clearcoatRoughness;
#endif
#ifdef USE_SHEEN
- vec3 sheenColor;
+ vec3 sheenTint;
#endif
};
@@ -157,7 +157,7 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricC
material.roughness,
directLight.direction,
geometry,
- material.sheenColor
+ material.sheenTint
);
#else
diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js
index cc3b7508fecf5c..188ba2a9a1636c 100644
--- a/src/renderers/shaders/ShaderLib.js
+++ b/src/renderers/shaders/ShaderLib.js
@@ -296,7 +296,7 @@ ShaderLib.physical = {
clearcoatRoughnessMap: { value: null },
clearcoatNormalScale: { value: new Vector2( 1, 1 ) },
clearcoatNormalMap: { value: null },
- sheen: { value: new Color( 0x000000 ) },
+ sheenTint: { value: new Color( 0x000000 ) },
transmission: { value: 0 },
transmissionMap: { value: null },
transmissionSamplerSize: { value: new Vector2() },
diff --git a/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js b/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js
index b1077a6c31f0d7..a8dbf0b6ad5e74 100644
--- a/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js
+++ b/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js
@@ -36,7 +36,7 @@ uniform float opacity;
#endif
#ifdef USE_SHEEN
- uniform vec3 sheen;
+ uniform vec3 sheenTint;
#endif
varying vec3 vViewPosition;
diff --git a/src/renderers/webgl/WebGLMaterials.js b/src/renderers/webgl/WebGLMaterials.js
index 00fe07a9b8878e..f5a982951dac1b 100644
--- a/src/renderers/webgl/WebGLMaterials.js
+++ b/src/renderers/webgl/WebGLMaterials.js
@@ -583,7 +583,7 @@ function WebGLMaterials( properties ) {
uniforms.clearcoat.value = material.clearcoat;
uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
- if ( material.sheen ) uniforms.sheen.value.copy( material.sheen );
+ if ( material.sheenTint ) uniforms.sheenTint.value.copy( material.sheenTint );
if ( material.clearcoatMap ) {
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index 8961a077127c9a..3694ed61971089 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -621,7 +621,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
- parameters.sheen ? '#define USE_SHEEN' : '',
+ parameters.sheenTint ? '#define USE_SHEEN' : '',
parameters.transmission ? '#define USE_TRANSMISSION' : '',
parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js
index 7e5c563ace1414..20af4dfe12f6b0 100644
--- a/src/renderers/webgl/WebGLPrograms.js
+++ b/src/renderers/webgl/WebGLPrograms.js
@@ -46,7 +46,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
'numDirLightShadows', 'numPointLightShadows', 'numSpotLightShadows',
'shadowMapEnabled', 'shadowMapType', 'toneMapping', 'physicallyCorrectLights',
'alphaTest', 'doubleSided', 'flipSided', 'numClippingPlanes', 'numClipIntersection', 'depthPacking', 'dithering',
- 'sheen', 'transmission', 'transmissionMap', 'thicknessMap'
+ 'sheenTint', 'transmission', 'transmissionMap', 'thicknessMap'
];
function getMaxBones( object ) {
@@ -204,7 +204,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
gradientMap: !! material.gradientMap,
- sheen: !! material.sheen,
+ sheenTint: ( !! material.sheenTint && ! material.sheenTint.isBlack() ),
transmission: material.transmission > 0,
transmissionMap: !! material.transmissionMap,