Passing PointLight Info to a custom Shader with three.js

glsl, javascript, three.js, webgl

Solution

Q1: Correct. Although, some users on this board have posted work-arounds for hacking `MeshPhongMaterial`, but that is not the original intent.

Q2 and Q3: Look at `ShaderLib.js` and you will see the "Normal Map Shader". This is a perfect template for you. Yes, you can duplicate/rename it and modify it to your liking.

It uses a Phong-based lighting model, and even accesses the scene lights for you. You call it like so:

var shader = THREE.ShaderLib[ "normalmap" ];

var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

. . .

var parameters = {
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: uniforms,
    lights: true // set this flag and you have access to scene lights
};

var material = new THREE.ShaderMaterial( parameters );

See these examples: http://threejs.org/examples/webgl_materials_normalmap.html and http://threejs.org/examples/webgl_materials_normalmap2.html.

For coding patterns to follow, see `ShaderLib.js` and `ShaderChunk.js`.

three.js r.67

Problem

I want to create an effect like the undulating sphere described in the Aerotwist Tutorial. However, in the tutorial Paul creates a fake GLSL hard-coded light in the fragment shader - instead I want to pass info from a three.js PointLight instance to my shaders, manipulate vertices/normals, then perform Phong shading. My understanding of the various levels of GPU consideration when shading a scene in three.js is as follows (sticking with Phong, for example): - No GPU consideration: Use a MeshPhongMaterial and don't worry about shaders. This is super easy but doesn't let you mess around on the GPU side. - Some GPU consideration: Use a ShaderLib Phong shader. This allows you to push shading calculations to the GPU, but since they're pre-written you can't do any custom modification of vertex positions, normals, or illumination calculations. - Full GPU management: Use a ShaderMesh and write your shaders from scratch. This gives you full customization, but also forces you to explicitly pass the attributes and uniforms your shaders will need. Q1: Is the above understanding accurate? Q2: Is there a way to do something between levels 2 and 3? I want the ability to customize the shaders to mess with vertex positions/normals, but I don't want to write my own Phong shader when a perfectly good one is included with three.js. Q3: If there is no such middle ground between levels 2 and 3, and I need to just go for level 3, whats the best way to go about it? Do I pass the light's position, intensity, etc. as uniforms, do my vertex/normal modifications, then finally explicitly write the Phong shading calculations?

Original source