فهرست منبع

Added bump and specular maps to simple skin shader.

Added corresponding example. Tweaked bit previous bump map example.
alteredq 13 سال پیش
والد
کامیت
aac882984d
3فایلهای تغییر یافته به همراه425 افزوده شده و 9 حذف شده
  1. 45 3
      examples/js/ShaderSkin.js
  2. 10 6
      examples/webgl_materials_bumpmap.html
  3. 370 0
      examples/webgl_materials_bumpmap_skin.html

+ 45 - 3
examples/js/ShaderSkin.js

@@ -12,6 +12,8 @@ THREE.ShaderSkin = {
 	//		- physically based specular term (Kelemen/Szirmay-Kalos specular reflectance)
 	//
 	//		- diffuse map
+	//		- bump map
+	//		- specular map
 	//		- point and directional lights (use with "lights: true" material option)
 	//		- fog (use with "fog: true" material option)
 	//		- shadow maps
@@ -28,6 +30,9 @@ THREE.ShaderSkin = {
 
 			{
 
+			"enableBump"	: { type: "i", value: 0 },
+			"enableSpecular": { type: "i", value: 0 },
+
 			"tDiffuse"	: { type: "t", value: 0, texture: null },
 			"tBeckmann"	: { type: "t", value: 1, texture: null },
 
@@ -39,6 +44,13 @@ THREE.ShaderSkin = {
 			"uRoughness": 	  		{ type: "f", value: 0.15 },
 			"uSpecularBrightness": 	{ type: "f", value: 0.75 },
 
+			"bumpMap"	: { type: "t", value: 2, texture: null },
+			"bumpScale" : { type: "f", value: 1 },
+
+			"specularMap" : { type: "t", value: 3, texture: null },
+
+			"offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
+
 			"uWrapRGB":	{ type: "v3", value: new THREE.Vector3( 0.75, 0.375, 0.1875 ) }
 
 			}
@@ -47,6 +59,12 @@ THREE.ShaderSkin = {
 
 		fragmentShader: [
 
+			"#define USE_BUMPMAP",
+			"#extension GL_OES_standard_derivatives : enable",
+
+			"uniform bool enableBump;",
+			"uniform bool enableSpecular;",
+
 			"uniform vec3 uAmbientColor;",
 			"uniform vec3 uDiffuseColor;",
 			"uniform vec3 uSpecularColor;",
@@ -60,6 +78,8 @@ THREE.ShaderSkin = {
 			"uniform sampler2D tDiffuse;",
 			"uniform sampler2D tBeckmann;",
 
+			"uniform sampler2D specularMap;",
+
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -84,6 +104,7 @@ THREE.ShaderSkin = {
 
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
+			THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
 
 			// Fresnel term
 
@@ -140,6 +161,25 @@ THREE.ShaderSkin = {
 				"vec3 normal = normalize( vNormal );",
 				"vec3 viewPosition = normalize( vViewPosition );",
 
+				"float specularStrength;",
+
+				"if ( enableSpecular ) {",
+
+					"vec4 texelSpecular = texture2D( specularMap, vUv );",
+					"specularStrength = texelSpecular.r;",
+
+				"} else {",
+
+					"specularStrength = 1.0;",
+
+				"}",
+
+				"#ifdef USE_BUMPMAP",
+
+					"if ( enableBump ) normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
+
+				"#endif",
+
 				// point lights
 
 				"vec3 specularTotal = vec3( 0.0 );",
@@ -168,7 +208,7 @@ THREE.ShaderSkin = {
 						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
 
 						"pointTotal    += lDistance * uDiffuseColor * pointLightColor[ i ] * pointDiffuseWeight;",
-						"specularTotal += lDistance * uSpecularColor * pointLightColor[ i ] * pointSpecularWeight;",
+						"specularTotal += lDistance * uSpecularColor * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
 
 					"}",
 
@@ -193,7 +233,7 @@ THREE.ShaderSkin = {
 						"float dirSpecularWeight =  KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
 
 						"dirTotal 	   += uDiffuseColor * directionalLightColor[ i ] * dirDiffuseWeight;",
-						"specularTotal += uSpecularColor * directionalLightColor[ i ] * dirSpecularWeight;",
+						"specularTotal += uSpecularColor * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
 
 					"}",
 
@@ -223,6 +263,8 @@ THREE.ShaderSkin = {
 
 		vertexShader: [
 
+			"uniform vec4 offsetRepeat;",
+
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -237,7 +279,7 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalMatrix * normal;",
 
-				"vUv = uv;",
+				"vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
 
 				"gl_Position = projectionMatrix * mvPosition;",
 

+ 10 - 6
examples/webgl_materials_bumpmap.html

@@ -67,6 +67,9 @@
 			var mouseX = 0;
 			var mouseY = 0;
 
+			var targetX = 0;
+			var targetY = 0;
+
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 
@@ -236,10 +239,10 @@
 
 			}
 
-			function onDocumentMouseMove(event) {
+			function onDocumentMouseMove( event ) {
 
-				mouseX = ( event.clientX - windowHalfX ) * 10;
-				mouseY = ( event.clientY - windowHalfY ) * 10;
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
 
 			}
 
@@ -256,12 +259,13 @@
 
 			function render() {
 
-				var ry = mouseX * 0.0003, rx = mouseY * 0.0003;
+				targetX = mouseX * .001;
+				targetY = mouseY * .001;
 
 				if ( mesh ) {
 
-					mesh.rotation.y = ry;
-					mesh.rotation.x = rx;
+					mesh.rotation.y += 0.05 * ( targetX - mesh.rotation.y );
+					mesh.rotation.x += 0.05 * ( targetY - mesh.rotation.x );
 
 				}
 

+ 370 - 0
examples/webgl_materials_bumpmap_skin.html

@@ -0,0 +1,370 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - materials - bump map - skin [Lee Perry-Smith]</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				background:#000;
+				color:#fff;
+				padding:0;
+				margin:0;
+				font-weight: bold;
+				overflow:hidden;
+			}
+
+			a {	color: #ffffff;	}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				color: #ffffff;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+				z-index:1000;
+			}
+
+			#oldie {
+				background:rgb(200,100,0) !important;
+				color:#fff;
+			}
+
+		</style>
+	</head>
+
+	<body>
+		<div id="info">
+			<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - webgl simple single-pass skin material with <a href="http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html">tangent-less bump mapping</a> -
+			<a href="http://www.ir-ltd.net/infinite-3d-head-scan-released/" target="_blank">Lee Perry-Smith</a> head
+		</div>
+
+		<script src="../build/Three.js"></script>
+
+		<script src="js/ShaderSkin.js"></script>
+
+		<script src="js/ShaderExtras.js"></script>
+
+		<script src="js/postprocessing/EffectComposer.js"></script>
+		<script src="js/postprocessing/RenderPass.js"></script>
+		<script src="js/postprocessing/BloomPass.js"></script>
+		<script src="js/postprocessing/FilmPass.js"></script>
+		<script src="js/postprocessing/DotScreenPass.js"></script>
+		<script src="js/postprocessing/TexturePass.js"></script>
+		<script src="js/postprocessing/ShaderPass.js"></script>
+		<script src="js/postprocessing/MaskPass.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var statsEnabled = true;
+
+			var container, stats, loader;
+
+			var camera, scene, renderer;
+
+			var mesh, mesh2;
+
+			var directionalLight, directionalLight2, pointLight, ambientLight, spotLight;
+
+			var mouseX = 0;
+			var mouseY = 0;
+
+			var targetX = 0, targetY = 0;
+
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			var mapColor, mapHeight, mapSpecular;
+
+			var firstPass = true;
+
+			var composer, composerBeckmann;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				//
+
+				camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 10000 );
+				camera.position.z = 1200;
+
+				scene = new THREE.Scene();
+
+				// LIGHTS
+
+				ambientLight = new THREE.AmbientLight( 0x555555 );
+				scene.add( ambientLight );
+
+				//
+
+				pointLight = new THREE.PointLight( 0xffffff, 1.5, 1000 );
+				pointLight.position.set( 0, 0, 600 );
+
+				scene.add( pointLight );
+
+				// shadow for PointLight
+
+				spotLight = new THREE.SpotLight( 0xffffff, 1 );
+				spotLight.position.set( 0.05, 0.05, 1 );
+				scene.add( spotLight );
+
+				spotLight.position.multiplyScalar( 700 );
+
+				spotLight.castShadow = true;
+				spotLight.onlyShadow = true;
+				//spotLight.shadowCameraVisible = true;
+
+				spotLight.shadowMapWidth = 2048;
+				spotLight.shadowMapHeight = 2048;
+
+				spotLight.shadowCameraNear = 200;
+				spotLight.shadowCameraFar = 1500;
+
+				spotLight.shadowCameraFov = 40;
+
+				spotLight.shadowBias = -0.005;
+				spotLight.shadowDarkness = 0.15;
+
+				//
+
+				directionalLight = new THREE.DirectionalLight( 0xffffff, 0.85 );
+				directionalLight.position.set( 1, -0.5, 1 );
+				directionalLight.color.setHSV( 0.6, 0.3, 1 );
+				scene.add( directionalLight );
+
+				directionalLight.position.multiplyScalar( 500 );
+
+				directionalLight.castShadow = true;
+				//directionalLight.shadowCameraVisible = true;
+
+				directionalLight.shadowMapWidth = 2048;
+				directionalLight.shadowMapHeight = 2048;
+
+				directionalLight.shadowCameraNear = 200;
+				directionalLight.shadowCameraFar = 1500;
+
+				directionalLight.shadowCameraLeft = -500;
+				directionalLight.shadowCameraRight = 500;
+				directionalLight.shadowCameraTop = 500;
+				directionalLight.shadowCameraBottom = -500;
+
+				directionalLight.shadowBias = -0.005;
+				directionalLight.shadowDarkness = 0.15;
+
+				//
+
+				directionalLight2 = new THREE.DirectionalLight( 0xffffff, 0.85 );
+				directionalLight2.position.set( 1, -0.5, -1 );
+				scene.add( directionalLight2 );
+
+				//
+
+				loader = new THREE.JSONLoader( true );
+				document.body.appendChild( loader.statusDomElement );
+
+				loader.load( "obj/leeperrysmith/LeePerrySmith.js", function( geometry ) { createScene( geometry, 100 ) } );
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true, clearColor: 0x060708, clearAlpha: 1 } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				var color = new THREE.Color();
+				color.setHSV( 0.6, 0.15, 0.35 );
+				renderer.setClearColor( color, 1 );
+
+				renderer.shadowMapEnabled = true;
+				renderer.shadowMapCullFrontFaces = false;
+
+				renderer.autoClear = false;
+
+				//
+
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+				renderer.physicallyBasedShading = true;
+
+				//
+
+				if ( statsEnabled ) {
+
+					stats = new Stats();
+					stats.domElement.style.position = 'absolute';
+					stats.domElement.style.top = '0px';
+					stats.domElement.style.zIndex = 100;
+
+					stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa";
+					stats.domElement.children[ 0 ].style.background = "transparent";
+					stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
+
+					container.appendChild( stats.domElement );
+
+				}
+
+
+				// COMPOSER
+
+				renderer.autoClear = false;
+
+				// BECKMANN
+
+				var effectBeckmann = new THREE.ShaderPass( THREE.ShaderSkin[ "beckmann" ] );
+				var effectScreen = new THREE.ShaderPass( THREE.ShaderExtras[ "screen" ] );
+
+				effectScreen.renderToScreen = true;
+
+				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBufer: false };
+				var rtwidth = 512, rtheight = 512;
+
+				composerBeckmann = new THREE.EffectComposer( renderer, new THREE.WebGLRenderTarget( rtwidth, rtheight, pars ) );
+				composerBeckmann.addPass( effectBeckmann );
+				composerBeckmann.addPass( effectScreen );
+
+				// EVENTS
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function createScene( geometry, scale ) {
+
+				var mapHeight = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
+
+				mapHeight.anisotropy = 16;
+				mapHeight.repeat.set( 0.998, 0.998 );
+				mapHeight.offset.set( 0.001, 0.001 )
+				mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
+
+				var mapSpecular = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
+
+				mapSpecular.anisotropy = 16;
+				mapSpecular.repeat.set( 0.998, 0.998 );
+				mapSpecular.offset.set( 0.001, 0.001 )
+				mapSpecular.wrapS = mapSpecular.wrapT = THREE.RepeatWrapping;
+
+				var mapColor = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+
+				mapColor.anisotropy = 16;
+				mapColor.repeat.set( 0.998, 0.998 );
+				mapColor.offset.set( 0.001, 0.001 )
+				mapColor.wrapS = mapColor.wrapT = THREE.RepeatWrapping;
+
+				var shader = THREE.ShaderSkin[ "skinSimple" ];
+
+				var fragmentShader = shader.fragmentShader;
+				var vertexShader = shader.vertexShader;
+
+				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+
+				uniforms[ "enableBump" ].value = true;
+				uniforms[ "enableSpecular" ].value = true;
+
+				uniforms[ "tBeckmann" ].texture = composerBeckmann.renderTarget1;
+				uniforms[ "tDiffuse" ].texture = mapColor;
+
+				uniforms[ "bumpMap" ].texture = mapHeight;
+				uniforms[ "specularMap" ].texture = mapSpecular;
+
+				uniforms[ "uAmbientColor" ].value.setHex( 0xa0a0a0 );
+				uniforms[ "uDiffuseColor" ].value.setHex( 0xa0a0a0 );
+				uniforms[ "uSpecularColor" ].value.setHex( 0xa0a0a0 );
+
+				uniforms[ "uRoughness" ].value = 0.145;
+				uniforms[ "uSpecularBrightness" ].value = 0.75;
+
+				uniforms[ "bumpScale" ].value = 16;
+
+				uniforms[ "offsetRepeat" ].value.set( 0.001, 0.001, 0.998, 0.998 );
+
+				var material = new THREE.ShaderMaterial( { fragmentShader: fragmentShader, vertexShader: vertexShader, uniforms: uniforms, lights: true } );
+
+				mesh = new THREE.Mesh( geometry, material );
+
+				mesh.position.y = - 50;
+				mesh.scale.set( scale, scale, scale );
+
+				mesh.castShadow = true;
+				mesh.receiveShadow = true;
+
+				scene.add( mesh );
+
+				loader.statusDomElement.style.display = "none";
+
+			}
+
+			//
+
+			function onWindowResize( event ) {
+
+				SCREEN_WIDTH = window.innerWidth;
+				SCREEN_HEIGHT = window.innerHeight;
+
+				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+
+				camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
+				camera.updateProjectionMatrix();
+
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX ) * 1;
+				mouseY = ( event.clientY - windowHalfY ) * 1;
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				if ( statsEnabled ) stats.update();
+
+			}
+
+			function render() {
+
+				targetX = mouseX * .001;
+				targetY = mouseY * .001;
+
+				if ( mesh ) {
+
+					mesh.rotation.y += 0.05 * ( targetX - mesh.rotation.y );
+					mesh.rotation.x += 0.05 * ( targetY - mesh.rotation.x );
+
+				}
+
+				if ( firstPass ) {
+
+					composerBeckmann.render();
+					firstPass = false;
+
+				}
+
+				renderer.clear();
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>