Browse Source

Merge pull request #17256 from sunag/dev-clearcoat-normal

Node clearcoat normals (2)
Mr.doob 6 years ago
parent
commit
b6a4a25af6

+ 2 - 1
examples/jsm/nodes/accessors/NormalNode.js

@@ -36,7 +36,8 @@ NormalNode.prototype.generate = function ( builder, output ) {
 
 		case NormalNode.LOCAL:
 
-			result = 'normal';
+			if ( builder.isShader( 'vertex' ) ) result = 'objectNormal';
+			else result = 'geometryNormal';
 
 			break;
 

+ 6 - 1
examples/jsm/nodes/accessors/ReflectNode.js

@@ -3,6 +3,8 @@
  */
 
 import { TempNode } from '../core/TempNode.js';
+import { PositionNode } from './PositionNode.js';
+import { NormalNode } from './NormalNode.js';
 
 function ReflectNode( scope ) {
 
@@ -44,7 +46,10 @@ ReflectNode.prototype.generate = function ( builder, output ) {
 
 			case ReflectNode.VECTOR:
 
-				builder.addNodeCode( 'vec3 reflectVec = inverseTransformDirection( reflect( -normalize( vViewPosition ), normal ), viewMatrix );' );
+				var viewNormal = new NormalNode().build( builder, 'v3' );
+				var viewPosition = new PositionNode( PositionNode.VIEW ).build( builder, 'v3' );
+
+				builder.addNodeCode( 'vec3 reflectVec = inverseTransformDirection( reflect( -normalize( ' + viewPosition + ' ), ' + viewNormal + ' ), viewMatrix );' );
 
 				result = 'reflectVec';
 

+ 1 - 0
examples/jsm/nodes/materials/StandardNodeMaterial.js

@@ -27,6 +27,7 @@ NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [
 	'reflectivity',
 	'clearCoat',
 	'clearCoatRoughness',
+	'clearCoatNormal',
 	'normal',
 	'emissive',
 	'ambient',

+ 13 - 1
examples/jsm/nodes/materials/nodes/StandardNode.js

@@ -32,7 +32,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 	var code;
 
-	builder.define( this.clearCoat || this.clearCoatRoughness ? 'PHYSICAL' : 'STANDARD' );
+	builder.define( this.clearCoat || this.clearCoatRoughness || this.clearCoatNormal ? 'PHYSICAL' : 'STANDARD' );
 
 	builder.requires.lights = true;
 
@@ -145,6 +145,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 		if ( this.clearCoat ) this.clearCoat.analyze( builder );
 		if ( this.clearCoatRoughness ) this.clearCoatRoughness.analyze( builder );
+		if ( this.clearCoatNormal ) this.clearCoatNormal.analyze( builder );
 
 		if ( this.reflectivity ) this.reflectivity.analyze( builder );
 
@@ -184,6 +185,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 		var clearCoat = this.clearCoat ? this.clearCoat.flow( builder, 'f' ) : undefined;
 		var clearCoatRoughness = this.clearCoatRoughness ? this.clearCoatRoughness.flow( builder, 'f' ) : undefined;
+		var clearCoatNormal = this.clearCoatNormal ? this.clearCoatNormal.flow( builder, 'v3' ) : undefined;
 
 		var reflectivity = this.reflectivity ? this.reflectivity.flow( builder, 'f' ) : undefined;
 
@@ -238,6 +240,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 			// add before: prevent undeclared normal
 			"	#include <normal_fragment_begin>",
+			"	#include <clearcoat_normal_fragment_begin>",
 
 			// add before: prevent undeclared material
 			"	PhysicalMaterial material;",
@@ -289,6 +292,15 @@ StandardNode.prototype.build = function ( builder ) {
 
 		}
 
+		if ( clearCoatNormal ) {
+
+			output.push(
+				clearCoatNormal.code,
+				'clearCoatNormal = ' + clearCoatNormal.result + ';'
+			);
+
+		}
+
 		// optimization for now
 
 		output.push(

+ 22 - 16
examples/webgl_materials_nodes.html

@@ -742,6 +742,7 @@
 						//mtl.reflectivity = // reflectivity (float)
 						//mtl.clearCoat = // clearCoat (float)
 						//mtl.clearCoatRoughness = // clearCoatRoughness (float)
+						//mtl.clearCoatNormal = // clearCoatNormal (vec3)
 						//mtl.normal = // normal (vec3)
 						//mtl.emissive = // emissive color (vec3)
 						//mtl.ambient = // ambient color (vec3)
@@ -754,6 +755,7 @@
 						var mask = new Nodes.SwitchNode( new Nodes.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
 
 						var normalScale = new Nodes.FloatNode( .3 );
+						var clearCoatNormalScale = new Nodes.FloatNode( .1 );
 
 						var roughnessA = new Nodes.FloatNode( .5 );
 						var metalnessA = new Nodes.FloatNode( .5 );
@@ -785,12 +787,20 @@
 							Nodes.OperatorNode.MUL
 						);
 
+						var clearCoatNormalMask = new Nodes.OperatorNode(
+							mask,
+							clearCoatNormalScale,
+							Nodes.OperatorNode.MUL
+						);
+
 						mtl.color = new Nodes.ColorNode( 0xEEEEEE );
 						mtl.roughness = roughness;
 						mtl.metalness = metalness;
 						mtl.reflectivity = reflectivity;
 						mtl.clearCoat = clearCoat;
 						mtl.clearCoatRoughness = clearCoatRoughness;
+						mtl.clearCoatNormal = new Nodes.NormalMapNode( new Nodes.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.clearCoatNormal.scale = clearCoatNormalMask;
 						mtl.environment = new Nodes.CubeTextureNode( cubemap );
 						mtl.normal = new Nodes.NormalMapNode( new Nodes.TextureNode( getTexture( "grassNormal" ) ) );
 						mtl.normal.scale = normalMask;
@@ -821,6 +831,12 @@
 
 						}, false, 0, 1 );
 
+						addGui( 'clearCoatNormalScale', clearCoatNormalScale.value, function ( val ) {
+
+							clearCoatNormalScale.value = val;
+
+						}, false, 0, 1 );
+
 						addGui( 'roughnessA', roughnessA.value, function ( val ) {
 
 							roughnessA.value = val;
@@ -2586,12 +2602,14 @@
 
 							var nodeMaterial = new Nodes.StandardNodeMaterial();
 							nodeMaterial.environment = new Nodes.CubeTextureNode( cubemap, node );
-							nodeMaterial.roughness = new Nodes.FloatNode(0);
-							nodeMaterial.metalness = new Nodes.FloatNode(1);
+							nodeMaterial.roughness.value = .5;
+							nodeMaterial.metalness.value = 1;
 
 							var standardMaterial = new THREE.MeshStandardMaterial( {
+								color: nodeMaterial.color.value,
+								side: defaultSide,
 								envMap: cubemap,
-								roughness: 0,
+								roughness: nodeMaterial.roughness.value,
 								metalness: 1
 							} );
 
@@ -2599,18 +2617,6 @@
 
 							// GUI
 
-							addGui( 'scope', {
-								vector: Nodes.ReflectNode.VECTOR,
-								cube: Nodes.ReflectNode.CUBE,
-								sphere: Nodes.ReflectNode.SPHERE
-							}, function ( val ) {
-
-								node.scope = val;
-
-								nodeMaterial.needsUpdate = true;
-
-							} );
-
 							addGui( 'node', true, function ( val ) {
 
 								mtl = val ? nodeMaterial : standardMaterial;
@@ -2618,7 +2624,7 @@
 
 							} );
 
-							addGui( 'roughness', 0, function ( val ) {
+							addGui( 'roughness', nodeMaterial.roughness.value, function ( val ) {
 
 								nodeMaterial.roughness.value = val;
 								standardMaterial.roughness = val;

+ 2 - 2
src/renderers/shaders/ShaderChunk/clearcoat_normal_fragment_begin.glsl.js

@@ -1,7 +1,7 @@
 export default /* glsl */`
-#ifdef USE_CLEARCOAT_NORMALMAP
+#ifdef PHYSICAL
 
-  vec3 clearCoatNormal = geometryNormal;
+	vec3 clearCoatNormal = geometryNormal;
 
 #endif
 `;

+ 2 - 0
src/renderers/shaders/ShaderChunk/common.glsl.js

@@ -39,7 +39,9 @@ struct GeometricContext {
 	vec3 position;
 	vec3 normal;
 	vec3 viewDir;
+#ifdef PHYSICAL
 	vec3 clearCoatNormal;
+#endif
 };
 
 vec3 transformDirection( in vec3 dir, in mat4 matrix ) {

+ 1 - 5
src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js

@@ -20,14 +20,10 @@ geometry.position = - vViewPosition;
 geometry.normal = normal;
 geometry.viewDir = normalize( vViewPosition );
 
-#ifdef USE_CLEARCOAT_NORMALMAP
+#ifdef PHYSICAL
 
 	geometry.clearCoatNormal = clearCoatNormal;
 
-#else
-
-	geometry.clearCoatNormal = geometryNormal;
-
 #endif
 
 IncidentLight directLight;

+ 1 - 1
src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js

@@ -27,7 +27,7 @@ export default /* glsl */`
 
 	radiance += getLightProbeIndirectRadiance( /*specularLightProbe,*/ geometry.viewDir, geometry.normal, Material_BlinnShininessExponent( material ), maxMipLevel );
 
-	#ifndef STANDARD
+	#ifdef PHYSICAL
 
 		clearCoatRadiance += getLightProbeIndirectRadiance( /*specularLightProbe,*/ geometry.viewDir, geometry.clearCoatNormal, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );
 

+ 3 - 3
src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js

@@ -5,7 +5,7 @@ struct PhysicalMaterial {
 	float	specularRoughness;
 	vec3	specularColor;
 
-	#ifndef STANDARD
+	#ifdef PHYSICAL
 		float clearCoat;
 		float clearCoatRoughness;
 	#endif
@@ -76,7 +76,7 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricC
 
 	#endif
 
-	#ifndef STANDARD
+	#ifdef PHYSICAL
 
 		float ccDotNL = saturate( dot( geometry.clearCoatNormal, directLight.direction ) );
 
@@ -111,7 +111,7 @@ void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricCo
 
 void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {
 
-	#ifndef STANDARD
+	#ifdef PHYSICAL
 
 		float ccDotNV = saturate( dot( geometry.clearCoatNormal, geometry.viewDir ) );
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js

@@ -33,7 +33,7 @@ export default /* glsl */`
 
 #endif
 
-// non perturbed normal for clearcoat
+// non perturbed normal for clearcoat among others
 
 vec3 geometryNormal = normal;
 

+ 1 - 1
src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js

@@ -7,7 +7,7 @@ uniform float roughness;
 uniform float metalness;
 uniform float opacity;
 
-#ifndef STANDARD
+#ifdef PHYSICAL
 	uniform float clearCoat;
 	uniform float clearCoatRoughness;
 #endif