<script type="text/javascript">
draw_vert =
"precision mediump float; \n" +
"attribute vec3 inPos; \n" +
"uniform mat4 u_projectionMat44;" +
"uniform mat4 u_viewMat44;" +
"uniform mat4 u_modelMat44;" +
"void main()" +
"{" +
" vec4 modolPos = u_modelMat44 * vec4(inPos, 1.0);" +
" vec4 viewPos = u_viewMat44 * modolPos;" +
" gl_Position = u_projectionMat44 * viewPos;" +
"}";
draw_frag =
"precision mediump float; \n" +
"void main()" +
"{" +
" float depth = abs(gl_FragCoord.z/gl_FragCoord.w);" +
" gl_FragColor = vec4(vec3(depth), 1.0);" +
"}";
post_vert =
"precision mediump float; \n" +
"attribute vec2 inPos; \n" +
"varying vec2 pos;" +
"void main()" +
"{" +
" pos = inPos;" +
" gl_Position = vec4(inPos, 0.0, 1.0);" +
"}";
post_frag =
"precision mediump float; \n" +
"varying vec2 pos;" +
"uniform sampler2D u_texture;" +
"uniform vec2 u_textureSize;" +
"" +
"float Depth(in sampler2D depthSampler, in vec2 texC)" +
"{" +
" float depth = texture2D(depthSampler, texC.st).x;" +
" return depth;" +
"}" +
"" +
"float DepthEdgeDist(in sampler2D colorSampler, in vec2 texCoord)" +
"{" +
" float dx = 2.0/u_textureSize.x;" +
" float dy = 2.0/u_textureSize.y;" +
" float s00 = Depth(colorSampler, texCoord.st + vec2(-dx, dy));" +
" float s10 = Depth(colorSampler, texCoord.st + vec2(-dx, 0.0));" +
" float s20 = Depth(colorSampler, texCoord.st + vec2(-dx, -dy));" +
" float s01 = Depth(colorSampler, texCoord.st + vec2(0.0, dy));" +
" float s21 = Depth(colorSampler, texCoord.st + vec2(0.0,- dy));" +
" float s02 = Depth(colorSampler, texCoord.st + vec2( dx, dy));" +
" float s12 = Depth(colorSampler, texCoord.st + vec2( dx, 0.0));" +
" float s22 = Depth(colorSampler, texCoord.st + vec2( dx, -dy));" +
" float sx = s00 + 2.0 * s10 + s20 - (s02 + 2.0 * s12 + s22);" +
" float sy = s00 + 2.0 * s01 + s02 - (s20 + 2.0 * s21 + s22);" +
" return sx * sx + sy * sy;" +
" }" +
"" +
"void main()" +
"{" +
" vec2 texC = pos * 0.5 + 0.5;" +
" float edgeDist = DepthEdgeDist(u_texture, texC.st);" +
" gl_FragColor = vec4(vec3(1.0 - edgeDist), 1.0);" +
"}";
glArrayType = typeof Float32Array !="undefined" ? Float32Array : (typeof WebGLFloatArray != "undefined" ? WebGLFloatArray : Array);
function IdentityMat44() {
var a=new glArrayType(16);
a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;
return a;
};
function Cross(a, b) { return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], 0.0 ]; }
function Dot(a, b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; }
function Normalize(v) {
var len = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
return [ v[0]/len, v[1]/len, v[2]/len ];
}
var Camera = {};
Camera.create = function() {
this.pos = [0, 8, 0.5];
this.target = [0, 0, 0];
this.up = [0, 0, 1];
this.fov_y = 90;
this.vp = [800, 600];
this.near = 0.5;
this.far = 100.0;
}
Camera.Perspective = function() {
var fn = this.far + this.near;
var f_n = this.far - this.near;
var r = this.vp[0]/this.vp[1];
var t = 1/Math.tan(Math.PI * this.fov_y/360);
var m = IdentityMat44();
m[0] = t/r; m[1] = 0; m[2] = 0; m[3] = 0;
m[4] = 0; m[5] = t; m[6] = 0; m[7] = 0;
m[8] = 0; m[9] = 0; m[10] = -fn/f_n; m[11] = -1;
m[12] = 0; m[13] = 0; m[14] = -2 * this.far * this.near/f_n; m[15] = 0;
return m;
}
function ToVP(v) { return [ v[1], v[2], -v[0] ] }
Camera.LookAt = function() {
var p = ToVP(this.pos); t = ToVP(this.target); u = ToVP(this.up);
var mx = Normalize([ t[0]-p[0], t[1]-p[1], t[2]-p[2] ]);
var my = Normalize(Cross(u, mx));
var mz = Normalize(Cross(mx, my));
var eyeInv = [ -this.pos[0], -this.pos[1], -this.pos[2] ];
var tx = Dot(eyeInv, [mx[0], my[0], mz[0]]);
var ty = Dot(eyeInv, [mx[1], my[1], mz[1]]);
var tz = Dot(eyeInv, [mx[2], my[2], mz[2]]);
var m = IdentityMat44();
m[0] = mx[0]; m[1] = mx[1]; m[2] = mx[2]; m[3] = 0;
m[4] = my[0]; m[5] = my[1]; m[6] = my[2]; m[7] = 0;
m[8] = mz[0]; m[9] = mz[1]; m[10] = mz[2]; m[11] = 0;
m[12] = tx; m[13] = ty; m[14] = tz; m[15] = 1;
return m;
}
// shader program object
var ShaderProgram = {};
ShaderProgram.Create = function(shaderList, uniformNames) {
var shaderObjs = [];
for (var i_sh = 0; i_sh < shaderList.length; ++ i_sh) {
var shderObj = this.CompileShader(shaderList[i_sh].source, shaderList[i_sh].stage);
if (shderObj == 0)
return 0;
shaderObjs.push(shderObj);
}
var progObj = this.LinkProgram(shaderObjs)
if (progObj != 0) {
progObj.unifomLocation = {};
for (var i_n = 0; i_n < uniformNames.length; ++ i_n) {
var name = uniformNames[i_n];
progObj.unifomLocation[name] = gl.getUniformLocation(progObj, name);
}
}
return progObj;
}
ShaderProgram.Use = function(progObj) { gl.useProgram(progObj); }
ShaderProgram.SetUniformInt = function(progObj, name, val) { gl.uniform1i(progObj.unifomLocation[name], val); }
ShaderProgram.SetUniform2f = function(progObj, name, arr) { gl.uniform2fv(progObj.unifomLocation[name], arr); }
ShaderProgram.SetUniformMat44 = function(progObj, name, mat) { gl.uniformMatrix4fv(progObj.unifomLocation[name], false, mat); }
ShaderProgram.CompileShader = function(source, shaderStage) {
var shaderObj = gl.createShader(shaderStage);
gl.shaderSource(shaderObj, source);
gl.compileShader(shaderObj);
var status = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS);
if (!status) alert(gl.getShaderInfoLog(shaderObj));
return status ? shaderObj : 0;
}
ShaderProgram.LinkProgram = function(shaderObjs) {
var prog = gl.createProgram();
for (var i_sh = 0; i_sh < shaderObjs.length; ++ i_sh)
gl.attachShader(prog, shaderObjs[i_sh]);
gl.linkProgram(prog);
status = gl.getProgramParameter(prog, gl.LINK_STATUS);
if (!status) alert("Could not initialise shaders");
gl.useProgram(null);
return status ? prog : 0;
}
function drawScene(){
var canvas = document.getElementById("camera-canvas");
Camera.create();
Camera.vp = [canvas.width, canvas.height];
var currentTime = Date.now();
var deltaMS = currentTime - startTime;
Camera.pos = EllipticalPosition(8, 5.5, CalcAng(currentTime, 10.0));
gl.viewport(0, 0, canvas.width, canvas.height);
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// set up framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// set up draw shader
ShaderProgram.Use(progDraw);
ShaderProgram.SetUniformMat44(progDraw, "u_projectionMat44", Camera.Perspective());
ShaderProgram.SetUniformMat44(progDraw, "u_viewMat44", Camera.LookAt());
ShaderProgram.SetUniformMat44(progDraw, "u_modelMat44", IdentityMat44());
// draw scene
gl.enableVertexAttribArray(progDraw.inPos);
gl.bindBuffer(gl.ARRAY_BUFFER, bufObj.pos);
gl.vertexAttribPointer(progDraw.inPos, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufObj.inx);
gl.drawElements(gl.TRIANGLES, bufObj.inxLen, gl.UNSIGNED_SHORT, 0);
gl.disableVertexAttribArray(bufObj.pos);
// reset framebuffer and bind frambuffer texture
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var texUnit = 0;
gl.activeTexture(gl.TEXTURE0 + texUnit);
gl.bindTexture(gl.TEXTURE_2D, fb.color0_texture);
// set up post process shader
ShaderProgram.Use(progPost);
ShaderProgram.SetUniformInt(progPost, "u_texture", texUnit)
ShaderProgram.SetUniform2f(progPost, "u_textureSize", [ fb.width, fb.height ]);
// draw full screen space
gl.enableVertexAttribArray(progPost.inPos);
gl.bindBuffer(gl.ARRAY_BUFFER, bufQuad.pos);
gl.vertexAttribPointer(progPost.inPos, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.disableVertexAttribArray(bufQuad.pos);
}
var startTime;
function Fract(val) {
return val - Math.trunc(val);
}
function CalcAng(currentTime, intervall) {
return Fract((currentTime - startTime)/(1000*intervall)) * 2.0 * Math.PI;
}
function CalcMove(currentTime, intervall, range) {
var pos = self.Fract((currentTime - startTime)/(1000*intervall)) * 2.0
var pos = pos < 1.0 ? pos : (2.0-pos)
return range[0] + (range[1] - range[0]) * pos;
}
function EllipticalPosition(a, b, angRag) {
var a_b = a * a - b * b
var ea = (a_b <= 0) ? 0 : Math.sqrt(a_b);
var eb = (a_b >= 0) ? 0 : Math.sqrt(-a_b);
return [ a * Math.sin(angRag) - ea, b * Math.cos(angRag) - eb, 0 ];
}
var gl;
var progDraw;
var progPost;
var bufObj = {};
var bufQuad = {};
function cameraStart() {
var canvas = document.getElementById("camera-canvas");
var vp = [canvas.width, canvas.height];
gl = canvas.getContext("experimental-webgl");
if (!gl)
return;
progDraw = ShaderProgram.Create(
[ { source : draw_vert, stage : gl.VERTEX_SHADER },
{ source : draw_frag, stage : gl.FRAGMENT_SHADER }
],
[ "u_projectionMat44", "u_viewMat44", "u_modelMat44"]);
progDraw.inPos = gl.getAttribLocation(progDraw, "inPos");
if (progDraw == 0)
return;
progPost = ShaderProgram.Create(
[ { source : post_vert, stage : gl.VERTEX_SHADER },
{ source : post_frag, stage : gl.FRAGMENT_SHADER }
],
[ "u_texture", "u_textureSize" ]);
progPost.inPos = gl.getAttribLocation(progPost, "inPos");
if (progPost == 0)
return;
fb = gl.createFramebuffer();
fb.width = vp[0];
fb.height = vp[1];
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
fb.color0_texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, fb.color0_texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, fb.width, fb.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
fb.renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, fb.renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, fb.width, fb.height);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fb.color0_texture, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, fb.renderbuffer);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
var pos = [];
var circumferenceCount = 32;
for (var cTB = 0; cTB < 2; cTB ++) {
var z = cTB == 0 ? -1.0 : 1.0;
for (var cInx = 0; cInx <= circumferenceCount; ++ cInx) {
var angle = 2.0 * Math.PI * cInx/circumferenceCount;
pos.push(Math.cos(angle), Math.sin(angle), z);
}
}
var inx = [];
for (var iInx = 0; iInx < circumferenceCount; ++ iInx) {
iB = iInx;
iT = iInx + circumferenceCount + 1;
inx.push(iB, iT+1, iT, iB, iB+1, iT+1);
}
bufObj.pos = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufObj.pos);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pos), gl.STATIC_DRAW);
bufObj.inx = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufObj.inx);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(inx), gl.STATIC_DRAW);
bufObj.inxLen = inx.length;
bufQuad.pos = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufQuad.pos);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ]), gl.STATIC_DRAW);
bufQuad.inx = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([ 0, 1, 2, 0, 2, 3 ]), gl.STATIC_DRAW);
startTime = Date.now();
setInterval(drawScene, 50);
}
</script>
<body onload="cameraStart();">
<canvas id="camera-canvas" style="border: none;" width="512" height="256"></canvas>
</body>
を始めています"OpenGLモード"で考えることができます。よくやった。 "太い線"を忘れてしまいます。 – Ripi2
あなたが探しているものを見つけたい場合は、代わりに 'volumetric lines in opengl'を検索することをお勧めします – Jherico