提交 60c23544 编写于 作者: U unknown

Added OBJ -> Three.js converter.

Added OBJ converter test example.

Modified Three.js to handle converted models:

 - extended WebGL renderer to use texturing
   - broke down model into multiple VBOs according to materials
   - textures are lazy created when images get loaded
     (converter takes care of resizing images to nearest power of 2
      dimensions using 2d canvas)

 - changed material array semantics in Mesh object
    - before: multiple materials were applied to all faces (broken in WebGL, needs multitexturing shader)
    - now: there is only single material per face, but one mesh can have faces with different materials

 - added per vertex normals (to get smooth shading in WebGL)
上级 647b4a57
此差异已折叠。
此差异已折叠。
......@@ -43,7 +43,7 @@ var Sphere = function ( radius, segments_width, segments_height ) {
}
var iVerNum = aVtc.length;
var n1, n2, n3, iVerNum = aVtc.length;
for ( j = 0; j < iVerNum; j++ ) {
......@@ -70,15 +70,31 @@ var Sphere = function ( radius, segments_width, segments_height ) {
var aP4uv = new THREE.UV( 1 - fI0, fJ1 );
if ( j < ( aVtc.length - 1 ) ) {
n1 = this.vertices[aP1].position.clone();
n2 = this.vertices[aP2].position.clone();
n3 = this.vertices[aP3].position.clone();
n1.normalize();
n2.normalize();
n3.normalize();
this.faces.push( new THREE.Face3( aP1, aP2, aP3 ) );
this.faces.push( new THREE.Face3( aP1, aP2, aP3, [new THREE.Vector3(n1.x,n1.y,n1.z), new THREE.Vector3(n2.x,n2.y,n2.z), new THREE.Vector3(n3.x,n3.y,n3.z)] ) );
//this.faces.push( new THREE.Face3( aP1, aP2, aP3 ) );
this.uvs.push( [ aP1uv, aP2uv, aP3uv ] );
}
if ( j > 1 ) {
this.faces.push( new THREE.Face3( aP1, aP3, aP4 ) );
n1 = this.vertices[aP1].position.clone();
n2 = this.vertices[aP3].position.clone();
n3 = this.vertices[aP4].position.clone();
n1.normalize();
n2.normalize();
n3.normalize();
this.faces.push( new THREE.Face3( aP1, aP3, aP4, [new THREE.Vector3(n1.x,n1.y,n1.z), new THREE.Vector3(n2.x,n2.y,n2.z), new THREE.Vector3(n3.x,n3.y,n3.z)] ) );
//this.faces.push( new THREE.Face3( aP1, aP3, aP4 ) );
this.uvs.push( [ aP1uv, aP3uv, aP4uv ] );
}
......
<Files *.js>
SetOutputFilter DEFLATE
</Files>
此差异已折叠。
# Material Count: 6
newmtl FrontColorNoCullingID__01_-_Default1noCulli
Ns 154.901961
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
map_Kd _01_-_Default1noCulling.JPG
newmtl _02_-_Default1noCulli__02_-_Default1noCulli
Ns 154.901961
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
map_Kd _02_-_Default1noCulling.JPG
newmtl _01_-_Default1noCulli__01_-_Default1noCulli
Ns 154.901961
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
map_Kd _01_-_Default1noCulling.JPG
newmtl FrontColorNoCullingID__03_-_Default1noCulli
Ns 154.901961
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
map_Kd _03_-_Default1noCulling.JPG
newmtl _03_-_Default1noCulli__03_-_Default1noCulli
Ns 154.901961
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
map_Kd _03_-_Default1noCulling.JPG
newmtl FrontColorNoCullingID__02_-_Default1noCulli
Ns 154.901961
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
map_Kd _02_-_Default1noCulling.JPG
此差异已折叠。
Model by Reallusion iClone from Google 3d Warehouse:
http://sketchup.google.com/3dwarehouse/details?mid=2c6fd128fca34052adc5f5b98d513da1
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>three.js - OBJ converter test</title>
<meta charset="utf-8">
<style type="text/css">
body {
background: #fff;
margin: 0px;
overflow: hidden;
font-family:georgia;
text-align:center;
}
h1 { }
a { color:skyblue }
canvas { pointer-events:none; z-index:10; position:relative }
#log { position:absolute; top:0 }
#d { text-align:center; margin:1em 0 -15em 0; z-index:0; position:relative; display:block }
.button { background:#000; color:#fff; padding:0.2em 0.5em; cursor:pointer }
.inactive { background:#999; color:#eee }
</style>
</head>
<body>
<div id="d">
<h1>OBJ to Three.js converter test</h1>
<span id="rcanvas" class="button inactive">2d canvas renderer</span>
<span id="rwebgl" class="button">WebGL renderer</span>
<br/>
<p>Model by <a href="http://sketchup.google.com/3dwarehouse/details?mid=2c6fd128fca34052adc5f5b98d513da1">Reallusion iClone</a>.
<p>Using a modified version of <a href="http://github.com/alteredq/three.js">Three.js</a> by mrdoob.
<br/>
<p>Best viewed in Chrome 7/8 or Firefox 4 using WebGL renderer.
<p>Canvas renderer is very slow on anything other than Chrome.
</div>
<div id="log"></div>
<script type="text/javascript" src="../build/Three.js"></script>
<!--
-->
<!--
<script type="text/javascript" src="../src/Three.js"></script>
<script type="text/javascript" src="../src/core/Color.js"></script>
<script type="text/javascript" src="../src/core/Vector2.js"></script>
<script type="text/javascript" src="../src/core/Vector3.js"></script>
<script type="text/javascript" src="../src/core/Vector4.js"></script>
<script type="text/javascript" src="../src/core/Rectangle.js"></script>
<script type="text/javascript" src="../src/core/Matrix4.js"></script>
<script type="text/javascript" src="../src/core/Vertex.js"></script>
<script type="text/javascript" src="../src/core/Face3.js"></script>
<script type="text/javascript" src="../src/core/Face4.js"></script>
<script type="text/javascript" src="../src/core/UV.js"></script>
<script type="text/javascript" src="../src/core/Geometry.js"></script>
<script type="text/javascript" src="../src/cameras/Camera.js"></script>
<script type="text/javascript" src="../src/lights/Light.js"></script>
<script type="text/javascript" src="../src/lights/AmbientLight.js"></script>
<script type="text/javascript" src="../src/lights/DirectionalLight.js"></script>
<script type="text/javascript" src="../src/lights/PointLight.js"></script>
<script type="text/javascript" src="../src/objects/Object3D.js"></script>
<script type="text/javascript" src="../src/objects/Mesh.js"></script>
<script type="text/javascript" src="../src/objects/Particle.js"></script>
<script type="text/javascript" src="../src/objects/Line.js"></script>
<script type="text/javascript" src="../src/materials/LineColorMaterial.js"></script>
<script type="text/javascript" src="../src/materials/MeshBitmapUVMappingMaterial.js"></script>
<script type="text/javascript" src="../src/materials/MeshColorFillMaterial.js"></script>
<script type="text/javascript" src="../src/materials/MeshColorStrokeMaterial.js"></script>
<script type="text/javascript" src="../src/materials/MeshFaceColorFillMaterial.js"></script>
<script type="text/javascript" src="../src/materials/MeshFaceColorStrokeMaterial.js"></script>
<script type="text/javascript" src="../src/materials/ParticleCircleMaterial.js"></script>
<script type="text/javascript" src="../src/materials/ParticleBitmapMaterial.js"></script>
<script type="text/javascript" src="../src/scenes/Scene.js"></script>
<script type="text/javascript" src="../src/renderers/Projector.js"></script>
<script type="text/javascript" src="../src/renderers/CanvasRenderer.js"></script>
<script type="text/javascript" src="../src/renderers/SVGRenderer.js"></script>
<script type="text/javascript" src="../src/renderers/WebGLRenderer.js"></script>
<script type="text/javascript" src="../src/renderers/renderables/RenderableFace3.js"></script>
<script type="text/javascript" src="../src/renderers/renderables/RenderableFace4.js"></script>
<script type="text/javascript" src="../src/renderers/renderables/RenderableParticle.js"></script>
<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>
-->
<!--
<script type="text/javascript" src="obj/female02/female02.js"></script>
-->
<script type="text/javascript" src="geometry/primitives/Sphere.js"></script>
<script type="text/javascript" src="geometry/primitives/Plane.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<script type="text/javascript">
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var FLOOR = -200;
var container;
var stats;
var camera;
var scene;
var canvasRenderer, webglRenderer;
var mesh, zmesh, geometry;
var mouseX = 0;
var mouseY = 0;
var windowHalfX = window.innerWidth >> 1;
var windowHalfY = window.innerHeight >> 1;
var render_canvas = 1, render_gl = 1;
var has_gl = 0;
var bcanvas = document.getElementById("rcanvas");
var bwebgl = document.getElementById("rwebgl");
document.addEventListener('mousemove', onDocumentMouseMove, false);
init();
loop();
render_canvas = !has_gl;
bwebgl.style.display = has_gl ? "inline" : "none";
bcanvas.className = render_canvas ? "button" : "button inactive";
setInterval(loop, 1000/60);
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.Camera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 100000 );
camera.position.z = 500;
camera.updateMatrix();
scene = new THREE.Scene();
// GROUND
var x = document.createElement( "canvas" );
var xc = x.getContext("2d");
x.width = x.height = 128;
xc.fillStyle = "#fff";
xc.fillRect(0, 0, 128, 128);
xc.fillStyle = "#000";
xc.fillRect(0, 0, 64, 64);
xc.fillStyle = "#999";
xc.fillRect(32, 32, 32, 32);
xc.fillStyle = "#000";
xc.fillRect(64, 64, 64, 64);
xc.fillStyle = "#555";
xc.fillRect(96, 96, 32, 32);
var xm = new THREE.MeshBitmapUVMappingMaterial( x );
xm.loaded = 1;
geometry = new Plane( 100, 100, 15, 10 );
for(var i=0; i<geometry.uvs.length; i++) {
var uvs = geometry.uvs[i];
for ( j = 0, jl = uvs.length; j < jl; j++ ) {
uvs[j].u *= 10;
uvs[j].v *= 10;
}
}
mesh = new THREE.Mesh( geometry, xm );
mesh.position.x = 0;
mesh.position.y = FLOOR;
mesh.position.z = 0;
mesh.rotation.x = 1.57;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 10;
mesh.doubleSided = true;
mesh.updateMatrix();
scene.add(mesh);
// SPHERES
sphere = new Sphere( 100, 16, 8 );
for (var i=0; i<10; i++) {
mesh = new THREE.Mesh( sphere, new THREE.MeshColorFillMaterial( 0xffdddddd ) );
mesh.position.x = 500 * (Math.random() - 0.5);
mesh.position.y = 300 * (Math.random() - 0) + FLOOR;
mesh.position.z = 100 * (Math.random() - 1);
mesh.scale.x = mesh.scale.y = mesh.scale.z = 0.25 * (Math.random() + 0.5);
//mesh.doubleSided = true;
mesh.overdraw = true;
mesh.updateMatrix();
scene.add(mesh);
}
// LIGHTS
var ambient = new THREE.AmbientLight( 0x221100 );
scene.addLight( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.y = -70;
directionalLight.position.z = 100;
directionalLight.position.normalize();
scene.addLight( directionalLight );
var pointLight = new THREE.PointLight( 0xff0000, 1 );
scene.addLight( pointLight );
if ( render_gl ) {
try {
webglRenderer = new THREE.WebGLRenderer();
webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
container.appendChild( webglRenderer.domElement );
has_gl = 1;
}
catch (e) {
}
}
if( render_canvas ) {
canvasRenderer = new THREE.CanvasRenderer();
canvasRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
container.appendChild( canvasRenderer.domElement );
}
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
bcanvas.addEventListener("click", toggleCanvas, false);
bwebgl.addEventListener("click", toggleWebGL, false);
function createModel() {
// MESH
geometry = new Female02( "obj/female02" );
zmesh = new THREE.Mesh( geometry, geometry.materials, 1 );
zmesh.position.z = 50;
zmesh.position.y = FLOOR;
zmesh.scale.x = zmesh.scale.y = zmesh.scale.z = 3;
//zmesh.doubleSided = true;
//zmesh.flipSided = true;
zmesh.overdraw = true;
zmesh.updateMatrix();
scene.add(zmesh);
// PLANES with all materials from the model
createMaterialsPalette( geometry.materials, 100 );
}
loadAsync( "obj/female02/female02.js", createModel);
}
function loadAsync( url, callback ) {
var el = document.createElement( 'script' );
el.type = 'text/javascript';
el.onload = callback;
el.src = url;
document.getElementsByTagName("head")[0].appendChild(el);
}
function createMaterialsPalette( materials, size ) {
for ( var i=0; i<materials.length; ++i ) {
// material
mesh = new THREE.Mesh( new Plane( size, size ), materials[i] );
mesh.position.x = i * (size + 5) - ( ( materials.length - 1 )* ( size + 5 )/2);
mesh.position.y = FLOOR + size/2;
mesh.position.z = -100;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
mesh.doubleSided = true;
mesh.updateMatrix();
scene.add(mesh);
// number
var x = document.createElement( "canvas" );
var xc = x.getContext("2d");
x.width = x.height = 128;
xc.shadowColor = "#000";
xc.shadowBlur = 7;
xc.fillStyle = "orange";
xc.font = "50pt arial bold";
xc.fillText(i, 10, 64);
var xm = new THREE.MeshBitmapUVMappingMaterial( x );
xm.loaded = 1;
mesh = new THREE.Mesh( new Plane( size, size ), xm );
mesh.position.x = i * (size + 5) - ( ( materials.length - 1 )* ( size + 5 )/2);
mesh.position.y = FLOOR + size/2;
mesh.position.z = -99;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
mesh.doubleSided = true;
mesh.updateMatrix();
scene.add(mesh);
}
}
function onDocumentMouseMove(event) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
function loop() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY - camera.position.y ) * .05;
camera.updateMatrix();
if ( zmesh && 0 ) {
zmesh.rotation.y += 0.005;
zmesh.updateMatrix();
}
if ( render_canvas ) canvasRenderer.render( scene, camera );
if ( render_gl && has_gl ) webglRenderer.render( scene, camera );
stats.update();
}
function log(text) {
var e = document.getElementById("log");
e.innerHTML = text + "<br/>" + e.innerHTML;
}
function toggleCanvas() {
render_canvas = !render_canvas;
bcanvas.className = render_canvas ? "button" : "button inactive";
render_gl = !render_canvas;
bwebgl.className = render_gl ? "button" : "button inactive";
if( has_gl )
webglRenderer.domElement.style.display = render_gl ? "block" : "none";
canvasRenderer.domElement.style.display = render_canvas ? "block" : "none";
}
function toggleWebGL() {
render_gl = !render_gl;
bwebgl.className = render_gl ? "button" : "button inactive";
render_canvas = !render_gl;
bcanvas.className = render_canvas ? "button" : "button inactive";
if( has_gl )
webglRenderer.domElement.style.display = render_gl ? "block" : "none";
canvasRenderer.domElement.style.display = render_canvas ? "block" : "none";
}
</script>
</body>
</html>
......@@ -2,17 +2,20 @@
* @author mr.doob / http://mrdoob.com/
*/
THREE.Face3 = function ( a, b, c, normal, color ) {
THREE.Face3 = function ( a, b, c, normal, color, material ) {
this.a = a;
this.b = b;
this.c = c;
this.centroid = new THREE.Vector3();
this.normal = normal || new THREE.Vector3();
this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
this.color = color || new THREE.Color( 0xff000000 );
this.vertexNormals = normal instanceof Array ? normal : [];
this.material = material || 0;
};
THREE.Face3.prototype = {
......
......@@ -2,7 +2,7 @@
* @author mr.doob / http://mrdoob.com/
*/
THREE.Face4 = function ( a, b, c, d, normal, color ) {
THREE.Face4 = function ( a, b, c, d, normal, color, material ) {
this.a = a;
this.b = b;
......@@ -10,12 +10,16 @@ THREE.Face4 = function ( a, b, c, d, normal, color ) {
this.d = d;
this.centroid = new THREE.Vector3();
this.normal = normal || new THREE.Vector3();
this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
this.color = color || new THREE.Color( 0xff000000 );
this.vertexNormals = normal instanceof Array ? normal : [];
this.material = material || 0;
};
THREE.Face4.prototype = {
// TODO: Dupe? (Geometry/computeCentroid)
......
......@@ -43,9 +43,9 @@ THREE.Geometry.prototype = {
},
computeNormals: function () {
computeNormals: function ( useVertexNormals ) {
var v, vl, vertex, f, fl, face, vA, vB, vC, cb = new THREE.Vector3(), ab = new THREE.Vector3();
var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC, cb = new THREE.Vector3(), ab = new THREE.Vector3();
for ( v = 0, vl = this.vertices.length; v < vl; v++ ) {
......@@ -58,6 +58,33 @@ THREE.Geometry.prototype = {
face = this.faces[ f ];
if ( useVertexNormals && face.vertexNormals.length ) {
// set face normal to average of vertex normals
cb.set( 0, 0, 0 );
for ( n = 0, nl = face.normal.length; n < nl; n++ ) {
cb.x += face.vertexNormals[n].x;
cb.y += face.vertexNormals[n].y;
cb.z += face.vertexNormals[n].z;
}
cb.x /= 3;
cb.y /= 3;
cb.z /= 3;
if ( !cb.isZero() ) {
cb.normalize();
}
face.normal.copy( cb );
}
else {
vA = this.vertices[ face.a ];
vB = this.vertices[ face.b ];
vC = this.vertices[ face.c ];
......@@ -73,11 +100,45 @@ THREE.Geometry.prototype = {
}
face.normal.copy( cb );
}
}
},
computeBoundingBox: function ( ) {
if ( this.vertices.length > 0 ) {
this.bbox = { 'x': [ this.vertices[ 0 ].position.x, this.vertices[ 0 ].position.x ],
'y': [ this.vertices[ 0 ].position.y, this.vertices[ 0 ].position.y ],
'z': [ this.vertices[ 0 ].position.z, this.vertices[ 0 ].position.z ] };
var v, vl;
for ( v = 1, vl = this.vertices.length; v < vl; v++ ) {
vertex = this.vertices[ v ];
if ( vertex.position.x < this.bbox.x[ 0 ] )
this.bbox.x[ 0 ] = vertex.position.x;
else if ( vertex.position.x > this.bbox.x[ 1 ] )
this.bbox.x[ 1 ] = vertex.position.x;
if ( vertex.position.y < this.bbox.y[ 0 ] )
this.bbox.y[ 0 ] = vertex.position.y;
else if ( vertex.position.y > this.bbox.y[ 1 ] )
this.bbox.y[ 1 ] = vertex.position.y;
if ( vertex.position.z < this.bbox.z[ 0 ] )
this.bbox.z[ 0 ] = vertex.position.z;
else if ( vertex.position.z > this.bbox.z[ 1 ] )
this.bbox.z[ 1 ] = vertex.position.z;
}
}
},
toString: function () {
return 'THREE.Geometry ( vertices: ' + this.vertices + ', faces: ' + this.faces + ' )';
......
......@@ -2,7 +2,7 @@
* @author mr.doob / http://mrdoob.com/
*/
THREE.Mesh = function ( geometry, material ) {
THREE.Mesh = function ( geometry, material, normUVs ) {
THREE.Object3D.call( this );
......@@ -14,7 +14,51 @@ THREE.Mesh = function ( geometry, material ) {
this.overdraw = false;
this.materialFaces = {};
this.sortFacesByMaterial();
if( normUVs ) this.normalizeUVs();
this.geometry.computeBoundingBox();
};
THREE.Mesh.prototype = new THREE.Object3D();
THREE.Mesh.prototype.constructor = THREE.Mesh;
THREE.Mesh.prototype.sortFacesByMaterial = function () {
var f, fl, face, material;
for ( f = 0, fl = this.geometry.faces.length; f < fl; f++ ) {
face = this.geometry.faces[ f ];
material = face.material;
if ( this.materialFaces[material] == undefined )
this.materialFaces[material] = { 'faces': [] };
this.materialFaces[material].faces.push( f );
}
}
THREE.Mesh.prototype.normalizeUVs = function () {
var i,j;
for ( i = 0, l = this.geometry.uvs.length; i < l; i++ ) {
var uvs = this.geometry.uvs[i];
for ( j = 0, jl = uvs.length; j < jl; j++ ) {
// texture repeat
// (WebGL does this by default but canvas renderer needs to do it explicitly)
if( uvs[j].u != 1.0 ) uvs[j].u = uvs[j].u - Math.floor(uvs[j].u);
if( uvs[j].v != 1.0 ) uvs[j].v = uvs[j].v - Math.floor(uvs[j].v);
}
}
}
......@@ -358,7 +358,6 @@ THREE.CanvasRenderer = function () {
_context.moveTo( v1x, v1y );
_context.lineTo( v2x, v2y );
_context.lineTo( v3x, v3y );
_context.lineTo( v4x, v4y );
_context.lineTo( v1x, v1y );
_context.closePath();
......@@ -669,6 +668,10 @@ THREE.CanvasRenderer = function () {
_context.save();
_context.clip();
// debug triangle outline
//_context.strokeStyle = "black";
//_context.stroke();
denom = uv1u * ( uv3v - uv2v ) - uv2u * uv3v + uv3u * uv2v + ( uv2u - uv3u ) * uv1v;
m11 = - ( uv1v * (v3x - v2x ) - uv2v * v3x + uv3v * v2x + ( uv2v - uv3v ) * v1x ) / denom;
......
......@@ -96,7 +96,7 @@ THREE.Projector = function() {
_face3.z = Math.max( v1.positionScreen.z, Math.max( v2.positionScreen.z, v3.positionScreen.z ) );
_face3.material = object.material;
_face3.material = [ object.material[face.material] ];
_face3.overdraw = object.overdraw;
_face3.uvs = object.geometry.uvs[ f ];
_face3.color = face.color;
......@@ -135,7 +135,7 @@ THREE.Projector = function() {
_face4.z = Math.max( v1.positionScreen.z, Math.max( v2.positionScreen.z, Math.max( v3.positionScreen.z, v4.positionScreen.z ) ) );
_face4.material = object.material;
_face4.material = [ object.material[face.material] ];
_face4.overdraw = object.overdraw;
_face4.uvs = object.geometry.uvs[ f ];
_face4.color = face.color;
......
......@@ -33,7 +33,8 @@ THREE.WebGLRenderer = function () {
var face, faceColor, object, material, normal, lightColor, lightPosition, light,
vertexArray, faceArray, colorArray, normalArray, vertexIndex,
o, ol, f, fl, m, ml, i, v1, v2, v3, v4,
l, ll;
l, ll,
uv, uvArray;
if ( this.autoClear ) {
......@@ -68,21 +69,50 @@ THREE.WebGLRenderer = function () {
object = scene.objects[ o ];
var materialFace, fi;
if ( object instanceof THREE.Mesh ) {
if ( !object.__webGLVertexBuffer ) {
viewMatrix.multiply( camera.matrix, object.matrix );
_program.viewMatrixArray = new Float32Array( viewMatrix.flatten() );
_program.projectionMatrixArray = new Float32Array( camera.projectionMatrix.flatten() );
normalMatrix = THREE.Matrix4.makeInvert(viewMatrix).transpose();
_program.normalMatrixArray = new Float32Array( normalMatrix.flatten() );
_gl.uniformMatrix4fv( _program.viewMatrix, false, _program.viewMatrixArray );
_gl.uniformMatrix4fv( _program.projectionMatrix, false, _program.projectionMatrixArray );
_gl.uniformMatrix4fv( _program.normalMatrix, false, _program.normalMatrixArray );
// create separate VBOs per material
for (var m in object.materialFaces ) {
materialFace = object.materialFaces[m];
material = object.material[m];
if( !material ) continue;
//log(material);
if( !materialFace.__webGLVertexBuffer ) {
vertexArray = [];
faceArray = [];
colorArray = [];
normalArray = [];
uvArray = [];
vertexIndex = 0;
for ( f = 0, fl = object.geometry.faces.length; f < fl; f++ ) {
//log( "object.geometry.uvs: " + object.geometry.uvs.length + " " + object.geometry.uvs);
for ( f = 0, fl = materialFace.faces.length; f < fl; f++ ) {
fi = materialFace.faces[f];
face = object.geometry.faces[ f ];
face = object.geometry.faces[ fi ];
faceColor = face.color;
vertexNormals = face.vertexNormals;
normal = face.normal;
uv = object.geometry.uvs[ fi ];
if ( face instanceof THREE.Face3 ) {
......@@ -94,14 +124,33 @@ THREE.WebGLRenderer = function () {
vertexArray.push( v2.x, v2.y, v2.z );
vertexArray.push( v3.x, v3.y, v3.z );
if ( vertexNormals.length == 3 ) {
normalArray.push( vertexNormals[0].x, vertexNormals[0].y, vertexNormals[0].z );
normalArray.push( vertexNormals[1].x, vertexNormals[1].y, vertexNormals[1].z );
normalArray.push( vertexNormals[2].x, vertexNormals[2].y, vertexNormals[2].z );
}
else {
normalArray.push( normal.x, normal.y, normal.z );
normalArray.push( normal.x, normal.y, normal.z );
normalArray.push( normal.x, normal.y, normal.z );
}
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
if ( uv ) {
uvArray.push( uv[0].u, uv[0].v );
uvArray.push( uv[1].u, uv[1].v );
uvArray.push( uv[2].u, uv[2].v );
}
faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );
vertexIndex += 3;
......@@ -118,16 +167,37 @@ THREE.WebGLRenderer = function () {
vertexArray.push( v3.x, v3.y, v3.z );
vertexArray.push( v4.x, v4.y, v4.z );
if ( vertexNormals.length == 4 ) {
normalArray.push( vertexNormals[0].x, vertexNormals[0].y, vertexNormals[0].z );
normalArray.push( vertexNormals[1].x, vertexNormals[1].y, vertexNormals[1].z );
normalArray.push( vertexNormals[2].x, vertexNormals[2].y, vertexNormals[2].z );
normalArray.push( vertexNormals[3].x, vertexNormals[3].y, vertexNormals[3].z );
}
else {
normalArray.push( normal.x, normal.y, normal.z );
normalArray.push( normal.x, normal.y, normal.z );
normalArray.push( normal.x, normal.y, normal.z );
normalArray.push( normal.x, normal.y, normal.z );
}
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
if ( uv ) {
uvArray.push( uv[0].u, uv[0].v );
uvArray.push( uv[1].u, uv[1].v );
uvArray.push( uv[2].u, uv[2].v );
uvArray.push( uv[3].u, uv[3].v );
}
faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );
faceArray.push( vertexIndex, vertexIndex + 2, vertexIndex + 3 );
......@@ -141,93 +211,132 @@ THREE.WebGLRenderer = function () {
}
object.__webGLVertexBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer );
/*
log( "vertices: " + vertexArray.length/3 );
log( "faces: " + faceArray.length/3 );
log( "normals: " + normalArray.length/3 );
log( "colors: " + colorArray.length/4 );
log( "uvs: " + uvArray.length/2 );
*/
materialFace.__webGLVertexBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLVertexBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertexArray ), _gl.STATIC_DRAW );
object.__webGLNormalBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer );
materialFace.__webGLNormalBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLNormalBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( normalArray ), _gl.STATIC_DRAW );
object.__webGLColorBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLColorBuffer );
if( material instanceof THREE.MeshFaceColorFillMaterial || material instanceof THREE.MeshBitmapUVMappingMaterial ) {
materialFace.__webGLColorBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLColorBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( colorArray ), _gl.STATIC_DRAW );
}
object.__webGLFaceBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, object.__webGLFaceBuffer );
materialFace.__webGLUVBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLUVBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( uvArray ), _gl.STATIC_DRAW );
materialFace.__webGLFaceBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, materialFace.__webGLFaceBuffer );
_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faceArray ), _gl.STATIC_DRAW );
object.__webGLFaceCount = faceArray.length;
materialFace.__webGLFaceCount = faceArray.length;
}
if ( material instanceof THREE.MeshColorFillMaterial ) {
viewMatrix.multiply( camera.matrix, object.matrix );
if ( !materialFace.__webGLColorBuffer ) {
_program.viewMatrixArray = new Float32Array( viewMatrix.flatten() );
_program.projectionMatrixArray = new Float32Array( camera.projectionMatrix.flatten() );
colorArray = [];
normalMatrix = THREE.Matrix4.makeInvert(viewMatrix).transpose();
_program.normalMatrixArray = new Float32Array( normalMatrix.flatten() );
for ( i = 0; i < materialFace.__webGLFaceCount; i ++ ) {
_gl.uniformMatrix4fv( _program.viewMatrix, false, _program.viewMatrixArray );
_gl.uniformMatrix4fv( _program.projectionMatrix, false, _program.projectionMatrixArray );
_gl.uniformMatrix4fv( _program.normalMatrix, false, _program.normalMatrixArray );
colorArray.push( material.color.r, material.color.g, material.color.b, material.color.a );
_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer );
_gl.vertexAttribPointer( _program.position, 3, _gl.FLOAT, false, 0, 0 );
}
_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer );
_gl.vertexAttribPointer( _program.normal, 3, _gl.FLOAT, false, 0, 0 );
materialFace.__webGLColorBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLColorBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( colorArray ), _gl.STATIC_DRAW );
for ( m = 0, ml = object.material.length; m < ml; m++ ) {
}
material = object.material[ m ];
_gl.uniform1i( _program.enableTexture, 0 );
if ( material instanceof THREE.MeshColorFillMaterial ) {
} else if ( material instanceof THREE.MeshFaceColorFillMaterial ) {
if ( !material.__webGLColorBuffer ) {
_gl.uniform1i( _program.enableTexture, 0 );
colorArray = [];
} else if ( material instanceof THREE.MeshBitmapUVMappingMaterial ) {
for ( i = 0; i < object.__webGLFaceCount; i ++ ) {
if ( !material.__webGLTexture && material.loaded ) {
colorArray.push( material.color.r, material.color.g, material.color.b, material.color.a );
//log(material.bitmap);
material.__webGLTexture = _gl.createTexture();
_gl.bindTexture( _gl.TEXTURE_2D, material.__webGLTexture );
_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, material.bitmap ) ;
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.LINEAR );
//_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_NEAREST );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_LINEAR );
_gl.generateMipmap( _gl.TEXTURE_2D );
_gl.bindTexture( _gl.TEXTURE_2D, null );
}
material.__webGLColorBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, material.__webGLColorBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( colorArray ), _gl.STATIC_DRAW );
_gl.uniform1i( _program.enableTexture, 1 );
_gl.activeTexture( _gl.TEXTURE0 );
_gl.bindTexture( _gl.TEXTURE_2D, material.__webGLTexture );
_gl.uniform1i( _program.diffuse, 0 );
}
_gl.bindBuffer( _gl.ARRAY_BUFFER, material.__webGLColorBuffer );
_gl.vertexAttribPointer( _program.color, 4, _gl.FLOAT, false, 0, 0 );
// vertices
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLVertexBuffer );
_gl.vertexAttribPointer( _program.position, 3, _gl.FLOAT, false, 0, 0 );
} else if ( material instanceof THREE.MeshFaceColorFillMaterial ) {
// normals
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLNormalBuffer );
_gl.vertexAttribPointer( _program.normal, 3, _gl.FLOAT, false, 0, 0 );
_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLColorBuffer );
_gl.enableVertexAttribArray( _program.color );
_gl.vertexAttribPointer( _program.color, 4, _gl.FLOAT, false, 0, 0 );
// uvs
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLUVBuffer );
if ( object.geometry.uvs.length ) {
_gl.enableVertexAttribArray( _program.uv );
_gl.vertexAttribPointer( _program.uv, 2, _gl.FLOAT, false, 0, 0 );
}
else {
_gl.disableVertexAttribArray( _program.uv );
}
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, object.__webGLFaceBuffer );
_gl.drawElements( _gl.TRIANGLES, object.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
// colors
_gl.bindBuffer( _gl.ARRAY_BUFFER, materialFace.__webGLColorBuffer );
_gl.enableVertexAttribArray( _program.color );
_gl.vertexAttribPointer( _program.color, 4, _gl.FLOAT, false, 0, 0 );
// render faces
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, materialFace.__webGLFaceBuffer );
_gl.drawElements( _gl.TRIANGLES, materialFace.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
}
}
}
};
function initGL() {
try {
_gl = _canvas.getContext( 'experimental-webgl' );
_gl = _canvas.getContext( 'experimental-webgl', { antialias: true} );
} catch(e) { }
......@@ -245,8 +354,9 @@ THREE.WebGLRenderer = function () {
_gl.depthFunc( _gl.LEQUAL );
_gl.enable( _gl.BLEND );
_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
//_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
// _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); // cool!
_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
_gl.clearColor( 0, 0, 0, 0 );
}
......@@ -260,13 +370,20 @@ THREE.WebGLRenderer = function () {
"precision highp float;",
"#endif",
"uniform bool enableTexture;",
"uniform sampler2D diffuse;",
"varying vec2 vuv;",
"varying vec4 vcolor;",
"varying vec3 lightWeighting;",
"void main(){",
"if(enableTexture) {",
"vec4 texelColor = texture2D(diffuse, vuv);",
"gl_FragColor = vec4(texelColor.rgb * lightWeighting, texelColor.a);",
"} else {",
"gl_FragColor = vec4(vcolor.rgb * lightWeighting, vcolor.a);",
"}",
"}"
].join("\n") ) );
......@@ -274,6 +391,7 @@ THREE.WebGLRenderer = function () {
"attribute vec3 position;",
"attribute vec3 normal;",
"attribute vec4 color;",
"attribute vec2 uv;",
"uniform bool enableLighting;",
"uniform vec3 ambientColor;",
......@@ -285,6 +403,7 @@ THREE.WebGLRenderer = function () {
"uniform mat4 normalMatrix;",
"varying vec4 vcolor;",
"varying vec3 lightWeighting;",
"varying vec2 vuv;",
"void main(void) {",
......@@ -292,11 +411,12 @@ THREE.WebGLRenderer = function () {
"lightWeighting = vec3(1.0, 1.0, 1.0);",
"} else {",
"vec4 transformedNormal = normalMatrix * vec4(normal, 1.0);",
"float directionalLightWeighting = max(dot(transformedNormal.xyz, lightingDirection), 0.0);",
"float directionalLightWeighting = max(dot(normalize(transformedNormal.xyz), lightingDirection), 0.0);",
"lightWeighting = ambientColor + directionalColor * directionalLightWeighting;",
"}",
"vcolor = color;",
"vuv = uv;",
"gl_Position = projectionMatrix * viewMatrix * vec4( position, 1.0 );",
"}"].join("\n") ) );
......@@ -320,6 +440,8 @@ THREE.WebGLRenderer = function () {
_program.directionalColor = _gl.getUniformLocation(_program, 'directionalColor');
_program.lightingDirection = _gl.getUniformLocation(_program, 'lightingDirection');
_program.enableTexture = _gl.getUniformLocation(_program, 'enableTexture');
_program.color = _gl.getAttribLocation( _program, "color" );
_gl.enableVertexAttribArray( _program.color );
......@@ -329,6 +451,12 @@ THREE.WebGLRenderer = function () {
_program.normal = _gl.getAttribLocation( _program, "normal" );
_gl.enableVertexAttribArray( _program.normal );
_program.uv = _gl.getAttribLocation( _program, "uv" );
_gl.enableVertexAttribArray( _program.uv );
_program.diffuse = _gl.getUniformLocation( _program, "diffuse");
_gl.uniform1i( _program.diffuse, 0 );
_program.viewMatrixArray = new Float32Array(16);
_program.projectionMatrixArray = new Float32Array(16);
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册