mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-23 11:56:02 +10:00
Added support for custom attributes in MeshShaderMaterial.
Added support for THREE.Vector4 as uniform.
This commit is contained in:
@@ -30,6 +30,7 @@ THREE.MeshShaderMaterial = function ( parameters ) {
|
||||
this.fragmentShader = parameters.fragmentShader !== undefined ? parameters.fragmentShader : "void main() {}";
|
||||
this.vertexShader = parameters.vertexShader !== undefined ? parameters.vertexShader : "void main() {}";
|
||||
this.uniforms = parameters.uniforms !== undefined ? parameters.uniforms : {};
|
||||
this.attributes = parameters.attributes;
|
||||
|
||||
this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
|
||||
|
||||
|
||||
@@ -437,12 +437,14 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
function initMeshBuffers ( geometryGroup, object ) {
|
||||
|
||||
var f, fl, fi, face,
|
||||
m, ml, size,
|
||||
nvertices = 0, ntris = 0, nlines = 0,
|
||||
|
||||
uvType,
|
||||
vertexColorType,
|
||||
normalType,
|
||||
materials,
|
||||
attribute,
|
||||
|
||||
geometry = object.geometry,
|
||||
obj_faces = geometry.faces,
|
||||
@@ -527,7 +529,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
if ( geometryGroup.numMorphTargets ) {
|
||||
|
||||
var m, ml;
|
||||
geometryGroup.__morphTargetsArrays = [];
|
||||
|
||||
for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
|
||||
@@ -546,9 +547,43 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
|
||||
geometryGroup.__webglLineCount = nlines * 2;
|
||||
|
||||
|
||||
// custom attributes
|
||||
|
||||
for( m = 0, ml = materials.length; m < ml; m++ ) {
|
||||
|
||||
if( materials[ m ].attributes ) {
|
||||
|
||||
geometryGroup.__webglCustomAttributes = {};
|
||||
|
||||
for( a in materials[ m ].attributes ) {
|
||||
|
||||
attribute = materials[ m ].attributes[ a ];
|
||||
|
||||
size = 1; // "f" and "i"
|
||||
|
||||
if( attribute.type === "v2" ) size = 2;
|
||||
else if( attribute.type === "v3" ) size = 3;
|
||||
else if( attribute.type === "v4" ) size = 4;
|
||||
else if( attribute.type === "c" ) size = 3;
|
||||
|
||||
attribute.size = size;
|
||||
attribute.dirty = true;
|
||||
attribute.array = new Float32Array( nvertices * size );
|
||||
attribute.buffer = _gl.createBuffer();
|
||||
|
||||
geometryGroup.__webglCustomAttributes[ a ] = attribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
function setMeshBuffers ( geometryGroup, object, hint ) {
|
||||
|
||||
var f, fl, fi, face,
|
||||
@@ -565,6 +600,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
m, ml, i,
|
||||
vn, uvi, uv2i,
|
||||
vk, vkl, vka,
|
||||
a,
|
||||
|
||||
vertexIndex = 0,
|
||||
|
||||
@@ -578,6 +614,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
offset_color = 0,
|
||||
offset_skin = 0,
|
||||
offset_morphTarget = 0,
|
||||
offset_custom = 0,
|
||||
|
||||
vertexArray = geometryGroup.__vertexArray,
|
||||
uvArray = geometryGroup.__uvArray,
|
||||
@@ -592,6 +629,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
skinWeightArray = geometryGroup.__skinWeightArray,
|
||||
|
||||
morphTargetsArrays = geometryGroup.__morphTargetsArrays,
|
||||
|
||||
customAttributes = geometryGroup.__webglCustomAttributes,
|
||||
customAttribute,
|
||||
|
||||
faceArray = geometryGroup.__faceArray,
|
||||
lineArray = geometryGroup.__lineArray,
|
||||
@@ -629,6 +669,18 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
morphTargets = geometry.morphTargets;
|
||||
|
||||
if ( customAttributes ) {
|
||||
|
||||
for ( a in customAttributes ) {
|
||||
|
||||
customAttributes[ a ].offset = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
for ( f = 0, fl = chunk_faces.length; f < fl; f ++ ) {
|
||||
|
||||
fi = chunk_faces[ f ];
|
||||
@@ -678,6 +730,83 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
}
|
||||
|
||||
if ( customAttributes ) {
|
||||
|
||||
for ( a in customAttributes ) {
|
||||
|
||||
customAttribute = customAttributes[ a ];
|
||||
|
||||
if ( customAttribute.dirty ) {
|
||||
|
||||
offset_custom = customAttribute.offset;
|
||||
|
||||
if( customAttribute.size === 1 ) {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ face.a ];
|
||||
customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
|
||||
customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
|
||||
|
||||
customAttribute.offset += 3;
|
||||
|
||||
} else {
|
||||
|
||||
v1 = customAttribute.value[ face.a ];
|
||||
v2 = customAttribute.value[ face.b ];
|
||||
v3 = customAttribute.value[ face.c ];
|
||||
|
||||
if( customAttribute.size === 2 ) {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = v1.x;
|
||||
customAttribute.array[ offset_custom + 1 ] = v1.y;
|
||||
customAttribute.array[ offset_custom + 2 ] = v2.x;
|
||||
customAttribute.array[ offset_custom + 3 ] = v2.y;
|
||||
customAttribute.array[ offset_custom + 4 ] = v3.x;
|
||||
customAttribute.array[ offset_custom + 5 ] = v3.y;
|
||||
|
||||
customAttribute.offset += 6;
|
||||
|
||||
} else if( customAttribute.size === 3 ) {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = v1.x;
|
||||
customAttribute.array[ offset_custom + 1 ] = v1.y;
|
||||
customAttribute.array[ offset_custom + 2 ] = v1.z;
|
||||
customAttribute.array[ offset_custom + 3 ] = v2.x;
|
||||
customAttribute.array[ offset_custom + 4 ] = v2.y;
|
||||
customAttribute.array[ offset_custom + 5 ] = v2.z;
|
||||
customAttribute.array[ offset_custom + 6 ] = v3.x;
|
||||
customAttribute.array[ offset_custom + 7 ] = v3.y;
|
||||
customAttribute.array[ offset_custom + 8 ] = v3.z;
|
||||
|
||||
customAttribute.offset += 9;
|
||||
|
||||
} else {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = v1.x;
|
||||
customAttribute.array[ offset_custom + 1 ] = v1.y;
|
||||
customAttribute.array[ offset_custom + 2 ] = v1.z;
|
||||
customAttribute.array[ offset_custom + 3 ] = v1.w;
|
||||
customAttribute.array[ offset_custom + 4 ] = v2.x;
|
||||
customAttribute.array[ offset_custom + 5 ] = v2.y;
|
||||
customAttribute.array[ offset_custom + 6 ] = v2.z;
|
||||
customAttribute.array[ offset_custom + 7 ] = v2.w;
|
||||
customAttribute.array[ offset_custom + 8 ] = v3.x;
|
||||
customAttribute.array[ offset_custom + 9 ] = v3.y;
|
||||
customAttribute.array[ offset_custom + 10 ] = v3.z;
|
||||
customAttribute.array[ offset_custom + 11 ] = v3.w;
|
||||
|
||||
customAttribute.offset += 12;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( dirtyMorphTargets ) {
|
||||
|
||||
for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
|
||||
@@ -967,6 +1096,94 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
}
|
||||
|
||||
if ( customAttributes ) {
|
||||
|
||||
for ( a in customAttributes ) {
|
||||
|
||||
customAttribute = customAttributes[ a ];
|
||||
|
||||
if ( customAttribute.dirty ) {
|
||||
|
||||
offset_custom = customAttribute.offset;
|
||||
|
||||
if( customAttribute.size === 1 ) {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ face.a ];
|
||||
customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
|
||||
customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
|
||||
customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.d ];
|
||||
|
||||
customAttribute.offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
v1 = customAttribute.value[ face.a ];
|
||||
v2 = customAttribute.value[ face.b ];
|
||||
v3 = customAttribute.value[ face.c ];
|
||||
v4 = customAttribute.value[ face.d ];
|
||||
|
||||
if( customAttribute.size === 2 ) {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = v1.x;
|
||||
customAttribute.array[ offset_custom + 1 ] = v1.y;
|
||||
customAttribute.array[ offset_custom + 2 ] = v2.x;
|
||||
customAttribute.array[ offset_custom + 3 ] = v2.y;
|
||||
customAttribute.array[ offset_custom + 4 ] = v3.x;
|
||||
customAttribute.array[ offset_custom + 5 ] = v3.y;
|
||||
customAttribute.array[ offset_custom + 6 ] = v4.x;
|
||||
customAttribute.array[ offset_custom + 7 ] = v4.y;
|
||||
|
||||
customAttribute.offset += 8;
|
||||
|
||||
} else if( customAttribute.size === 3 ) {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = v1.x;
|
||||
customAttribute.array[ offset_custom + 1 ] = v1.y;
|
||||
customAttribute.array[ offset_custom + 2 ] = v1.z;
|
||||
customAttribute.array[ offset_custom + 3 ] = v2.x;
|
||||
customAttribute.array[ offset_custom + 4 ] = v2.y;
|
||||
customAttribute.array[ offset_custom + 5 ] = v2.z;
|
||||
customAttribute.array[ offset_custom + 6 ] = v3.x;
|
||||
customAttribute.array[ offset_custom + 7 ] = v3.y;
|
||||
customAttribute.array[ offset_custom + 8 ] = v3.z;
|
||||
customAttribute.array[ offset_custom + 9 ] = v4.x;
|
||||
customAttribute.array[ offset_custom + 10 ] = v4.y;
|
||||
customAttribute.array[ offset_custom + 11 ] = v4.z;
|
||||
|
||||
customAttribute.offset += 12;
|
||||
|
||||
} else {
|
||||
|
||||
customAttribute.array[ offset_custom + 0 ] = v1.x;
|
||||
customAttribute.array[ offset_custom + 1 ] = v1.y;
|
||||
customAttribute.array[ offset_custom + 2 ] = v1.z;
|
||||
customAttribute.array[ offset_custom + 3 ] = v1.w;
|
||||
customAttribute.array[ offset_custom + 4 ] = v2.x;
|
||||
customAttribute.array[ offset_custom + 5 ] = v2.y;
|
||||
customAttribute.array[ offset_custom + 6 ] = v2.z;
|
||||
customAttribute.array[ offset_custom + 7 ] = v2.w;
|
||||
customAttribute.array[ offset_custom + 8 ] = v3.x;
|
||||
customAttribute.array[ offset_custom + 9 ] = v3.y;
|
||||
customAttribute.array[ offset_custom + 10 ] = v3.z;
|
||||
customAttribute.array[ offset_custom + 11 ] = v3.w;
|
||||
customAttribute.array[ offset_custom + 12 ] = v4.x;
|
||||
customAttribute.array[ offset_custom + 13 ] = v4.y;
|
||||
customAttribute.array[ offset_custom + 14 ] = v4.z;
|
||||
customAttribute.array[ offset_custom + 15 ] = v4.w;
|
||||
|
||||
customAttribute.offset += 16;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( dirtyMorphTargets ) {
|
||||
|
||||
for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
|
||||
@@ -1302,6 +1519,23 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
}
|
||||
|
||||
if ( customAttributes ) {
|
||||
|
||||
for ( a in customAttributes ) {
|
||||
|
||||
customAttribute = customAttributes[ a ];
|
||||
|
||||
if ( customAttribute.dirty ) {
|
||||
|
||||
_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
|
||||
_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( dirtyMorphTargets ) {
|
||||
|
||||
for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
|
||||
@@ -1791,10 +2025,18 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
}
|
||||
|
||||
for ( a in material.attributes ) {
|
||||
|
||||
if( attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( material.morphTargets ) {
|
||||
|
||||
material.numSupportedMorphTargets = 0;
|
||||
|
||||
|
||||
if ( attributes.morphTarget0 >= 0 ) {
|
||||
|
||||
_gl.enableVertexAttribArray( attributes.morphTarget0 );
|
||||
@@ -1892,7 +2134,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
material instanceof THREE.MeshLambertMaterial ||
|
||||
material instanceof THREE.MeshPhongMaterial ||
|
||||
material instanceof THREE.LineBasicMaterial ||
|
||||
material instanceof THREE.ParticleBasicMaterial )
|
||||
material instanceof THREE.ParticleBasicMaterial ||
|
||||
material.fog )
|
||||
) {
|
||||
|
||||
refreshUniformsFog( m_uniforms, fog );
|
||||
@@ -2002,7 +2245,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
if ( material.opacity == 0 ) return;
|
||||
|
||||
var program, attributes, linewidth, primitives;
|
||||
var program, attributes, linewidth, primitives, a, attribute;
|
||||
|
||||
program = setProgram( camera, lights, fog, material, object );
|
||||
|
||||
@@ -2021,6 +2264,27 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// custom attributes
|
||||
|
||||
if ( geometryGroup.__webglCustomAttributes ) {
|
||||
|
||||
for( a in geometryGroup.__webglCustomAttributes ) {
|
||||
|
||||
if( attributes[ a ] >= 0 ) {
|
||||
|
||||
attribute = geometryGroup.__webglCustomAttributes[ a ];
|
||||
|
||||
_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
|
||||
_gl.vertexAttribPointer( attributes[ a ], attribute.size, _gl.FLOAT, false, 0, 0 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// colors
|
||||
|
||||
if ( attributes.color >= 0 ) {
|
||||
@@ -3117,6 +3381,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
geometry.__dirtyTangents = true;
|
||||
geometry.__dirtyColors = true;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// create separate wrapper per each use of VBO
|
||||
@@ -3197,7 +3463,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
function updateObject ( object, scene ) {
|
||||
|
||||
var g, geometry, geometryGroup;
|
||||
var g, geometry, geometryGroup, a, customAttributeDirty;
|
||||
|
||||
if ( object instanceof THREE.Mesh ) {
|
||||
|
||||
@@ -3209,9 +3475,21 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
geometryGroup = geometry.geometryGroups[ g ];
|
||||
|
||||
customAttributeDirty = false;
|
||||
|
||||
for( a in geometryGroup.__webglCustomAttributes ) {
|
||||
|
||||
if( geometryGroup.__webglCustomAttributes[ a ].dirty ) {
|
||||
|
||||
customAttributeDirty = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
|
||||
geometry.__dirtyUvs || geometry.__dirtyNormals ||
|
||||
geometry.__dirtyColors || geometry.__dirtyTangents ) {
|
||||
geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
|
||||
|
||||
setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );
|
||||
|
||||
@@ -3641,6 +3919,10 @@ THREE.WebGLRenderer = function ( parameters ) {
|
||||
|
||||
_gl.uniform3f( location, value.x, value.y, value.z );
|
||||
|
||||
} else if( type == "v4" ) {
|
||||
|
||||
_gl.uniform4f( location, value.x, value.y, value.z, value.w );
|
||||
|
||||
} else if( type == "c" ) {
|
||||
|
||||
_gl.uniform3f( location, value.r, value.g, value.b );
|
||||
|
||||
Reference in New Issue
Block a user