How can I add a direction light to a transforming cube in webGL.
I know it requires normals and i've add them in the snippet (i've commented them out)
It will also require some math in the vertex shader. unfortunatly this code doesnt work when i uncomment.
attribute vec4 coords;
uniform mat4 transformMatrix;
attribute vec3 normal;
attribute vec4 colors;
uniform vec3 lightColor;
uniform vec3 lightDirection;
varying vec4 varyingColors;
uniform mat4 perspectiveMatrix;
void main(void) {
vec3 norm = normalize(normal);
vec3 ld = normalize(lightDirection);
float dotProduct = max(dot(norm, ld), 0.0);
vec3 vertexColor = lightColor * colors * dotProduct;
varyingColors = vec4(vertexColor, 1);
gl_Position = perspectiveMatrix * transformMatrix * coords;
}
var gl,
shaderProgram,
vertices,
matrix = mat4.create(),
vertexCount,
indexCount,
q = quat.create(),
translate =[-3, 0, -10],
scale = [1,1,1],
pivot = [0,0,0];
translate2 = [0, 0, -8],
scale2 = [3,3,3],
pivot2 = [1,1,1]
initGL();
createShaders();
createVertices();
createIndices();
draw();
function initGL() {
var canvas = document.getElementById("canvas");
gl = canvas.getContext("webgl");
gl.enable(gl.DEPTH_TEST);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1, 1, 1, 1);
}
function createShaders() {
var vertexShader = getShader(gl, "shader-vs");
var fragmentShader = getShader(gl, "shader-fs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
}
function createVertices() {
vertices = [
-1, -1, -1, 1, 0, 0, 1, // 0
1, -1, -1, 1, 1, 0, 1, // 1
-1, 1, -1, 0, 1, 1, 1, // 2
1, 1, -1, 0, 0, 1, 1, // 3
-1, 1, 1, 1, 0.5, 0, 1, // 4
1, 1, 1, 0.5, 1, 1, 1, // 5
-1, -1, 1, 1, 0, 0.5, 1, // 6
1, -1, 1, 0.5, 0, 1, 1, // 7
];
vertexCount = vertices.length / 7;
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var coords = gl.getAttribLocation(shaderProgram, "coords");
gl.vertexAttribPointer(coords, 3, gl.FLOAT, false, Float32Array.BYTES_PER_ELEMENT * 7, 0);
gl.enableVertexAttribArray(coords);
/**
var normals = [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0
];
var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
var normalLocation = gl.getAttribLocation(shaderProgram, "normal");
gl.vertexAttribPointer(normalLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
var lightColor = gl.getUniformLocation(shaderProgram, "lightColor");
gl.uniform3f(lightColor, 1, 1, 1);
var lightDirection = gl.getUniformLocation(shaderProgram, "lightDirection");
gl.uniform3f(lightDirection, 0.5, 1, 0);
*/
var colorsLocation = gl.getAttribLocation(shaderProgram, "colors");
gl.vertexAttribPointer(colorsLocation, 4, gl.FLOAT, false, Float32Array.BYTES_PER_ELEMENT * 7, Float32Array.BYTES_PER_ELEMENT * 3);
gl.enableVertexAttribArray(colorsLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
var perspectiveMatrix = mat4.create();
mat4.perspective(perspectiveMatrix, 1, canvas.width / canvas.height, 0.1, 11);
var perspectiveLoc = gl.getUniformLocation(shaderProgram, "perspectiveMatrix");
gl.uniformMatrix4fv(perspectiveLoc, false, perspectiveMatrix);
}
function createIndices() {
var indices = [
0, 1, 2, 1, 2, 3,
2, 3, 4, 3, 4, 5,
4, 5, 6, 5, 6, 7,
6, 7, 0, 7, 0, 1,
0, 2, 6, 2, 6, 4,
1, 3, 7, 3, 7, 5
];
indexCount = indices.length;
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);
}
function draw(timeMs) {
requestAnimationFrame(draw);
let interval = timeMs / 3000
let t = interval - Math.floor(interval);
let trans_t = vec3.lerp([], translate, translate2, t);
let scale_t = vec3.lerp([], scale, scale2, t);
let pivot_t = vec3.lerp([], pivot, pivot2, t);
mat4.fromRotationTranslationScaleOrigin(matrix, q, trans_t, scale_t, pivot_t);
var transformMatrix = gl.getUniformLocation(shaderProgram, "transformMatrix");
gl.uniformMatrix4fv(transformMatrix, false, matrix);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_BYTE, 0);
}
/*
* https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
*/
function getShader(gl, id) {
var shaderScript, theSource, currentChild, shader;
shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
theSource = "";
currentChild = shaderScript.firstChild;
while (currentChild) {
if (currentChild.nodeType == currentChild.TEXT_NODE) {
theSource += currentChild.textContent;
}
currentChild = currentChild.nextSibling;
}
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
// Unknown shader type
return null;
}
gl.shaderSource(shader, theSource);
// Compile the shader program
gl.compileShader(shader);
// See if it compiled successfully
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 coords;
attribute float pointSize;
uniform mat4 transformMatrix;
attribute vec4 colors;
varying vec4 varyingColors;
uniform mat4 perspectiveMatrix;
void main(void) {
gl_Position = perspectiveMatrix * transformMatrix * coords;
gl_PointSize = pointSize;
varyingColors = colors;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 color;
varying vec4 varyingColors;
void main(void) {
gl_FragColor = varyingColors;
}
</script>
<canvas id="canvas" width="600" height="600"></canvas>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>