提交 484f364e 编写于 作者: M Michael Bond

Adding different environment mapping types including equirectangular mapping and sphere mapping

上级 33f25b17
此差异已折叠。
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - materials - cube reflection [cars]</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;
overflow:hidden;
font-family:georgia;
text-align:center;
}
h1 { }
a { color:skyblue; text-decoration:none }
canvas { pointer-events:none; z-index:10; position:relative; }
#d { position:absolute; width: 100%; text-align:center; margin:1em 0 -4.5em 0; z-index:1000; }
.bwrap { margin:0.5em 0 0 0 }
button { font-family:georgia; border:0; background:#000; color:#fff; padding:0.2em 0.5em; cursor:pointer; border-radius:3px; }
button:hover { background:#333 }
#buttons_cars button { color:#fa0 }
#car_info { text-align:center; }
#car_name { font-size:1em }
#car_author { font-size:1em }
.dg { z-index: 100 }
#oldie { background:rgb(50,0,0) !important; color:#fff !important; margin-top:7em!important }
</style>
</head>
<body>
<script src="../build/three.js"></script>
<script src="js/loaders/BinaryLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - webgl environment mapping example<br/>
Equirectangular Map by <a href="http://gl.ict.usc.edu/Data/HighResProbes/">University of Southern California</a><br/>
Spherical Map by <a href="http://www.pauldebevec.com/Probes/">Paul Debevec</a>
</div>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var STATS_ENABLED = false;
var container, stats;
var camera, scene, renderer;
var cameraCube, sceneCube;
var textureEquirec, textureCube, textureSphere;
var cubeMesh, sphereMesh;
var sphereMaterial;
var refract;
var m, mi;
var directionalLight, pointLight;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
// var loader = new THREE.BinaryLoader( true );
// document.body.appendChild( loader.statusDomElement );
init();
animate();
function init() {
params = {
stuff: 0.4,
useCube: function() {
cubeMesh.material = cubeMaterial;
sphereMaterial.envMap = textureCube;
sphereMaterial.needsUpdate = true;
},
useEquirect: function() {
cubeMesh.material = equirectMaterial;
sphereMaterial.envMap = textureEquirec;
sphereMaterial.needsUpdate = true;
},
useSphere: function() {
cubeMesh.material = equirectMaterial;
sphereMaterial.envMap = textureSphere;
sphereMaterial.needsUpdate = true;
},
toggleRefraction: function() {
refract = !refract;
if ( refract ) {
textureEquirec.mapping = THREE.EquirectangularRefractionMapping;
textureCube.mapping = THREE.CubeRefractionMapping;
textureSphere.mapping = THREE.SphericalRefractionMapping;
}
else {
textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
textureCube.mapping = THREE.CubeReflectionMapping;
textureSphere.mapping = THREE.SphericalReflectionMapping;
}
sphereMaterial.needsUpdate = true;
}
};
container = document.createElement( 'div' );
document.body.appendChild( container );
// CAMERAS
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
cameraCube = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
// SCENE
scene = new THREE.Scene();
sceneCube = new THREE.Scene();
// LIGHTS
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
// directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
// directionalLight.position.set( 2, 1.2, 10 ).normalize();
// scene.add( directionalLight );
// directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
// directionalLight.position.set( -2, 1.2, -10 ).normalize();
// scene.add( directionalLight );
// pointLight = new THREE.PointLight( 0xffaa00, 2 );
// pointLight.position.set( 2000, 1200, 10000 );
// scene.add( pointLight );
// Skybox
var equirectShader = THREE.ShaderLib[ "equirect" ];
// shader.uniforms[ "tCube" ].value = textureCube;
var equirectMaterial = new THREE.ShaderMaterial( {
fragmentShader: equirectShader.fragmentShader,
vertexShader: equirectShader.vertexShader,
uniforms: equirectShader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
var cubeShader = THREE.ShaderLib[ "cube" ];
var cubeMaterial = new THREE.ShaderMaterial( {
fragmentShader: cubeShader.fragmentShader,
vertexShader: cubeShader.vertexShader,
uniforms: cubeShader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
cubeMesh = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100 ), cubeMaterial );
sceneCube.add( cubeMesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setFaceCulling( THREE.CullFaceNone );
renderer.autoClear = false;
container.appendChild( renderer.domElement );
if ( STATS_ENABLED ) {
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
}
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
var r = "textures/cube/Bridge2/";
var urls = [ r + "posx.jpg", r + "negx.jpg",
r + "posy.jpg", r + "negy.jpg",
r + "posz.jpg", r + "negz.jpg" ];
textureCube = THREE.ImageUtils.loadTextureCube( urls );
textureCube.format = THREE.RGBFormat;
textureCube.mapping = THREE.CubeReflectionMapping;
cubeMaterial.uniforms[ "tCube" ].value = textureCube;
textureEquirec = THREE.ImageUtils.loadTexture( "textures/environment/grace-new.jpg" );
textureEquirec.format = THREE.RGBAFormat;
textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
textureEquirec.magFilter = THREE.LinearFilter;
textureEquirec.minFilter = THREE.LinearFilter;
equirectMaterial.uniforms[ "tEquirect" ].value = textureEquirec;
textureSphere = THREE.ImageUtils.loadTexture( "textures/environment/grace_probe.jpg" );
textureSphere.mapping = THREE.SphericalReflectionMapping;
var gui = new dat.GUI();
// gui.domElement.style['z-index'] = 100;
gui.add( params, 'toggleRefraction' );
gui.add( params, 'useCube' );
gui.add( params, 'useEquirect' );
gui.add( params, 'useSphere' );
gui.open();
createScene();
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
cameraCube.aspect = window.innerWidth / window.innerHeight;
cameraCube.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function createScene( ) {
var geometry = new THREE.SphereGeometry( 400.0, 24, 24 );
sphereMaterial = new THREE.MeshLambertMaterial( { envMap: textureCube } );
sphereMesh = new THREE.Mesh( geometry, sphereMaterial );
// sphereMesh.scale.x = mesh.scale.y = mesh.scale.z = s;
scene.add( sphereMesh );
$('.dg.ac').css('z-index', 100);
}
function onDocumentMouseMove(event) {
mouseY = ( event.clientY - window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var timer = -0.0002 * Date.now();
camera.position.x = 1000 * Math.cos( timer );
camera.position.y += ( - mouseY - camera.position.y ) * .05;
camera.position.z = 1000 * Math.sin( timer );
camera.lookAt( scene.position );
cameraCube.rotation.copy( camera.rotation );
renderer.render( sceneCube, cameraCube );
renderer.render( scene, camera );
if ( STATS_ENABLED ) stats.update();
}
</script>
</body>
</html>
......@@ -115,13 +115,16 @@ THREE.AddOperation = 2;
// Mapping modes
THREE.UVMapping = function () {};
THREE.UVMapping = 300;
THREE.CubeReflectionMapping = function () {};
THREE.CubeRefractionMapping = function () {};
THREE.CubeReflectionMapping = 301;
THREE.CubeRefractionMapping = 302;
THREE.SphericalReflectionMapping = function () {};
THREE.SphericalRefractionMapping = function () {};
THREE.SphericalReflectionMapping = 303;
THREE.SphericalRefractionMapping = 304;
THREE.EquirectangularReflectionMapping = 305;
THREE.EquirectangularRefractionMapping = 306;
// Wrapping modes
......
......@@ -4716,7 +4716,10 @@ THREE.WebGLRenderer = function ( parameters ) {
uniforms.refractionRatio.value = material.refractionRatio;
uniforms.combine.value = material.combine;
uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
uniforms.useRefract.value = material.envMap && (
material.envMap.mapping === THREE.CubeRefractionMapping ||
material.envMap.mapping === THREE.SphericalRefractionMapping ||
material.envMap.mapping === THREE.EquirectangularRefractionMapping );
}
......
......@@ -28,33 +28,45 @@
#endif
#ifdef DOUBLE_SIDED
float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );
vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
#else
float flipNormal = 1.0;
#endif
#ifdef ENVMAP_TYPE_CUBE
vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
#elif defined( ENVMAP_TYPE_EQUIREC )
// #ifdef DOUBLE_SIDED
vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
// float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );
vec2 sampleUV;
sampleUV.y = clamp( flipNormal * reflectVec.y * 0.5 + 0.5, 0.0, 1.0);
sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * 0.15915494309189533576888376337251 + 0.5; // reciprocal( 2 PI ) + 0.5
vec4 envColor = texture2D( envMap, sampleUV );
#elif defined( ENVMAP_TYPE_SPHERE )
vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));
vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
#endif
#ifdef GAMMA_INPUT
cubeColor.xyz *= cubeColor.xyz;
envColor.xyz *= envColor.xyz;
#endif
if ( combine == 1 ) {
gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );
gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );
} else if ( combine == 2 ) {
gl_FragColor.xyz += cubeColor.xyz * specularStrength * reflectivity;
gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;
} else {
gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );
gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );
}
......
#ifdef USE_ENVMAP
uniform float reflectivity;
uniform samplerCube envMap;
#ifdef ENVMAP_TYPE_CUBE
uniform samplerCube envMap;
#else
uniform sampler2D envMap;
#endif
uniform float flipEnvMap;
uniform int combine;
......
......@@ -1254,6 +1254,60 @@ THREE.ShaderLib = {
},
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
'equirect': {
uniforms: { "tEquirect": { type: "t", value: null },
"tFlip": { type: "f", value: - 1 } },
vertexShader: [
"varying vec3 vWorldPosition;",
THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
"void main() {",
" vec4 worldPosition = modelMatrix * vec4( position, 1.0 );",
" vWorldPosition = worldPosition.xyz;",
" gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
THREE.ShaderChunk[ "logdepthbuf_vertex" ],
"}"
].join("\n"),
fragmentShader: [
"uniform sampler2D tEquirect;",
"uniform float tFlip;",
"varying vec3 vWorldPosition;",
THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
"void main() {",
// " gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",
"vec3 direction = normalize( vWorldPosition );",
"vec2 sampleUV;",
"sampleUV.y = clamp( tFlip * direction.y * -0.5 + 0.5, 0.0, 1.0);",
"sampleUV.x = atan( direction.z, direction.x ) * 0.15915494309189533576888376337251 + 0.5;", // reciprocal( 2 PI ) + 0.5
"gl_FragColor = texture2D( tEquirect, sampleUV );",
THREE.ShaderChunk[ "logdepthbuf_fragment" ],
"}"
].join("\n")
},
/* Depth encoding into RGBA texture
*
* based on SpiderGL shadow map example
......
......@@ -84,6 +84,24 @@ THREE.WebGLProgram = ( function () {
}
var envMapTypeDefine = null;
if ( parameters.envMap ) {
switch ( material.envMap.mapping ) {
case THREE.CubeReflectionMapping:
case THREE.CubeRefractionMapping:
envMapTypeDefine = "ENVMAP_TYPE_CUBE";
break;
case THREE.SphericalReflectionMapping:
case THREE.SphericalRefractionMapping:
envMapTypeDefine = "ENVMAP_TYPE_SPHERE";
break;
case THREE.EquirectangularReflectionMapping:
case THREE.EquirectangularRefractionMapping:
envMapTypeDefine = "ENVMAP_TYPE_EQUIREC";
break;
}
}
// console.log( "building new program " );
//
......@@ -233,6 +251,7 @@ THREE.WebGLProgram = ( function () {
parameters.map ? "#define USE_MAP" : "",
parameters.envMap ? "#define USE_ENVMAP" : "",
envMapTypeDefine ? "#define " + envMapTypeDefine : "",
parameters.lightMap ? "#define USE_LIGHTMAP" : "",
parameters.bumpMap ? "#define USE_BUMPMAP" : "",
parameters.normalMap ? "#define USE_NORMALMAP" : "",
......
......@@ -4,6 +4,7 @@
THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
mapping = mapping !== undefined ? mapping : THREE.CubeReflectionMapping;
THREE.Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
this.images = images;
......
......@@ -42,7 +42,7 @@ THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, f
};
THREE.Texture.DEFAULT_IMAGE = undefined;
THREE.Texture.DEFAULT_MAPPING = new THREE.UVMapping();
THREE.Texture.DEFAULT_MAPPING = THREE.UVMapping;
THREE.Texture.prototype = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册