Adding a vertex shader to a dynamically loaded 3D model, possible?

Hello.

I am trying to add a vertex shader dynamically to an animated 3D model in dddance.party

It is safe to say, I have no idea what I am doing : U

function AddVertexDisplacement(shader) {

 var newUniforms = {
     time: {
         value: 0
     },
     step: {
         value: 0
     },
     x_active: {
         value: 0
     },
     x_ampl: {
         value: 0
     },
     y_active: {
         value: 0
     },
     y_ampl: {
         value: 0
     },
     z_active: {
         value: 0
     },
     z_ampl: {
         value: 0
     },
     freq:{
         value: 0
     }
 };
 $.extend(shader.uniforms, newUniforms);

 console.log(shader.uniforms);

 shader.vertexShader = 'uniform float time;\n uniform float step;\n uniform float speed, x_active, y_active, z_active, x_ampl, y_ampl, z_ampl, freq; \n' + shader.vertexShader;
 shader.vertexShader = shader.vertexShader.replace(
     '#include <begin_vertex>',
     [
         'float pi = 3.14159265358979323846;',
        //  'float theta = sin( step + abs(10.*position.x)) / 10.0;',
        //  'float theta2 = sin( step + abs(10.*position.x + pi/2.)) / 10.0;',
        //  'theta = position.x/10.;',
        //  'float c = cos( theta );',
        //  'float s = sin( theta );',
        //  'float c2 = cos( theta2 );',
        //  'float s2 = sin( theta2 );',
        //  'mat3 mx = mat3( 1, 0, 0, 0, c, -s, 0, s, c );',
        //  'mat3 my = mat3( c, 0, s, 0, 1, 0, -s, 0, c );',
        //  'mat3 mz = mat3(c2, -s2, 0, s2, c2, 0, 0, 0, 1);',
        //  'mat3 m = my;',

         'vec3 transformed = position;',
        //  'transformed = vec3( transformed ) * m*mz;',
         'float p = 1.;',
         'float q = 1.;',
        //  'time *= ',
         'float tx = step + 3.*freq*( position.x/(2.*pi));',
         'float r = cos(q*tx);',
         'float x = r*cos(p*tx);',
         'float y = r*sin(p*tx);',
         'float z = -sin(q*tx);',
         'transformed.x += x_active * x_ampl* x;',
         'transformed.y += y_active * y_ampl * y;',
         'transformed.z += z_active * z_ampl * z;',
         // 'transformed.z += z;',
         //  'transformed = transformed.xzy;',

         // 'vNormal = vNormal * m;'
     ].join('\n')
 );

}

^^ here is my shader

	var WAVY_MATERIAL0 = new THREE.MeshPhongMaterial({
	color: 0xffffff,
	shininess: 0,
	specular: 0xffffff,
	skinning: true
});
dancers[0].wavy_material = WAVY_MATERIAL0;
WAVY_MATERIAL0.onBeforeCompile = (shader) => { // trouble :(
	AddVertexDisplacement(shader);
	dancers[0].wavy_shader = shader;
};

^^ here is my code to setup shader.

	if( USE_SHADER ){ //set vertex shader on phong materials
	avatar.traverse( function ( child ) {
		if ( child instanceof THREE.Object3D ) {
			if(child.material !== undefined){
				dancers[idx].wavy_material.map = child.material.map;
				dancers[idx].wavy_material.name = child.material.name;
				child.material = dancers[idx].wavy_material;
			}
		}
	});
}

^^ here is my code to add shader to model, after it loads.

I tried a few things but get a lot of strange behavior. I know the shader works because I can add it to models that are not loaded dynamically.

This seems very complicated. Maybe someone knows an easy solution here? This onBeforeCompile is bizarre.

Thanks.

Hi, I would check the child material maps before using them.

Also just a note, perhaps is better to replace
if ( child instanceof THREE.Object3D ) {
by
if ( child.isMesh ) {

Thanks for the reply.

As I mentioned the code is working fine for models that are loaded on init, but doesn’t work for models loaded dynamically.

Did you try material.needsUpdate?

Normally it helps alot to make a live fiddle for a question, it receives more feedback.

Ah yeah, let me put an example on Glitch this weekend! : )