Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGLRenderer: Support more than 8 morph targets. #22293

Merged
merged 2 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ function WebGLRenderer( parameters = {} ) {
bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities );
geometries = new WebGLGeometries( _gl, attributes, info, bindingStates );
objects = new WebGLObjects( _gl, geometries, attributes, info );
morphtargets = new WebGLMorphtargets( _gl );
morphtargets = new WebGLMorphtargets( _gl, capabilities, textures );
clipping = new WebGLClipping( properties );
programCache = new WebGLPrograms( _this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping );
materials = new WebGLMaterials( properties );
Expand Down Expand Up @@ -1499,6 +1499,7 @@ function WebGLRenderer( parameters = {} ) {
materialProperties.skinning = parameters.skinning;
materialProperties.morphTargets = parameters.morphTargets;
materialProperties.morphNormals = parameters.morphNormals;
materialProperties.morphTargetsCount = parameters.morphTargetsCount;
materialProperties.numClippingPlanes = parameters.numClippingPlanes;
materialProperties.numIntersection = parameters.numClipIntersection;
materialProperties.vertexAlphas = parameters.vertexAlphas;
Expand All @@ -1520,6 +1521,7 @@ function WebGLRenderer( parameters = {} ) {
const vertexTangents = !! object.geometry && !! object.geometry.attributes.tangent;
const morphTargets = !! object.geometry && !! object.geometry.morphAttributes.position;
const morphNormals = !! object.geometry && !! object.geometry.morphAttributes.normal;
const morphTargetsCount = ( !! object.geometry && !! object.geometry.morphAttributes.position ) ? object.geometry.morphAttributes.position.length : 0;

const materialProperties = properties.get( material );
const lights = currentRenderState.state.lights;
Expand Down Expand Up @@ -1601,6 +1603,10 @@ function WebGLRenderer( parameters = {} ) {

needsProgramChange = true;

} else if ( capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount ) {

needsProgramChange = true;

}

} else {
Expand Down
21 changes: 17 additions & 4 deletions src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ export default /* glsl */`
// When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in normal = sum((target - base) * influence)
// When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting
objectNormal *= morphTargetBaseInfluence;
objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];
objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];
objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];
objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];

#ifdef MORPHTARGETS_TEXTURE

for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

if ( morphTargetInfluences[ i ] > 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1, 2 ) * morphTargetInfluences[ i ];

}

#else

objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];
objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];
objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];
objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];

#endif

#endif
`;
27 changes: 24 additions & 3 deletions src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,34 @@ export default /* glsl */`

uniform float morphTargetBaseInfluence;

#ifndef USE_MORPHNORMALS
#ifdef MORPHTARGETS_TEXTURE

uniform float morphTargetInfluences[ 8 ];
uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];
uniform sampler2DArray morphTargetsTexture;
uniform vec2 morphTargetsTextureSize;

vec3 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset, const in int stride ) {

float texelIndex = float( vertexIndex * stride + offset );
float y = floor( texelIndex / morphTargetsTextureSize.x );
float x = texelIndex - y * morphTargetsTextureSize.x;

vec3 morphUV = vec3( ( x + 0.5 ) / morphTargetsTextureSize.x, y / morphTargetsTextureSize.y, morphTargetIndex );
return texture( morphTargetsTexture, morphUV ).xyz;

}

#else

uniform float morphTargetInfluences[ 4 ];
#ifndef USE_MORPHNORMALS

uniform float morphTargetInfluences[ 8 ];

#else

uniform float morphTargetInfluences[ 4 ];

#endif

#endif

Expand Down
39 changes: 30 additions & 9 deletions src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,38 @@ export default /* glsl */`
// When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in position = sum((target - base) * influence)
// When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting
transformed *= morphTargetBaseInfluence;
transformed += morphTarget0 * morphTargetInfluences[ 0 ];
transformed += morphTarget1 * morphTargetInfluences[ 1 ];
transformed += morphTarget2 * morphTargetInfluences[ 2 ];
transformed += morphTarget3 * morphTargetInfluences[ 3 ];

#ifndef USE_MORPHNORMALS
#ifdef MORPHTARGETS_TEXTURE

transformed += morphTarget4 * morphTargetInfluences[ 4 ];
transformed += morphTarget5 * morphTargetInfluences[ 5 ];
transformed += morphTarget6 * morphTargetInfluences[ 6 ];
transformed += morphTarget7 * morphTargetInfluences[ 7 ];
for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {

#ifndef USE_MORPHNORMALS

if ( morphTargetInfluences[ i ] > 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 1 ) * morphTargetInfluences[ i ];

#else

if ( morphTargetInfluences[ i ] > 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 2 ) * morphTargetInfluences[ i ];

#endif

}

#else

transformed += morphTarget0 * morphTargetInfluences[ 0 ];
transformed += morphTarget1 * morphTargetInfluences[ 1 ];
transformed += morphTarget2 * morphTargetInfluences[ 2 ];
transformed += morphTarget3 * morphTargetInfluences[ 3 ];

#ifndef USE_MORPHNORMALS

transformed += morphTarget4 * morphTargetInfluences[ 4 ];
transformed += morphTarget5 * morphTargetInfluences[ 5 ];
transformed += morphTarget6 * morphTargetInfluences[ 6 ];
transformed += morphTarget7 * morphTargetInfluences[ 7 ];

#endif

#endif

Expand Down
Loading