Converting or replicating custom MeshPhongMaterial from Three to Babylon

Hi there,

Just starting up on a new (rather exciting) Babylon project and ran into a first head scratcher. I was supplied with a Three.js shader sample which seems equivalent to a Fresnel refraction. I have to admit I’m really out of my league here but I was wondering if it’s possible to port this over to Babylon:

var mesh, renderer, scene, camera, controls;
    // renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
    // scene
    scene = new THREE.Scene();
    // camera
    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.set( 2, 2, 4 );
    camera.lookAt(new THREE.Vector3(0,0,0));
    // controls
    controls = new THREE.OrbitControls( camera, document.body );
    // ambient light
    scene.add( new THREE.AmbientLight( 0xffffff ) );
    // directional light
    var light = new THREE.DirectionalLight( 0xffffff, 0 );
    light.position.set( 90, 90, 90 );
    scene.add( light );
    // axes
    scene.add( new THREE.AxesHelper( 20 ) );
    // geometry
    var geometry = new THREE.TorusKnotBufferGeometry( 1, 0.3, 128, 16 );
// https://github.com/Fyrestar/THREE.extendMaterial
    var material = THREE.extendMaterial(THREE.MeshPhongMaterial, {
      // Will be prepended to vertex and fragment code
      header: 'varying vec3 vNN; varying vec3 vEye;',
      // Insert code lines by hinting at a existing
      vertex: {
        // Inserts the line after #include <fog_vertex>
        '#include <fog_vertex>': `
          mat4 LM = modelMatrix;
          LM[2][3] = 0.0;
          LM[3][0] = 0.0;
          LM[3][1] = 0.0;
          LM[3][2] = 0.0;
          vec4 GN = LM * vec4(objectNormal.xyz, 1.0);
          vNN = normalize(GN.xyz);
          vEye = normalize(GN.xyz-cameraPosition);`
      },
      fragment: {
        'gl_FragColor = vec4( outgoingLight, diffuseColor.a );' : `
gl_FragColor.rgb +=  0.5 - -min(dot(vEye, normalize(vNN) ), 0.0);
`
      },
      // Uniforms (will be applied to existing or added)
      uniforms: {
        diffuse: new THREE.Color('black')
      }
    });
    // mesh
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
  function animate() {
    mesh.rotateY(0.02);
      requestAnimationFrame( animate );
      renderer.render( scene, camera );
  }
animate();

Any suggestions or directions would be quite helpful. I’m reviewing the docs trying to find a similar way to extend or define one?

Thanks!

David

You should be able to use the ShaderMaterial to achieve the same:
Putting Shader Code Into Babylon.js | Babylon.js Documentation

I think it’s more a CustomMaterial (CustomMaterial | Babylon.js Documentation - there’s also a lot of samples using CustomMaterial in this forum) that should be used as the 3js version is building upon a MeshPhongMaterial which I think is somewhat the same thing than our StandardMaterial. Or a node material could also be created.

I just attempted porting the 3JS vertex and fragment parts into CYOS but I’m not familiar enough with the scripting to make it work. I’ll have to resort to trying a StandardMaterial to create a similar effect.

Thanks guys =)

Maybe nme? Node Material | Babylon.js Documentation

@Deltakosh we ended up using CYOS shader to solve this problem. The issue that I’m battling now is that the GLB that we’re using has mesh colours (I suppose it’s treated as a texture at this point). When I apply the generated shader it overrides all the textures/colourization of the GLB.

This may seem like a basic question but can I not apply the shader as an effect on top of the textures/colours etc baked into the GLB? Is this more of a question of having the GLB include the shader itself?

ie. the following sample declares a shader material then uses setTexture on top. I’m going the opposite direction where the GLB is set with baked values…

https://playground.babylonjs.com/#1OH09K#131

meshes have only on material so if you use your own material it will replace the one used before. So there is no “on top of”.

Now if the mesh has vertex color, you have to support it in your shader (like position, uv, there is also color)