Browse Source

Merge pull request #19909 from martinRenou/raw_node_material

NodeMaterials: Introduce a new BasicNodeMaterial class
Mr.doob 5 years ago
parent
commit
f45387b957

+ 2 - 0
examples/jsm/nodes/Nodes.d.ts

@@ -85,6 +85,7 @@ export * from './effects/LuminanceNode';
 // material nodes
 
 export * from './materials/nodes/RawNode';
+export * from './materials/nodes/BasicNode';
 export * from './materials/nodes/SpriteNode';
 export * from './materials/nodes/PhongNode';
 export * from './materials/nodes/StandardNode';
@@ -93,6 +94,7 @@ export * from './materials/nodes/MeshStandardNode';
 // materials
 
 export * from './materials/NodeMaterial';
+export * from './materials/BasicNodeMaterial';
 export * from './materials/SpriteNodeMaterial';
 export * from './materials/PhongNodeMaterial';
 export * from './materials/StandardNodeMaterial';

+ 2 - 0
examples/jsm/nodes/Nodes.js

@@ -88,6 +88,7 @@ export { LuminanceNode } from './effects/LuminanceNode.js';
 // material nodes
 
 export { RawNode } from './materials/nodes/RawNode.js';
+export { BasicNode } from './materials/nodes/BasicNode.js';
 export { SpriteNode } from './materials/nodes/SpriteNode.js';
 export { PhongNode } from './materials/nodes/PhongNode.js';
 export { StandardNode } from './materials/nodes/StandardNode.js';
@@ -96,6 +97,7 @@ export { MeshStandardNode } from './materials/nodes/MeshStandardNode.js';
 // materials
 
 export { NodeMaterial } from './materials/NodeMaterial.js';
+export { BasicNodeMaterial } from './materials/BasicNodeMaterial.js';
 export { SpriteNodeMaterial } from './materials/SpriteNodeMaterial.js';
 export { PhongNodeMaterial } from './materials/PhongNodeMaterial.js';
 export { StandardNodeMaterial } from './materials/StandardNodeMaterial.js';

+ 13 - 0
examples/jsm/nodes/materials/BasicNodeMaterial.d.ts

@@ -0,0 +1,13 @@
+import { Node } from '../core/Node';
+import { NodeMaterial } from './NodeMaterial';
+
+export class BasicNodeMaterial extends NodeMaterial {
+
+	constructor();
+
+	color: Node;
+	alpha: Node;
+	mask: Node;
+	position: Node;
+
+}

+ 30 - 0
examples/jsm/nodes/materials/BasicNodeMaterial.js

@@ -0,0 +1,30 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ * @author martinRenou / https://github.com/martinRenou
+ */
+
+import { BasicNode } from './nodes/BasicNode.js';
+import { NodeMaterial } from './NodeMaterial.js';
+import { NodeUtils } from '../core/NodeUtils.js';
+
+function BasicNodeMaterial() {
+
+	var node = new BasicNode();
+
+	NodeMaterial.call( this, node, node );
+
+	this.type = "BasicNodeMaterial";
+
+}
+
+BasicNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
+BasicNodeMaterial.prototype.constructor = BasicNodeMaterial;
+
+NodeUtils.addShortcuts( BasicNodeMaterial.prototype, 'fragment', [
+	'color',
+	'alpha',
+	'mask',
+	'position'
+] );
+
+export { BasicNodeMaterial };

+ 17 - 0
examples/jsm/nodes/materials/nodes/BasicNode.d.ts

@@ -0,0 +1,17 @@
+import { NodeBuilder } from '../../core/NodeBuilder';
+import { Node } from '../../core/Node';
+
+export class BasicNode extends Node {
+
+	constructor();
+
+	position: Node;
+	color: Node;
+	alpha: Node;
+	mask: Node;
+	nodeType: string;
+
+	build( builder: NodeBuilder ): string;
+	copy( source: BasicNode ): this;
+
+}

+ 141 - 0
examples/jsm/nodes/materials/nodes/BasicNode.js

@@ -0,0 +1,141 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ * @author martinRenou / https://github.com/martinRenou
+ */
+
+import { Node } from '../../core/Node.js';
+import { ColorNode } from '../../inputs/ColorNode.js';
+
+function BasicNode() {
+
+	Node.call( this );
+
+	this.color = new ColorNode( 0xFFFFFF );
+
+}
+
+BasicNode.prototype = Object.create( Node.prototype );
+BasicNode.prototype.constructor = BasicNode;
+BasicNode.prototype.nodeType = "Basic";
+
+BasicNode.prototype.generate = function ( builder ) {
+
+	var code;
+
+	if ( builder.isShader( 'vertex' ) ) {
+
+		var position = this.position ? this.position.analyzeAndFlow( builder, 'v3', { cache: 'position' } ) : undefined;
+
+		var output = [
+			"vec3 transformed = position;"
+		];
+
+		if ( position ) {
+
+			output.push(
+				position.code,
+				position.result ? "gl_Position = projectionMatrix * modelViewMatrix * vec4(" + position.result + ", 1.0);" : ''
+			);
+
+		} else {
+
+			output.push( "gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);" );
+
+		}
+
+		code = output.join( "\n" );
+
+	} else {
+
+		// Analyze all nodes to reuse generate codes
+		this.color.analyze( builder, { slot: 'color' } );
+
+		if ( this.alpha ) this.alpha.analyze( builder );
+		if ( this.mask ) this.mask.analyze( builder );
+
+		// Build code
+		var color = this.color.flow( builder, 'c', { slot: 'color' } );
+		var alpha = this.alpha ? this.alpha.flow( builder, 'f' ) : undefined;
+		var mask = this.mask ? this.mask.flow( builder, 'b' ) : undefined;
+
+		builder.requires.transparent = alpha !== undefined;
+
+		var output = [
+			color.code,
+		];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
+
+		}
+
+		if ( alpha ) {
+
+			output.push(
+				alpha.code,
+				'#ifdef ALPHATEST',
+
+				' if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
+
+				'#endif'
+			);
+
+		}
+
+		if ( alpha ) {
+
+			output.push( "gl_FragColor = vec4(" + color.result + ", " + alpha.result + " );" );
+
+		} else {
+
+			output.push( "gl_FragColor = vec4(" + color.result + ", 1.0 );" );
+
+		}
+
+		code = output.join( "\n" );
+
+	}
+
+	return code;
+
+};
+
+BasicNode.prototype.copy = function ( source ) {
+
+	Node.prototype.copy.call( this, source );
+
+	this.color = source.color;
+
+	if ( source.position ) this.position = source.position;
+	if ( source.alpha ) this.alpha = source.alpha;
+	if ( source.mask ) this.mask = source.mask;
+
+	return this;
+
+};
+
+BasicNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.color = this.color.toJSON( meta ).uuid;
+
+		if ( this.position ) data.position = this.position.toJSON( meta ).uuid;
+		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
+export { BasicNode };

+ 32 - 0
examples/webgl_materials_nodes.html

@@ -220,6 +220,7 @@
 					'misc / reserved-keywords': 'reserved-keywords',
 					'misc / varying': 'varying',
 					'misc / void-function': 'void-function',
+					'misc / basic-material': 'basic-material',
 					'misc / readonly': 'readonly',
 					'misc / label': 'label',
 					'misc / custom-attribute': 'custom-attribute'
@@ -2703,6 +2704,37 @@
 
 						break;
 
+					case 'basic-material':
+
+						// MATERIAL
+
+						mtl = new Nodes.BasicNodeMaterial();
+
+						var positionNode = new Nodes.PositionNode();
+
+						var a = new Nodes.OperatorNode(
+							new Nodes.SwitchNode( positionNode, 'x' ),
+							new Nodes.SwitchNode( positionNode, 'y' ),
+							Nodes.OperatorNode.ADD
+						);
+						var b = new Nodes.FloatNode( 0. );
+						var ifNode = new Nodes.FloatNode( 1. );
+						var elseNode = new Nodes.FloatNode( 0. );
+
+						mtl.mask = new Nodes.CondNode( a, b, Nodes.CondNode.GREATER, ifNode, elseNode );
+
+						var sin = new Nodes.MathNode( new Nodes.TimerNode(), Nodes.MathNode.SIN );
+
+						mtl.position = new Nodes.OperatorNode(
+							positionNode,
+							sin,
+							Nodes.OperatorNode.ADD
+						);
+
+						mtl.color = new Nodes.ColorNode( 'green' );
+
+						break;
+
 					case 'conditional':
 
 						// MATERIAL