|
@@ -0,0 +1,484 @@
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
+<html lang="en">
|
|
|
|
+ <head>
|
|
|
|
+ <title>three.js webgl - box projected cubemap environment mapping</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: #888888;
|
|
|
|
+ font-family:Monospace;
|
|
|
|
+ font-size:13px;
|
|
|
|
+
|
|
|
|
+ background-color: #000;
|
|
|
|
+ margin: 0px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #info {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0px;
|
|
|
|
+ width: 500px;
|
|
|
|
+ left: calc(50% - 250px);
|
|
|
|
+ text-align: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ a {
|
|
|
|
+ color: #00f;
|
|
|
|
+ }
|
|
|
|
+ </style>
|
|
|
|
+ </head>
|
|
|
|
+ <body>
|
|
|
|
+
|
|
|
|
+ <div id="container"></div>
|
|
|
|
+ <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - box projected cubemap environment mapping
|
|
|
|
+ </div>
|
|
|
|
+ <script src="../build/three.js"></script>
|
|
|
|
+ <script src="js/objects/Reflector.js"></script>
|
|
|
|
+ <script src="js/controls/OrbitControls.js"></script>
|
|
|
|
+ <script src="js/libs/dat.gui.min.js"></script>
|
|
|
|
+ <script src="js/lights/RectAreaLightUniformsLib.js"></script>
|
|
|
|
+
|
|
|
|
+ <script>
|
|
|
|
+
|
|
|
|
+ // shader injection for box projected cube environment mapping
|
|
|
|
+ var worldposReplace = `
|
|
|
|
+ #define BOX_PROJECTED_ENV_MAP
|
|
|
|
+
|
|
|
|
+ #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
|
|
|
|
+
|
|
|
|
+ vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
|
|
|
|
+
|
|
|
|
+ #ifdef BOX_PROJECTED_ENV_MAP
|
|
|
|
+
|
|
|
|
+ vWorldPosition = worldPosition.xyz;
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+ `
|
|
|
|
+
|
|
|
|
+ var envmapParsReplace = `
|
|
|
|
+ #define BOX_PROJECTED_ENV_MAP
|
|
|
|
+
|
|
|
|
+ #if defined( USE_ENVMAP ) || defined( PHYSICAL )
|
|
|
|
+
|
|
|
|
+ uniform float reflectivity;
|
|
|
|
+ uniform float envMapIntensity;
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ #ifdef USE_ENVMAP
|
|
|
|
+
|
|
|
|
+ #ifdef BOX_PROJECTED_ENV_MAP
|
|
|
|
+
|
|
|
|
+ uniform vec3 cubeMapSize;
|
|
|
|
+ uniform vec3 cubeMapPos;
|
|
|
|
+ varying vec3 vWorldPosition;
|
|
|
|
+
|
|
|
|
+ vec3 parallaxCorrectNormal( vec3 v, vec3 cubeSize, vec3 cubePos ) {
|
|
|
|
+
|
|
|
|
+ vec3 nDir = normalize( v );
|
|
|
|
+ vec3 rbmax = ( .5 * ( cubeSize - cubePos ) - vWorldPosition ) / nDir;
|
|
|
|
+ vec3 rbmin = ( - .5 * ( cubeSize - cubePos ) - vWorldPosition ) / nDir;
|
|
|
|
+
|
|
|
|
+ vec3 rbminmax;
|
|
|
|
+ rbminmax.x = ( nDir.x > 0. ) ? rbmax.x : rbmin.x;
|
|
|
|
+ rbminmax.y = ( nDir.y > 0. ) ? rbmax.y : rbmin.y;
|
|
|
|
+ rbminmax.z = ( nDir.z > 0. ) ? rbmax.z : rbmin.z;
|
|
|
|
+
|
|
|
|
+ float correction = min( min( rbminmax.x, rbminmax.y ), rbminmax.z );
|
|
|
|
+ vec3 boxIntersection = vWorldPosition + nDir * correction;
|
|
|
|
+
|
|
|
|
+ return boxIntersection - cubePos;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ #if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )
|
|
|
|
+
|
|
|
|
+ varying vec3 vWorldPosition;
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ #ifdef ENVMAP_TYPE_CUBE
|
|
|
|
+
|
|
|
|
+ uniform samplerCube envMap;
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ uniform sampler2D envMap;
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ uniform float flipEnvMap;
|
|
|
|
+ uniform int maxMipLevel;
|
|
|
|
+
|
|
|
|
+ #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )
|
|
|
|
+
|
|
|
|
+ uniform float refractionRatio;
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ varying vec3 vReflect;
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+ `;
|
|
|
|
+
|
|
|
|
+ var envmapPhysicalParsReplace = `
|
|
|
|
+ #if defined( USE_ENVMAP ) && defined( PHYSICAL )
|
|
|
|
+
|
|
|
|
+ vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {
|
|
|
|
+ vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );
|
|
|
|
+ #ifdef ENVMAP_TYPE_CUBE
|
|
|
|
+
|
|
|
|
+ vec3 worldNormalFinal = worldNormal;
|
|
|
|
+
|
|
|
|
+ #ifdef BOX_PROJECTED_ENV_MAP
|
|
|
|
+
|
|
|
|
+ worldNormalFinal = parallaxCorrectNormal( worldNormal, cubeMapSize, cubeMapPos );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ vec3 queryVec = vec3( flipEnvMap * worldNormalFinal.x, worldNormalFinal.yz );
|
|
|
|
+
|
|
|
|
+ #ifdef TEXTURE_LOD_EXT
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
|
|
|
|
+
|
|
|
|
+ #elif defined( ENVMAP_TYPE_CUBE_UV )
|
|
|
|
+
|
|
|
|
+ vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );
|
|
|
|
+ vec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = vec4( 0.0 );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ return PI * envMapColor.rgb * envMapIntensity;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {
|
|
|
|
+ float maxMIPLevelScalar = float( maxMIPLevel );
|
|
|
|
+ float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
|
|
|
|
+ return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ vec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {
|
|
|
|
+
|
|
|
|
+ #ifdef ENVMAP_MODE_REFLECTION
|
|
|
|
+
|
|
|
|
+ vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
|
|
|
|
+ float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );
|
|
|
|
+
|
|
|
|
+ #ifdef ENVMAP_TYPE_CUBE
|
|
|
|
+
|
|
|
|
+ vec3 reflectVecFinal = reflectVec;
|
|
|
|
+
|
|
|
|
+ #ifdef BOX_PROJECTED_ENV_MAP
|
|
|
|
+
|
|
|
|
+ reflectVecFinal = parallaxCorrectNormal( reflectVec, cubeMapSize, cubeMapPos );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ vec3 queryReflectVec = vec3( flipEnvMap * reflectVecFinal.x, reflectVecFinal.yz );
|
|
|
|
+
|
|
|
|
+ #ifdef TEXTURE_LOD_EXT
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
|
|
|
|
+
|
|
|
|
+ #elif defined( ENVMAP_TYPE_CUBE_UV )
|
|
|
|
+
|
|
|
|
+ vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
|
|
|
|
+ vec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));
|
|
|
|
+
|
|
|
|
+ #elif defined( ENVMAP_TYPE_EQUIREC )
|
|
|
|
+
|
|
|
|
+ vec2 sampleUV;
|
|
|
|
+ sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
|
|
|
|
+ sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
|
|
|
|
+
|
|
|
|
+ #ifdef TEXTURE_LOD_EXT
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
|
|
|
|
+ #elif defined( ENVMAP_TYPE_SPHERE )
|
|
|
|
+
|
|
|
|
+ vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );
|
|
|
|
+
|
|
|
|
+ #ifdef TEXTURE_LOD_EXT
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
|
|
|
|
+
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ return envMapColor.rgb * envMapIntensity;
|
|
|
|
+ }
|
|
|
|
+ #endif
|
|
|
|
+ `;
|
|
|
|
+
|
|
|
|
+ // scene size
|
|
|
|
+ var WIDTH = window.innerWidth;
|
|
|
|
+ var HEIGHT = window.innerHeight;
|
|
|
|
+
|
|
|
|
+ // camera
|
|
|
|
+ var VIEW_ANGLE = 45;
|
|
|
|
+ var ASPECT = WIDTH / HEIGHT;
|
|
|
|
+ var NEAR = 1;
|
|
|
|
+ var FAR = 800;
|
|
|
|
+
|
|
|
|
+ var camera, scene, renderer;
|
|
|
|
+
|
|
|
|
+ var cameraControls;
|
|
|
|
+
|
|
|
|
+ var groundPlane, smallSphere, wallMat;
|
|
|
|
+
|
|
|
|
+ init();
|
|
|
|
+ animate();
|
|
|
|
+
|
|
|
|
+ function init() {
|
|
|
|
+
|
|
|
|
+ var container = document.getElementById( 'container' );
|
|
|
|
+
|
|
|
|
+ // renderer
|
|
|
|
+ renderer = new THREE.WebGLRenderer( { antialias: true } );
|
|
|
|
+ renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
|
+ renderer.setSize( WIDTH, HEIGHT );
|
|
|
|
+ container.appendChild( renderer.domElement );
|
|
|
|
+
|
|
|
|
+ // gui controls
|
|
|
|
+ var gui = new dat.GUI();
|
|
|
|
+ var params = {
|
|
|
|
+ 'box projected': true
|
|
|
|
+ };
|
|
|
|
+ var bpcemGui = gui.add( params, 'box projected' );
|
|
|
|
+
|
|
|
|
+ bpcemGui.onChange( function( value ) {
|
|
|
|
+ if ( value ){
|
|
|
|
+
|
|
|
|
+ groundPlane.material = boxProjectedMat;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ groundPlane.material = defaultMat;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // scene
|
|
|
|
+ scene = new THREE.Scene();
|
|
|
|
+
|
|
|
|
+ // camera
|
|
|
|
+ camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
|
|
|
|
+ camera.position.set( 280, 106, -5 );
|
|
|
|
+
|
|
|
|
+ cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
|
|
|
|
+ cameraControls.target.set( 0, -10, 0 );
|
|
|
|
+ cameraControls.maxDistance = 400;
|
|
|
|
+ cameraControls.minDistance = 10;
|
|
|
|
+ cameraControls.update();
|
|
|
|
+
|
|
|
|
+ // cube camera for environment map
|
|
|
|
+ cubeCamera = new THREE.CubeCamera( 1, 1000, 512 );
|
|
|
|
+ cubeCamera.renderTarget.texture.generateMipmaps = true;
|
|
|
|
+ cubeCamera.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter;
|
|
|
|
+ cubeCamera.renderTarget.texture.magFilter = THREE.LinearFilter;
|
|
|
|
+ cubeCamera.renderTarget.texture.mapping = THREE.CubeReflectionMapping;
|
|
|
|
+
|
|
|
|
+ cubeCamera.position.set( 0, -100, 0 );
|
|
|
|
+ scene.add( cubeCamera );
|
|
|
|
+
|
|
|
|
+ // ground floor ( with box projected environment mapping )
|
|
|
|
+ var loader = new THREE.TextureLoader();
|
|
|
|
+ var rMap = loader.load( 'textures/lava/lavatile.jpg' );
|
|
|
|
+ rMap.wrapS = THREE.RepeatWrapping;
|
|
|
|
+ rMap.wrapT = THREE.RepeatWrapping;
|
|
|
|
+ rMap.repeat.set(2,1);
|
|
|
|
+
|
|
|
|
+ var defaultMat = new THREE.MeshPhysicalMaterial({
|
|
|
|
+ roughness: 1,
|
|
|
|
+ envMap: cubeCamera.renderTarget.texture,
|
|
|
|
+ roughnessMap: rMap,
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ var boxProjectedMat = new THREE.MeshPhysicalMaterial({
|
|
|
|
+ color: new THREE.Color('#ffffff'),
|
|
|
|
+ roughness: 1,
|
|
|
|
+ envMap: cubeCamera.renderTarget.texture,
|
|
|
|
+ roughnessMap: rMap,
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ boxProjectedMat.onBeforeCompile = function ( shader ) {
|
|
|
|
+
|
|
|
|
+ shader.uniforms.cubeMapSize = { value: new THREE.Vector3( 200, 100, 100 ) };
|
|
|
|
+ shader.uniforms.cubeMapPos = { value: new THREE.Vector3( 0, -50, 0 ) };
|
|
|
|
+ shader.uniforms.flipEnvMap.value = true;
|
|
|
|
+
|
|
|
|
+ //replace shader chunks with box projection chunks
|
|
|
|
+ shader.vertexShader = 'varying vec3 vWorldPosition;\n' + shader.vertexShader;
|
|
|
|
+
|
|
|
|
+ shader.vertexShader = shader.vertexShader.replace(
|
|
|
|
+ '#include <worldpos_vertex>',
|
|
|
|
+ worldposReplace
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ shader.fragmentShader = shader.fragmentShader.replace(
|
|
|
|
+ '#include <envmap_pars_fragment>',
|
|
|
|
+ envmapParsReplace
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ shader.fragmentShader = shader.fragmentShader.replace(
|
|
|
|
+ '#include <envmap_physical_pars_fragment>',
|
|
|
|
+ envmapPhysicalParsReplace
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ materialShader = shader;
|
|
|
|
+
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ groundPlane = new THREE.Mesh( new THREE.PlaneGeometry( 200, 100, 100 ), boxProjectedMat );
|
|
|
|
+ groundPlane.rotateX( - Math.PI / 2 );
|
|
|
|
+ groundPlane.position.set( 0, - 49, 0 );
|
|
|
|
+ groundPlane.geometry.computeVertexNormals();
|
|
|
|
+ scene.add( groundPlane );
|
|
|
|
+
|
|
|
|
+ // walls
|
|
|
|
+ var diffuseTex = loader.load( 'textures/brick_diffuse.jpg', () => {
|
|
|
|
+ updateCubeMap();
|
|
|
|
+ } );
|
|
|
|
+ var bumpTex = loader.load( 'textures/brick_bump.jpg', () => {
|
|
|
|
+ updateCubeMap();
|
|
|
|
+ } );
|
|
|
|
+ wallMat = new THREE.MeshPhysicalMaterial({
|
|
|
|
+ map: diffuseTex,
|
|
|
|
+ bumpMap: bumpTex,
|
|
|
|
+ bumpScale: 0.3,
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ var planeGeo = new THREE.PlaneBufferGeometry( 100, 100 );
|
|
|
|
+
|
|
|
|
+ var planeBack1 = new THREE.Mesh( planeGeo, wallMat );
|
|
|
|
+ planeBack1.position.z = - 50;
|
|
|
|
+ planeBack1.position.x = - 50;
|
|
|
|
+ scene.add( planeBack1 );
|
|
|
|
+
|
|
|
|
+ var planeBack2 = new THREE.Mesh( planeGeo, wallMat );
|
|
|
|
+ planeBack2.position.z = - 50;
|
|
|
|
+ planeBack2.position.x = 50;
|
|
|
|
+ scene.add( planeBack2 );
|
|
|
|
+
|
|
|
|
+ var planeFront1 = new THREE.Mesh( planeGeo, wallMat );
|
|
|
|
+ planeFront1.position.z = 50;
|
|
|
|
+ planeFront1.position.x = - 50;
|
|
|
|
+ planeFront1.rotateY( Math.PI );
|
|
|
|
+ scene.add( planeFront1 );
|
|
|
|
+
|
|
|
|
+ var planeFront2 = new THREE.Mesh( planeGeo, wallMat );
|
|
|
|
+ planeFront2.position.z = 50;
|
|
|
|
+ planeFront2.position.x = 50;
|
|
|
|
+ planeFront2.rotateY( Math.PI );
|
|
|
|
+ scene.add( planeFront2 );
|
|
|
|
+
|
|
|
|
+ var planeRight = new THREE.Mesh( planeGeo, wallMat );
|
|
|
|
+ planeRight.position.x = 100;
|
|
|
|
+ planeRight.rotateY( - Math.PI / 2 );
|
|
|
|
+ scene.add( planeRight );
|
|
|
|
+
|
|
|
|
+ var planeLeft = new THREE.Mesh( planeGeo, wallMat );
|
|
|
|
+ planeLeft.position.x = - 100;
|
|
|
|
+ planeLeft.rotateY( Math.PI / 2 );
|
|
|
|
+ scene.add( planeLeft );
|
|
|
|
+
|
|
|
|
+ //lights
|
|
|
|
+ var width = 50;
|
|
|
|
+ var height = 50;
|
|
|
|
+ var intensity = 10;
|
|
|
|
+ var blueRectLight = new THREE.RectAreaLight( 0xf3aaaa, intensity, width, height );
|
|
|
|
+ blueRectLight.position.set( 99, 5, 0 );
|
|
|
|
+ blueRectLight.lookAt( 0, 5, 0 );
|
|
|
|
+ scene.add( blueRectLight );
|
|
|
|
+
|
|
|
|
+ blueRectLightHelper = new THREE.RectAreaLightHelper( blueRectLight, 0xffffff );
|
|
|
|
+ blueRectLight.add( blueRectLightHelper );
|
|
|
|
+
|
|
|
|
+ var redRectLight = new THREE.RectAreaLight( 0x9aaeff, intensity, width, height );
|
|
|
|
+ redRectLight.position.set( - 99, 5, 0 );
|
|
|
|
+ redRectLight.lookAt( 0, 5, 0 );
|
|
|
|
+ scene.add( redRectLight );
|
|
|
|
+
|
|
|
|
+ redRectLightHelper = new THREE.RectAreaLightHelper( redRectLight, 0xffffff );
|
|
|
|
+ redRectLight.add( redRectLightHelper );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function updateCubeMap () {
|
|
|
|
+
|
|
|
|
+ //disable specular highlights on walls in the environment map
|
|
|
|
+ wallMat.roughness = 1;
|
|
|
|
+
|
|
|
|
+ groundPlane.visible = false;
|
|
|
|
+
|
|
|
|
+ cubeCamera.position.copy( groundPlane.position );
|
|
|
|
+
|
|
|
|
+ cubeCamera.update( renderer, scene );
|
|
|
|
+
|
|
|
|
+ wallMat.roughness = 0.6;
|
|
|
|
+
|
|
|
|
+ groundPlane.visible = true;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function animate() {
|
|
|
|
+
|
|
|
|
+ requestAnimationFrame( animate );
|
|
|
|
+
|
|
|
|
+ renderer.render( scene, camera );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ </script>
|
|
|
|
+ </body>
|
|
|
|
+</html>
|