概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。
練習問題
Livebookの、kino.jsで、shaderを動作させよ。
写真
サンプルコード
defmodule KinoHTML.Shader do
use Kino.JS
def new(shader) do
Kino.JS.new(__MODULE__, shader)
end
asset "main.js" do
"""
export async function init(ctx, shader) {
ctx.root.innerHTML = `
<canvas id="canvas"></canvas>
`;
var canvas = document.getElementById('canvas');
canvas.setAttribute('width', 400);
canvas.setAttribute('height', 300);
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.getExtension('OES_texture_float');
gl.getExtension('OES_texture_float_linear');
gl.getExtension('OES_texture_half_float');
gl.getExtension('OES_texture_half_float_linear');
gl.getExtension('OES_standard_derivatives');
gl.getExtension('WEBGL_draw_buffers');
gl.getExtension('WEBGL_depth_texture');
gl.getExtension('EXT_shader_texture_lod');
gl.getExtension('EXT_texture_filter_anisotropic');
var sd = new ShaderDrawer(shader);
gl.clearColor(0, 0, 0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
render();
function ShaderDrawer(shader) {
'use strict';
var fs = gl.createShader(gl.FRAGMENT_SHADER);
var vs = gl.createShader(gl.VERTEX_SHADER);
var pr;
gl.shaderSource(vs, "attribute vec4 p;void main(){gl_Position = p;}");
gl.shaderSource(fs, shader);
gl.compileShader(vs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
{
alert("ng0");
return null;
}
gl.compileShader(fs);
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
{
alert(gl.getShaderInfoLog(fs));
return null;
}
pr = gl.createProgram();
gl.attachShader(pr, vs);
gl.attachShader(pr, fs);
gl.linkProgram(pr);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, 1, -3, -3, 1]), gl.STATIC_DRAW);
this.prg = pr;
this.draw = function(tm, w, h, wave) {
var now = new Date();
var nYear = now.getFullYear();
var nMonth = now.getMonth();
var nDate = now.getDate();
var ntime = now.getHours() * 60.0 * 60 + now.getMinutes() * 60 + now.getSeconds();
var times = [nYear, nMonth, nDate, ntime];
var wavimg = document.createElement("canvas").getContext("2d").createImageData(256, 1);
gl.viewport(0, 0, w, h);
gl.useProgram(this.prg);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, wavimg);
gl.generateMipmap(gl.TEXTURE_2D);
gl.uniform1i(gl.getUniformLocation(this.prg, "iChannel0"), 0);
gl.uniform2fv(gl.getUniformLocation(this.prg, "iResolution"), [w, h]);
gl.uniform4fv(gl.getUniformLocation(this.prg, "iChannelTime"), times);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
};
function render() {
'use strict';
var wave;
var demotime;
sd.draw(demotime, 400, 300, wave);
requestAnimationFrame(render);
};
}
"""
end
end
KinoHTML.Shader.new("""
precision mediump float;
uniform vec2 iResolution;
uniform float iGlobalTime;
uniform int iFrame;
vec3 rgb(float r, float g, float b) {
return vec3(r / 255.0, g / 255.0, b / 255.0);
}
vec4 circle(vec2 uv, vec2 pos, float rad, vec3 color) {
float d = length(pos - uv) - rad;
float t = clamp(d, 0.0, 1.0);
return vec4(color, 1.0 - t);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy;
vec2 center = iResolution.xy * 0.1;
center.x = center.x + (iGlobalTime + .5) * 64.0 + 132.0;
center.y = center.y + 128.0;
float radius = 0.3 * iResolution.y;
vec4 layer1 = vec4(rgb(210.0, 222.0, 228.0), 1.0);
vec3 red = rgb(225.0, 0.0, 0.0);
vec4 layer2 = circle(uv, center, radius, red);
fragColor = mix(layer1, layer2, layer2.a);
}
void main(void) {
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
mainImage(color, gl_FragCoord.xy);
color.w = 1.0;
gl_FragColor = color;
}
""")
以上。