Переглянути джерело

fix ibl normals in reflectnode using StandardNode

sunag 6 роки тому
батько
коміт
41d738ad96

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

@@ -87,7 +87,7 @@ NormalNode.prototype.toJSON = function ( meta ) {
 
 };
 
-NodeLib.addKeyword( 'normal', function () {
+NodeLib.addKeyword( 'viewNormal', function () {
 
 	return new NormalNode();
 

+ 48 - 8
examples/jsm/nodes/accessors/ReflectNode.js

@@ -8,7 +8,7 @@ import { NormalNode } from './NormalNode.js';
 
 function ReflectNode( scope ) {
 
-	TempNode.call( this, 'v3', { unique: true } );
+	TempNode.call( this, 'v3' );
 
 	this.scope = scope || ReflectNode.CUBE;
 
@@ -22,6 +22,12 @@ ReflectNode.prototype = Object.create( TempNode.prototype );
 ReflectNode.prototype.constructor = ReflectNode;
 ReflectNode.prototype.nodeType = "Reflect";
 
+ReflectNode.prototype.getUnique = function ( builder ) {
+
+	return !builder.context.viewNormal;
+
+};
+
 ReflectNode.prototype.getType = function ( /* builder */ ) {
 
 	switch ( this.scope ) {
@@ -38,6 +44,8 @@ ReflectNode.prototype.getType = function ( /* builder */ ) {
 
 ReflectNode.prototype.generate = function ( builder, output ) {
 
+	var isUnique = this.getUnique( builder );
+
 	if ( builder.isShader( 'fragment' ) ) {
 
 		var result;
@@ -46,12 +54,24 @@ ReflectNode.prototype.generate = function ( builder, output ) {
 
 			case ReflectNode.VECTOR:
 
-				var viewNormal = new NormalNode().build( builder, 'v3' );
+				var viewNormalNode = builder.context.viewNormal || new NormalNode();
+
+				var viewNormal = viewNormalNode.build( builder, 'v3' );
 				var viewPosition = new PositionNode( PositionNode.VIEW ).build( builder, 'v3' );
 
-				builder.addNodeCode( 'vec3 reflectVec = inverseTransformDirection( reflect( -normalize( ' + viewPosition + ' ), ' + viewNormal + ' ), viewMatrix );' );
+				var code = `inverseTransformDirection( reflect( -normalize( ${viewPosition} ), ${viewNormal} ), viewMatrix )`;
+
+				if ( isUnique ) {
+
+					builder.addNodeCode( `vec3 reflectVec = ${result};` );
+
+					result = 'reflectVec';
+
+				} else {
+
+					result = code;
 
-				result = 'reflectVec';
+				}
 
 				break;
 
@@ -59,9 +79,19 @@ ReflectNode.prototype.generate = function ( builder, output ) {
 
 				var reflectVec = new ReflectNode( ReflectNode.VECTOR ).build( builder, 'v3' );
 
-				builder.addNodeCode( 'vec3 reflectCubeVec = vec3( -1.0 * ' + reflectVec + '.x, ' + reflectVec + '.yz );' );
+				var code = 'vec3( -' + reflectVec + '.x, ' + reflectVec + '.yz )';
 
-				result = 'reflectCubeVec';
+				if ( isUnique ) {
+
+					builder.addNodeCode( `vec3 reflectCubeVec = ${result};` );
+
+					result = 'reflectCubeVec';
+
+				} else {
+
+					result = code;
+
+				}
 
 				break;
 
@@ -69,9 +99,19 @@ ReflectNode.prototype.generate = function ( builder, output ) {
 
 				var reflectVec = new ReflectNode( ReflectNode.VECTOR ).build( builder, 'v3' );
 
-				builder.addNodeCode( 'vec2 reflectSphereVec = normalize( ( viewMatrix * vec4( ' + reflectVec + ', 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) ).xy * 0.5 + 0.5;' );
+				var code = 'normalize( ( viewMatrix * vec4( ' + reflectVec + ', 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) ).xy * 0.5 + 0.5';
+
+				if ( isUnique ) {
+
+					builder.addNodeCode( `vec2 reflectSphereVec = ${result};` );
+
+					result = 'reflectSphereVec';
+
+				} else {
+
+					result = code;
 
-				result = 'reflectSphereVec';
+				}
 
 				break;
 

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

@@ -8,6 +8,7 @@ import {
 } from '../../../../../build/three.module.js';
 
 import { Node } from '../../core/Node.js';
+import { ExpressionNode } from '../../core/ExpressionNode.js';
 import { ColorNode } from '../../inputs/ColorNode.js';
 import { FloatNode } from '../../inputs/FloatNode.js';
 import { RoughnessToBlinnExponentNode } from '../../bsdfs/RoughnessToBlinnExponentNode.js';
@@ -122,6 +123,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 		var contextEnvironment = {
 			bias: RoughnessToBlinnExponentNode,
+			viewNormal: new ExpressionNode('normal', 'v3'),
 			gamma: true
 		};
 
@@ -129,6 +131,12 @@ StandardNode.prototype.build = function ( builder ) {
 			gamma: true
 		};
 
+		var contextClearCoatEnvironment = {
+			bias: RoughnessToBlinnExponentNode,
+			viewNormal: new ExpressionNode('clearCoatNormal', 'v3'),
+			gamma: true
+		};
+
 		var useClearCoat = ! builder.isDefined( 'STANDARD' );
 
 		// analyze all nodes to reuse generate codes
@@ -212,7 +220,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 		}
 
-		var clearCoatEnv = useClearCoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearCoat', context: contextEnvironment, slot: 'environment' } ) : undefined;
+		var clearCoatEnv = useClearCoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearCoat', context: contextClearCoatEnvironment, slot: 'environment' } ) : undefined;
 
 		builder.requires.transparent = alpha !== undefined;
 
@@ -493,6 +501,7 @@ StandardNode.prototype.copy = function ( source ) {
 
 	if ( source.clearCoat ) this.clearCoat = source.clearCoat;
 	if ( source.clearCoatRoughness ) this.clearCoatRoughness = source.clearCoatRoughness;
+	if ( source.clearCoatNormal ) this.clearCoatNormal = source.clearCoatNormal;
 
 	if ( source.reflectivity ) this.reflectivity = source.reflectivity;
 
@@ -536,6 +545,7 @@ StandardNode.prototype.toJSON = function ( meta ) {
 
 		if ( this.clearCoat ) data.clearCoat = this.clearCoat.toJSON( meta ).uuid;
 		if ( this.clearCoatRoughness ) data.clearCoatRoughness = this.clearCoatRoughness.toJSON( meta ).uuid;
+		if ( this.clearCoatNormal ) data.clearCoatNormal = this.clearCoatNormal.toJSON( meta ).uuid;
 
 		if ( this.reflectivity ) data.reflectivity = this.reflectivity.toJSON( meta ).uuid;