123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- /**
- * @author zz85 https://github.com/zz85 / http://www.lab4games.net/zz85/blog
- *
- * Bird Simulation Render
- *
- * A simple scene rendering a quad of the following shaders
- * 1. Pass-thru Shader,
- * 2. Bird Position Update Shader,
- * 3. Bird Velocity Update Shader
- *
- */
- function SimulationRenderer( WIDTH, renderer ) {
- WIDTH = WIDTH || 4;
- var camera = new THREE.Camera();
- camera.position.z = 1;
- if ( ! renderer.extensions.get( "OES_texture_float" ) ) {
- alert( "No OES_texture_float support for float textures!" );
- return;
- }
- if ( renderer.capabilities.maxVertexTextures === 0 ) {
- alert( "No support for vertex shader textures!" );
- return;
- }
- var scene = new THREE.Scene();
- var uniforms = {
- time: { type: "f", value: 1.0 },
- resolution: { type: "v2", value: new THREE.Vector2( WIDTH, WIDTH ) },
- texture: { type: "t", value: null }
- };
- var passThruShader = new THREE.ShaderMaterial( {
- uniforms: uniforms,
- vertexShader: document.getElementById( 'vertexShader' ).textContent,
- fragmentShader: document.getElementById( 'fragmentShader' ).textContent
- } );
- var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), passThruShader );
- var positionShader = new THREE.ShaderMaterial( {
- uniforms: {
- time: { type: "f", value: 1.0 },
- delta: { type: "f", value: 0.0 },
- resolution: { type: "v2", value: new THREE.Vector2( WIDTH, WIDTH ) },
- texturePosition: { type: "t", value: null },
- textureVelocity: { type: "t", value: null },
- },
- vertexShader: document.getElementById( 'vertexShader' ).textContent,
- fragmentShader: document.getElementById( 'fragmentShaderPosition' ).textContent
- } );
- this.positionShader = positionShader;
- var velocityShader = new THREE.ShaderMaterial( {
- uniforms: {
- time: { type: "f", value: 1.0 },
- delta: { type: "f", value: 0.0 },
- resolution: { type: "v2", value: new THREE.Vector2( WIDTH, WIDTH ) },
- texturePosition: { type: "t", value: null },
- textureVelocity: { type: "t", value: null },
- testing: { type: "f", value: 1.0 },
- seperationDistance: { type: "f", value: 1.0 },
- alignmentDistance: { type: "f", value: 1.0 },
- cohesionDistance: { type: "f", value: 1.0 },
- freedomFactor: { type: "f", value: 1.0 },
- predator: { type: "v3", value: new THREE.Vector3() }
- },
- defines: {
- WIDTH: WIDTH.toFixed( 2 )
- },
- vertexShader: document.getElementById( 'vertexShader' ).textContent,
- fragmentShader: document.getElementById( 'fragmentShaderVelocity' ).textContent
- } );
- this.velocityUniforms = velocityShader.uniforms;
- scene.add( mesh );
- var flipflop = true;
- var rtPosition1, rtPosition2, rtVelocity1, rtVelocity2;
- function init() {
- var dtPosition = generatePositionTexture();
- var dtVelocity = generateVelocityTexture();
- rtPosition1 = getRenderTarget( THREE.RGBAFormat );
- rtPosition2 = rtPosition1.clone();
- rtVelocity1 = getRenderTarget( THREE.RGBAFormat );
- rtVelocity2 = rtVelocity1.clone();
- simulator.renderTexture( dtPosition, rtPosition1 );
- simulator.renderTexture( rtPosition1.texture, rtPosition2 );
- simulator.renderTexture( dtVelocity, rtVelocity1 );
- simulator.renderTexture( rtVelocity1.texture, rtVelocity2 );
- simulator.velocityUniforms.testing.value = 10;
- }
- this.init = init;
- function getRenderTarget( type ) {
- var renderTarget = new THREE.WebGLRenderTarget( WIDTH, WIDTH, {
- wrapS: THREE.RepeatWrapping,
- wrapT: THREE.RepeatWrapping,
- minFilter: THREE.NearestFilter,
- magFilter: THREE.NearestFilter,
- format: type,
- type: THREE.FloatType,
- stencilBuffer: false
- } );
- return renderTarget;
- }
- // Takes a texture, and render out as another texture
- this.renderTexture = function ( input, output ) {
- mesh.material = passThruShader;
- uniforms.texture.value = input;
- renderer.render( scene, camera, output );
- };
- this.renderPosition = function( position, velocity, output, delta ) {
- mesh.material = positionShader;
- positionShader.uniforms.texturePosition.value = position;
- positionShader.uniforms.textureVelocity.value = velocity;
- positionShader.uniforms.time.value = performance.now();
- positionShader.uniforms.delta.value = delta;
- renderer.render( scene, camera, output );
- this.currentPosition = output.texture;
- };
- this.renderVelocity = function( position, velocity, output, delta ) {
- mesh.material = velocityShader;
- velocityShader.uniforms.texturePosition.value = position;
- velocityShader.uniforms.textureVelocity.value = velocity;
- velocityShader.uniforms.time.value = performance.now();
- velocityShader.uniforms.delta.value = delta;
- renderer.render( scene, camera, output );
- this.currentVelocity = output.texture;
- };
- this.simulate = function( delta ) {
- if ( flipflop ) {
- simulator.renderVelocity( rtPosition1.texture, rtVelocity1.texture, rtVelocity2, delta );
- simulator.renderPosition( rtPosition1.texture, rtVelocity2.texture, rtPosition2, delta );
- } else {
- simulator.renderVelocity( rtPosition2.texture, rtVelocity2.texture, rtVelocity1, delta );
- simulator.renderPosition( rtPosition2.texture, rtVelocity1.texture, rtPosition1, delta );
- }
- flipflop = ! flipflop;
- };
- function generatePositionTexture() {
- var a = new Float32Array( PARTICLES * 4 );
- for ( var k = 0, kl = a.length; k < kl; k += 4 ) {
- var x = Math.random() * BOUNDS - BOUNDS_HALF;
- var y = Math.random() * BOUNDS - BOUNDS_HALF;
- var z = Math.random() * BOUNDS - BOUNDS_HALF;
- a[ k + 0 ] = x;
- a[ k + 1 ] = y;
- a[ k + 2 ] = z;
- a[ k + 3 ] = 1;
- }
- var texture = new THREE.DataTexture( a, WIDTH, WIDTH, THREE.RGBAFormat, THREE.FloatType );
- texture.needsUpdate = true;
- return texture;
- }
- function generateVelocityTexture() {
- var a = new Float32Array( PARTICLES * 4 );
- for ( var k = 0, kl = a.length; k < kl; k += 4 ) {
- var x = Math.random() - 0.5;
- var y = Math.random() - 0.5;
- var z = Math.random() - 0.5;
- a[ k + 0 ] = x * 10;
- a[ k + 1 ] = y * 10;
- a[ k + 2 ] = z * 10;
- a[ k + 3 ] = 1;
- }
- var texture = new THREE.DataTexture( a, WIDTH, WIDTH, THREE.RGBAFormat, THREE.FloatType ); // was RGB format. changed to RGBA format. see discussion in #8415 / #8450
- texture.needsUpdate = true;
- return texture;
- }
- }
|