1

So I spent quite a bit of time writing my own simple Phong shader before figuring that there must be some way to modify the existing three.js Phong shaders to suit my needs. What I ended up doing looked like this

var phongShader = THREE.ShaderLib.phong;
var phongMatUniforms = THREE.UniformsUtils.clone(phongShader.uniforms);
var uniforms = phongMatUniforms;
uniforms.currentTime = {
    type : "f",
    value : 1.0
};
uniforms.hourlyValues = {
    type : "fv1",
    value : hourlyValuesArray
}

Now that I had access to the Phong vertex and fragment shader, I went poking through the shader and modified the section that I thought would achieve what I was looking for :

//original Three.js phong shader line
mvPosition = modelViewMatrix * vec4( position, 1.0 );
//my edited / updated line
mvPosition = modelViewMatrix * vec4( position.x, position.y, position.z + interpolatedValue, 1.0 );

Great! Everything worked just like I thought it should. Then I decided to try and add shadows with a spotlight. The good news was that shadows worked but they didn't work with the geometry that the shader had modified. Here's a screenshot example:

https://i.stack.imgur.com/bp3E6.jpg

So I figured that there must be somewhere else in the Phong vertex shader that needs another simple update. The problem is, I can't find it. It looked to me like this:

#if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )

    //original shader code
    vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
    //updated to account for distorted geometry
    worldPosition = modelMatrix * vec4( position.x, position.y, position.z + interpolatedValue, 1.0 );
#endif

Should do the trick but all it did was produce the screenshot above.

I'm kind of at a loss here as to what / where in the shader I should be modifying to take into account my distorted geometry. It looks like this bit at the end:

#ifdef USE_SHADOWMAP

    for( int i = 0; i < MAX_SHADOWS; i ++ ) {

        vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;

    }

#endif

Sets the shadow varyings that I need, but updating "worldPosition" like I did should fix that, no?

Brenden
  • 185
  • 2
  • 10
  • Here is an answer that alters the phongshader. It may be useful to you. http://stackoverflow.com/questions/13678523/three-js-material-texture-and-color – 2pha Oct 01 '14 at 03:56
  • Mmmm. Maybe I need to modify the uv / normal? I'm not 100% sure that makes sense. – Brenden Oct 02 '14 at 02:28
  • So modifying the vShadowCoord seems to mean that all the distorted geometry *receives* shadows properly. After a little poking at a different portion of the source it looks like I may need to look at "THREE.ShadowMapPlugin" to get the geometry to *cast* shadows correctly. Specifically at "var depthShader = THREE.ShaderLib[ "depthRGBA" ];". This looks promising. – Brenden Oct 02 '14 at 04:10

1 Answers1

1

Ok, so I found the relavant shaders for the shadow casting. They do reside in THREE.ShadowMapPlugin. Specifically there is a line :

if ( object.customDepthMaterial ) {

    material = object.customDepthMaterial;

} 

So you assign a material to the objects.customDepthMaterial.

I used:

var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
depthUniforms.currentTime = {
    type : "f",
    value : 1.0
};
depthUniforms.hourlyValues = {
    type : "fv1",
    value : hourlyValuesArray
}

As the basis for the depthmaterial and then assigned it to the object thusly:

extrudedMesh.customDepthMaterial = depthMaterial;

Worked like a charm. You can then update the uniforms for the depth material just like you would for any other material.

Brenden
  • 185
  • 2
  • 10