Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign up| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <title>three.js webgl - physically based shading</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 { | |
| color: #fff; | |
| font-family: Monospace; | |
| font-size: 13px; | |
| text-align: center; | |
| font-weight: bold; | |
| background-color: #000; | |
| margin: 0px; | |
| overflow: hidden; | |
| } | |
| #info { | |
| position: absolute; | |
| width: 100%; | |
| text-align: center; | |
| padding: 5px; | |
| } | |
| a { color: skyblue; } | |
| </style> | |
| <script> | |
| (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | |
| (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | |
| m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | |
| })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); | |
| ga('create', 'UA-89125623-1', 'auto'); | |
| ga('send', 'pageview'); | |
| </script> | |
| </head> | |
| <body> | |
| <div id="info"> | |
| <a href="http://threejs.org" target="_blank">three.js</a> - webgl physically based shading testbed | |
| </div> | |
| <div class="buttonHolder" style="position:relative;text-align:center;top:40px"> | |
| <button class="startButton" onclick="startCapture360()">Start Capture</button> | |
| <button class="saveButton" onclick="stopCapture360()">Stop Capture</button> | |
| </div> | |
| <script src="js/three.min.js"></script> | |
| <script src="js/TrackballControls.js"></script> | |
| <!-- movie capture section --> | |
| <script src="js/CCapture.js"></script> | |
| <!-- Include tar.js if you want to export PNG or JPEG --> | |
| <script src="js/tar.js"></script> | |
| <!-- Include download.js for easier file download --> | |
| <script src="js/download.js"></script> | |
| <!-- 360 capture section --> | |
| <script src="js/CubemapToEquirectangular.js"></script> | |
| <script> | |
| var container; | |
| var camera, scene, renderer, canvas; | |
| var mesh, geometry; | |
| var cubeCamera; | |
| var sunLight, pointLight, ambientLight; | |
| var mixer; | |
| var clock = new THREE.Clock(); | |
| var shadowCameraHelper, shadowConfig = { | |
| shadowCameraVisible: false, | |
| shadowCameraNear: 750, | |
| shadowCameraFar: 4000, | |
| shadowCameraFov: 30, | |
| shadowBias: -0.0002 | |
| }; | |
| // Create a capturer that exports Equirectangular 360 JPG images in a TAR file | |
| var capturer360 = new CCapture({ | |
| format: 'threesixty', | |
| display:true, | |
| autoSaveTime: 3, | |
| }); | |
| function startCapture360(event) { | |
| capturer360.start(); | |
| } | |
| function saveCapture360(event) { | |
| capturer360.save(); | |
| } | |
| function stopCapture360(event) { | |
| capturer360.stop(); | |
| } | |
| function capture360(event) { | |
| return equiManaged.update(camera, scene); | |
| } | |
| init(); | |
| animate(); | |
| function init() { | |
| container = document.createElement( 'div' ); | |
| document.body.appendChild( container ); | |
| // CAMERA | |
| camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 2, 10000 ); | |
| camera.position.set( 500, 400, 1200 ); | |
| // SCENE | |
| scene = new THREE.Scene(); | |
| scene.fog = new THREE.Fog( 0, 1000, 10000 ); | |
| // CUBE CAMERA | |
| cubeCamera = new THREE.CubeCamera( 1, 10000, 128 ); | |
| // TEXTURES | |
| var textureLoader = new THREE.TextureLoader(); | |
| var textureSquares = textureLoader.load( "textures/bright_squares256.png" ); | |
| textureSquares.repeat.set( 50, 50 ); | |
| textureSquares.wrapS = textureSquares.wrapT = THREE.RepeatWrapping; | |
| textureSquares.magFilter = THREE.NearestFilter; | |
| textureSquares.format = THREE.RGBFormat; | |
| var textureNoiseColor = textureLoader.load( "textures/disturb.jpg" ); | |
| textureNoiseColor.repeat.set( 1, 1 ); | |
| textureNoiseColor.wrapS = textureNoiseColor.wrapT = THREE.RepeatWrapping; | |
| textureNoiseColor.format = THREE.RGBFormat; | |
| var textureLava = textureLoader.load( "textures/lavatile.jpg" ); | |
| textureLava.repeat.set( 6, 2 ); | |
| textureLava.wrapS = textureLava.wrapT = THREE.RepeatWrapping; | |
| textureLava.format = THREE.RGBFormat; | |
| // | |
| var path = "textures/SwedishRoyalCastle/"; | |
| var format = '.jpg'; | |
| var urls = [ | |
| path + 'px' + format, path + 'nx' + format, | |
| path + 'py' + format, path + 'ny' + format, | |
| path + 'pz' + format, path + 'nz' + format | |
| ]; | |
| var reflectionCube = new THREE.CubeTextureLoader().load( urls ); | |
| // GROUND | |
| var groundMaterial = new THREE.MeshPhongMaterial( { | |
| shininess: 80, | |
| color: 0xffffff, | |
| specular: 0xffffff, | |
| map: textureSquares | |
| } ); | |
| var planeGeometry = new THREE.PlaneBufferGeometry( 100, 100 ); | |
| var ground = new THREE.Mesh( planeGeometry, groundMaterial ); | |
| ground.position.set( 0, 0, 0 ); | |
| ground.rotation.x = - Math.PI / 2; | |
| ground.scale.set( 1000, 1000, 1000 ); | |
| ground.receiveShadow = true; | |
| scene.add( ground ); | |
| // MATERIALS | |
| var materialLambert = new THREE.MeshPhongMaterial( { shininess: 50, color: 0xffffff, map: textureNoiseColor } ); | |
| var materialPhong = new THREE.MeshPhongMaterial( { shininess: 50, color: 0xffffff, specular: 0x999999, map: textureLava } ); | |
| var materialPhongCube = new THREE.MeshPhongMaterial( { shininess: 50, color: 0xffffff, specular: 0x999999, envMap: cubeCamera.renderTarget.texture } ); | |
| // OBJECTS | |
| var sphereGeometry = new THREE.SphereGeometry( 100, 64, 32 ); | |
| var torusGeometry = new THREE.TorusGeometry( 240, 60, 32, 64 ); | |
| var cubeGeometry = new THREE.BoxGeometry( 150, 150, 150 ); | |
| addObject( torusGeometry, materialPhong, 0, 100, 0, 0 ); | |
| addObject( cubeGeometry, materialLambert, 350, 75, 300, 0 ); | |
| mesh = addObject( sphereGeometry, materialPhongCube, 350, 100, -350, 0 ); | |
| mesh.add( cubeCamera ); | |
| function addObjectColor( geometry, color, x, y, z, ry ) { | |
| var material = new THREE.MeshPhongMaterial( { color: 0xffffff } ); | |
| return addObject( geometry, material, x, y, z, ry ); | |
| } | |
| function addObject( geometry, material, x, y, z, ry ) { | |
| var tmpMesh = new THREE.Mesh( geometry, material ); | |
| tmpMesh.material.color.offsetHSL( 0.1, -0.1, 0 ); | |
| tmpMesh.position.set( x, y, z ); | |
| tmpMesh.rotation.y = ry; | |
| tmpMesh.castShadow = true; | |
| tmpMesh.receiveShadow = true; | |
| scene.add( tmpMesh ); | |
| return tmpMesh; | |
| } | |
| var bigCube = new THREE.BoxGeometry( 50, 500, 50 ); | |
| var midCube = new THREE.BoxGeometry( 50, 200, 50 ); | |
| var smallCube = new THREE.BoxGeometry( 100, 100, 100 ); | |
| addObjectColor( bigCube, 0xff0000, -500, 250, 0, 0 ); | |
| addObjectColor( smallCube, 0xff0000, -500, 50, -150, 0 ); | |
| addObjectColor( midCube, 0x00ff00, 500, 100, 0, 0 ); | |
| addObjectColor( smallCube, 0x00ff00, 500, 50, -150, 0 ); | |
| addObjectColor( midCube, 0x0000ff, 0, 100, -500, 0 ); | |
| addObjectColor( smallCube, 0x0000ff, -150, 50, -500, 0 ); | |
| addObjectColor( midCube, 0xff00ff, 0, 100, 500, 0 ); | |
| addObjectColor( smallCube, 0xff00ff, -150, 50, 500, 0 ); | |
| addObjectColor( new THREE.BoxGeometry( 500, 10, 10 ), 0xffff00, 0, 600, 0, Math.PI/4 ); | |
| addObjectColor( new THREE.BoxGeometry( 250, 10, 10 ), 0xffff00, 0, 600, 0, 0 ); | |
| addObjectColor( new THREE.SphereGeometry( 100, 32, 26 ), 0xffffff, -300, 100, 300, 0 ); | |
| // MORPHS | |
| var loader = new THREE.JSONLoader(); | |
| loader.load( "textures/sittingBox.js", function( geometry ) { | |
| var morphMaterial = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0xff9900, shininess: 50, morphTargets: true, side: THREE.DoubleSide, shading: THREE.FlatShading } ); | |
| var mesh = new THREE.Mesh( geometry, morphMaterial ); | |
| mixer = new THREE.AnimationMixer( mesh ); | |
| mixer.clipAction( geometry.animations[0] ).setDuration( 10 ).play(); | |
| var s = 200; | |
| mesh.scale.set( s, s, s ); | |
| mesh.castShadow = true; | |
| mesh.receiveShadow = true; | |
| scene.add( mesh ); | |
| } ); | |
| // LIGHTS | |
| ambientLight = new THREE.AmbientLight( 0x3f2806 ); | |
| scene.add( ambientLight ); | |
| pointLight = new THREE.PointLight( 0xffaa00, 1, 5000 ); | |
| scene.add( pointLight ); | |
| sunLight = new THREE.SpotLight( 0xffffff, 0.3, 0, Math.PI/2 ); | |
| sunLight.position.set( 1000, 2000, 1000 ); | |
| sunLight.castShadow = true; | |
| sunLight.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( shadowConfig.shadowCameraFov, 1, shadowConfig.shadowCameraNear, shadowConfig.shadowCameraFar ) ); | |
| sunLight.shadow.bias = shadowConfig.shadowBias; | |
| scene.add( sunLight ); | |
| // SHADOW CAMERA HELPER | |
| shadowCameraHelper = new THREE.CameraHelper( sunLight.shadow.camera ); | |
| shadowCameraHelper.visible = shadowConfig.shadowCameraVisible; | |
| scene.add( shadowCameraHelper ); | |
| // RENDERER | |
| renderer = new THREE.WebGLRenderer( { antialias: true } ); | |
| renderer.setPixelRatio( window.devicePixelRatio ); | |
| renderer.setSize( window.innerWidth, window.innerHeight ); | |
| canvas=container.appendChild( renderer.domElement ); | |
| // | |
| renderer.shadowMap.enabled = true; | |
| renderer.shadowMap.type = THREE.PCFSoftShadowMap; | |
| // | |
| renderer.gammaInput = true; | |
| renderer.gammaOutput = true; | |
| // | |
| equiManaged = new CubemapToEquirectangular(renderer, true,"4K"); | |
| controls = new THREE.TrackballControls( camera, renderer.domElement ); | |
| controls.target.set( 0, 120, 0 ); | |
| controls.rotateSpeed = 1.0; | |
| controls.zoomSpeed = 1.2; | |
| controls.panSpeed = 0.8; | |
| controls.noZoom = false; | |
| controls.noPan = false; | |
| controls.staticMoving = true; | |
| controls.dynamicDampingFactor = 0.15; | |
| controls.keys = [ 65, 83, 68 ]; | |
| } | |
| // | |
| function onWindowResize( event ) { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize( window.innerWidth, window.innerHeight ); | |
| controls.handleResize(); | |
| } | |
| // | |
| function animate() { | |
| requestAnimationFrame( animate ); | |
| render(); | |
| } | |
| function render() { | |
| // update | |
| var delta = clock.getDelta(); | |
| controls.update(); | |
| if ( mixer ) { | |
| mixer.update( delta ); | |
| } | |
| // render cube map | |
| mesh.visible = false; | |
| cubeCamera.updateCubeMap( renderer, scene ); | |
| mesh.visible = true; | |
| // render scene | |
| renderer.render( scene, camera ); | |
| capturer360.capture(canvas); | |
| } | |
| </script> | |
| </body> | |
| </html> |