123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /**
- * @author sunag / http://www.sunag.com.br/
- */
- THREE.NodeMaterial = function( vertex, fragment ) {
-
- THREE.ShaderMaterial.call( this );
-
- this.vertex = vertex || new THREE.NodeRaw( new THREE.NodePosition( THREE.NodePosition.PROJECTION ) );
- this.fragment = fragment || new THREE.NodeRaw( new THREE.NodeColor( 0xFF0000 ) );
-
- };
- THREE.NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
- THREE.NodeMaterial.prototype.constructor = THREE.NodeMaterial;
- THREE.NodeMaterial.Type = {
- t : 'sampler2D',
- tc : 'samplerCube',
- bv1 : 'bool',
- iv1 : 'int',
- fv1 : 'float',
- c : 'vec3',
- v2 : 'vec2',
- v3 : 'vec3',
- v4 : 'vec4'
- };
- THREE.NodeMaterial.GetShortcuts = function( prop, name ) {
-
- return {
- get: function () { return this[prop][name]; },
- set: function ( val ) { this[prop][name] = val; }
- };
- };
- THREE.NodeMaterial.Shortcuts = function( proto, prop, list ) {
-
- var shortcuts = {};
-
- for(var i = 0; i < list.length; ++i) {
-
- var name = list[i];
-
- shortcuts[name] = this.GetShortcuts( prop, name );
-
- }
-
- Object.defineProperties( proto, shortcuts );
- };
- THREE.NodeMaterial.prototype.updateAnimation = function( delta ) {
-
- for(var i = 0; i < this.requestUpdate.length; ++i) {
- this.requestUpdate[i].updateAnimation( delta );
-
- }
-
- };
- THREE.NodeMaterial.prototype.build = function() {
-
- var vertex, fragment;
-
- this.defines = {};
- this.uniforms = {};
-
- this.nodeData = {};
-
- this.vertexUniform = [];
- this.fragmentUniform = [];
-
- this.vertexTemps = [];
- this.fragmentTemps = [];
-
- this.uniformList = [];
-
- this.consts = [];
- this.functions = [];
-
- this.requestUpdate = [];
-
- this.requestAttrib = {
- uv:[],
- color:[]
- };
-
- this.needsColor = false;
- this.needsLight = false;
- this.needsPosition = false;
- this.needsTransparent = false;
-
- this.vertexPars = '';
- this.fragmentPars = '';
-
- this.vertexCode = '';
- this.fragmentCode = '';
-
- this.vertexNode = '';
- this.fragmentNode = '';
-
- var builder = new THREE.NodeBuilder(this);
-
- vertex = this.vertex.build( builder.setShader('vertex'), 'v4' );
- fragment = this.fragment.build( builder.setShader('fragment'), 'v4' );
-
- if (this.requestAttrib.uv[0]) {
-
- this.addVertexPars( 'varying vec2 vUv;' );
- this.addFragmentPars( 'varying vec2 vUv;' );
-
- this.addVertexCode( 'vUv = uv;' );
-
- }
-
- if (this.requestAttrib.uv[1]) {
-
- this.addVertexPars( 'varying vec2 vUv2; attribute vec2 uv2;' );
- this.addFragmentPars( 'varying vec2 vUv2;' );
-
- this.addVertexCode( 'vUv2 = uv2;' );
-
- }
-
- if (this.requestAttrib.color[0]) {
- this.addVertexPars( 'varying vec4 vColor; attribute vec4 color;' );
- this.addFragmentPars( 'varying vec4 vColor;' );
-
- this.addVertexCode( 'vColor = color;' );
-
- }
-
- if (this.requestAttrib.color[1]) {
- this.addVertexPars( 'varying vec4 vColor2; attribute vec4 color2;' );
- this.addFragmentPars( 'varying vec4 vColor2;' );
-
- this.addVertexCode( 'vColor2 = color2;' );
-
- }
-
- if (this.requestAttrib.position) {
- this.addVertexPars( 'varying vec3 vPosition;' );
- this.addFragmentPars( 'varying vec3 vPosition;' );
-
- this.addVertexCode( 'vPosition = transformed;' );
-
- }
-
- if (this.requestAttrib.worldPosition) {
-
- // for future update replace from the native "varying vec3 vWorldPosition" for optimization
-
- this.addVertexPars( 'varying vec3 vWPosition;' );
- this.addFragmentPars( 'varying vec3 vWPosition;' );
-
- this.addVertexCode( 'vWPosition = worldPosition.xyz;' );
- }
-
- if (this.requestAttrib.normal) {
- this.addVertexPars( 'varying vec3 vObjectNormal;' );
- this.addFragmentPars( 'varying vec3 vObjectNormal;' );
-
- this.addVertexCode( 'vObjectNormal = normal;' );
-
- }
-
- if (this.requestAttrib.worldNormal) {
- this.addVertexPars( 'varying vec3 vWNormal;' );
- this.addFragmentPars( 'varying vec3 vWNormal;' );
-
- this.addVertexCode( 'vWNormal = ( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz;' );
-
- }
-
- this.lights = this.needsLight;
- this.transparent = this.needsTransparent;
-
- this.vertexShader = [
- this.vertexPars,
- this.getCodePars( this.vertexUniform, 'uniform' ),
- this.getIncludes(this.consts['vertex']),
- this.getIncludes(this.functions['vertex']),
- 'void main(){',
- this.getCodePars( this.vertexTemps ),
- vertex,
- this.vertexCode,
- '}'
- ].join( "\n" );
- this.fragmentShader = [
- this.fragmentPars,
- this.getCodePars( this.fragmentUniform, 'uniform' ),
- this.getIncludes(this.consts['fragment']),
- this.getIncludes(this.functions['fragment']),
- 'void main(){',
- this.getCodePars( this.fragmentTemps ),
- this.fragmentCode,
- fragment,
- '}'
- ].join( "\n" );
-
- this.needsUpdate = true;
- this.dispose(); // force update
-
- return this;
- };
- THREE.NodeMaterial.prototype.define = function(name, value) {
- this.defines[name] = value == undefined ? 1 : value;
- };
- THREE.NodeMaterial.prototype.isDefined = function(name) {
- return this.defines[name] != undefined;
- };
- THREE.NodeMaterial.prototype.mergeUniform = function( uniforms ) {
-
- for (var name in uniforms) {
-
- this.uniforms[ name ] = uniforms[ name ];
-
- }
-
- };
- THREE.NodeMaterial.prototype.createUniform = function( value, type, needsUpdate ) {
-
- var index = this.uniformList.length;
-
- var uniform = {
- type : type,
- value : value,
- needsUpdate : needsUpdate,
- name : 'nVu' + index
- };
-
- this.uniformList.push(uniform);
-
- return uniform;
-
- };
- THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type ) {
-
- if (!this.vertexTemps[ uuid ]) {
-
- var index = this.vertexTemps.length,
- name = 'nVt' + index,
- data = { name : name, type : type };
-
- this.vertexTemps.push( data );
- this.vertexTemps[uuid] = data;
-
- }
-
- return this.vertexTemps[uuid];
-
- };
- THREE.NodeMaterial.prototype.getIncludes = function( incs ) {
-
- function sortByPosition(a, b){
- return b.deps - a.deps;
- }
-
- return function( incs ) {
-
- if (!incs) return '';
-
- var code = '';
- var incs = incs.sort(sortByPosition);
-
- for(var i = 0; i < incs.length; i++) {
-
- code += incs[i].node.src + '\n';
-
- }
-
- return code;
- }
- }();
- THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type ) {
-
- if (!this.fragmentTemps[ uuid ]) {
-
- var index = this.fragmentTemps.length,
- name = 'nVt' + index,
- data = { name : name, type : type };
-
- this.fragmentTemps.push( data );
- this.fragmentTemps[uuid] = data;
-
- }
-
- return this.fragmentTemps[uuid];
-
- };
- THREE.NodeMaterial.prototype.addVertexPars = function( code ) {
- this.vertexPars += code + '\n';
- };
- THREE.NodeMaterial.prototype.addFragmentPars = function( code ) {
- this.fragmentPars += code + '\n';
- };
- THREE.NodeMaterial.prototype.addVertexCode = function( code ) {
- this.vertexCode += code + '\n';
- };
- THREE.NodeMaterial.prototype.addFragmentCode = function( code ) {
- this.fragmentCode += code + '\n';
- };
- THREE.NodeMaterial.prototype.addVertexNode = function( code ) {
- this.vertexNode += code + '\n';
- };
- THREE.NodeMaterial.prototype.clearVertexNode = function() {
- var code = this.fragmentNode;
-
- this.fragmentNode = '';
-
- return code;
- };
- THREE.NodeMaterial.prototype.addFragmentNode = function( code ) {
- this.fragmentNode += code + '\n';
- };
- THREE.NodeMaterial.prototype.clearFragmentNode = function() {
- var code = this.fragmentNode;
-
- this.fragmentNode = '';
-
- return code;
- };
- THREE.NodeMaterial.prototype.getCodePars = function( pars, prefix ) {
- prefix = prefix || '';
- var code = '';
-
- for (var i = 0, l = pars.length; i < l; ++i) {
-
- var parsType = pars[i].type;
- var parsName = pars[i].name;
- var parsValue = pars[i].value;
-
- if (parsType == 't' && parsValue instanceof THREE.CubeTexture) parsType = 'tc';
-
- var type = THREE.NodeMaterial.Type[ parsType ];
-
- if (type == undefined) throw new Error( "Node pars " + parsType + " not found." );
-
- code += prefix + ' ' + type + ' ' + parsName + ';\n';
- }
- return code;
- };
- THREE.NodeMaterial.prototype.getVertexUniform = function( value, type, needsUpdate ) {
- var uniform = this.createUniform( value, type, needsUpdate );
-
- this.vertexUniform.push(uniform);
- this.vertexUniform[uniform.name] = uniform;
-
- this.uniforms[ uniform.name ] = uniform;
-
- return uniform;
- };
- THREE.NodeMaterial.prototype.getFragmentUniform = function( value, type, needsUpdate ) {
- var uniform = this.createUniform( value, type, needsUpdate );
-
- this.fragmentUniform.push(uniform);
- this.fragmentUniform[uniform.name] = uniform;
-
- this.uniforms[ uniform.name ] = uniform;
-
- return uniform;
- };
- THREE.NodeMaterial.prototype.getNodeData = function( uuid ) {
- return this.nodeData[uuid] = this.nodeData[uuid] || {};
- };
- THREE.NodeMaterial.prototype.include = function( shader, node ) {
-
- var includes;
-
- node = typeof node === 'string' ? THREE.NodeLib.get(node) : node;
-
- if (node instanceof THREE.NodeFunction) {
-
- for (var i = 0; i < node.includes.length; i++) {
-
- this.include( shader, node.includes[i] );
-
- }
-
- includes = this.functions[shader] = this.functions[shader] || [];
-
- }
- else if (node instanceof THREE.NodeConst) {
-
- includes = this.consts[shader] = this.consts[shader] || [];
-
- }
-
- if (includes[node.name] === undefined) {
-
- for (var ext in node.extensions) {
-
- this.extensions[ext] = true;
-
- }
-
- includes[node.name] = {
- node : node,
- deps : 1
- };
-
- includes.push(includes[node.name]);
-
- }
- else ++includes[node.name].deps;
- };
|