Browse Source

Editor: added handling of HemisphereLights. Added HemisphereLightHelper.

In the process found some issues:

- HemisphereLight shading is wrong for objects not in origin, it shouldn't depend on light position amplitude and object position in the scene
- GL errors about uniforms thrown when all lights have "visible = false"
- object dragging in the viewport sometimes hits invisible wall (I guess it's because of limited picking plane size?)
- ArrowHelper doesn't seem to work for (0,-1,0) direction
alteredq 12 years ago
parent
commit
b92df1f673

+ 129 - 0
build/three.js

@@ -32744,6 +32744,135 @@ THREE.DirectionalLightHelper.prototype.update = function () {
 
 }
 
+/**
+ * @author alteredq / http://alteredqualia.com/
+ *
+ *	- shows hemisphere light intensity, sky and ground colors and directions
+ */
+
+THREE.HemisphereLightHelper = function ( light, sphereSize, arrowLength, domeSize ) {
+
+	THREE.Object3D.call( this );
+
+	this.light = light;
+
+	// position
+
+	this.position = light.position;
+
+	//
+
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	// sky color
+
+	this.color = light.color.clone();
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	var hexColor = this.color.getHex();
+
+	// ground color
+
+	this.groundColor = light.groundColor.clone();
+
+	this.groundColor.r *= intensity;
+	this.groundColor.g *= intensity;
+	this.groundColor.b *= intensity;
+
+	var hexColorGround = this.groundColor.getHex();
+
+	// double colored light bulb
+
+	var bulbGeometry = new THREE.SphereGeometry( sphereSize, 16, 8, 0, Math.PI * 2, 0, Math.PI * 0.5 );
+	var bulbGroundGeometry = new THREE.SphereGeometry( sphereSize, 16, 8, 0, Math.PI * 2, Math.PI * 0.5, Math.PI );
+
+	var bulbSkyMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false } );
+	var bulbGroundMaterial = new THREE.MeshBasicMaterial( { color: hexColorGround, fog: false } );
+
+	bulbGeometry.materials[ 0 ] = bulbSkyMaterial;
+	bulbGroundGeometry.materials[ 0 ] = bulbGroundMaterial;
+
+	for ( var i = 0, il = bulbGeometry.faces.length; i < il; i ++ ) {
+
+		bulbGeometry.faces[ i ].materialIndex = 0;
+
+	}
+
+	for ( var i = 0, il = bulbGroundGeometry.faces.length; i < il; i ++ ) {
+
+		bulbGroundGeometry.faces[ i ].materialIndex = 0;
+
+	}
+
+	THREE.GeometryUtils.merge( bulbGeometry, bulbGroundGeometry );
+
+	this.lightSphere = new THREE.Mesh( bulbGeometry, new THREE.MeshFaceMaterial() );
+
+	// arrows for sky and ground light directions
+
+	this.lightArrow = new THREE.ArrowHelper( new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, ( sphereSize + arrowLength ) * 1.1, 0 ), arrowLength, hexColor );
+	this.lightArrow.rotation.x = Math.PI;
+
+	this.lightArrowGround = new THREE.ArrowHelper( new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, ( sphereSize + arrowLength ) * -1.1, 0 ), arrowLength, hexColorGround );
+
+	var joint = new THREE.Object3D();
+	joint.rotation.x = -Math.PI * 0.5;
+
+	joint.add( this.lightSphere );
+	joint.add( this.lightArrow );
+	joint.add( this.lightArrowGround );
+
+	this.add( joint );
+
+	//
+
+	this.lightSphere.properties.isGizmo = true;
+	this.lightSphere.properties.gizmoSubject = light;
+	this.lightSphere.properties.gizmoRoot = this;
+
+	//
+
+	this.properties.isGizmo = true;
+
+	//
+
+	this.target = new THREE.Vector3();
+	this.lookAt( this.target );
+
+}
+
+THREE.HemisphereLightHelper.prototype = Object.create( THREE.Object3D.prototype );
+
+THREE.HemisphereLightHelper.prototype.update = function () {
+
+	// update sphere sky and ground colors to light color * light intensity
+
+	var intensity = THREE.Math.clamp( this.light.intensity, 0, 1 );
+
+	this.color.copy( this.light.color );
+	this.groundColor.copy( this.light.groundColor );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	this.groundColor.r *= intensity;
+	this.groundColor.g *= intensity;
+	this.groundColor.b *= intensity;
+
+	this.lightSphere.geometry.materials[ 0 ].color.copy( this.color );
+	this.lightSphere.geometry.materials[ 1 ].color.copy( this.groundColor );
+
+	this.lightArrow.setColor( this.color.getHex() );
+	this.lightArrowGround.setColor( this.groundColor.getHex() );
+
+	this.lookAt( this.target );
+
+}
+
 /**
  * @author alteredq / http://alteredqualia.com/
  *

+ 6 - 0
build/three.min.js

@@ -701,6 +701,12 @@ new THREE.SphereGeometry(b,8,4);c=new THREE.MeshBasicMaterial({color:d,wireframe
 d.computeLineDistances();this.targetLine=new THREE.Line(d,a);this.targetLine.properties.isGizmo=true}this.properties.isGizmo=true};THREE.DirectionalLightHelper.prototype=Object.create(THREE.Object3D.prototype);
 THREE.DirectionalLightHelper.prototype.update=function(){this.direction.sub(this.light.target.position,this.light.position);this.lightArrow.setDirection(this.direction);this.color.copy(this.light.color);var a=THREE.Math.clamp(this.light.intensity,0,1);this.color.r=this.color.r*a;this.color.g=this.color.g*a;this.color.b=this.color.b*a;this.lightArrow.setColor(this.color.getHex());this.lightSphere.material.color.copy(this.color);this.lightRays.material.color.copy(this.color);this.targetSphere.material.color.copy(this.color);
 this.targetLine.material.color.copy(this.color);this.targetLine.geometry.vertices[0].copy(this.light.position);this.targetLine.geometry.vertices[1].copy(this.light.target.position);this.targetLine.geometry.computeLineDistances();this.targetLine.geometry.verticesNeedUpdate=true};
+THREE.HemisphereLightHelper=function(a,b,c){THREE.Object3D.call(this);this.light=a;this.position=a.position;var d=THREE.Math.clamp(a.intensity,0,1);this.color=a.color.clone();this.color.r=this.color.r*d;this.color.g=this.color.g*d;this.color.b=this.color.b*d;var e=this.color.getHex();this.groundColor=a.groundColor.clone();this.groundColor.r=this.groundColor.r*d;this.groundColor.g=this.groundColor.g*d;this.groundColor.b=this.groundColor.b*d;var d=this.groundColor.getHex(),f=new THREE.SphereGeometry(b,
+16,8,0,Math.PI*2,0,Math.PI*0.5),g=new THREE.SphereGeometry(b,16,8,0,Math.PI*2,Math.PI*0.5,Math.PI),h=new THREE.MeshBasicMaterial({color:e,fog:false}),i=new THREE.MeshBasicMaterial({color:d,fog:false});f.materials[0]=h;g.materials[0]=i;h=0;for(i=f.faces.length;h<i;h++)f.faces[h].materialIndex=0;h=0;for(i=g.faces.length;h<i;h++)g.faces[h].materialIndex=0;THREE.GeometryUtils.merge(f,g);this.lightSphere=new THREE.Mesh(f,new THREE.MeshFaceMaterial);this.lightArrow=new THREE.ArrowHelper(new THREE.Vector3(0,
+1,0),new THREE.Vector3(0,(b+c)*1.1,0),c,e);this.lightArrow.rotation.x=Math.PI;this.lightArrowGround=new THREE.ArrowHelper(new THREE.Vector3(0,1,0),new THREE.Vector3(0,(b+c)*-1.1,0),c,d);b=new THREE.Object3D;b.rotation.x=-Math.PI*0.5;b.add(this.lightSphere);b.add(this.lightArrow);b.add(this.lightArrowGround);this.add(b);this.lightSphere.properties.isGizmo=true;this.lightSphere.properties.gizmoSubject=a;this.lightSphere.properties.gizmoRoot=this;this.properties.isGizmo=true;this.target=new THREE.Vector3;
+this.lookAt(this.target)};THREE.HemisphereLightHelper.prototype=Object.create(THREE.Object3D.prototype);
+THREE.HemisphereLightHelper.prototype.update=function(){var a=THREE.Math.clamp(this.light.intensity,0,1);this.color.copy(this.light.color);this.groundColor.copy(this.light.groundColor);this.color.r=this.color.r*a;this.color.g=this.color.g*a;this.color.b=this.color.b*a;this.groundColor.r=this.groundColor.r*a;this.groundColor.g=this.groundColor.g*a;this.groundColor.b=this.groundColor.b*a;this.lightSphere.geometry.materials[0].color.copy(this.color);this.lightSphere.geometry.materials[1].color.copy(this.groundColor);
+this.lightArrow.setColor(this.color.getHex());this.lightArrowGround.setColor(this.groundColor.getHex());this.lookAt(this.target)};
 THREE.PointLightHelper=function(a,b){THREE.Object3D.call(this);this.light=a;this.position=a.position;this.color=a.color.clone();var c=THREE.Math.clamp(a.intensity,0,1);this.color.r=this.color.r*c;this.color.g=this.color.g*c;this.color.b=this.color.b*c;var d=this.color.getHex(),c=new THREE.SphereGeometry(b,16,8),e=new THREE.AsteriskGeometry(b*1.25,b*2.25),f=new THREE.IcosahedronGeometry(1,2),g=new THREE.MeshBasicMaterial({color:d,fog:false}),h=new THREE.LineBasicMaterial({color:d,fog:false}),d=new THREE.MeshBasicMaterial({color:d,
 fog:false,wireframe:true,opacity:0.1,transparent:true});this.lightSphere=new THREE.Mesh(c,g);this.lightRays=new THREE.Line(e,h,THREE.LinePieces);this.lightDistance=new THREE.Mesh(f,d);c=a.distance;c===0?this.lightDistance.visible=false:this.lightDistance.scale.set(c,c,c);this.add(this.lightSphere);this.add(this.lightRays);this.add(this.lightDistance);this.lightSphere.properties.isGizmo=true;this.lightSphere.properties.gizmoSubject=a;this.lightSphere.properties.gizmoRoot=this;this.properties.isGizmo=
 true};THREE.PointLightHelper.prototype=Object.create(THREE.Object3D.prototype);

+ 30 - 0
editor/js/ui/Sidebar.Object3D.js

@@ -5,6 +5,7 @@ Sidebar.Object3D = function ( signals ) {
 		'PerspectiveCamera': THREE.PerspectiveCamera,
 		'AmbientLight': THREE.AmbientLight,
 		'DirectionalLight': THREE.DirectionalLight,
+		'HemisphereLight': THREE.HemisphereLight,
 		'PointLight': THREE.PointLight,
 		'SpotLight': THREE.SpotLight,
 		'Mesh': THREE.Mesh,
@@ -137,6 +138,16 @@ Sidebar.Object3D = function ( signals ) {
 
 	container.add( objectColorRow );
 
+	// ground color
+
+	var objectGroundColorRow = new UI.Panel();
+	var objectGroundColor = new UI.Color( 'absolute' ).setLeft( '100px' ).onChange( update );
+
+	objectGroundColorRow.add( new UI.Text().setValue( 'Ground color' ).setColor( '#666' ) );
+	objectGroundColorRow.add( objectGroundColor );
+
+	container.add( objectGroundColorRow );
+
 	// distance
 
 	var objectDistanceRow = new UI.Panel();
@@ -272,6 +283,12 @@ Sidebar.Object3D = function ( signals ) {
 
 			}
 
+			if ( selected.groundColor !== undefined ) {
+
+				selected.groundColor.setHex( objectGroundColor.getHexValue() );
+
+			}
+
 			if ( selected.distance !== undefined ) {
 
 				selected.distance = objectDistance.getValue();
@@ -304,6 +321,7 @@ Sidebar.Object3D = function ( signals ) {
 			'far': objectFarRow,
 			'intensity': objectIntensityRow,
 			'color': objectColorRow,
+			'groundColor': objectGroundColorRow,
 			'distance' : objectDistanceRow,
 			'angle' : objectAngleRow,
 			'exponent' : objectExponentRow
@@ -401,6 +419,12 @@ Sidebar.Object3D = function ( signals ) {
 
 			}
 
+			if ( object.groundColor !== undefined ) {
+
+				objectGroundColor.setValue( '#' + object.groundColor.getHexString() );
+
+			}
+
 			if ( object.distance !== undefined ) {
 
 				objectDistance.setValue( object.distance );
@@ -503,6 +527,12 @@ Sidebar.Object3D = function ( signals ) {
 
 		}
 
+		if ( object.groundColor !== undefined ) {
+
+			objectGroundColor.setValue( '#' + object.groundColor.getHexString() );
+
+		}
+
 		if ( object.distance !== undefined ) {
 
 			objectDistance.setValue( object.distance );

+ 1 - 0
editor/js/ui/Sidebar.Scene.js

@@ -5,6 +5,7 @@ Sidebar.Scene = function ( signals ) {
 		'PerspectiveCamera': THREE.PerspectiveCamera,
 		'AmbientLight': THREE.AmbientLight,
 		'DirectionalLight': THREE.DirectionalLight,
+		'HemisphereLight': THREE.HemisphereLight,
 		'PointLight': THREE.PointLight,
 		'SpotLight': THREE.SpotLight,
 		'Mesh': THREE.Mesh,

+ 16 - 6
editor/js/ui/Viewport.js

@@ -56,7 +56,7 @@ var Viewport = function ( signals ) {
 	camera.lookAt( scene.position );
 	scene.add( camera );
 
-	var light1 = new THREE.DirectionalLight( 0xffffff );
+	var light1 = new THREE.DirectionalLight( 0xffffff, 0.8 );
 	light1.position.set( 1, 0.5, 0 ).multiplyScalar( 400 );
 
 	var light2 = new THREE.SpotLight( 0xffffff, 1.5, 500, Math.PI * 0.025 );
@@ -66,9 +66,11 @@ var Viewport = function ( signals ) {
 	light2.target.properties.targetInverse = light2;
 
 	var light3 = new THREE.PointLight( 0xffaa00, 0.75 );
-	light3.position.set( 0, -200, 0 );
+	light3.position.set( -200, 200, -200 );
 
-	var light4 = new THREE.AmbientLight( 0x111111 );
+	//var light4 = new THREE.AmbientLight( 0x111111 );
+	var light4 = new THREE.HemisphereLight( 0x00aaff, 0xff0000, 1 );
+	light4.position.y = 500;
 
 	// fog
 
@@ -365,8 +367,16 @@ var Viewport = function ( signals ) {
 
 		} else if ( object instanceof THREE.HemisphereLight ) {
 
-			//var lightGizmo = new THREE.HemisphereLightHelper( object );
-			//sceneHelpers.add( lightGizmo );
+			var sphereSize = 5;
+			var arrowLength = 30;
+
+			var lightGizmo = new THREE.HemisphereLightHelper( object, sphereSize, arrowLength );
+			sceneHelpers.add( lightGizmo );
+
+			object.properties.helper = lightGizmo;
+			object.properties.pickingProxy = lightGizmo.lightSphere;
+
+			objects.push( lightGizmo.lightSphere );
 
 		}
 
@@ -393,12 +403,12 @@ var Viewport = function ( signals ) {
 			object.updateProjectionMatrix();
 
 		} else if ( object instanceof THREE.DirectionalLight ||
+					object instanceof THREE.HemisphereLight ||
 					object instanceof THREE.PointLight ||
 					object instanceof THREE.SpotLight ) {
 
 			object.properties.helper.update();
 
-		} else if ( object instanceof THREE.HemisphereLight ) {
 		} else if ( object.properties.targetInverse ) {
 
 			object.properties.targetInverse.properties.helper.update();

+ 129 - 0
src/extras/helpers/HemisphereLightHelper.js

@@ -0,0 +1,129 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ *
+ *	- shows hemisphere light intensity, sky and ground colors and directions
+ */
+
+THREE.HemisphereLightHelper = function ( light, sphereSize, arrowLength, domeSize ) {
+
+	THREE.Object3D.call( this );
+
+	this.light = light;
+
+	// position
+
+	this.position = light.position;
+
+	//
+
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	// sky color
+
+	this.color = light.color.clone();
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	var hexColor = this.color.getHex();
+
+	// ground color
+
+	this.groundColor = light.groundColor.clone();
+
+	this.groundColor.r *= intensity;
+	this.groundColor.g *= intensity;
+	this.groundColor.b *= intensity;
+
+	var hexColorGround = this.groundColor.getHex();
+
+	// double colored light bulb
+
+	var bulbGeometry = new THREE.SphereGeometry( sphereSize, 16, 8, 0, Math.PI * 2, 0, Math.PI * 0.5 );
+	var bulbGroundGeometry = new THREE.SphereGeometry( sphereSize, 16, 8, 0, Math.PI * 2, Math.PI * 0.5, Math.PI );
+
+	var bulbSkyMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false } );
+	var bulbGroundMaterial = new THREE.MeshBasicMaterial( { color: hexColorGround, fog: false } );
+
+	bulbGeometry.materials[ 0 ] = bulbSkyMaterial;
+	bulbGroundGeometry.materials[ 0 ] = bulbGroundMaterial;
+
+	for ( var i = 0, il = bulbGeometry.faces.length; i < il; i ++ ) {
+
+		bulbGeometry.faces[ i ].materialIndex = 0;
+
+	}
+
+	for ( var i = 0, il = bulbGroundGeometry.faces.length; i < il; i ++ ) {
+
+		bulbGroundGeometry.faces[ i ].materialIndex = 0;
+
+	}
+
+	THREE.GeometryUtils.merge( bulbGeometry, bulbGroundGeometry );
+
+	this.lightSphere = new THREE.Mesh( bulbGeometry, new THREE.MeshFaceMaterial() );
+
+	// arrows for sky and ground light directions
+
+	this.lightArrow = new THREE.ArrowHelper( new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, ( sphereSize + arrowLength ) * 1.1, 0 ), arrowLength, hexColor );
+	this.lightArrow.rotation.x = Math.PI;
+
+	this.lightArrowGround = new THREE.ArrowHelper( new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, ( sphereSize + arrowLength ) * -1.1, 0 ), arrowLength, hexColorGround );
+
+	var joint = new THREE.Object3D();
+	joint.rotation.x = -Math.PI * 0.5;
+
+	joint.add( this.lightSphere );
+	joint.add( this.lightArrow );
+	joint.add( this.lightArrowGround );
+
+	this.add( joint );
+
+	//
+
+	this.lightSphere.properties.isGizmo = true;
+	this.lightSphere.properties.gizmoSubject = light;
+	this.lightSphere.properties.gizmoRoot = this;
+
+	//
+
+	this.properties.isGizmo = true;
+
+	//
+
+	this.target = new THREE.Vector3();
+	this.lookAt( this.target );
+
+}
+
+THREE.HemisphereLightHelper.prototype = Object.create( THREE.Object3D.prototype );
+
+THREE.HemisphereLightHelper.prototype.update = function () {
+
+	// update sphere sky and ground colors to light color * light intensity
+
+	var intensity = THREE.Math.clamp( this.light.intensity, 0, 1 );
+
+	this.color.copy( this.light.color );
+	this.groundColor.copy( this.light.groundColor );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	this.groundColor.r *= intensity;
+	this.groundColor.g *= intensity;
+	this.groundColor.b *= intensity;
+
+	this.lightSphere.geometry.materials[ 0 ].color.copy( this.color );
+	this.lightSphere.geometry.materials[ 1 ].color.copy( this.groundColor );
+
+	this.lightArrow.setColor( this.color.getHex() );
+	this.lightArrowGround.setColor( this.groundColor.getHex() );
+
+	this.lookAt( this.target );
+
+}
+

+ 1 - 0
utils/includes/extras.json

@@ -38,6 +38,7 @@
 	"../src/extras/helpers/ArrowHelper.js",
 	"../src/extras/helpers/CameraHelper.js",
 	"../src/extras/helpers/DirectionalLightHelper.js",
+	"../src/extras/helpers/HemisphereLightHelper.js",
 	"../src/extras/helpers/PointLightHelper.js",
 	"../src/extras/helpers/SpotLightHelper.js",
 	"../src/extras/modifiers/SubdivisionModifier.js",

+ 1 - 0
utils/includes/webgl.json

@@ -78,6 +78,7 @@
 	"../src/extras/core/Gyroscope.js",
 	"../src/extras/helpers/CameraHelper.js",
 	"../src/extras/helpers/DirectionalLightHelper.js",
+	"../src/extras/helpers/HemisphereLightHelper.js",
 	"../src/extras/helpers/PointLightHelper.js",
 	"../src/extras/helpers/SpotLightHelper.js",
 	"../src/extras/objects/LensFlare.js",