提交 5739f754 编写于 作者: A alteredq

Made "needsUpdate" working for custom attributes. Added example for custom attributes.

Not perfect solution but better than nothing.
上级 70f417b8
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>three.js webgl - custom attributes</title>
<style>
body {
color: #ffffff;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 0px; width: 100%;
padding: 5px;
z-index:100;
}
</style>
</head>
<body>
<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - custom attributes example</div>
<div id="container"></div>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<script src="../build/Three.js"></script>
<script type="x-shader/x-vertex" id="vertexshader">
uniform float amplitude;
attribute float displacement;
varying vec3 vNormal;
varying vec2 vUv;
void main() {
vNormal = normal;
vUv = ( 0.5 + amplitude ) * uv + vec2( amplitude );
vec3 newPosition = position + amplitude * normal * vec3( displacement );
gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
varying vec3 vNormal;
varying vec2 vUv;
uniform vec3 color;
uniform sampler2D texture;
void main() {
vec3 light = vec3( 0.5, 0.2, 1.0 );
light = normalize( light );
float dProd = dot( vNormal, light ) * 0.5 + 0.5;
vec4 tcolor = texture2D( texture, vUv );
vec4 gray = vec4( vec3( tcolor.r * 0.3 + tcolor.g * 0.59 + tcolor.b * 0.11 ), 1.0 );
gl_FragColor = gray * vec4( vec3( dProd ) * vec3( color ), 1.0 );
}
</script>
<script type="text/javascript">
var renderer, scene, camera, stats;
var sphere, uniforms, attributes;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
init();
animate();
function init() {
camera = new THREE.Camera( 30, WIDTH / HEIGHT, 1, 10000 );
camera.position.z = 300;
scene = new THREE.Scene();
attributes = {
displacement: { type: 'f', value: [] }
};
uniforms = {
amplitude: { type: "f", value: 1.0 },
color: { type: "c", value: new THREE.Color( 0xff2200 ) },
texture: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/water.jpg" ) },
};
uniforms.texture.texture.wrapS = uniforms.texture.texture.wrapT = THREE.RepeatWrapping;
var shaderMaterial = new THREE.MeshShaderMaterial( {
uniforms: uniforms,
attributes: attributes,
vertexShader: document.getElementById( 'vertexshader' ).textContent,
fragmentShader: document.getElementById( 'fragmentshader' ).textContent
});
var radius = 50, segments = 128, rings = 64;
var geometry = new THREE.SphereGeometry( radius, segments, rings );
sphere = new THREE.Mesh( geometry, shaderMaterial );
sphere.dynamic = true;
var vertices = sphere.geometry.vertices;
var values = attributes.displacement.value;
for( var v = 0; v < vertices.length; v++ ) {
values[ v ] = Math.random() * 5;
}
scene.addChild( sphere );
renderer = new THREE.WebGLRenderer( { clearColor: 0x050505, clearAlpha: 1 } );
renderer.setSize( WIDTH, HEIGHT );
var container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
}
var i, value;
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
sphere.rotation.y += 0.01;
sphere.rotation.z += 0.01;
uniforms.amplitude.value = 2.5 * Math.sin( sphere.rotation.y * 0.125 );
THREE.ColorUtils.adjustHSV( uniforms.color.value, 0.0005, 0, 0 );
for( i = 0; i < attributes.displacement.value.length; i++ ) {
value = attributes.displacement.value[ i ];
value[ i ] += 0.5 * ( 0.5 - Math.random() );
if ( value[ i ] < -5 ) value[ i ] = -5;
if ( value[ i ] > 5 ) value[ i ] = 5;
}
attributes.displacement.needsUpdate = true;
renderer.render( scene, camera );
}
</script>
</body>
</html>
\ No newline at end of file
......@@ -582,8 +582,8 @@ THREE.WebGLRenderer = function ( parameters ) {
uvType,
vertexColorType,
normalType,
materials,
attribute,
materials, material,
attribute, property, originalAttribute,
geometry = object.geometry,
obj_faces = geometry.faces,
......@@ -611,6 +611,14 @@ THREE.WebGLRenderer = function ( parameters ) {
}
materials = unrollGroupMaterials( geometryGroup, object );
// this will not work if materials would change in run-time
// it should be refreshed every frame
// but need to do unrollGroupMaterials
// more properly without push to array
// like unrollBufferMaterials
geometryGroup.__materials = materials;
uvType = bufferGuessUVType( materials, geometryGroup, object );
normalType = bufferGuessNormalType( materials, geometryGroup, object );
......@@ -692,17 +700,25 @@ THREE.WebGLRenderer = function ( parameters ) {
for ( m = 0, ml = materials.length; m < ml; m ++ ) {
if ( materials[ m ].attributes ) {
material = materials[ m ];
if ( material.attributes ) {
geometryGroup.__webglCustomAttributes = {};
for ( a in materials[ m ].attributes ) {
for ( a in material.attributes ) {
// Do a shallow copy of the attribute object so different geometryGroup chunks use different
// attribute buffers which are correctly indexed in the setMeshBuffers function
originalAttribute = material.attributes[ a ];
// Do a shallow copy of the attribute object so different geometryGroup chunks use different
// attribute buffers which are correctly indexed in the setMeshBuffers function
attribute = {};
for (prop in materials[ m ].attributes[ a ] ) {
attribute [ prop ] = materials[ m ].attributes[ a ][ prop ];
for ( property in originalAttribute ) {
attribute[ property ] = originalAttribute[ property ];
}
if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
......@@ -717,10 +733,12 @@ THREE.WebGLRenderer = function ( parameters ) {
else if( attribute.type === "c" ) size = 3;
attribute.size = size;
attribute.needsUpdate = true;
attribute.array = new Float32Array( nvertices * size );
attribute.buffer = _gl.createBuffer();
attribute.buffer.belongsToAttribute = a;
originalAttribute.needsUpdate = true;
attribute.__original = originalAttribute;
}
......@@ -896,8 +914,8 @@ THREE.WebGLRenderer = function ( parameters ) {
for ( a in customAttributes ) {
customAttribute = customAttributes[ a ];
if ( customAttribute.needsUpdate ) {
if ( customAttribute.__original.needsUpdate ) {
offset_custom = customAttribute.offset;
offset_customSrc = customAttribute.offsetSrc;
......@@ -1328,7 +1346,7 @@ THREE.WebGLRenderer = function ( parameters ) {
customAttribute = customAttributes[ a ];
if ( customAttribute.needsUpdate ) {
if ( customAttribute.__original.needsUpdate ) {
offset_custom = customAttribute.offset;
offset_customSrc = customAttribute.offsetSrc;
......@@ -1826,13 +1844,11 @@ THREE.WebGLRenderer = function ( parameters ) {
customAttribute = customAttributes[ a ];
if ( customAttribute.needsUpdate ) {
if ( customAttribute.__original.needsUpdate ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
customAttribute.needsUpdate = false;
}
}
......@@ -2578,7 +2594,8 @@ THREE.WebGLRenderer = function ( parameters ) {
// custom attributes
// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
if ( geometryGroup.__webglCustomAttributes ) {
for( a in geometryGroup.__webglCustomAttributes ) {
......@@ -3396,7 +3413,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( !material.program ) _this.initMaterial( material, lights, undefined, object );
program = material.program,
p_uniforms = program.uniforms,
p_uniforms = program.uniforms,
m_uniforms = material.uniforms,
attributes = program.attributes;
......@@ -3557,8 +3574,8 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth ) / halfViewportWidth,
( halfViewportHeight - object.position.y ) / halfViewportHeight,
Math.max( 0, Math.min( 1, object.position.z )));
( halfViewportHeight - object.position.y ) / halfViewportHeight,
Math.max( 0, Math.min( 1, object.position.z )));
} else {
......@@ -4013,6 +4030,57 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function areCustomAttributesDirty( geometryGroup ) {
var a, m, ml, material, materials;
materials = geometryGroup.__materials;
for ( m = 0, ml = materials.length; m < ml; m ++ ) {
material = materials[ m ];
if ( material.attributes ) {
for ( a in material.attributes ) {
if ( material.attributes[ a ].needsUpdate ) return true;
}
}
}
return false;
};
function clearCustomAttributes( geometryGroup ) {
var a, m, ml, material, materials;
materials = geometryGroup.__materials;
for ( m = 0, ml = materials.length; m < ml; m ++ ) {
material = materials[ m ];
if ( material.attributes ) {
for ( a in material.attributes ) {
material.attributes[ a ].needsUpdate = false;
}
}
}
};
function updateObject( object, scene ) {
var g, geometry, geometryGroup, a, customAttributeDirty;
......@@ -4027,22 +4095,11 @@ THREE.WebGLRenderer = function ( parameters ) {
geometryGroup = geometry.geometryGroups[ g ];
customAttributeDirty = false;
for ( a in geometryGroup.__webglCustomAttributes ) {
if( geometryGroup.__webglCustomAttributes[ a ].needsUpdate ) {
customAttributeDirty = true;
break;
}
}
customAttributeDirty = areCustomAttributesDirty( geometryGroup );
if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
geometry.__dirtyUvs || geometry.__dirtyNormals ||
geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
geometry.__dirtyUvs || geometry.__dirtyNormals ||
geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );
......@@ -4058,6 +4115,8 @@ THREE.WebGLRenderer = function ( parameters ) {
geometry.__dirtyTangents = false;
geometry.__dirtyColors = false;
clearCustomAttributes( geometryGroup );
} else if ( object instanceof THREE.Ribbon ) {
geometry = object.geometry;
......@@ -4140,7 +4199,7 @@ THREE.WebGLRenderer = function ( parameters ) {
} else if ( object instanceof THREE.Mesh ||
object instanceof THREE.ParticleSystem ||
object instanceof THREE.Ribbon ||
object instanceof THREE.Line ) {
object instanceof THREE.Line ) {
removeInstances( scene.__webglObjects, object );
......
python build.py --common --minified
python build.py --common --minified --includes
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册