webgl_materials_bumpmap_skin.html 7.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<!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">
39 40
			<a href="http://threejs.org" target="_blank" rel="noopener">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://graphics.cs.williams.edu/data/meshes.xml#14" target="_blank" rel="noopener">Lee Perry-Smith</a> head
41 42
		</div>

W
WestLangley 已提交
43
		<script src="../build/three.js"></script>
44 45 46

		<script src="js/ShaderSkin.js"></script>

47
		<script src="js/shaders/CopyShader.js"></script>
48 49 50 51 52 53 54

		<script src="js/postprocessing/EffectComposer.js"></script>
		<script src="js/postprocessing/RenderPass.js"></script>
		<script src="js/postprocessing/ShaderPass.js"></script>
		<script src="js/postprocessing/MaskPass.js"></script>

		<script src="js/Detector.js"></script>
55
		<script src="js/libs/stats.min.js"></script>
56 57 58 59 60 61 62 63 64 65 66 67 68

		<script>

			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

			var statsEnabled = true;

			var container, stats, loader;

			var camera, scene, renderer;

			var mesh, mesh2;

M
Mr.doob 已提交
69
			var directionalLight;
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

			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();
100
				scene.background = new THREE.Color( 0x242a34 );
101 102 103

				// LIGHTS

M
Mr.doob 已提交
104 105 106
				scene.add( new THREE.AmbientLight( 0x333344 ) );

				directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
M
Mr.doob 已提交
107
				directionalLight.position.set( 500, 0, 500 );
108 109 110

				directionalLight.castShadow = true;

M
Mugen87 已提交
111 112
				directionalLight.shadow.mapSize.width = 2048;
				directionalLight.shadow.mapSize.height = 2048;
113

M
Mugen87 已提交
114 115
				directionalLight.shadow.camera.near = 200;
				directionalLight.shadow.camera.far = 1500;
116

M
Mugen87 已提交
117 118 119 120
				directionalLight.shadow.camera.left = -500;
				directionalLight.shadow.camera.right = 500;
				directionalLight.shadow.camera.top = 500;
				directionalLight.shadow.camera.bottom = -500;
121

M
Mugen87 已提交
122
				directionalLight.shadow.bias = -0.005;
123

M
Mr.doob 已提交
124 125
				scene.add( directionalLight );

126 127
				//

M
Mr.doob 已提交
128
				loader = new THREE.JSONLoader();
129
				loader.load( "models/json/leeperrysmith/LeePerrySmith.json", function ( geometry ) {
130 131 132 133

					createScene( geometry, 100 )

				} );
134 135 136

				//

137
				renderer = new THREE.WebGLRenderer( { antialias: true } );
138
				renderer.setPixelRatio( window.devicePixelRatio );
139 140 141
				renderer.setSize( window.innerWidth, window.innerHeight );
				container.appendChild( renderer.domElement );

M
Mr.doob 已提交
142
				renderer.shadowMap.enabled = true;
143 144 145 146 147 148 149 150 151 152 153 154 155

				renderer.autoClear = false;

				//

				renderer.gammaInput = true;
				renderer.gammaOutput = true;

				//

				if ( statsEnabled ) {

					stats = new Stats();
M
Mr.doob 已提交
156
					container.appendChild( stats.dom );
157 158 159 160 161 162 163 164 165 166 167

				}


				// COMPOSER

				renderer.autoClear = false;

				// BECKMANN

				var effectBeckmann = new THREE.ShaderPass( THREE.ShaderSkin[ "beckmann" ] );
168
				var effectCopy = new THREE.ShaderPass( THREE.CopyShader );
169

170
				effectCopy.renderToScreen = true;
171

172
				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
173 174 175 176
				var rtwidth = 512, rtheight = 512;

				composerBeckmann = new THREE.EffectComposer( renderer, new THREE.WebGLRenderTarget( rtwidth, rtheight, pars ) );
				composerBeckmann.addPass( effectBeckmann );
177
				composerBeckmann.addPass( effectCopy );
178 179 180 181 182 183 184 185 186 187

				// EVENTS

				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
				window.addEventListener( 'resize', onWindowResize, false );

			}

			function createScene( geometry, scale ) {

188 189
				var textureLoader = new THREE.TextureLoader();

190
				var mapHeight = textureLoader.load( "models/json/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
191

192
				mapHeight.anisotropy = 4;
193
				mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
194
				mapHeight.format = THREE.RGBFormat;
195

196
				var mapSpecular = textureLoader.load( "models/json/leeperrysmith/Map-SPEC.jpg" );
197

198
				mapSpecular.anisotropy = 4;
199
				mapSpecular.wrapS = mapSpecular.wrapT = THREE.RepeatWrapping;
200
				mapSpecular.format = THREE.RGBFormat;
201

202
				var mapColor = textureLoader.load( "models/json/leeperrysmith/Map-COL.jpg" );
203

204
				mapColor.anisotropy = 4;
205
				mapColor.wrapS = mapColor.wrapT = THREE.RepeatWrapping;
206
				mapColor.format = THREE.RGBFormat;
207 208 209 210 211 212

				var shader = THREE.ShaderSkin[ "skinSimple" ];

				var fragmentShader = shader.fragmentShader;
				var vertexShader = shader.vertexShader;

213
				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
214 215 216 217

				uniforms[ "enableBump" ].value = true;
				uniforms[ "enableSpecular" ].value = true;

218
				uniforms[ "tBeckmann" ].value = composerBeckmann.renderTarget1.texture;
219
				uniforms[ "tDiffuse" ].value = mapColor;
220

221 222
				uniforms[ "bumpMap" ].value = mapHeight;
				uniforms[ "specularMap" ].value = mapSpecular;
223

B
Ben Houston 已提交
224 225
				uniforms[ "diffuse" ].value.setHex( 0xa0a0a0 );
				uniforms[ "specular" ].value.setHex( 0xa0a0a0 );
226

227 228
				uniforms[ "uRoughness" ].value = 0.2;
				uniforms[ "uSpecularBrightness" ].value = 0.5;
229

230
				uniforms[ "bumpScale" ].value = 8;
231

232 233
				var material = new THREE.ShaderMaterial( { fragmentShader: fragmentShader, vertexShader: vertexShader, uniforms: uniforms, lights: true } );
				material.extensions.derivatives = true;
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250

				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 );

			}

			//

			function onWindowResize( event ) {

M
Mr.doob 已提交
251
				renderer.setSize( window.innerWidth, window.innerHeight );
252

M
Mr.doob 已提交
253
				camera.aspect = window.innerWidth / window.innerHeight;
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
				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>