Jelajahi Sumber

new sub-slot and prem example

sunag 6 tahun lalu
induk
melakukan
2827000bb0
1 mengubah file dengan 248 tambahan dan 7 penghapusan
  1. 248 7
      examples/webgl_materials_nodes.html

+ 248 - 7
examples/webgl_materials_nodes.html

@@ -20,14 +20,20 @@
 
 			import { GUI } from './jsm/libs/dat.gui.module.js';
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
-			import { NodeMaterialLoader, NodeMaterialLoaderUtils } from './jsm/loaders/NodeMaterialLoader.js';
+
 			import { TeapotBufferGeometry } from './jsm/geometries/TeapotBufferGeometry.js';
 
+			import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
+			import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
+			import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
+
+			import { NodeMaterialLoader, NodeMaterialLoaderUtils } from './jsm/loaders/NodeMaterialLoader.js';
+
 			import * as Nodes from './jsm/nodes/Nodes.js';
 
 			var container = document.getElementById( 'container' );
 
-			var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
+			var renderer, scene, lightGroup, camera, clock = new THREE.Clock(), fov = 50;
 			var frame = new Nodes.NodeFrame();
 			var teapot, mesh;
 			var controls;
@@ -84,6 +90,45 @@
 
 			}();
 
+			function generatePREM( cubeMap, textureSize ) {
+
+				textureSize = textureSize || 1024;
+
+				var pmremGenerator = new PMREMGenerator( cubeMap, undefined, textureSize / 4 );
+				pmremGenerator.update( renderer );
+
+				var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
+				pmremCubeUVPacker.update( renderer );
+
+				pmremGenerator.dispose();
+				pmremCubeUVPacker.dispose();
+
+				return pmremCubeUVPacker.CubeUVRenderTarget.texture;
+
+			}
+
+			var premTexture;
+
+			function getPREM( callback, textureSize ) {
+
+				if ( premTexture ) return callback( premTexture );
+
+				var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
+				var hdrCubeMap = new HDRCubeTextureLoader()
+					.setPath( './textures/cube/pisaHDR/' )
+					.setDataType( THREE.UnsignedByteType )
+					.load( hdrUrls, function () {
+
+						premTexture = generatePREM( hdrCubeMap, textureSize );
+
+						library[ premTexture.uuid ] = premTexture;
+
+						callback( premTexture );
+
+					} );
+
+			}
+
 			window.addEventListener( 'load', init );
 
 			function init() {
@@ -107,15 +152,20 @@
 				controls.minDistance = 50;
 				controls.maxDistance = 200;
 
-				scene.add( new THREE.AmbientLight( 0x464646 ) );
+				lightGroup = new THREE.Group();
+				scene.add( lightGroup );
+
+				var light;
+
+				lightGroup.add( new THREE.AmbientLight( 0x464646 ) );
 
-				var light = new THREE.DirectionalLight( 0xffddcc, 1 );
+				light = new THREE.DirectionalLight( 0xffddcc, 1 );
 				light.position.set( 1, 0.75, 0.5 );
-				scene.add( light );
+				lightGroup.add( light );
 
-				var light = new THREE.DirectionalLight( 0xccccff, 1 );
+				light = new THREE.DirectionalLight( 0xccccff, 1 );
 				light.position.set( - 1, 0.75, - 0.5 );
-				scene.add( light );
+				lightGroup.add( light );
 
 				teapot = new TeapotBufferGeometry( 15, 18 );
 
@@ -145,6 +195,7 @@
 					'basic / mesh-standard': 'mesh-standard',
 					'basic / standard': 'standard',
 					'basic / physical': 'physical',
+					'basic / prem': 'prem',
 					'basic / phong': 'phong',
 					'basic / layers': 'layers',
 					'basic / rim': 'rim',
@@ -178,6 +229,7 @@
 					'node / position': 'node-position',
 					'node / normal': 'node-normal',
 					'node / reflect': 'node-reflect',
+					'misc / sub-slot': 'sub-slot',
 					'misc / smoke': 'smoke',
 					'misc / firefly': 'firefly',
 					'misc / reserved-keywords': 'reserved-keywords',
@@ -238,6 +290,8 @@
 
 				move = false;
 
+				lightGroup.visible = true;
+
 				if ( mesh.material ) mesh.material.dispose();
 
 				if ( rtTexture ) {
@@ -393,6 +447,193 @@
 
 						break;
 
+					case 'prem':
+
+						// MATERIAL
+
+						mtl = new Nodes.StandardNodeMaterial();
+
+						//mtl.color = // albedo (vec3)
+						//mtl.alpha = // opacity (float)
+						//mtl.roughness = // roughness (float)
+						//mtl.metalness = // metalness (float)
+						//mtl.normal = // normal (vec3)
+						//mtl.emissive = // emissive color (vec3)
+						//mtl.ambient = // ambient color (vec3)
+						//mtl.shadow = // shadowmap (vec3)
+						//mtl.light = // custom-light (vec3)
+						//mtl.ao = // ambient occlusion (float)
+						//mtl.environment = // reflection/refraction (vec3)
+						//mtl.position = // vertex local position (vec3)
+
+						var mask = new Nodes.SwitchNode( new Nodes.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
+
+						var intensity = new Nodes.FloatNode( 1 );
+
+						var normalScale = new Nodes.FloatNode( .3 );
+
+						var roughnessA = new Nodes.FloatNode( .5 );
+						var metalnessA = new Nodes.FloatNode( .5 );
+
+						var roughnessB = new Nodes.FloatNode( 0 );
+						var metalnessB = new Nodes.FloatNode( 1 );
+
+						var roughness = new Nodes.MathNode(
+							roughnessA,
+							roughnessB,
+							mask,
+							Nodes.MathNode.MIX
+						);
+
+						var metalness = new Nodes.MathNode(
+							metalnessA,
+							metalnessB,
+							mask,
+							Nodes.MathNode.MIX
+						);
+
+						var normalMask = new Nodes.OperatorNode(
+							new Nodes.MathNode( mask, Nodes.MathNode.INVERT ),
+							normalScale,
+							Nodes.OperatorNode.MUL
+						);
+
+						mtl.color = new Nodes.ColorNode( 0xEEEEEE );
+						mtl.roughness = roughness;
+						mtl.metalness = metalness;
+						mtl.normal = new Nodes.NormalMapNode( new Nodes.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.normal.scale = normalMask;
+
+						getPREM(function(texture) {
+
+							var envNode = new Nodes.TextureCubeNode( new Nodes.TextureNode( texture ) );
+
+							mtl.environment = new Nodes.OperatorNode( envNode, intensity, Nodes.OperatorNode.MUL );
+							mtl.needsUpdate = true;
+
+						});
+
+						// GUI
+
+						addGui( 'color', mtl.color.value.getHex(), function ( val ) {
+
+							mtl.color.value.setHex( val );
+
+						}, true );
+
+						addGui( 'intensity', intensity.value, function ( val ) {
+
+							intensity.value = val;
+
+						}, false, 0, 2 );
+
+						addGui( 'roughnessA', roughnessA.value, function ( val ) {
+
+							roughnessA.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'metalnessA', metalnessA.value, function ( val ) {
+
+							metalnessA.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'roughnessB', roughnessB.value, function ( val ) {
+
+							roughnessB.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'metalnessB', metalnessB.value, function ( val ) {
+
+							metalnessB.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'normalScale', normalScale.value, function ( val ) {
+
+							normalScale.value = val;
+
+						}, false, 0, 1 );
+
+						break;
+
+					case 'sub-slot':
+
+						// disable dynamic light
+
+						lightGroup.visible = false;
+
+						// MATERIAL
+
+						mtl = new Nodes.StandardNodeMaterial();
+
+						// NODES
+
+						var mask = new Nodes.SwitchNode( new Nodes.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
+
+						var normalScale = new Nodes.FloatNode( .3 );
+
+						var radiance = new Nodes.FloatNode( 1 );
+						var irradiance = new Nodes.FloatNode( 1 );
+
+						var roughness = new Nodes.FloatNode( .5 );
+						var metalness = new Nodes.FloatNode( .5 );
+
+						mtl.color = new Nodes.ColorNode( 0xEEEEEE );
+						mtl.roughness = roughness;
+						mtl.metalness = metalness;
+						mtl.normal = new Nodes.NormalMapNode( new Nodes.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.normal.scale = normalScale;
+
+						getPREM(function(texture) {
+
+							var envNode = new Nodes.TextureCubeNode( new Nodes.TextureNode( texture ) );
+
+							var subSlotNode = new Nodes.SubSlotNode();
+							subSlotNode.slots['radiance'] = new Nodes.OperatorNode( radiance, envNode, Nodes.OperatorNode.MUL );
+							subSlotNode.slots['irradiance'] = new Nodes.OperatorNode( irradiance, envNode, Nodes.OperatorNode.MUL );
+
+							mtl.environment = subSlotNode;
+							mtl.needsUpdate = true;
+
+						});
+
+						// GUI
+
+						addGui( 'radiance', radiance.value, function ( val ) {
+
+							radiance.value = val;
+
+						}, false, 0, 2 );
+
+						addGui( 'irradiance', irradiance.value, function ( val ) {
+
+							irradiance.value = val;
+
+						}, false, 0, 2 );
+
+						addGui( 'roughness', roughness.value, function ( val ) {
+
+							roughness.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'metalness', metalness.value, function ( val ) {
+
+							metalness.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'normalScale', normalScale.value, function ( val ) {
+
+							normalScale.value = val;
+
+						}, false, 0, 1 );
+
+						break;
+
 					case 'mesh-standard':
 
 						// MATERIAL