API Docs for: 1.0.2
Show:

File: GIScene\ShaderMaterials\PointAlignmentMaterial.js

/**
 * The PointAlignmentMaterial highlights fragments whose normals are heading to a given point.
 * 
 * @namespace GIScene
 * @class PointAlignmentMaterial
 * @constructor
 * @param {THREE.Vector3} point
 * @param {Number} maxDeviationDeg
 * @param {Number} maxUpDeviationDeg
 * 
 */

GIScene.PointAlignmentMaterial = function(point, maxDeviationDeg, maxUpDeviationDeg) {
	
	var _point = point || new THREE.Vector3(0,0,0);
	var _maxDeviationDeg = maxDeviationDeg || 15.0;
	var _maxUpDeviationDeg = maxUpDeviationDeg || 5.0;
	var _emissive = new THREE.Color( 0x000000 );
	
	Object.defineProperty(this, 'point', {
	    get: function() {
	      return _point;
	    },
	    set: function(value) {
	      _point = value;
	      this.uniforms.uPoint.value = value;
	    }
	  });
	  
	  Object.defineProperty(this, 'maxDeviationDeg', {
	    get: function() {
	      return _maxDeviationDeg;
	    },
	    set: function(value) {
	      _maxDeviationDeg = value;
	      this.uniforms.maxDeviationDeg.value = value;
	    }
	  });
	  
	  Object.defineProperty(this, 'maxUpDeviationDeg', {
	    get: function() {
	      return _maxUpDeviationDeg;
	    },
	    set: function(value) {
	      _maxUpDeviationDeg = value;
	      this.uniforms.maxUpDeviationDeg.value = value;
	    }
	  });
	  
	  Object.defineProperty(this, 'emissive', {
	    get: function() {
	      return _emissive;
	    },
	    set: function(value) {
	      _emissive = value;
	      this.uniforms.emissive.value = value;
	    }
	  });
	
	
	
	var parameters = {
		
		uniforms : {

			"opacity" : 		{type : "f",  value : 1.0},
			"uPoint"  : 		{type : "v3", value : this.point},
			"maxDeviationDeg" : {type : "f",  value : this.maxDeviationDeg},
			"maxUpDeviationDeg":{type : "f",  value : this.maxUpDeviationDeg},
			"emissive" : 		{type : "c",  value : this.emissive}

		},

		vertexShader : [
			"varying vec3 vNormal;", 
			"varying vec3 vWorldPosition;",
			"uniform vec3 emissive;",
			
			THREE.ShaderChunk["morphtarget_pars_vertex"], 
			
			"void main() {", 
				"vNormal = normalize(  normal );", 
				
				THREE.ShaderChunk["morphtarget_vertex"], 
				THREE.ShaderChunk["default_vertex"], 
				//THREE.ShaderChunk[ "worldpos_vertex" ],
				"vec4 worldPosition = modelMatrix * vec4( position, 1.0 );",
				"vWorldPosition = worldPosition.xyz;",
			"}"
			].join("\n"),

		fragmentShader : [
			"uniform float opacity;", 
			"uniform vec3 uPoint;", 
			"uniform float maxDeviationDeg;", 
			"uniform float maxUpDeviationDeg;",
			"uniform vec3 emissive;",
			
			"varying vec3 vNormal;", 
			"varying vec3 vWorldPosition;",
			"float red;", 
			"float maxDeviation;", 
			"float maxUpDeviation;",
			
			"const float M_PI = 3.14159265358979323846;", 
			"vec3 hDir;", 
			"uniform mat4 modelMatrix;", 
			
			"void main() {", 
				"vec3 worldNormal = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * vNormal;", 
				"worldNormal = normalize( worldNormal );", 
				"maxDeviation = maxDeviationDeg * (M_PI / 180.0);",
				"maxUpDeviation = maxUpDeviationDeg * (M_PI / 180.0);",
	
				// 3D Direction
				//"red = (maxDeviation - acos(dot(worldNormal, compassDirection))) / maxDeviation;",
	
				//2D Direction (Aspect)
				//project face normal on horizontal plane
				// "hDir = worldNormal -  ( dot(worldNormal, vec3(0.0,1.0,0.0)) * vec3(0.0,1.0,0.0));",
				// "red = (maxDeviation - acos(dot(normalize(hDir), compassDirection))) / maxDeviation;",
		
				//exclude flat and almost flat areas from beeing colorized
				"float upDeviation = acos(dot(normalize(worldNormal), vec3(0.0,1.0,0.0)));", //deviation from up vector
				
				"if (upDeviation < maxUpDeviation || upDeviation > M_PI - maxUpDeviation)",
				"{",
					// "red = 0.0;",
					"gl_FragColor = vec4( vec3(0.5)+emissive, opacity );",
				"}",
				"else",
				"{",
				//3D direction to point
				"vec3 direction = uPoint-vWorldPosition;",
				
				//project directions on horizontal plane
				"vec3 hDirection = direction - ( dot(direction, vec3(0.0,1.0,0.0)) * vec3(0.0,1.0,0.0));",
				"vec3 hNormalDirection = worldNormal -  ( dot(worldNormal, vec3(0.0,1.0,0.0)) * vec3(0.0,1.0,0.0));",
				
				//angle between horizontal directions
				"float angle = acos(dot(normalize(hNormalDirection), normalize(hDirection)));",
				
				"red = (maxDeviation - angle) / maxDeviation;", //colorValue between 0..1
				
				"gl_FragColor = vec4( vec3(1.0,1.0-red,1.0-red) + emissive, opacity );",
				
				"}",
				
			
			"}"
			].join("\n")
	};
	
	THREE.ShaderMaterial.call(this, parameters);
	
	this.point = point || new THREE.Vector3(0,0,0);
	this.maxDeviationDeg = maxDeviationDeg || 15.0;
	this.maxUpDeviationDeg = maxUpDeviationDeg || 5.0;
	this.emissive = new THREE.Color( 0x000000 );
	
};

GIScene.PointAlignmentMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );

GIScene.PointAlignmentMaterial.prototype.clone = function() {
	
	var material = new GIScene.PointAlignmentMaterial();
	
	THREE.ShaderMaterial.prototype.clone.call( this, material );
	
	material.point = this.point.clone();
	
	material.maxDeviationDeg = this.maxDeviationDeg;
	
	material.maxUpDeviationDeg = this.maxUpDeviationDeg;
	
	material.emissive = this.emissive;
	
	return material;
};