提交 bedee743 编写于 作者: S Sneha Belkhale

adding example for box projected cube environment mapping

上级 327c9dde
......@@ -4,6 +4,7 @@ var files = {
"webgl_animation_keyframes",
"webgl_animation_skinning_blending",
"webgl_animation_skinning_morph",
"webgl_box_projected_cubemap_environment_mapping",
"webgl_camera",
"webgl_camera_array",
"webgl_camera_cinematic",
......
<!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>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册