提交 559e6aaf 编写于 作者: M MiiBond 提交者: Mr.doob

Added support for default attribute values.

If attributes are used by a shader but not supplied in the data, default
values can be assigned.
When a shader is created, default values for "color", "uv" and "uv2" are
automatically created.
上级 315b3a4a
......@@ -57,6 +57,18 @@ THREE.ShaderMaterial = function ( parameters ) {
this.morphTargets = false; // set to use morph targets
this.morphNormals = false; // set to use morph normals
//When rendered geometry doesn't include these attributes but the material does,
//use these default values in WebGL. This avoids errors when buffer data is missing.
this.defaultAttributeValues = {
"color" : [ 1, 1, 1],
"uv" : [ 0, 0 ],
"uv2" : [ 0, 0 ]
};
//By default, bind position to attribute index 0. In WebGL, attribute 0
//should always be used to avoid potentially expensive emulation.
this.index0AttributeName = "position";
this.setValues( parameters );
};
......
......@@ -2761,19 +2761,27 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( updateBuffers ) {
for ( attributeName in geometryAttributes ) {
if ( attributeName === 'index' ) continue;
for ( attributeName in programAttributes ) {
attributePointer = programAttributes[ attributeName ];
attributeItem = geometryAttributes[ attributeName ];
attributeSize = attributeItem.itemSize;
if ( attributePointer >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, startIndex * attributeSize * 4 ); // 4 bytes per Float32
if ( attributeItem ) {
attributeSize = attributeItem.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, startIndex * attributeSize * 4 ); // 4 bytes per Float32
}
else if ( material.defaultAttributeValues ) {
if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
_gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
_gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
}
}
......@@ -2801,19 +2809,29 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( updateBuffers ) {
for ( attributeName in geometryAttributes ) {
for ( attributeName in programAttributes ) {
if ( attributeName === 'index') continue;
attributePointer = programAttributes[ attributeName ];
attributeItem = geometryAttributes[ attributeName ];
attributeSize = attributeItem.itemSize;
if ( attributePointer >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
if ( attributeItem ) {
attributeSize = attributeItem.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
}
else if ( material.defaultAttributeValues && material.defaultAttributeValues[ attributeName ] ) {
if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
_gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
_gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
}
}
......@@ -2839,18 +2857,27 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( updateBuffers ) {
for ( attributeName in geometryAttributes ) {
for ( attributeName in programAttributes ) {
attributePointer = programAttributes[ attributeName ];
attributeItem = geometryAttributes[ attributeName ];
attributeSize = attributeItem.itemSize;
if ( attributePointer >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
if ( attributeItem ) {
attributeSize = attributeItem.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
}
else if ( material.defaultAttributeValues && material.defaultAttributeValues[ attributeName ] ) {
if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
_gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
_gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
}
}
}
......@@ -2870,17 +2897,27 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( updateBuffers ) {
for ( attributeName in geometryAttributes ) {
for ( attributeName in programAttributes ) {
attributePointer = programAttributes[ attributeName ];
attributeItem = geometryAttributes[ attributeName ];
attributeSize = attributeItem.itemSize;
if ( attributePointer >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
if ( attributeItem ) {
attributeSize = attributeItem.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
enableAttribute( attributePointer );
_gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
}
else if ( material.defaultAttributeValues && material.defaultAttributeValues[ attributeName ] ) {
if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
_gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
_gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
}
}
}
......@@ -2984,10 +3021,15 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( attributes.color >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
enableAttribute( attributes.color );
_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
if ( object.geometry.faces.length && object.geometry.faces[0].vertexColors.length > 0 ||
object.geometry.__webglColorBuffer ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
enableAttribute( attributes.color );
_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
}
else if ( material.defaultAttributeValues ) {
_gl.vertexAttrib3fv( attributes.color, material.defaultAttributeValues.color );
}
}
// normals
......@@ -3014,17 +3056,27 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( attributes.uv >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
enableAttribute( attributes.uv );
_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
if ( object.geometry.faceVertexUvs[0] ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
enableAttribute( attributes.uv );
_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
}
else if ( material.defaultAttributeValues ) {
_gl.vertexAttrib2fv( attributes.uv, material.defaultAttributeValues.uv );
}
}
if ( attributes.uv2 >= 0 ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
enableAttribute( attributes.uv2 );
_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
if ( object.geometry.faceVertexUvs[1] ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
enableAttribute( attributes.uv2 );
_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
}
else if ( material.defaultAttributeValues ) {
_gl.vertexAttrib2fv( attributes.uv2, material.defaultAttributeValues.uv2 );
}
}
......@@ -4316,7 +4368,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, material.defines, parameters );
material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, material.defines, parameters, material.index0AttributeName );
var attributes = material.program.attributes;
......@@ -5556,7 +5608,7 @@ THREE.WebGLRenderer = function ( parameters ) {
// Shaders
function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, defines, parameters ) {
function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, defines, parameters, index0AttributeName ) {
var p, pl, d, program, code;
var chunks = [];
......@@ -5789,6 +5841,13 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.attachShader( program, glVertexShader );
_gl.attachShader( program, glFragmentShader );
//Force a particular attribute to index 0.
// because potentially expensive emulation is done by browser if attribute 0 is disabled.
//And, color, for example is often automatically bound to index 0 so disabling it
if ( index0AttributeName ) {
_gl.bindAttribLocation( program, 0, index0AttributeName );
}
_gl.linkProgram( program );
if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册