Explorar o código

First version of WebGLRenderer3.

Mr.doob %!s(int64=12) %!d(string=hai) anos
pai
achega
fedc2d1d16

+ 148 - 0
examples/webgl3_performance.html

@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - performance</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:#fff;
+				padding:0;
+				margin:0;
+				font-weight: bold;
+				overflow:hidden;
+			}
+		</style>
+	</head>
+	<body>
+
+		<script src="../build/three.min.js"></script>
+		<script src="../src/renderers/WebGLRenderer3.js"></script>
+
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			var container, stats;
+
+			var camera, scene, renderer;
+
+			var objects;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+			init();
+			animate();
+
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
+				camera.position.z = 3200;
+
+				scene = new THREE.Scene();
+
+				objects = [];
+
+				var material = new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading } );
+
+				var loader = new THREE.JSONLoader();
+				loader.load( 'obj/Suzanne.js', function ( geometry ) {
+
+					geometry.computeVertexNormals();
+
+					for ( var i = 0; i < 500; i ++ ) {
+
+						var mesh = new THREE.Mesh( geometry, material );
+
+						mesh.position.x = Math.random() * 8000 - 4000;
+						mesh.position.y = Math.random() * 8000 - 4000;
+						mesh.position.z = Math.random() * 8000 - 4000;
+						mesh.rotation.x = Math.random() * 2 * Math.PI;
+						mesh.rotation.y = Math.random() * 2 * Math.PI;
+						mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50 + 100;
+
+						objects.push( mesh );
+
+						scene.add( mesh );
+
+					}
+
+				} );
+
+				renderer = new THREE.WebGLRenderer3( { contextAttributes: { antialias: false } } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function onDocumentMouseMove(event) {
+
+				mouseX = ( event.clientX - windowHalfX ) * 10;
+				mouseY = ( event.clientY - windowHalfY ) * 10;
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+				camera.lookAt( scene.position );
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					objects[ i ].rotation.x += 0.01;
+					objects[ i ].rotation.y += 0.02;
+
+				}
+
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 0 - 1
examples/webgl_performance.html

@@ -36,7 +36,6 @@
 			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 
 			init();
-			// render();
 			animate();
 
 

+ 277 - 0
src/renderers/WebGLRenderer3.js

@@ -0,0 +1,277 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ *
+ * parameters = {
+ *   canvas: canvas,
+ *   contextAttributes: {
+ *     alpha: true,
+ *     depth: true,
+ *     stencil: false,
+ *     antialias: true,
+ *     premultipliedAlpha: true,
+ *     preserveDrawingBuffer: false
+ *   }
+ * }
+ *
+ */
+
+THREE.WebGLRenderer3 = function ( parameters ) {
+
+	console.log( 'THREE.WebGLRenderer3', THREE.REVISION );
+
+	parameters = parameters || {};
+
+	var canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' );
+
+	var gl;
+
+	try {
+
+		var attributes = parameters.contextAttributes || {}
+
+		gl = canvas.getContext( 'webgl', attributes ) || canvas.getContext( 'experimental-webgl', attributes );
+
+	} catch ( exception ) {
+
+		console.error( exception );
+
+	}
+
+	var extensions = {};
+
+	if ( gl !== null ) {
+
+		extensions.element_index_uint = gl.getExtension( 'OES_element_index_uint' );
+		extensions.texture_float = gl.getExtension( 'OES_texture_float' );
+		extensions.standard_derivatives = gl.getExtension( 'OES_standard_derivatives' );
+		extensions.texture_filter_anisotropic = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
+		extensions.compressed_texture_s3tc = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
+
+		gl.clearColor( 0, 0, 0, 1 );
+		gl.clearDepth( 1 );
+		gl.clearStencil( 0 );
+
+		gl.enable( gl.DEPTH_TEST );
+		gl.depthFunc( gl.LEQUAL );
+
+		gl.enable( gl.CULL_FACE );
+		gl.frontFace( gl.CCW );
+		gl.cullFace( gl.BACK );
+
+		gl.enable( gl.BLEND );
+		gl.blendEquation( gl.FUNC_ADD );
+		gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA );
+
+		gl.clearColor( 1, 0, 0, 1 );
+
+	}
+
+	//
+
+	var modelViewMatrix = new THREE.Matrix4();
+
+	// buffers
+
+	var buffers = {};
+
+	var getBuffer = function ( geometry ) {
+
+		if ( buffers[ geometry.id ] !== undefined ) {
+
+			return buffers[ geometry.id ];
+
+		}
+
+		var vertices = geometry.vertices;
+		var faces = geometry.faces;
+
+		var positions = [];
+
+		function addVertex( vertex ) {
+
+			positions.push( vertex.x, vertex.y, vertex.z );
+
+		}
+
+		for ( var i = 0, l = faces.length; i < l; i ++ ) {
+
+			var face = faces[ i ];
+
+			addVertex( vertices[ face.a ] );
+			addVertex( vertices[ face.b ] );
+			addVertex( vertices[ face.c ] );
+
+			if ( face instanceof THREE.Face4 ) {
+
+				addVertex( vertices[ face.a ] );
+				addVertex( vertices[ face.c ] );
+				addVertex( vertices[ face.d ] );
+
+			}
+
+		}
+
+		var buffer = {
+			data: gl.createBuffer(),
+			count: positions.length / 3
+		};
+
+		gl.bindBuffer( gl.ARRAY_BUFFER, buffer.data );
+		gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( positions ), gl.STATIC_DRAW );
+
+		buffers[ geometry.id ] = buffer;
+
+		return buffer;
+
+	};
+
+	// programs
+
+	var programs = {};
+
+	var getProgram = function ( material ) {
+
+		if ( programs[ material.id ] !== undefined ) {
+
+			return programs[ material.id ];
+
+		}
+
+		var program = gl.createProgram();
+
+		var vertexShader = [
+			'uniform mat4 modelViewMatrix;',
+			'uniform mat4 projectionMatrix;',
+			'attribute vec3 position;',
+			'void main() {',
+			'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			'}'
+		].join( '\n' );
+		var fragmentShader = [
+			'void main() {',
+			'	gl_FragColor = vec4(0,1,0,1);',
+			'}'
+		].join( '\n' );
+
+		gl.attachShader( program, createShader( gl.VERTEX_SHADER, vertexShader ) );
+		gl.attachShader( program, createShader( gl.FRAGMENT_SHADER, fragmentShader ) );
+		gl.linkProgram( program );
+
+		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === true ) {
+
+			programs[ material.id ] = program;
+
+		} else {
+
+			programs[ material.id ] = null;
+			console.error( 'VALIDATE_STATUS: ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) );
+			console.error( 'GL_ERROR: ' + gl.getError() );
+
+		}
+
+		return program;
+
+	};
+
+	var createShader = function ( type, string ) {
+
+		var shader = gl.createShader( type );
+
+		gl.shaderSource( shader, string );
+		gl.compileShader( shader );
+
+		if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === true ) {
+
+			// console.log( string );
+
+		} else {
+
+			console.error( gl.getShaderInfoLog( shader ), string );
+			return null;
+
+		}
+
+		return shader;
+
+	};
+
+	this.domElement = canvas;
+	this.extensions = extensions;
+
+	this.setSize = function ( width, height ) {
+
+		canvas.width = width;
+		canvas.height = height;
+
+		gl.viewport( 0, 0, canvas.width, canvas.height );
+
+	};
+
+	this.clear = function ( color, depth, stencil ) {
+
+		var bits = 0;
+
+		if ( color === undefined || color ) bits |= gl.COLOR_BUFFER_BIT;
+		if ( depth === undefined || depth ) bits |= gl.DEPTH_BUFFER_BIT;
+		if ( stencil === undefined || stencil ) bits |= gl.STENCIL_BUFFER_BIT;
+
+		gl.clear( bits );
+
+	};
+
+	this.render = function ( scene, camera ) {
+
+		this.clear();
+
+		scene.updateMatrixWorld();
+
+		if ( camera.parent === undefined ) camera.updateMatrixWorld();
+
+		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
+
+		var currentBuffer, currentProgram;
+		var locations = {};
+
+		for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
+
+			var object = scene.children[ i ];
+
+			var program = getProgram( object.material );
+
+			if ( program !== currentProgram ) {
+
+				gl.useProgram( program );
+
+				locations.position = gl.getAttribLocation( program, 'position' );
+				locations.modelViewMatrix = gl.getUniformLocation( program, 'modelViewMatrix' );
+				locations.projectionMatrix = gl.getUniformLocation( program, 'projectionMatrix' );
+
+				gl.uniformMatrix4fv( locations.projectionMatrix, false, camera.projectionMatrix.elements );
+
+				currentProgram = program;
+
+			}
+
+			var buffer = getBuffer( object.geometry );
+
+			if ( buffer !== currentBuffer ) {
+
+				gl.bindBuffer( gl.ARRAY_BUFFER, buffer.data );
+				gl.enableVertexAttribArray( locations.position );
+				gl.vertexAttribPointer( locations.position, 3, gl.FLOAT, false, 0, 0 );
+
+				currentBuffer = buffer;
+
+			}
+
+			modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
+
+			gl.uniformMatrix4fv( locations.modelViewMatrix, false, modelViewMatrix.elements );
+
+			gl.drawArrays( gl.TRIANGLES, 0, buffer.count );
+
+		}
+
+	};
+
+};