瀏覽代碼

float and half HDR CUbe Maps load and are properly generated. Something wrong when using RGBE encoding.

Ben Houston 9 年之前
父節點
當前提交
4c1eaac555

+ 6 - 5
examples/js/loaders/HDRCubeMapLoader.js

@@ -17,9 +17,10 @@ THREE.HDRCubeMapLoader.prototype.load = function(type, urls, onLoad, onProgress,
   texture.type = type;
   texture.encoding = (type === THREE.UnsignedByteType) ? THREE.RGBEEncoding : THREE.LinearEncoding;
   texture.format = (type === THREE.UnsignedByteType ) ? THREE.RGBAFormat : THREE.RGBFormat;
-  texture.minFilter = THREE.LinearFilter;
-  texture.magFilter = THREE.LinearFilter;
-  texture.generateMipmaps = false;
+  texture.minFilter = (texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
+  texture.magFilter = (texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
+  texture.generateMipmaps = (texture.encoding !== THREE.RGBEEncoding );
+  texture.anisotropy = 0;
 
   var scope = this.hdrLoader;
 
@@ -48,9 +49,9 @@ THREE.HDRCubeMapLoader.prototype.load = function(type, urls, onLoad, onProgress,
         var numElements = ( texData.data.length / 4 )*3;
         var halfdata = new Uint16Array( numElements );
         for( var j=0; j<numElements; j++) {
-          THREE.Encodings.RGBEByteToRGBHalf( texData.data, j*4, floatdata, j*3 );
+          THREE.Encodings.RGBEByteToRGBHalf( texData.data, j*4, halfdata, j*3 );
         }
-        texData.data = floatdata;
+        texData.data = halfdata;
       }
 
       if ( undefined !== texData.image ) {

+ 7 - 4
examples/js/pmrem/PMREMGenerator.js

@@ -4,7 +4,6 @@
  */
 
  THREE.PMREMGenerator = function( cubeTexture ) {
-   console.trace( 'cubeTexture', cubeTexture );
 	if ( cubeTexture instanceof THREE.CubeTexture ) {
 
 		if ( cubeTexture.images[ 0 ] === undefined )
@@ -34,8 +33,11 @@
 	this.numLods = Math.log2( size ) - 2;
   for ( var i = 0; i < this.numLods; i ++ ) {
 		var renderTarget = new THREE.WebGLRenderTargetCube( size, size, params );
-		renderTarget.texture.generateMipmaps = false;
+		renderTarget.texture.generateMipmaps = this.sourceTexture.generateMipmaps;
+    renderTarget.texture.anisotropy = this.sourceTexture.anisotropy;
     renderTarget.texture.encoding = this.sourceTexture.encoding;
+    renderTarget.texture.minFilter = this.sourceTexture.minFilter;
+    renderTarget.texture.magFilter = this.sourceTexture.magFilter;
 		this.cubeLods.push( renderTarget );
 		size = Math.max( 16, size / 2 );
 	}
@@ -84,7 +86,6 @@ THREE.PMREMGenerator.prototype = {
 	},
 
 	renderToCubeMapTargetFace: function( renderer, renderTarget, faceIndex ) {
-    console.log( 'renderTarget', renderTarget );
 		renderTarget.activeCubeFace = faceIndex;
 		this.shader.uniforms[ "faceIndex" ].value = faceIndex;
 		renderer.render( this.scene, this.camera, renderTarget, true );
@@ -150,7 +151,7 @@ THREE.PMREMGenerator.prototype = {
            return mat3(b1, b2, n);\n\
         }\n\
         \n\
-        vec4 testColorMap() {\n\
+        vec4 testColorMap(float Roughness) {\n\
            vec4 color;\n\
            if(faceIndex == 0)\n\
                color = vec4(1.0,0.0,0.0,1.0);\n\
@@ -164,6 +165,7 @@ THREE.PMREMGenerator.prototype = {
                color = vec4(0.0,1.0,1.0,1.0);\n\
            else\n\
                color = vec4(1.0,0.0,1.0,1.0);\n\
+           color *= ( 1.0 - Roughness );\n\
            return color;\n\
         }\n\
         void main() {\n\
@@ -207,6 +209,7 @@ THREE.PMREMGenerator.prototype = {
                rgbColor.rgb += color;\n\
            }\n\
            rgbColor /= float(NumSamples);\n\
+           //rgbColor = testColorMap( roughness ).rgb;\n\
            gl_FragColor = linearToOutputTexel( vec4( rgbColor, 1.0 ) );\n\
         }"
       }

+ 19 - 10
examples/js/pmrem/PMREM_CubeUVPacker.js

@@ -13,9 +13,8 @@ THREE.PMREM_CubeUVPacker = function( cubeTextureLods, numLods ) {
 	this.CubeUVRenderTarget = new THREE.WebGLRenderTarget( size, size,
 	{ format: THREE.RGBAFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter, type:cubeTextureLods[ 0 ].type } );
 	this.CubeUVRenderTarget.texture.generateMipmaps = false;
-                this.CubeUVRenderTarget.mapping = THREE.CubeUVReflectionMapping;
+  this.CubeUVRenderTarget.mapping = THREE.CubeUVReflectionMapping;
 	this.camera = new THREE.OrthographicCamera( - size * 0.5, size * 0.5, - size * 0.5, size * 0.5, 0.0, 1000 );
-                this.CubeUVRenderTarget.encoding = this.cubeLods[0].encoding;
 
 	this.scene = new THREE.Scene();
 	this.scene.add( this.camera );
@@ -64,7 +63,8 @@ THREE.PMREM_CubeUVPacker = function( cubeTextureLods, numLods ) {
 
 				// 6 Cube Faces
 				var material = this.getShader();
-				material.uniforms[ "cubeTexture" ].value = this.cubeLods[ i ];
+				material.uniforms[ "envMap" ].value = this.cubeLods[ i ];
+				material.envMap = this.cubeLods[ i ]
 				material.uniforms[ "faceIndex" ].value = k;
 				material.uniforms[ "mapSize" ].value = mipSize;
 				var color = material.uniforms[ "testColor" ].value;
@@ -104,12 +104,12 @@ THREE.PMREM_CubeUVPacker.prototype = {
 
   getShader: function() {
 
-    return new THREE.ShaderMaterial( {
+    var shaderMaterial = new THREE.ShaderMaterial( {
 
       uniforms: {
        	"faceIndex": { type: 'i', value: 0 },
        	"mapSize": { type: 'f', value: 0 },
-       	"cubeTexture": { type: 't', value: null },
+       	"envMap": { type: 't', value: null },
        	"testColor": { type: 'v3', value: new THREE.Vector3( 1, 1, 1 ) }
       },
 
@@ -124,7 +124,7 @@ THREE.PMREM_CubeUVPacker.prototype = {
       fragmentShader:
        "precision highp float;\
         varying vec2 vUv;\
-        uniform samplerCube cubeTexture;\
+        uniform samplerCube envMap;\
         uniform float mapSize;\
         uniform vec3 testColor;\
         uniform int faceIndex;\
@@ -134,7 +134,7 @@ THREE.PMREM_CubeUVPacker.prototype = {
           float sinTheta = sin(theta);\
           float cosTheta = cos(theta);\
           vec3 sampleDir = vec3(cos(phi) * sinTheta, cosTheta, sin(phi) * sinTheta);\
-          vec4 color = textureCube(cubeTexture, sampleDir);\
+          vec4 color = envMapTexelToLinear( textureCube(envMap, sampleDir) );\
           return color * vec4(testColor, 1.0);\
         }\
         void main() {\
@@ -160,11 +160,20 @@ THREE.PMREM_CubeUVPacker.prototype = {
           else {\
               sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\
           }\
-          vec4 color = textureCube(cubeTexture, (sampleDirection));\
-          gl_FragColor = color * vec4(testColor, 1.0);\
-        }"
+          vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\
+          gl_FragColor = linearToOutputTexel( color * vec4(testColor, 1.0) );\
+        }",
+
+			blending: THREE.CustomBlending,
+			blendSrc: THREE.OneFactor,
+			blendDst: THREE.ZeroFactor,
+			blendSrcAlpha: THREE.OneFactor,
+			blendDstAlpha: THREE.ZeroFactor,
+			blendEquation: THREE.AddEquation
     });
 
+		return shaderMaterial;
+
   }
 
 };

+ 4 - 39
examples/webgl_materials_envmaps_hdr.html

@@ -29,7 +29,7 @@
 		<div id="container"></div>
 		<div id="info"><a href="http://threejs.org" target="_blank">threejs</a> - PMREM Generator by Prashant Sharma and <a href="http://clara.io/" target="_blank">Ben Houston</a>.</div>
 
-		<script src="../build/three.js"></script>
+		<script src="../build/three.min.js"></script>
 		<script src="../examples/js/controls/OrbitControls.js"></script>
 		<script src="../src/loaders/BinaryTextureLoader.js"></script>
 		<script src="../examples/js/loaders/RGBELoader.js"></script>
@@ -149,8 +149,6 @@
 			  var metalness = 1;
 			  var roughness = 0.50;
 			  var diffuseColor = new THREE.Color( 1, 1.0, 1.0 ).multiplyScalar( 1 - 0.08 );
-			  //reflectionCube.mapping = THREE.CubeUVReflectionMapping;
-			  //pmremCubeUVPacker.CubeUVRenderTarget.mapping = THREE.CubeUVReflectionMapping;
 			  standardMaterial = new THREE.MeshStandardMaterial( { map: null, bumpMap: null, roughnessMap: null, bumpScale: 1.0, color: diffuseColor, metalness: metalness, roughness: roughness, shading: THREE.SmoothShading, envMap: pmremCubeUVPacker.CubeUVRenderTarget } )
 			  var torusMesh1 = new THREE.Mesh( torusGeometry, standardMaterial );
 			  torusMesh1.position.x = -30.0;
@@ -218,7 +216,7 @@
 					//reflectionCube.encoding = THREE.sRGB;
 					//reflectionCube.format = THREE.RGBFormat;
 
-					hdrCubeMap = new THREE.HDRCubeMapLoader().load(THREE.UnsignedByteType, hdrurls, onTextureLoad);
+					hdrCubeMap = new THREE.HDRCubeMapLoader().load(THREE.HalfFloatType, hdrurls, onTextureLoad);
 
 					//                                                                hdrTexture = new THREE.RGBELoader().load( '../examples/textures/cube/hdrPisa/px.hdr', onHdrLoad );
 					var grass = new THREE.TextureLoader().load( '../examples/textures/terrain/grasslight-big.jpg' );
@@ -237,40 +235,7 @@
 					  textureCube.format = THREE.RGBFormat;
 					  return textureCube;
 					}();
-					var standardNodeMaterial = new THREE.StandardNodeMaterial();
-					var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' );
-					var normalScale = new THREE.FloatNode( 0.3 );
-					var roughnessA = new THREE.FloatNode( 0.5 );
-					var metalnessA = new THREE.FloatNode( 0.5 );
-					var roughnessB = new THREE.FloatNode( 0 );
-					var metalnessB = new THREE.FloatNode( 1 );
-					var roughness = new THREE.Math3Node(
-					  roughnessA,
-					  roughnessB,
-					  mask,
-					  THREE.Math3Node.MIX
-					);
-					var metalness = new THREE.Math3Node(
-					  metalnessA,
-					  metalnessB,
-					  mask,
-					  THREE.Math3Node.MIX
-					);
-					var normalMask = new THREE.OperatorNode(
-					  new THREE.Math1Node( mask, THREE.Math1Node.INVERT ),
-					  normalScale,
-					  THREE.OperatorNode.MUL
-					);
-					standardNodeMaterial.color = new THREE.ColorNode( 0xFFFFFF );
-					standardNodeMaterial.roughness = roughness;
-					standardNodeMaterial.metalness = metalness;
-					standardNodeMaterial.environment = new THREE.CubeTextureNode( cubemap );
-					standardNodeMaterial.normal = new THREE.TextureNode( grassNormal );
-					standardNodeMaterial.normalScale = normalMask;
-					standardNodeMaterial.build();
-					var torusMesh2 = new THREE.Mesh( torusGeometry, standardNodeMaterial );
-					torusMesh2.position.x = 30.0;
-					scene.add( torusMesh2 );
+
 
 					particleLight = new THREE.Mesh( new THREE.SphereBufferGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
 				//scene.add( particleLight );
@@ -303,7 +268,7 @@
 				container.appendChild( renderer.domElement );
 
 				renderer.gammaInput = true;
-				renderer.gammaOutput = false;
+				renderer.gammaOutput = true;
 
                                                                 var renderScene = new THREE.RenderPass(scene, camera);
 

+ 6 - 5
src/renderers/shaders/ShaderChunk/encodings.glsl

@@ -19,12 +19,13 @@ vec4 LinearTosRGB( in vec4 value ) {
 }
 
 vec4 RGBEToLinear( in vec4 value ) {
-  return vec4( value.xyz * exp2( value.w*256.0 - 128.0 ), 1.0 );
+  return vec4( value.rgb * exp2( value.a * 256.0 - 128.0 ), 1.0 );
 }
 vec4 LinearToRGBE( in vec4 value ) {
-  float maxComponent = max(max(value.r, value.g), value.b );
-  float fExp = ceil( log2(maxComponent) );
-  return vec4( value.rgb / exp2(fExp), (fExp + 128.0) / 255.0 );
+  float maxComponent = max( max( value.r, value.g ), value.b );
+  float fExp = ceil( log2( maxComponent ) );
+  return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 256.0 );
+//  return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 );
 }
 
 // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
@@ -33,7 +34,7 @@ vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
 }
 vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
   float maxRGB = max( value.x, max( value.g, value.b ) );
-  float M      = maxRGB / maxRange;
+  float M      = clamp( maxRGB / maxRange, 0.0, 1.0 );
   M            = ceil( M * 255.0 ) / 255.0;
   return vec4( value.rgb / ( M * maxRange ), M );
 }

+ 4 - 5
src/renderers/webgl/WebGLPrograms.js

@@ -70,18 +70,17 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
 
 		var encoding;
-
 		if( ! map ) {
 
 			encoding = THREE.LinearEncoding;
 
 		}
-		else if( map instanceof THREE.Texture ) {
+		else if( map instanceof THREE.Texture || map instanceof THREE.CubeTexture ) {
 
 			encoding = map.encoding;
 
 		}
-		else if( map instanceof THREE.WebGLRenderTarget ) {
+		else if( map instanceof THREE.WebGLRenderTarget || map instanceof THREE.THREE.WebGLRenderTargetCube ) {
 
 			encoding = map.texture.encoding;
 
@@ -117,7 +116,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 			}
 
 		}
-		console.log( "renderer.getCurrentRenderTarget()", renderer.getCurrentRenderTarget() );
+
 		var parameters = {
 
 			shaderID: shaderID,
@@ -181,7 +180,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 			flipSided: material.side === THREE.BackSide
 
 		};
-		console.log( 'parameters', parameters );
+
 		return parameters;
 
 	};