baobao
3/12/2018 - 1:52 PM

[WEBGL]平行ライト

[WEBGL]平行ライト

// required:https://github.com/doxas/minMatrix.js
window.onload = function()
{
	console.log("start");
	
	var canvas = document.getElementById("canvas");
	canvas.width = canvas.height = 300;
	var gl = canvas.getContext('webgl');
	var vs = gl.createShader(gl.VERTEX_SHADER);
	var fs = gl.createShader(gl.FRAGMENT_SHADER);
	gl.shaderSource(vs, document.getElementById('vs').text);
	gl.shaderSource(fs, document.getElementById('fs').text);
	gl.compileShader(vs);
	gl.compileShader(fs);
	
	var prog = gl.createProgram();
	gl.attachShader(prog, vs);
	gl.attachShader(prog, fs);
	
	gl.linkProgram(prog);
	if (gl.getProgramParameter(prog, gl.LINK_STATUS))
	{
		gl.useProgram(prog);
	}else{
		console.log(gl.getProgramInfoLog(prog));
		return;
	}
	
	var cubeData = new cube(1);
	var attrList = [];
	var strideList = [];
	var uniformList = [];
	
	attrList[0] = gl.getAttribLocation(prog, 'pos');
	attrList[1] = gl.getAttribLocation(prog, 'color');
	attrList[2] = gl.getAttribLocation(prog, 'normal');
	
	strideList[0] = 3;
	strideList[1] = 4;
	strideList[2] = 3;
	
	uniformList[0] = gl.getUniformLocation(prog, 'mvpMatrix');
	uniformList[1] = gl.getUniformLocation(prog, 'lightPos');
	uniformList[2] = gl.getUniformLocation(prog, 'invMMatrix');
	
	var vbo = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeData["position"]), gl.STATIC_DRAW);
	gl.enableVertexAttribArray(attrList[0]);
	gl.vertexAttribPointer(attrList[0], strideList[0], gl.FLOAT, false, 0, 0);
	gl.bindBuffer(gl.ARRAY_BUFFER, null);
	
	vbo = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeData["color"]), gl.STATIC_DRAW);
	gl.enableVertexAttribArray(attrList[1]);
	gl.vertexAttribPointer(attrList[1], strideList[1], gl.FLOAT, false, 0, 0);
	gl.bindBuffer(gl.ARRAY_BUFFER, null);
	
	vbo = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeData["normal"]), gl.STATIC_DRAW);
	gl.enableVertexAttribArray(attrList[2]);
	gl.vertexAttribPointer(attrList[2], strideList[2], gl.FLOAT, false, 0, 0);
	gl.bindBuffer(gl.ARRAY_BUFFER, null);
	
	var ibo = gl.createBuffer();
	gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
	gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array(cubeData['index']), gl.STATIC_DRAW);
	
	// matrix
	var m = new matIV();
	var mMatrix = m.identity(m.create());
	var vMatrix = m.identity(m.create());
	var pMatrix = m.identity(m.create());
	var vpMatrix = m.identity(m.create());
	var mvpMatrix = m.identity(m.create());
	var invMMatrix = m.identity(m.create());
	
	m.lookAt([0, -1, 1.2], [0, 0, 0], [0, 1, 0], vMatrix);
	m.perspective(90, 1, 0.1, 100, pMatrix);
	m.multiply(pMatrix, vMatrix, vpMatrix);
	
	// ライト位置
	gl.uniform3fv(uniformList[1], [2, 2, 2]);
	
	gl.enable(gl.DEPTH_TEST);
	
	draw();
	var count = 0;
	function draw()
	{
		gl.clearColor(0.1,0.1,0.1,1);
		gl.clear(gl.COLOR_BUFFER_BIT);
		
		var rad = 2*count++*Math.PI/180;
		m.identity(mMatrix);
		m.rotate(mMatrix, rad, [2, 1, -0.5], mMatrix);
		m.multiply(vpMatrix, mMatrix, mvpMatrix);
		
		gl.uniformMatrix4fv(uniformList[0], false, mvpMatrix);
		
		m.inverse(mMatrix, invMMatrix);
		gl.uniformMatrix4fv(uniformList[2], false, invMMatrix);
		
		gl.drawElements(gl.TRIANGLES, cubeData['index'].length, gl.UNSIGNED_SHORT, 0);
		
		setTimeout(draw, 1000/30);
	}
	
};

function cube(size)
{
    var len = size * 0.5;
    var pos = [
        -len, len, len,
        len, len, len,
        len, -len, len,
        -len, -len, len,

        -len, len, -len,
        len, len, -len,
        len, -len, -len,
        -len, -len, -len
    ];

    var index = [
        0, 1, 3,
        1, 2, 3,

        1, 5, 2,
        5, 6, 2,

        4, 0,7,
        0, 3, 7,

        5, 4, 6,
        4, 7, 6,

        0, 4, 5,
        1, 0, 5,

        3, 2, 7,
        2, 6, 7
    ];

    var color = [
      1, 1, 1, 1,
      1, 0, 0, 1,
      0, 1, 0, 1,
      0, 0, 1, 1,

      0, 1, 0, 1,
      0, 0, 1, 1,
      1, 1, 1, 1,
      1, 0, 0, 1

    ];

    return {
        "position":pos,
        "index" : index,
        "color" : color,
        "normal" : pos
    };
}
<!DOCTYPE html>
<html>
<head>
<title>Directional Light</title>
<meta charset="UTF-8">
<script src="minMatrix.js" type="text/javascript"></script>
<script src="directionallight.js" type="text/javascript"></script>
<script id="vs" type="x-shader/vertex">
attribute vec3 pos;
attribute vec4 color;
attribute vec3 normal;
uniform mat4 mvpMatrix;
varying vec4 vColor;
varying vec3 vNormal;
void main()
{
	vColor = color;
	vNormal = normal;
	gl_Position = mvpMatrix * vec4(pos, 1.0);
}
</script>

<script id="fs" type="x-shader/fragment">
precision mediump float;

uniform vec3 lightPos;
uniform mat4 invMMatrix;

varying vec4 vColor;
varying vec3 vNormal;
void main()
{
	vec4 invLightDir = invMMatrix * vec4(normalize(lightPos), 0);
	float diffuse = clamp(dot(vNormal.xyz, normalize(invLightDir.xyz)), 0.001, 1.0);
	gl_FragColor = vec4(vec3(diffuse), 1);
}
</script>
</head>
<body><canvas id="canvas"></canvas></body>
</html>