Three.js, Part 2
Lighting and materials
Review
In Three.js we have:
- scenes
- cameras
- geometries
- meshes
- materials
- renderers
Ambient Lighting
Ambient = background, applies to everything
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
Not meant to be the only light in the scene
Aside: THREE.Color
new THREE.AmbientLight(new THREE.Color(0xffffff));
setHSV, add(color), lerp, etc.
Point light
Light from a single source in all directions
var light = new THREE.PointLight(0xffffff);
light.distance = 100;
light.intensity = 0.8;
light.position = new THREE.Vector3(0, 10, 0);
Like a light bulb!
Spot light
A spot light is... a spot light. (cone-shaped)
var light = new THREE.SpotLight(0xffff);
light.position = new THREE.Vector3(0, 10, 0);
light.castShadow = true;
light.target = floor;
Most natural representation for a lot of lighting
Aside: shadows
Lighting is for A) color and B) shadows.
Shadows can be expensive to compute, so we have
a lot of properties for dealing with them.
directional light
Parallel rays, like the sun (something far away)
var light = new THREE.DirectionalLight(0xffffff);
light.position = new THREE.Vector3(-40, 60, -10);
light.castShadow = true;
light.shadowCameraNear = 2;
light.shadowCameraFar = 200;
light.shadowCameraLeft = -50;
light.shadowCameraRight = 50;
light.shadowCameraTop = 50;
light.shadowCameraBottom = -50;
light.distance = 0;
light.intensity = 0.5;
light.shadowMapHeight = 1024;
light.shadowMapWidth = 1024;
other lighting
Hemisphere light: for ground reflection
Area lighting: for non-point lighting
Lens flares: lololololol
material basics
All materials share the following properties:
-
opacity: 0 to 1, transparency
-
side: FrontSide, BackSide, DoubleSide
- and more...
basic material
Static colors
var material = new THREE.MeshBasicMaterial({color: 0xffffff});
new THREE.Mesh(someGeomtery, material);
depth material
Changes based on position
new THREE.MeshDepthMaterial();
normal material
Changes based on normal vector
new THREE.MeshNormalMaterial();
FACE MATERIAL
Combine multiple materials
var matArray = [];
matArray.push(new THREE.MeshBasicMaterial( { color: 0x009e60 }));
matArray.push(new THREE.MeshBasicMaterial( { color: 0x0051ba }));
matArray.push(new THREE.MeshBasicMaterial( { color: 0xffd500 }));
matArray.push(new THREE.MeshBasicMaterial( { color: 0xff5800 }));
matArray.push(new THREE.MeshBasicMaterial( { color: 0xC41E3A }));
matArray.push(new THREE.MeshBasicMaterial( { color: 0xffffff }));
var faceMaterial = new THREE.MeshFaceMaterial(materialArray);
lighting materials
Lambert: dull
-
ambient: combines with natural ambience
-
emissive: solid color emitted by object
Phong: shiny
-
specular: what color you shine as
-
shininess: how shiny you are
shaders
GLSL: GL Shading Language (almost C)
-
vertex shader: defines position of vertices
-
fragment shaders: defines color of pixels
Shader looks like:
uniform float time;
void main()
{
vec3 posChanged = position;
posChanged.x = posChanged.x*(abs(sin(time*1.0)));
posChanged.y = posChanged.y*(abs(cos(time*1.0)));
posChanged.z = posChanged.z*(abs(sin(time*1.0)));
gl_Position = projectionMatrix * modelViewMatrix * vec4(posChanged,1.0);
}
shaders
-
uniforms: variables shared between shader/JS
-
defines: #define globals in shader
-
attributes: information passed between shaders
function createMaterial(vertexShader, fragmentShader) {
var vertShader = document.getElementById(vertexShader).innerHTML;
var fragShader = document.getElementById(fragmentShader).innerHTML;
var attributes = {};
var uniforms = {
time: {type: 'f', value: 0.0},
scale: {type: 'f', value: 0.2},
alpha: {type: 'f', value: 0.6},
resolution: { type: "v2", value: new THREE.Vector2() }
};
uniforms.resolution.value.x = window.innerWidth;
uniforms.resolution.value.y = window.innerHeight;
var meshMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
attributes: attributes,
vertexShader: vertShader,
fragmentShader: fragShader,
});
return meshMaterial;
}
controls
We attach controls to a camera and update
them separately.
var controls = new FPSControls(camera);
controls.movementSpeed = 100;
shaders
precision highp float;
uniform float time;
uniform float alpha;
uniform vec2 resolution;
varying vec2 vUv;
void main2(void)
{
vec2 position = vUv;
float red = 1.0;
float green = 0.25 + sin(time) * 0.25;
float blue = 0.0;
vec3 rgb = vec3(red, green, blue);
vec4 color = vec4(rgb, alpha);
gl_FragColor = color;
}
#define PI 3.14159
#define TWO_PI (PI*2.0)
#define N 68.5
void main(void)
{
vec2 center = (gl_FragCoord.xy);
center.x=-10.12*sin(time/200.0);
center.y=-10.12*cos(time/200.0);
vec2 v = (gl_FragCoord.xy - resolution/20.0) / min(resolution.y,resolution.x) * 15.0;
v.x=v.x-10.0;
v.y=v.y-200.0;
float col = 0.0;
for(float i = 0.0; i < N; i++)
{
float a = i * (TWO_PI/N) * 61.95;
col += cos(TWO_PI*(v.y * cos(a) + v.x * sin(a) + sin(time*0.004)*100.0 ));
}
col /= 5.0;
gl_FragColor = vec4(col*1.0, -col*1.0,-col*4.0, 1.0);
}