three.js custom shader material

This post is going to assume you have used three.js to set up a basic scene with a camera and objects. The shaders can go in a script tag within the page and then can be referenced using the id of the script elements.

Vertex Shader:

[code lang="glsl"]
varying vec2 vUv;
uniform float delta;
uniform float scale;
uniform float alpha;

 

void main()
{
vUv = uv;
vec3 p = position;
p.z += sin(2.0 * p.y + delta) * 5.0;
p.z += cos(2.0 * p.z + delta / 2.0) * 5.0;
p.z += cos(2.0 * p.x + delta) * 5.0;
p.x += sin(p.y + delta / 2.0) * 10.0;
vec4 mvPosition = modelViewMatrix * vec4(scale * p, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
[/code]

This is a pulsing vertex shader that will distort the geometry in a geometric wave like fashion based on the delta value.

 

Fragment Shader:

[code lang="glsl"]
#ifdef GL_ES
precision highp float;
#endif
uniform float delta;
uniform float alpha;
varying vec2 vUv;

 

void main(void)
{
vec2 position = vUv;
float red = 1.0;
float green = 0.25 + sin(delta) * 0.25;
float blue = 0.0;
vec3 rgb = vec3(red, green, blue);
vec4 color = vec4(rgb, alpha);
gl_FragColor = color;
}
[/code]

This is a fragment shader that will transition from orange to red and back again based on the delta value.
We can set up our uniform values which correlate with our shader.

[code lang="javascript"]
//these should reference their respective shaders
vertShader = document.getElementById('vertShader').innerHTML;
fragShader = document.getElementById('fragShader').innerHTML;
attributes = {};
uniforms = {
  delta: {type: 'f', value: 0.0},
  scale: {type: 'f', value: 1.0},
  alpha: {type: 'f', value: 1.0}
};

 

material = new THREE.ShaderMaterial({
uniforms: uniforms,
attributes: attributes,
vertexShader: vertShader,
fragmentShader: fragShader,
transparent: true
});

//create sphere geometry and apply our new material
var sphere = new THREE.Mesh( new THREE.SphereGeometry(3000, 20, 20), material);

//update the delta value on an interval, 
//we could also alter other values like alpha or scale
function update() {
uniforms.delta.value += 0.1;
}

//set the interval
setInterval(update, 100);
[/code]

 

That should just about get you up and running with a basic vertex shader and fragment shader and an idea of how to manipulate values within them.  For more ideas on what you can do with fragment shaders and glsl, check out the glsl sandbox glsl sandbox.

Leave a Reply

Your email address will not be published. Required fields are marked *