Implemented material blendings (THREE.NormalBlending, THREE.AdditiveBlending, THREE.SubtractiveBlending) in CanvasRenderer

Added MeshNormalMaterial (per face)
This commit is contained in:
Mr.doob
2010-11-15 16:52:22 +00:00
parent 696bd4715f
commit 4d209ac433
8 changed files with 220 additions and 50 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>three.js - normal material</title>
<meta charset="utf-8">
<style type="text/css">
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
color: #808080;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
}
a {
color: #ffffff;
text-decoration: none;
}
a:hover {
color: #0080ff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - normal material.<br />
Walt Disney head by <a href="http://www.davidoreilly.com/2009/01/walt-disneys-head-on-a-plate" target="_blank">David OReilly</a>
</div>
<script type="text/javascript" src="../build/Three.js"></script>
<script type="text/javascript" src="geometry/WaltHead.js"></script>
<script type="text/javascript">
var camera, scene, renderer,
object;
init();
setInterval( loop, 1000 / 60 );
function init() {
var container = document.getElementById( 'container' );
camera = new THREE.Camera( 50, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 1000;
scene = new THREE.Scene();
object = new THREE.Mesh( new WaltHead(), new THREE.MeshNormalMaterial() );
object.overdraw = true;
object.scale.x = object.scale.y = object.scale.z = 10;
scene.addObject( object );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
}
function loop() {
var time = new Date().getTime() * 0.0005;
object.rotation.x -= 0.005;
object.rotation.y -= 0.01;
renderer.render(scene, camera);
}
</script>
</body>
</html>
+1 -1
View File
@@ -59,7 +59,7 @@
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
for (var i = 0; i < 1000; i++) {
for ( var i = 0; i < 1000; i++ ) {
particle = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: Math.random() * 0x808008 + 0x808080, opacity: 1 } ) );
particle.position.x = Math.random() * 2000 - 1000;
+4 -1
View File
@@ -4,7 +4,8 @@
* parameters = {
* near: <float>,
* far: <float>,
* opacity: <float>
* opacity: <float>,
* blending: THREE.NormalBlending
* }
*/
@@ -13,12 +14,14 @@ THREE.MeshDepthMaterial = function ( parameters ) {
this.near = 1;
this.far = 1000;
this.opacity = 1;
this.blending = THREE.NormalBlending;
if ( parameters ) {
if ( parameters.near !== undefined ) this.near = parameters.near;
if ( parameters.far !== undefined ) this.far = parameters.far;
if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
if ( parameters.blending !== undefined ) this.blending = parameters.blending;
}
+29
View File
@@ -0,0 +1,29 @@
/**
* @author mr.doob / http://mrdoob.com/
*
* parameters = {
* opacity: <float>,
* blending: THREE.NormalBlending
* }
*/
THREE.MeshNormalMaterial = function ( parameters ) {
this.opacity = 1;
this.blending = THREE.NormalBlending;
if ( parameters ) {
if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
if ( parameters.blending !== undefined ) this.blending = parameters.blending;
}
this.toString = function () {
return 'THREE.MeshNormalMaterial';
};
}
+91 -42
View File
@@ -12,6 +12,7 @@ THREE.CanvasRenderer = function () {
_context = _canvas.getContext( '2d' ),
_contextGlobalAlpha = 1,
_contextGlobalCompositeOperation = 0,
_contextStrokeStyle = '#000000',
_contextFillStyle = '#000000',
_contextLineWidth = 1,
@@ -28,7 +29,7 @@ THREE.CanvasRenderer = function () {
_light = new THREE.Color( 0xffffffff ),
_ambientLight = new THREE.Color( 0xff000000 ),
_pi2 = Math.PI * 2, _w, // z-buffer to w-buffer
_pi2 = Math.PI * 2,
_vector3 = new THREE.Vector3(), // Needed for PointLight
_uv1 = new THREE.UV(), _uv2 = new THREE.UV(), _uv3 = new THREE.UV(), _uv4 = new THREE.UV(),
@@ -287,6 +288,26 @@ THREE.CanvasRenderer = function () {
};
function setBlending( blending ) {
switch( blending ) {
case 0: // THREE.NormalBlending
_context.globalCompositeOperation = "source-over";
break;
case 1: // THREE.AdditiveBlending
_context.globalCompositeOperation = "lighter";
break;
case 2: // THREE.SubtractiveBlending
_context.globalCompositeOperation = "darker";
break;
}
_contextGlobalCompositeOperation = blending;
}
function calculateAmbientLight( scene, color ) {
var l, ll, light, lightColor,
@@ -389,12 +410,18 @@ THREE.CanvasRenderer = function () {
var width, height, scaleX, scaleY, offsetX, offsetY,
bitmap, bitmapWidth, bitmapHeight;
if ( _contextGlobalAlpha != material.opacity ) {
if ( material.opacity != _contextGlobalAlpha ) {
_context.globalAlpha = _contextGlobalAlpha = material.opacity;
}
if ( material.blending != _contextGlobalCompositeOperation ) {
setBlending( material.blending );
}
if ( material instanceof THREE.ParticleBasicMaterial ) {
bitmap = material.bitmap;
@@ -432,10 +459,10 @@ THREE.CanvasRenderer = function () {
/* DEBUG
_context.beginPath();
_context.moveTo( v1x - 10, v1y );
_context.lineTo( v1x + 10, v1y );
_context.moveTo( v1x, v1y - 10 );
_context.lineTo( v1x, v1y + 10 );
_context.moveTo( v1.x - 10, v1.y );
_context.lineTo( v1.x + 10, v1.y );
_context.moveTo( v1.x, v1.y - 10 );
_context.lineTo( v1.x, v1.y + 10 );
_context.closePath();
_context.strokeStyle = 'rgb(255,255,0)';
_context.stroke();
@@ -489,12 +516,18 @@ THREE.CanvasRenderer = function () {
function renderLine( v1, v2, element, material, scene ) {
if ( _contextGlobalAlpha != material.opacity ) {
if ( material.opacity != _contextGlobalAlpha ) {
_context.globalAlpha = _contextGlobalAlpha = material.opacity;
}
if ( material.blending != _contextGlobalCompositeOperation ) {
setBlending( material.blending );
}
if ( material instanceof THREE.LineBasicMaterial ) {
_context.beginPath();
@@ -528,12 +561,18 @@ THREE.CanvasRenderer = function () {
var bitmap, bitmapWidth, bitmapHeight;
if ( _contextGlobalAlpha != material.opacity ) {
if ( material.opacity != _contextGlobalAlpha ) {
_context.globalAlpha = _contextGlobalAlpha = material.opacity;
}
if ( material.blending != _contextGlobalCompositeOperation ) {
setBlending( material.blending );
}
if ( material.map ) {
bitmap = material.map.image;
@@ -553,17 +592,12 @@ THREE.CanvasRenderer = function () {
if ( material instanceof THREE.MeshDepthMaterial ) {
bitmap = _depthMap;
bitmapWidth = bitmap.width - 1;
bitmapHeight = bitmap.height - 1;
_w = material.__2near / (material.__farPlusNear - v1.positionScreen.z * material.__farMinusNear );
_uv1.u = _w * bitmapWidth; _uv1.v = 0;
_uv1.u = ( material.__2near / (material.__farPlusNear - v1.positionScreen.z * material.__farMinusNear ) ) * 255;
_uv2.u = ( material.__2near / (material.__farPlusNear - v2.positionScreen.z * material.__farMinusNear ) ) * 255;
_uv3.u = ( material.__2near / (material.__farPlusNear - v3.positionScreen.z * material.__farMinusNear ) ) * 255;
_w = material.__2near / (material.__farPlusNear - v2.positionScreen.z * material.__farMinusNear );
_uv2.u = _w * bitmapWidth; _uv2.v = 1;
_w = material.__2near / (material.__farPlusNear - v3.positionScreen.z * material.__farMinusNear );
_uv3.u = _w * bitmapWidth; _uv3.v = 2;
_uv1.v = 0; _uv2.v = 1; _uv3.v = 2;
drawTexturedTriangle( bitmap, v1.positionScreen.x, v1.positionScreen.y, v2.positionScreen.x, v2.positionScreen.y, v3.positionScreen.x, v3.positionScreen.y, _uv1.u, _uv1.v, _uv2.u, _uv2.v, _uv3.u, _uv3.v );
@@ -582,13 +616,6 @@ THREE.CanvasRenderer = function () {
_color.__styleString = material.color.__styleString;
} else if ( material instanceof THREE.MeshDepthMaterial ) {
/*
_w = 1 - ( material.__2near / (material.__farPlusNear - element.z * material.__farMinusNear ) );
_color.setRGBA( _w, _w, _w, 1 );
*/
} else if ( material instanceof THREE.MeshLambertMaterial ) {
if ( _enableLighting ) {
@@ -606,6 +633,16 @@ THREE.CanvasRenderer = function () {
}
}/* else if ( material instanceof THREE.MeshDepthMaterial ) {
_w = 1 - ( material.__2near / (material.__farPlusNear - element.z * material.__farMinusNear ) );
_color.setRGBA( _w, _w, _w, 1 );
}*/ else if ( material instanceof THREE.MeshNormalMaterial ) {
_color.setRGBA( normalToComponent( element.normalWorld.x ), normalToComponent( element.normalWorld.y ), normalToComponent( element.normalWorld.z ), 1 );
}
if ( material.wireframe ) {
@@ -644,12 +681,18 @@ THREE.CanvasRenderer = function () {
var bitmap, bitmapWidth, bitmapHeight;
if ( _contextGlobalAlpha != material.opacity ) {
if ( material.opacity != _contextGlobalAlpha ) {
_context.globalAlpha = _contextGlobalAlpha = material.opacity;
}
if ( material.blending != _contextGlobalCompositeOperation ) {
setBlending( material.blending );
}
if ( material.map ) {
bitmap = material.map.image;
@@ -676,20 +719,13 @@ THREE.CanvasRenderer = function () {
if ( material instanceof THREE.MeshDepthMaterial ) {
bitmap = _depthMap;
bitmapWidth = bitmap.width - 1;
bitmapHeight = bitmap.height - 1;
_w = material.__2near / (material.__farPlusNear - v1.positionScreen.z * material.__farMinusNear );
_uv1.u = _w * bitmapWidth; _uv1.v = 0;
_uv1.u = ( material.__2near / (material.__farPlusNear - v1.positionScreen.z * material.__farMinusNear ) ) * 255;
_uv2.u = ( material.__2near / (material.__farPlusNear - v2.positionScreen.z * material.__farMinusNear ) ) * 255;
_uv3.u = ( material.__2near / (material.__farPlusNear - v3.positionScreen.z * material.__farMinusNear ) ) * 255;
_uv4.u = ( material.__2near / (material.__farPlusNear - v4.positionScreen.z * material.__farMinusNear ) ) * 255;
_w = material.__2near / (material.__farPlusNear - v2.positionScreen.z * material.__farMinusNear );
_uv2.u = _w * bitmapWidth; _uv2.v = 1;
_w = material.__2near / (material.__farPlusNear - v3.positionScreen.z * material.__farMinusNear );
_uv3.u = _w * bitmapWidth; _uv3.v = 2;
_w = material.__2near / (material.__farPlusNear - v4.positionScreen.z * material.__farMinusNear );
_uv4.u = _w * bitmapWidth; _uv4.v = 3;
_uv1.v = 0; _uv2.v = 1; _uv3.v = 2; _uv4.v = 3;
drawTexturedTriangle( bitmap, v1.positionScreen.x, v1.positionScreen.y, v2.positionScreen.x, v2.positionScreen.y, v4.positionScreen.x, v4.positionScreen.y, _uv1.u, _uv1.v, _uv2.u, _uv2.v, _uv4.u, _uv4.v );
drawTexturedTriangle( bitmap, v5.positionScreen.x, v5.positionScreen.y, v3.positionScreen.x, v3.positionScreen.y, v6.positionScreen.x, v6.positionScreen.y, _uv2.u, _uv2.v, _uv3.u, _uv3.v, _uv4.u, _uv4.v );
@@ -710,11 +746,6 @@ THREE.CanvasRenderer = function () {
_color.__styleString = material.color.__styleString;
} else if ( material instanceof THREE.MeshDepthMaterial ) {
_w = 1 - ( material.__2near / (material.__farPlusNear - element.z * material.__farMinusNear ) );
_color.setRGBA( _w, _w, _w, 1 );
} else if ( material instanceof THREE.MeshLambertMaterial ) {
if ( _enableLighting ) {
@@ -732,6 +763,16 @@ THREE.CanvasRenderer = function () {
}
}/* else if ( material instanceof THREE.MeshDepthMaterial ) {
_w = 1 - ( material.__2near / (material.__farPlusNear - element.z * material.__farMinusNear ) );
_color.setRGBA( _w, _w, _w, 1 );
}*/ else if ( material instanceof THREE.MeshNormalMaterial ) {
_color.setRGBA( normalToComponent( element.normalWorld.x ), normalToComponent( element.normalWorld.y ), normalToComponent( element.normalWorld.z ), 1 );
}
if ( material.wireframe ) {
@@ -799,6 +840,14 @@ THREE.CanvasRenderer = function () {
_context.restore();
}
function normalToComponent( normal ) {
// https://gist.github.com/665829
return normal < 0 ? Math.min( 1 + normal, 0.5 ) : 0.5 + Math.min( normal, 0.5 );
}
// Hide anti-alias gaps
function expand( v1, v2 ) {
+8 -4
View File
@@ -111,9 +111,10 @@ def buildFull(debug):
'materials/Material.js',
'materials/LineBasicMaterial.js',
'materials/MeshBasicMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshLambertMaterial.js',
'materials/MeshPhongMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshNormalMaterial.js',
'materials/MeshFaceMaterial.js',
'materials/ParticleBasicMaterial.js',
'materials/ParticleCircleMaterial.js',
@@ -164,9 +165,10 @@ def buildCanvas(debug):
'materials/Material.js',
'materials/LineBasicMaterial.js',
'materials/MeshBasicMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshLambertMaterial.js',
'materials/MeshPhongMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshNormalMaterial.js',
'materials/MeshFaceMaterial.js',
'materials/ParticleBasicMaterial.js',
'materials/ParticleCircleMaterial.js',
@@ -213,9 +215,10 @@ def buildWebGL(debug):
'materials/Material.js',
'materials/LineBasicMaterial.js',
'materials/MeshBasicMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshLambertMaterial.js',
'materials/MeshPhongMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshNormalMaterial.js',
'materials/MeshFaceMaterial.js',
'materials/ParticleBasicMaterial.js',
'materials/ParticleCircleMaterial.js',
@@ -257,9 +260,10 @@ def buildSVG(debug):
'materials/Material.js',
'materials/LineBasicMaterial.js',
'materials/MeshBasicMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshLambertMaterial.js',
'materials/MeshPhongMaterial.js',
'materials/MeshDepthMaterial.js',
'materials/MeshNormalMaterial.js',
'materials/MeshFaceMaterial.js',
'materials/ParticleBasicMaterial.js',
'materials/ParticleCircleMaterial.js',