提交 cd924951 编写于 作者: A alteredq

WebGLDeferredRenderer: merged @MPanknin's area lights.

To be continued ...

todo:
- optimize vectors that don't need to be computed in shaders
- use material albedo
- add specular term
- wrapAround lighting (if possible)
- make attenuation parameters uniforms or defines instead of hardcoding them
- this is not using surface normal anywhere, this can't be right?
- maybe some box proxy instead of full-screen quad

See #2624
上级 96fd7a94
......@@ -7957,6 +7957,25 @@ THREE.AmbientLight = function ( hex ) {
};
THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );
/**
* @author MPanknin / http://www.redplant.de/
*/
THREE.AreaLight = function ( hex ) {
THREE.Light.call( this, hex );
this.normal = new THREE.Vector3( 0, -1, 0 );
this.right = new THREE.Vector3( 1, 0, 0 );
this.intensity = 1.0;
this.width = 1.0;
this.height = 1.0;
};
THREE.AreaLight.prototype = Object.create( THREE.Light.prototype );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
......
......@@ -162,7 +162,7 @@ this.attributes.uv)console.warn("Missing required attributes (index, position, n
var n,p,m,r,s,l,q,u,B,x,t,F,C,z,A,f=new THREE.Vector3,g=new THREE.Vector3,H,G,I,$,D,L,y,K=this.offsets;I=0;for($=K.length;I<$;++I){G=K[I].start;D=K[I].count;var J=K[I].index;H=G;for(G+=D;H<G;H+=3)D=J+b[H],L=J+b[H+1],y=J+b[H+2],n=c[3*D],p=c[3*D+1],m=c[3*D+2],r=c[3*L],s=c[3*L+1],l=c[3*L+2],q=c[3*y],u=c[3*y+1],B=c[3*y+2],x=e[2*D],t=e[2*D+1],F=e[2*L],C=e[2*L+1],z=e[2*y],A=e[2*y+1],r-=n,n=q-n,s-=p,p=u-p,l-=m,m=B-m,F-=x,x=z-x,C-=t,t=A-t,A=1/(F*t-x*C),f.set((t*r-C*n)*A,(t*s-C*p)*A,(t*l-C*m)*A),g.set((F*
n-x*r)*A,(F*p-x*s)*A,(F*m-x*l)*A),i[D].addSelf(f),i[L].addSelf(f),i[y].addSelf(f),k[D].addSelf(g),k[L].addSelf(g),k[y].addSelf(g)}var R=new THREE.Vector3,P=new THREE.Vector3,ca=new THREE.Vector3,xa=new THREE.Vector3,M,pa,ya;I=0;for($=K.length;I<$;++I){G=K[I].start;D=K[I].count;J=K[I].index;H=G;for(G+=D;H<G;H+=3)D=J+b[H],L=J+b[H+1],y=J+b[H+2],a(D),a(L),a(y)}this.tangentsNeedUpdate=this.hasTangents=!0}},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.Camera=function(){THREE.Object3D.call(this);this.matrixWorldInverse=new THREE.Matrix4;this.projectionMatrix=new THREE.Matrix4;this.projectionMatrixInverse=new THREE.Matrix4};THREE.Camera.prototype=Object.create(THREE.Object3D.prototype);THREE.Camera.prototype.lookAt=function(a){this.matrix.lookAt(this.position,a,this.up);!0===this.rotationAutoUpdate&&(!1===this.useQuaternion?this.rotation.setEulerFromRotationMatrix(this.matrix,this.eulerOrder):this.quaternion.copy(this.matrix.decompose()[1]))};THREE.OrthographicCamera=function(a,b,c,d,e,f){THREE.Camera.call(this);this.left=a;this.right=b;this.top=c;this.bottom=d;this.near=void 0!==e?e:0.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()};THREE.OrthographicCamera.prototype=Object.create(THREE.Camera.prototype);THREE.OrthographicCamera.prototype.updateProjectionMatrix=function(){this.projectionMatrix.makeOrthographic(this.left,this.right,this.top,this.bottom,this.near,this.far)};THREE.PerspectiveCamera=function(a,b,c,d){THREE.Camera.call(this);this.fov=void 0!==a?a:50;this.aspect=void 0!==b?b:1;this.near=void 0!==c?c:0.1;this.far=void 0!==d?d:2E3;this.updateProjectionMatrix()};THREE.PerspectiveCamera.prototype=Object.create(THREE.Camera.prototype);THREE.PerspectiveCamera.prototype.setLens=function(a,b){void 0===b&&(b=24);this.fov=2*THREE.Math.radToDeg(Math.atan(b/(2*a)));this.updateProjectionMatrix()};
THREE.PerspectiveCamera.prototype.setViewOffset=function(a,b,c,d,e,f){this.fullWidth=a;this.fullHeight=b;this.x=c;this.y=d;this.width=e;this.height=f;this.updateProjectionMatrix()};
THREE.PerspectiveCamera.prototype.updateProjectionMatrix=function(){if(this.fullWidth){var a=this.fullWidth/this.fullHeight,b=Math.tan(THREE.Math.degToRad(0.5*this.fov))*this.near,c=-b,d=a*c,a=Math.abs(a*b-d),c=Math.abs(b-c);this.projectionMatrix.makeFrustum(d+this.x*a/this.fullWidth,d+(this.x+this.width)*a/this.fullWidth,b-(this.y+this.height)*c/this.fullHeight,b-this.y*c/this.fullHeight,this.near,this.far)}else this.projectionMatrix.makePerspective(this.fov,this.aspect,this.near,this.far)};THREE.Light=function(a){THREE.Object3D.call(this);this.color=new THREE.Color(a)};THREE.Light.prototype=Object.create(THREE.Object3D.prototype);THREE.AmbientLight=function(a){THREE.Light.call(this,a)};THREE.AmbientLight.prototype=Object.create(THREE.Light.prototype);THREE.DirectionalLight=function(a,b){THREE.Light.call(this,a);this.position=new THREE.Vector3(0,1,0);this.target=new THREE.Object3D;this.intensity=void 0!==b?b:1;this.onlyShadow=this.castShadow=!1;this.shadowCameraNear=50;this.shadowCameraFar=5E3;this.shadowCameraLeft=-500;this.shadowCameraTop=this.shadowCameraRight=500;this.shadowCameraBottom=-500;this.shadowCameraVisible=!1;this.shadowBias=0;this.shadowDarkness=0.5;this.shadowMapHeight=this.shadowMapWidth=512;this.shadowCascade=!1;this.shadowCascadeOffset=
THREE.PerspectiveCamera.prototype.updateProjectionMatrix=function(){if(this.fullWidth){var a=this.fullWidth/this.fullHeight,b=Math.tan(THREE.Math.degToRad(0.5*this.fov))*this.near,c=-b,d=a*c,a=Math.abs(a*b-d),c=Math.abs(b-c);this.projectionMatrix.makeFrustum(d+this.x*a/this.fullWidth,d+(this.x+this.width)*a/this.fullWidth,b-(this.y+this.height)*c/this.fullHeight,b-this.y*c/this.fullHeight,this.near,this.far)}else this.projectionMatrix.makePerspective(this.fov,this.aspect,this.near,this.far)};THREE.Light=function(a){THREE.Object3D.call(this);this.color=new THREE.Color(a)};THREE.Light.prototype=Object.create(THREE.Object3D.prototype);THREE.AmbientLight=function(a){THREE.Light.call(this,a)};THREE.AmbientLight.prototype=Object.create(THREE.Light.prototype);THREE.AreaLight=function(a){THREE.Light.call(this,a);this.normal=new THREE.Vector3(0,-1,0);this.right=new THREE.Vector3(1,0,0);this.height=this.width=this.intensity=1};THREE.AreaLight.prototype=Object.create(THREE.Light.prototype);THREE.DirectionalLight=function(a,b){THREE.Light.call(this,a);this.position=new THREE.Vector3(0,1,0);this.target=new THREE.Object3D;this.intensity=void 0!==b?b:1;this.onlyShadow=this.castShadow=!1;this.shadowCameraNear=50;this.shadowCameraFar=5E3;this.shadowCameraLeft=-500;this.shadowCameraTop=this.shadowCameraRight=500;this.shadowCameraBottom=-500;this.shadowCameraVisible=!1;this.shadowBias=0;this.shadowDarkness=0.5;this.shadowMapHeight=this.shadowMapWidth=512;this.shadowCascade=!1;this.shadowCascadeOffset=
new THREE.Vector3(0,0,-1E3);this.shadowCascadeCount=2;this.shadowCascadeBias=[0,0,0];this.shadowCascadeWidth=[512,512,512];this.shadowCascadeHeight=[512,512,512];this.shadowCascadeNearZ=[-1,0.99,0.998];this.shadowCascadeFarZ=[0.99,0.998,1];this.shadowCascadeArray=[];this.shadowMatrix=this.shadowCamera=this.shadowMapSize=this.shadowMap=null};THREE.DirectionalLight.prototype=Object.create(THREE.Light.prototype);THREE.HemisphereLight=function(a,b,c){THREE.Light.call(this,a);this.groundColor=new THREE.Color(b);this.position=new THREE.Vector3(0,100,0);this.intensity=void 0!==c?c:1};THREE.HemisphereLight.prototype=Object.create(THREE.Light.prototype);THREE.PointLight=function(a,b,c){THREE.Light.call(this,a);this.position=new THREE.Vector3(0,0,0);this.intensity=void 0!==b?b:1;this.distance=void 0!==c?c:0};THREE.PointLight.prototype=Object.create(THREE.Light.prototype);THREE.SpotLight=function(a,b,c,d,e){THREE.Light.call(this,a);this.position=new THREE.Vector3(0,1,0);this.target=new THREE.Object3D;this.intensity=void 0!==b?b:1;this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/2;this.exponent=void 0!==e?e:10;this.onlyShadow=this.castShadow=!1;this.shadowCameraNear=50;this.shadowCameraFar=5E3;this.shadowCameraFov=50;this.shadowCameraVisible=!1;this.shadowBias=0;this.shadowDarkness=0.5;this.shadowMapHeight=this.shadowMapWidth=512;this.shadowMatrix=this.shadowCamera=
this.shadowMapSize=this.shadowMap=null};THREE.SpotLight.prototype=Object.create(THREE.Light.prototype);THREE.Loader=function(a){this.statusDomElement=(this.showStatus=a)?THREE.Loader.prototype.addStatusElement():null;this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){}};
THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:"anonymous",addStatusElement:function(){var a=document.createElement("div");a.style.position="absolute";a.style.right="0px";a.style.top="0px";a.style.fontSize="0.8em";a.style.textAlign="left";a.style.background="rgba(0,0,0,0.25)";a.style.color="#fff";a.style.width="120px";a.style.padding="0.5em 0.5em 0.5em 0.5em";a.style.zIndex=1E3;a.innerHTML="Loading ...";return a},updateProgress:function(a){var b="Loaded ",b=a.total?b+((100*a.loaded/
......
......@@ -583,8 +583,8 @@ THREE.ShaderDeferred = {
"uniform float viewHeight;",
"uniform float viewWidth;",
"uniform float lightAngle;"+
"uniform float lightIntensity;"+
"uniform float lightAngle;",
"uniform float lightIntensity;",
"uniform vec3 lightColor;",
"uniform mat4 matProjInverse;",
......@@ -824,6 +824,146 @@ THREE.ShaderDeferred = {
},
"areaLight" : {
uniforms: {
samplerNormalDepth: { type: "t", value: null },
samplerColor: { type: "t", value: null },
matProjInverse: { type: "m4", value: new THREE.Matrix4() },
matView: { type: "m4", value: new THREE.Matrix4() },
viewWidth: { type: "f", value: 800 },
viewHeight: { type: "f", value: 600 },
lightPosition: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
lightColor: { type: "c", value: new THREE.Color( 0x000000 ) },
lightIntensity: { type: "f", value: 1.0 },
lightRight: { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
lightNormal: { type: "v3", value: new THREE.Vector3( 0, -1, 0 ) },
lightWidth: { type: "f", value: 1.0 },
lightHeight: { type: "f", value: 1.0 }
},
fragmentShader : [
"varying vec3 lightPosVS;",
"varying vec3 lightNormalVS;",
"varying vec3 lightRightVS;",
"uniform sampler2D samplerColor;",
"uniform sampler2D samplerNormalDepth;",
"uniform float lightWidth;",
"uniform float lightHeight;",
"uniform float lightIntensity;",
"uniform vec3 lightColor;",
"uniform float viewHeight;",
"uniform float viewWidth;",
"uniform mat4 matProjInverse;",
THREE.DeferredShaderChunk[ "unpackFloat" ],
"vec3 projectOnPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
"return point - dot( point - planeCenter, planeNorm ) * planeNorm;",
"}",
"bool sideOfPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
"return ( dot( point - planeCenter, planeNorm ) >= 0.0 );",
"}",
"vec3 linePlaneIntersect( vec3 lp, vec3 lv, vec3 pc, vec3 pn ) {",
"return lp + lv * ( dot( pn, pc - lp ) / dot( pn, lv ) );",
"}",
"float calculateAttenuation( float dist ) {",
"float constAtten = 1.5;",
"float linAtten = 0.5;",
"float quadAtten = 0.1;",
"return ( 1.0 / ( constAtten + linAtten * dist + quadAtten * dist * dist ) );",
"}",
"void main() {",
THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
THREE.DeferredShaderChunk[ "computeNormal" ],
THREE.DeferredShaderChunk[ "unpackColorMap" ],
"float w = lightWidth;",
"float h = lightHeight;",
"vec3 lightUpVS = normalize( cross( lightRightVS, lightNormalVS ) );",
"vec3 proj = projectOnPlane( vertexPositionVS.xyz, lightPosVS, lightNormalVS );",
"vec3 dir = proj - lightPosVS;",
"vec2 diagonal = vec2( dot( dir, lightRightVS ), dot( dir, lightUpVS ) );",
"vec2 nearest2D = vec2( clamp( diagonal.x, -w, w ), clamp( diagonal.y, -h, h ) );",
"vec3 nearestPointInside = vec3( lightPosVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
"float dist = distance( vertexPositionVS.xyz, nearestPointInside );",
"float attenuation = calculateAttenuation( dist );",
"vec3 lightDir = normalize( nearestPointInside - vertexPositionVS.xyz );",
"vec3 color = vec3( 0.0 );",
"float NdotL = dot( lightNormalVS, -lightDir );",
"if ( NdotL != 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPosVS, lightNormalVS ) ) {",
"color.xyz = vec3( lightColor * attenuation * NdotL * 1.5 );",
"} else {",
"color.xyz = vec3( 0.0 );",
"}",
"gl_FragColor = vec4( color, 1.0 );",
"}"
].join("\n"),
vertexShader : [
"varying vec3 lightPosVS;",
"varying vec3 lightNormalVS;",
"varying vec3 lightRightVS;",
"uniform vec3 lightPosition;",
"uniform vec3 lightNormal;",
"uniform vec3 lightRight;",
"uniform mat4 matView;",
"void main() {",
"vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
"gl_Position = pos;",
"lightNormalVS = normalize( mat3( matView ) * lightNormal );",
"lightRightVS = normalize( mat3( matView ) * lightRight ); ",
"lightPosVS = vec3( matView * vec4( lightPosition, 1.0 ) );",
"}"
].join("\n")
},
"emissiveLight" : {
uniforms: {
......
......@@ -40,6 +40,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var positionVS = new THREE.Vector3();
var directionVS = new THREE.Vector3();
var right = new THREE.Vector3();
var normal = new THREE.Vector3();
//
var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
......@@ -57,6 +60,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var spotLightShader = THREE.ShaderDeferred[ "spotLight" ];
var directionalLightShader = THREE.ShaderDeferred[ "directionalLight" ];
var hemisphereLightShader = THREE.ShaderDeferred[ "hemisphereLight" ];
var areaLightShader = THREE.ShaderDeferred[ "areaLight" ];
var compositeShader = THREE.ShaderDeferred[ "composite" ];
......@@ -612,6 +616,80 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
};
var updateAreaLightProxy = function ( lightProxy ) {
var light = lightProxy.properties.originalLight;
var uniforms = lightProxy.material.uniforms;
uniforms[ "lightPosition" ].value.copy( light.matrixWorld.getPosition() );
var matrix = light.matrixWorld;
right.copy( light.right );
normal.copy( light.normal );
matrix.rotateAxis( right );
matrix.rotateAxis( normal );
uniforms[ "lightRight" ].value.copy( right );
uniforms[ "lightNormal" ].value.copy( normal );
uniforms[ "lightWidth" ].value = light.width;
uniforms[ "lightHeight" ].value = light.height;
// linear space colors
var intensity = light.intensity * light.intensity;
uniforms[ "lightIntensity" ].value = intensity;
uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
};
var createDeferredAreaLight = function ( light ) {
// setup light material
var uniforms = THREE.UniformsUtils.clone( areaLightShader.uniforms );
var materialLight = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: areaLightShader.vertexShader,
fragmentShader: areaLightShader.fragmentShader,
blending: THREE.AdditiveBlending,
depthWrite: false,
depthTest: false,
transparent: true
} );
uniforms[ "viewWidth" ].value = scaledWidth;
uniforms[ "viewHeight" ].value = scaledHeight;
uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
// create light proxy mesh
var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
// keep reference for color and intensity updates
meshLight.properties.originalLight = light;
// keep reference for size reset
resizableMaterials.push( materialLight );
// sync proxy uniforms to the original light
updateAreaLightProxy( meshLight );
return meshLight;
};
var createDeferredEmissiveLight = function () {
// setup light material
......@@ -652,32 +730,37 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
if ( object instanceof THREE.PointLight ) {
var meshLight = createDeferredPointLight( object );
var proxy = createDeferredPointLight( object );
if ( object.distance > 0 ) {
lightSceneProxy.add( meshLight );
lightSceneProxy.add( proxy );
} else {
lightSceneFullscreen.add( meshLight );
lightSceneFullscreen.add( proxy );
}
} else if ( object instanceof THREE.SpotLight ) {
var meshLight = createDeferredSpotLight( object );
lightSceneFullscreen.add( meshLight );
var proxy = createDeferredSpotLight( object );
lightSceneFullscreen.add( proxy );
} else if ( object instanceof THREE.DirectionalLight ) {
var meshLight = createDeferredDirectionalLight( object );
lightSceneFullscreen.add( meshLight );
var proxy = createDeferredDirectionalLight( object );
lightSceneFullscreen.add( proxy );
} else if ( object instanceof THREE.HemisphereLight ) {
var meshLight = createDeferredHemisphereLight( object );
lightSceneFullscreen.add( meshLight );
var proxy = createDeferredHemisphereLight( object );
lightSceneFullscreen.add( proxy );
} else if ( object instanceof THREE.AreaLight ) {
var proxy = createDeferredAreaLight( object );
lightSceneFullscreen.add( proxy );
}
......@@ -794,34 +877,38 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
//
function updateLightProxy ( lightProxy, camera ) {
function updateLightProxy ( proxy, camera ) {
var uniforms = lightProxy.material.uniforms;
var uniforms = proxy.material.uniforms;
if ( uniforms[ "matProjInverse" ] ) uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
if ( uniforms[ "matView" ] ) uniforms[ "matView" ].value = camera.matrixWorldInverse;
var originalLight = lightProxy.properties.originalLight;
var originalLight = proxy.properties.originalLight;
if ( originalLight ) {
lightProxy.visible = originalLight.visible;
proxy.visible = originalLight.visible;
if ( originalLight instanceof THREE.PointLight ) {
updatePointLightProxy( lightProxy );
updatePointLightProxy( proxy );
} else if ( originalLight instanceof THREE.SpotLight ) {
updateSpotLightProxy( lightProxy );
updateSpotLightProxy( proxy );
} else if ( originalLight instanceof THREE.DirectionalLight ) {
updateDirectionalLightProxy( lightProxy );
updateDirectionalLightProxy( proxy );
} else if ( originalLight instanceof THREE.HemisphereLight ) {
updateHemisphereLightProxy( lightProxy );
updateHemisphereLightProxy( proxy );
} else if ( originalLight instanceof THREE.AreaLight ) {
updateAreaLightProxy( proxy );
}
......@@ -918,15 +1005,15 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
for ( var i = 0, il = lightSceneProxy.children.length; i < il; i ++ ) {
var lightProxy = lightSceneProxy.children[ i ];
updateLightProxy( lightProxy, camera );
var proxy = lightSceneProxy.children[ i ];
updateLightProxy( proxy, camera );
}
for ( var i = 0, il = lightSceneFullscreen.children.length; i < il; i ++ ) {
var lightProxy = lightSceneFullscreen.children[ i ];
updateLightProxy( lightProxy, camera );
var proxy = lightSceneFullscreen.children[ i ];
updateLightProxy( proxy, camera );
}
......
{
"metadata" :
{
"formatVersion" : 3.1,
"sourceFile" : "box.obj",
"generatedBy" : "OBJConverter",
"vertices" : 36,
"faces" : 25,
"normals" : 8,
"uvs" : 0,
"materials" : 1
},
"materials": [ {
"DbgColor" : 15658734,
"DbgIndex" : 0,
"DbgName" : "",
"colorAmbient" : [0.0, 0.0, 0.0],
"colorDiffuse" : [0.8, 0.8, 0.8],
"colorSpecular" : [0.8, 0.8, 0.8],
"illumination" : 2,
"specularCoef" : 0.0,
"transparency" : 1.0
}],
"buffers": "box.bin"
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>three.js webgl - deferred rendering</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-color: #000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 20px; width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
}
a {
color: #ff0080;
text-decoration: none;
}
a:hover {
color: #0080ff;
}
#stats { position: absolute; top:10px; left: 5px }
#stats #fps { background: transparent !important }
#stats #fps #fpsText { color: #aaa !important }
#stats #fps #fpsGraph { display: none }
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - deferred area lights WebGL demo by <a href="http://de.redplant.de" target=_blank>redPlant</a> -
based on <a href="http://www.gamedev.net/topic/552315-glsl-area-light-implementation/" target=_blank>ArKano22's</a> glsl implementation
</div>
<div id="container"></div>
<script src="../build/three.min.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/renderers/WebGLDeferredRenderer.js"></script>
<script src="js/ShaderDeferred.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/shaders/FXAAShader.js"></script>
<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>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var SCALE = 1;
var MARGIN = 100;
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight - 2 * MARGIN;
var NEAR = 1.0, FAR = 350.0;
var VIEW_ANGLE = 40;
// controls
var mouseX = 0;
var mouseY = 0;
var targetX = 0, targetY = 0;
var angle = 0;
var target = new THREE.Vector3( 0, 0, 0 );
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
// core
var renderer, camera, scene, stats, clock;
// lights
var numLights = 50;
var lights = [];
//
init();
animate();
// -----------------------------
function init() {
// renderer
renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, antialias: true } );
renderer.domElement.style.position = "absolute";
renderer.domElement.style.top = MARGIN + "px";
renderer.domElement.style.left = "0px";
var container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
// camera
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
camera.position.y = 40;
// scene
scene = new THREE.Scene();
scene.add( camera );
// stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '8px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
// clock
clock = new THREE.Clock();
// add lights
initLights();
// add objects
initObjects();
// events
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
// -----------------------------
function createAreaEmitter( light ) {
var geometry = new THREE.CubeGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: light.color.getHex() } );
var emitter = new THREE.Mesh( geometry, material );
emitter.position = light.position;
emitter.rotation = light.rotation;
emitter.scale.set( light.width * 2, 0.2, light.height * 2 );
return emitter;
}
function setupAreaLight( light ) {
var matrix = light.matrixWorld;
light.right.set( 1, 0, 0 );
light.normal.set( 0, -1, 0 );
light.right = matrix.multiplyVector3( light.right );
light.normal = matrix.multiplyVector3( light.normal );
}
function initLights() {
var areaLight1 = new THREE.AreaLight( 0xffffff );
areaLight1.position.set( 0.0001, 10.0001, -19.5001 );
areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
areaLight1.width = 10;
areaLight1.height = 1;
scene.add( areaLight1 );
var meshEmitter = createAreaEmitter( areaLight1 );
scene.add( meshEmitter );
//
var areaLight2 = new THREE.AreaLight( 0x00ff00 );
areaLight2.position.set( -19.0001, 3.0001, 0.0001 );
areaLight2.rotation.set( -1.5707, 0.0001, 1.5707 );
areaLight2.width = 8;
areaLight2.height = 1;
scene.add( areaLight2 );
var meshEmitter = createAreaEmitter( areaLight2 );
scene.add( meshEmitter );
//
var areaLight3 = new THREE.AreaLight( 0x0000ff );
areaLight3.position.set( 19.0001, 3.0001, 0.0001 );
areaLight3.rotation.set( 1.5707, 0.0001, -1.5707 );
areaLight3.width = 8;
areaLight3.height = 1;
scene.add( areaLight3 );
var meshEmitter = createAreaEmitter( areaLight3 );
scene.add( meshEmitter );
}
// -----------------------------
function initObjects() {
var loader = new THREE.BinaryLoader();
loader.load( "obj/box/box.js", function( geometry, materials ) {
var object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( ) );
object.position.x = 0;
object.position.y = 0;
object.scale.multiplyScalar( 2 );
scene.add( object );
} );
}
// -----------------------------
function onWindowResize( event ) {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight - 2 * MARGIN;
renderer.setSize( WIDTH, HEIGHT );
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX ) * 1;
mouseY = ( event.clientY - windowHalfY ) * 1;
}
// -----------------------------
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
// update camera
var delta = clock.getDelta();
targetX = mouseX * .001;
targetY = mouseY * .001;
angle += 0.05 * ( targetX - angle );
camera.position.x = -Math.sin( angle ) * 40;
camera.position.z = Math.cos( angle ) * 40;
camera.lookAt( target );
// render
renderer.render( scene, camera );
}
</script>
</body>
</html>
......@@ -32,6 +32,7 @@
"../src/cameras/PerspectiveCamera.js",
"../src/lights/Light.js",
"../src/lights/AmbientLight.js",
"../src/lights/AreaLight.js",
"../src/lights/DirectionalLight.js",
"../src/lights/HemisphereLight.js",
"../src/lights/PointLight.js",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册