WebGLで座標変換のプログラムを全部書くのは大変なのでglMatrix-0.9.5.min.jsを導入した。物体の移動、回転、透視投影変換がとても楽になった。ライティングは『OpenGL+GLSLによる3D‐CGアニメーション』を参考にした。わかってないところが多く、ほとんどそのままだったりするが
OpenGL+GLSLによる3D‐CGアニメーション (I・O BOOKS)
- 作者: 酒井幸市
- 出版社/メーカー: 工学社
- 発売日: 2009/08
- メディア: 単行本
- 購入: 1人 クリック: 8回
- この商品を含むブログ (9件) を見る
<html> <head> <title></title> <script type="text/javascript" src="glMatrix-0.9.5.min.js"></script> <script> window.onload = function(){ var canvas = document.getElementById("canvas"); var gl = canvas.getContext("experimental-webgl"); var vertexShader = createShader(gl, "2d-vertex-shader", gl.VERTEX_SHADER); var fragmentShader = createShader(gl, "2d-fragment-shader", gl.FRAGMENT_SHADER); program = createProgram(gl, vertexShader, fragmentShader); var mvMatrix = mat4.create(); var pMatrix = mat4.create(); var pMatrixLocation = gl.getUniformLocation(program, "u_PMatrix"); var mvMatrixLocation = gl.getUniformLocation(program, "u_MVMatrix"); var positionLocation = gl.getAttribLocation(program, "a_position"); var buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, createArray(), gl.STATIC_DRAW); mat4.perspective(45, 300.0 / 300.0, 0.1, 100.0, pMatrix); mat4.identity(mvMatrix); mat4.translate(mvMatrix, [0.0, 0.0, -4.0]); mat4.rotate(mvMatrix, -80.0 * 3.1415 / 180.0, [1, 0, 0]); gl.uniformMatrix4fv(pMatrixLocation, false, pMatrix); gl.uniformMatrix4fv(mvMatrixLocation, false, mvMatrix); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); drawArray(gl, positionLocation, 2, 6); } function createShader(gl, shaderId, type) { var shader = gl.createShader(type); var source = document.getElementById(shaderId).innerHTML; gl.shaderSource(shader, source); gl.compileShader(shader); return shader; } function createProgram(gl, vertexShader, fragmentShader){ var program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { alert(gl.getShaderInfoLog(vertexShader)); alert(gl.getShaderInfoLog(fragmentShader)); } gl.useProgram(program); return program; } function createArray(){ return new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]) } function drawArray(gl, positionLocation, itemSize, itemCount){ gl.enableVertexAttribArray(positionLocation); gl.vertexAttribPointer(positionLocation, itemSize, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLES, 0, itemCount); } </script> <script id="2d-vertex-shader" type="x-shader/x-vertex"> attribute vec2 a_position; varying vec3 N; varying vec3 P; uniform mat4 u_MVMatrix; uniform mat4 u_PMatrix; void main(){ P = vec3(vec4(a_position, 0, 1) * u_MVMatrix * u_PMatrix); N = vec3(0.0, 0.0, -1.0); gl_Position = u_PMatrix * u_MVMatrix * vec4(a_position, 0, 1); } </script> <script id="2d-fragment-shader" type="x-shader/x-fragment"> precision mediump float; varying vec3 N; varying vec3 P; vec3 light_position = vec3(0.0, 0.0, -1.0); vec4 light_ambient = vec4(0.8, 0.0, 0.0, 1.0); vec4 light_diffuse = vec4(0.2, 0.2, 0.2, 1.0); vec4 light_specular = vec4(0.2, 0.2, 0.2, 1.0); void main(){ vec3 L = normalize(light_position - P); vec3 normal = normalize(N); float dotNL = dot(N, L); vec4 diffuse = light_diffuse * max(0.0, dotNL); vec3 V = normalize(-P); vec3 H = normalize(L + V); float powNH = pow(max(dot(N, H), 0.0), 0.5); if(dotNL <= 0.0) powNH = 0.0; vec4 specular = light_specular * powNH; gl_FragColor = light_ambient + diffuse + specular; } </script> </head> <body> <canvas id="canvas" width="300" height="300"></canvas> </body> </html>