提交 53b1867a 编写于 作者: W WestLangley

Add instancing lambert example

上级 624b4e6a
......@@ -284,6 +284,7 @@ var files = {
"webgl_buffergeometry_instancing_billboards",
"webgl_buffergeometry_instancing_dynamic",
"webgl_buffergeometry_instancing_interleaved_dynamic",
"webgl_buffergeometry_instancing_lambert",
"webgl_buffergeometry_lines",
"webgl_buffergeometry_lines_indexed",
"webgl_buffergeometry_points",
......
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - instancing - lambert shader</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: #ffffff;
font-family: Monospace;
font-size: 13px;
text-align: center;
font-weight: bold;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 5px;
}
a {
color: #ffffff;
}
#notSupported {
width: 50%;
margin: auto;
border: 2px red solid;
margin-top: 20px;
padding: 10px;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - instancing - lambert shader
<div id="notSupported" style="display:none">Sorry your graphics card + browser does not support hardware instancing</div>
</div>
<script src="../build/three.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/CurveExtras.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
THREE.CustomShaderLib = {
customDepthRGBA: { // this is a cut-and-paste of the depth shader -- modified to accommodate instancing for this app
uniforms: THREE.ShaderLib.depth.uniforms,
vertexShader:
`
// instanced
#ifdef INSTANCED
attribute vec3 instanceOffset;
attribute float instanceScale;
#endif
#include <common>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
#include <uv_vertex>
#include <skinbase_vertex>
#ifdef USE_DISPLACEMENTMAP
#include <beginnormal_vertex>
#include <morphnormal_vertex>
#include <skinnormal_vertex>
#endif
#include <begin_vertex>
// instanced
#ifdef INSTANCED
transformed *= instanceScale;
transformed = transformed + instanceOffset;
#endif
#include <morphtarget_vertex>
#include <skinning_vertex>
#include <displacementmap_vertex>
#include <project_vertex>
#include <logdepthbuf_vertex>
#include <clipping_planes_vertex>
}
`,
fragmentShader: THREE.ShaderChunk.depth_frag
},
lambert: { // this is a cut-and-paste of the lambert shader -- modified to accommodate instancing for this app
uniforms: THREE.ShaderLib.lambert.uniforms,
vertexShader:
`
#define LAMBERT
#ifdef INSTANCED
attribute vec3 instanceOffset;
attribute vec3 instanceColor;
attribute float instanceScale;
#endif
varying vec3 vLightFront;
#ifdef DOUBLE_SIDED
varying vec3 vLightBack;
#endif
#include <common>
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <envmap_pars_vertex>
#include <bsdfs>
#include <lights_pars_begin>
#include <lights_pars_maps>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
#include <uv_vertex>
#include <uv2_vertex>
#include <color_vertex>
// vertex colors instanced
#ifdef INSTANCED
#ifdef USE_COLOR
vColor.xyz = instanceColor.xyz;
#endif
#endif
#include <beginnormal_vertex>
#include <morphnormal_vertex>
#include <skinbase_vertex>
#include <skinnormal_vertex>
#include <defaultnormal_vertex>
#include <begin_vertex>
// position instanced
#ifdef INSTANCED
transformed *= instanceScale;
transformed = transformed + instanceOffset;
#endif
#include <morphtarget_vertex>
#include <skinning_vertex>
#include <project_vertex>
#include <logdepthbuf_vertex>
#include <clipping_planes_vertex>
#include <worldpos_vertex>
#include <envmap_vertex>
#include <lights_lambert_vertex>
#include <shadowmap_vertex>
#include <fog_vertex>
}
`,
fragmentShader: THREE.ShaderLib.lambert.fragmentShader
}
};
//
var mesh, renderer, scene, camera, controls;
var stats;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
document.body.appendChild( renderer.domElement );
renderer.gammaOutput = true;
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x000000, 0.004 );
renderer.setClearColor( scene.fog.color, 1 );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 80, 40, 80 );
scene.add( camera );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = false;
controls.maxPolarAngle = Math.PI / 2;
scene.add( new THREE.AmbientLight( 0xffffff, 0.7 ) );
var light = new THREE.DirectionalLight( 0xffffff, 0.4 );
light.position.set( 50, 40, 0 );
light.castShadow = true;
light.shadow.camera.left = - 40;
light.shadow.camera.right = 40;
light.shadow.camera.top = 40;
light.shadow.camera.bottom = - 40;
light.shadow.camera.near = 10;
light.shadow.camera.far = 180;
light.shadow.bias = - 0.001;
light.shadow.mapSize.width = 512;
light.shadow.mapSize.height = 512;
scene.add( light );
// light shadow camera helper
//light.shadowCameraHelper = new THREE.CameraHelper( light.shadow.camera );
//scene.add( light.shadowCameraHelper );
// instanced buffer geometry
var geometry = new THREE.InstancedBufferGeometry();
geometry.copy( new THREE.TorusBufferGeometry( 2, 0.5, 8, 128 ) );
const INSTANCES = 256;
var knot = new THREE.Curves.TorusKnot( 10 );
var positions = knot.getSpacedPoints( INSTANCES );
var offsets = new Float32Array( INSTANCES * 3 ); // xyz
var colors = new Float32Array( INSTANCES * 3 ); // rgb
var scales = new Float32Array( INSTANCES * 1 ); // s
var color = new THREE.Color();
for ( var i = 0, l = INSTANCES; i < l; i ++ ) {
var index = 3 * i;
// per-instance position offset
offsets[ index ] = positions[ i ].x;
offsets[ index + 1 ] = positions[ i ].y;
offsets[ index + 2 ] = positions[ i ].z;
// per-instance color tint - optional
colors[ index ] = 1;
colors[ index + 1 ] = 1;
colors[ index + 2 ] = 1;
// per-instance scale variation
scales[ i ] = 1 + 0.5 * Math.sin( 32 * Math.PI * i / INSTANCES );
}
geometry.addAttribute( 'instanceOffset', new THREE.InstancedBufferAttribute( offsets, 3 ) );
geometry.addAttribute( 'instanceColor', new THREE.InstancedBufferAttribute( colors, 3 ) );
geometry.addAttribute( 'instanceScale', new THREE.InstancedBufferAttribute( scales, 1 ) );
// material
var envMap = new THREE.TextureLoader().load( `textures/metal.jpg`, function ( texture ) {
texture.mapping = THREE.SphericalReflectionMapping;
} );
var shader = THREE.CustomShaderLib[ 'lambert' ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
uniforms[ "diffuse" ].value.set( 0xffb54a );
uniforms[ "envMap" ].value = envMap;
uniforms[ "reflectivity" ].value = 1;
// defines - Since we are reusing the ShaderChunks, we must specify the required defines.
// The renderer does not set these defines for ShaderMaterial
var defines = {
'INSTANCED': "",
'USE_ENVMAP': "",
'ENVMAP_TYPE_SPHERE': "",
'ENVMAP_MODE_REFLECTION': "",
'ENVMAP_BLENDING_MULTIPLY': "",
};
var material = new THREE.ShaderMaterial( {
// Material and ShaderMaterial properties can be set here -- except opacity
// the Lambert-properties must be set in the uniforms or defines
defines: defines,
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
vertexColors: THREE.VertexColors,
lights: true,
fog: true
} );
// custom depth material - required for instanced shadows
var shader = THREE.CustomShaderLib[ 'customDepthRGBA' ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
var customDepthMaterial = new THREE.ShaderMaterial( {
defines: {
'INSTANCED': "",
'DEPTH_PACKING': THREE.RGBADepthPacking
},
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
} );
//
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 1, 1, 2 );
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.customDepthMaterial = customDepthMaterial;
mesh.frustumCulled = false;
scene.add( mesh );
//
var ground = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 800, 800 ).rotateX( - Math.PI / 2 ),
new THREE.MeshPhongMaterial( { color: 0x888888 } )
);
ground.position.set( 0, - 40, 0 );
ground.receiveShadow = true;
scene.add( ground );
//
stats = new Stats();
document.body.appendChild( stats.dom );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.005;
stats.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册