Bläddra i källkod

implement basic physical lights mode.

Ben Houston 9 år sedan
förälder
incheckning
0abbb037dd

+ 4 - 0
src/renderers/WebGLRenderer.js

@@ -55,6 +55,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 	this.gammaInput = false;
 	this.gammaOutput = false;
 
+	// physical lights
+
+	this.physicalLights = false;
+	
 	// tone mapping
 
 	this.toneMapping = THREE.LinearToneMapping;

+ 13 - 0
src/renderers/shaders/ShaderChunk/bsdfs.glsl

@@ -16,6 +16,19 @@ float calcLightAttenuation( const in float lightDistance, const in float cutoffD
 
 }
 
+// based upon Frostbite 3 Moving to Physically-based Rendering
+// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+// this is intended to be used on spot and point lights.
+float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
+
+		if( decayExponent > 0.0 ) {
+
+			return pow( saturate( 1.0 - pow4( lightDistance / maxDistance ), decayExponent ) / max( pow( lightDistance, decayExponent ), 0.01 );
+
+		}
+
+		return 1.0;
+}
 
 vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {
 

+ 2 - 0
src/renderers/shaders/ShaderChunk/common.glsl

@@ -9,6 +9,8 @@
 #define whiteCompliment(a) ( 1.0 - saturate( a ) )
 
 float square( const in float x ) { return x*x; }
+float cube( const in float x ) { return x*x*x; }
+float pow4( const in float x ) { return x*x*x*x; }
 float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
 
 

+ 25 - 4
src/renderers/shaders/ShaderChunk/lights_pars.glsl

@@ -12,7 +12,7 @@
 
 	uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
 
-	IncidentLight getDirectionalDirectLight( const in DirectionalLight directionalLight, const in GeometricContext geometry ) {
+	IncidentLight getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry ) {
 
 		IncidentLight directLight;
 
@@ -43,7 +43,7 @@
 
 	uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
 
-	IncidentLight getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry ) {
+	IncidentLight getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry ) {
 
 		IncidentLight directLight;
 
@@ -55,7 +55,17 @@
 		if ( testLightInRange( lightDistance, pointLight.distance ) ) {
 
 			directLight.color = pointLight.color;
+
+#if defined( PHYSICAL_LIGHTS )
+
+			directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
+
+#else
+
 			directLight.color *= calcLightAttenuation( lightDistance, pointLight.distance, pointLight.decay );
+
+#endif
+
 			directLight.visible = true;
 
 		} else {
@@ -91,7 +101,7 @@
 
 	uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
 
-	IncidentLight getSpotDirectLight( const in SpotLight spotLight, const in GeometricContext geometry ) {
+	IncidentLight getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry ) {
 
 		IncidentLight directLight;
 
@@ -106,7 +116,18 @@
 			float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
 
 			directLight.color = spotLight.color;
-			directLight.color *= ( spotEffect * calcLightAttenuation( lightDistance, spotLight.distance, spotLight.decay ) );
+			directLight.color *= spotEffect;
+
+			#if defined( PHYSICAL_LIGHTS )
+
+						directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
+
+			#else
+
+						directLight.color *= calcLightAttenuation( lightDistance, pointLight.distance, pointLight.decay );
+
+			#endif
+
 			directLight.visible = true;
 
 		} else {

+ 3 - 3
src/renderers/shaders/ShaderChunk/lights_template.glsl

@@ -29,7 +29,7 @@ IncidentLight directLight;
 
 		pointLight = pointLights[ i ];
 
-		directLight = getPointDirectLight( pointLight, geometry );
+		directLight = getPointDirectLightIrradiance( pointLight, geometry );
 
 		#ifdef USE_SHADOWMAP
 		directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;
@@ -49,7 +49,7 @@ IncidentLight directLight;
 
 		spotLight = spotLights[ i ];
 
-		directLight = getSpotDirectLight( spotLight, geometry );
+		directLight = getSpotDirectLightIrradiance( spotLight, geometry );
 
 		#ifdef USE_SHADOWMAP
 		directLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
@@ -69,7 +69,7 @@ IncidentLight directLight;
 
 		directionalLight = directionalLights[ i ];
 
-		directLight = getDirectionalDirectLight( directionalLight, geometry );
+		directLight = getDirectionalDirectLightIrradiance( directionalLight, geometry );
 
 		#ifdef USE_SHADOWMAP
 		directLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;

+ 2 - 0
src/renderers/webgl/WebGLProgram.js

@@ -518,6 +518,8 @@ THREE.WebGLProgram = ( function () {
 
 				parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '',
 
+				parameters.physicalLights ? "#define PHYSICAL_LIGHTS" : '',
+
 				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
 				parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 

+ 2 - 1
src/renderers/webgl/WebGLPrograms.js

@@ -23,7 +23,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 		"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
 		"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
 		"numDirLights", "numPointLights", "numSpotLights", "numHemiLights",
-		"shadowMapEnabled", "pointLightShadows", "toneMapping",
+		"shadowMapEnabled", "pointLightShadows", "toneMapping", 'physicalLights',
 		"shadowMapType",
 		"alphaTest", "doubleSided", "flipSided"
 	];
@@ -176,6 +176,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 			shadowMapType: renderer.shadowMap.type,
 
 			toneMapping: renderer.toneMapping,
+			physicalLights: renderer.physicalLights,
 
 			premultipliedAlpha: ( material.blending === THREE.PremultipliedAlphaBlending ),
 			alphaTest: material.alphaTest,