Skip to content

Instantly share code, notes, and snippets.

@bczhc
Created February 10, 2026 15:09
Show Gist options
  • Select an option

  • Save bczhc/ccf72db1a115925894a11d0b725033d0 to your computer and use it in GitHub Desktop.

Select an option

Save bczhc/ccf72db1a115925894a11d0b725033d0 to your computer and use it in GitHub Desktop.
vsbm带帧率版本
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no">
<title>volumeshader_bm</title>
<style>
#fps-span {
position: fixed;
right: 10px;
color: white;
}
body {
background: #131115;
}
#c1 {
background: #fbf7fe;
}
#btn {
position: fixed;
left: 0px;
top: 0px;
}
#c1 {
position: fixed;
left: 0px;
top: 0px;
}
#main {
transform-origin: 0px 0px;
position: fixed;
left: 0px;
top: 0px;
}
#config {
position: fixed;
left: 0px;
top: 30px;
display: none;
}
</style>
</head>
<body style="overflow-x:hidden;overflow-y:hidden">
<div id="main">
<canvas id="c1" width="1024" height="1024">
<span>???canvas???</span>
</canvas>
</div>
<span id="fps-span">FPS: </span>
<button id="btn">CONFIG</button>
<div id="config">
<textarea name="" id="kernel" cols="30" rows="10"></textarea>
<br/>
<button id="apply">APPLY</button>
<button id="cancle">CANCLE</button>
</div>
<script>
var cx, cy;
var glposition;
var glright;
var glforward;
var glup;
var glorigin;
var glx;
var gly;
var gllen;
var canvas;
var gl;
var date = new Date();
var md = 0, mx, my;
var t2, t1 = date.getTime();
var mx = 0, my = 0, mx1 = 0, my1 = 0, lasttimen = 0;
var ml = 0, mr = 0, mm = 0;
var len = 1.6;
var ang1 = 2.8;
var ang2 = 0.4;
var cenx = 0.0;
var ceny = 0.0;
var cenz = 0.0;
var KERNEL = "float kernal(vec3 ver){\n" +
" vec3 a;\n" +
"float b,c,d,e;\n" +
" a=ver;\n" +
" for(int i=0;i<5;i++){\n" +
" b=length(a);\n" +
" c=atan(a.y,a.x)*8.0;\n" +
" e=1.0/b;\n" +
" d=acos(a.z/b)*8.0;\n" +
" b=pow(b,8.0);\n" +
" a=vec3(b*sin(d)*cos(c),b*sin(d)*sin(c),b*cos(d))+ver;\n" +
" if(b>6.0){\n" +
" break;\n" +
" }\n" +
" }" +
" return 4.0-a.x*a.x-a.y*a.y-a.z*a.z;" +
"}";
var vertshade;
var fragshader;
var shaderProgram;
var lastTimestamp = 0
function ontimer() {
ang1 += 0.01;
draw();
window.requestAnimationFrame(ontimer);
}
let fpsSpan = document.querySelector('#fps-span');
function draw() {
date = new Date();
var t2 = date.getTime();
//ang1 += (t2 - t1)*0.001;
let fps = 1 / ((t2 - lastTimestamp) / 1000)
fpsSpan.innerHTML = `FPS: ${Math.floor(fps)}`
lastTimestamp = t2
t1 = t2;
//ang1 += 0.1;
gl.uniform1f(glx, cx * 2.0 / (cx + cy));
gl.uniform1f(gly, cy * 2.0 / (cx + cy));
gl.uniform1f(gllen, len);
gl.uniform3f(glorigin, len * Math.cos(ang1) * Math.cos(ang2) + cenx, len * Math.sin(ang2) + ceny, len * Math.sin(ang1) * Math.cos(ang2) + cenz);
gl.uniform3f(glright, Math.sin(ang1), 0, -Math.cos(ang1));
gl.uniform3f(glup, -Math.sin(ang2) * Math.cos(ang1), Math.cos(ang2), -Math.sin(ang2) * Math.sin(ang1));
gl.uniform3f(glforward, -Math.cos(ang1) * Math.cos(ang2), -Math.sin(ang2), -Math.sin(ang1) * Math.cos(ang2));
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.finish();
}
window.onresize = function () {
cx = document.body.clientWidth;
cy = document.body.clientHeight;
if (cx > cy) {
cx = cy;
} else {
cy = cx;
}
document.getElementById("main").style.width = 1024 + "px";
document.getElementById("main").style.height = 1024 + "px";
document.getElementById("main").style.transform = "scale(" + cx / 1024 + "," + cy / 1024 + ")";
}
window.onload = function () {
cx = document.body.clientWidth;
cy = document.body.clientHeight;
if (cx > cy) {
cx = cy;
} else {
cy = cx;
}
document.getElementById("main").style.width = 1024 + "px";
document.getElementById("main").style.height = 1024 + "px";
document.getElementById("main").style.transform = "scale(" + cx / 1024 + "," + cy / 1024 + ")";
var positions = [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0.0];
var VSHADER_SOURCE =
"#version 100 \n" +
"precision highp float;\n" +
"attribute vec4 position;" +
"varying vec3 dir, localdir;" +
"uniform vec3 right, forward, up, origin;" +
"uniform float x,y;" +
"void main() {" +
" gl_Position = position; " +
" dir = forward + right * position.x*x + up * position.y*y;" +
" localdir.x = position.x*x;" +
" localdir.y = position.y*y;" +
" localdir.z = -1.0;" +
"} ";
var FSHADER_SOURCE =
"#version 100 \n" +
"#define PI 3.14159265358979324\n" +
"#define M_L 0.3819660113\n" +
"#define M_R 0.6180339887\n" +
"#define MAXR 8\n" +
"#define SOLVER 8\n" +
"precision highp float;\n" +
"float kernal(vec3 ver)\n;" +
"uniform vec3 right, forward, up, origin;\n" +
"varying vec3 dir, localdir;\n" +
"uniform float len;\n" +
"vec3 ver;\n" +
"int sign;" +
"float v, v1, v2;\n" +
"float r1, r2, r3, r4, m1, m2, m3, m4;\n" +
"vec3 n, reflect;\n" +
"const float step = 0.002;\n" +
"vec3 color;\n" +
"void main() {\n" +
" color.r=0.0;\n" +
" color.g=0.0;\n" +
" color.b=0.0;\n" +
" sign=0;" +
" v1 = kernal(origin + dir * (step*len));\n" +
" v2 = kernal(origin);\n" +
" for (int k = 2; k < 1002; k++) {\n" +
" ver = origin + dir * (step*len*float(k));\n" +
" v = kernal(ver);\n" +
" if (v > 0.0 && v1 < 0.0) {\n" +
" r1 = step * len*float(k - 1);\n" +
" r2 = step * len*float(k);\n" +
" m1 = kernal(origin + dir * r1);\n" +
" m2 = kernal(origin + dir * r2);\n" +
" for (int l = 0; l < SOLVER; l++) {\n" +
" r3 = r1 * 0.5 + r2 * 0.5;\n" +
" m3 = kernal(origin + dir * r3);\n" +
" if (m3 > 0.0) {\n" +
" r2 = r3;\n" +
" m2 = m3;\n" +
" }\n" +
" else {\n" +
" r1 = r3;\n" +
" m1 = m3;\n" +
" }\n" +
" }\n" +
" if (r3 < 2.0 * len) {\n" +
" sign=1;" +
" break;\n" +
" }\n" +
" }\n" +
" if (v < v1&&v1>v2&&v1 < 0.0 && (v1*2.0 > v || v1 * 2.0 > v2)) {\n" +
" r1 = step * len*float(k - 2);\n" +
" r2 = step * len*(float(k) - 2.0 + 2.0*M_L);\n" +
" r3 = step * len*(float(k) - 2.0 + 2.0*M_R);\n" +
" r4 = step * len*float(k);\n" +
" m2 = kernal(origin + dir * r2);\n" +
" m3 = kernal(origin + dir * r3);\n" +
" for (int l = 0; l < MAXR; l++) {\n" +
" if (m2 > m3) {\n" +
" r4 = r3;\n" +
" r3 = r2;\n" +
" r2 = r4 * M_L + r1 * M_R;\n" +
" m3 = m2;\n" +
" m2 = kernal(origin + dir * r2);\n" +
" }\n" +
" else {\n" +
" r1 = r2;\n" +
" r2 = r3;\n" +
" r3 = r4 * M_R + r1 * M_L;\n" +
" m2 = m3;\n" +
" m3 = kernal(origin + dir * r3);\n" +
" }\n" +
" }\n" +
" if (m2 > 0.0) {\n" +
" r1 = step * len*float(k - 2);\n" +
" r2 = r2;\n" +
" m1 = kernal(origin + dir * r1);\n" +
" m2 = kernal(origin + dir * r2);\n" +
" for (int l = 0; l < SOLVER; l++) {\n" +
" r3 = r1 * 0.5 + r2 * 0.5;\n" +
" m3 = kernal(origin + dir * r3);\n" +
" if (m3 > 0.0) {\n" +
" r2 = r3;\n" +
" m2 = m3;\n" +
" }\n" +
" else {\n" +
" r1 = r3;\n" +
" m1 = m3;\n" +
" }\n" +
" }\n" +
" if (r3 < 2.0 * len&&r3> step*len) {\n" +
" sign=1;" +
" break;\n" +
" }\n" +
" }\n" +
" else if (m3 > 0.0) {\n" +
" r1 = step * len*float(k - 2);\n" +
" r2 = r3;\n" +
" m1 = kernal(origin + dir * r1);\n" +
" m2 = kernal(origin + dir * r2);\n" +
" for (int l = 0; l < SOLVER; l++) {\n" +
" r3 = r1 * 0.5 + r2 * 0.5;\n" +
" m3 = kernal(origin + dir * r3);\n" +
" if (m3 > 0.0) {\n" +
" r2 = r3;\n" +
" m2 = m3;\n" +
" }\n" +
" else {\n" +
" r1 = r3;\n" +
" m1 = m3;\n" +
" }\n" +
" }\n" +
" if (r3 < 2.0 * len&&r3> step*len) {\n" +
" sign=1;" +
" break;\n" +
" }\n" +
" }\n" +
" }\n" +
" v2 = v1;\n" +
" v1 = v;\n" +
" }\n" +
" if (sign==1) {\n" +
" ver = origin + dir*r3 ;\n" +
" r1=ver.x*ver.x+ver.y*ver.y+ver.z*ver.z;" +
" n.x = kernal(ver - right * (r3*0.00025)) - kernal(ver + right * (r3*0.00025));\n" +
" n.y = kernal(ver - up * (r3*0.00025)) - kernal(ver + up * (r3*0.00025));\n" +
" n.z = kernal(ver + forward * (r3*0.00025)) - kernal(ver - forward * (r3*0.00025));\n" +
" r3 = n.x*n.x+n.y*n.y+n.z*n.z;\n" +
" n = n * (1.0 / sqrt(r3));\n" +
" ver = localdir;\n" +
" r3 = ver.x*ver.x+ver.y*ver.y+ver.z*ver.z;\n" +
" ver = ver * (1.0 / sqrt(r3));\n" +
" reflect = n * (-2.0*dot(ver, n)) + ver;\n" +
" r3 = reflect.x*0.276+reflect.y*0.920+reflect.z*0.276;\n" +
" r4 = n.x*0.276+n.y*0.920+n.z*0.276;\n" +
" r3 = max(0.0,r3);\n" +
" r3 = r3 * r3*r3*r3;\n" +
" r3 = r3 * 0.45 + r4 * 0.25 + 0.3;\n" +
" n.x = sin(r1*10.0)*0.5+0.5;\n" +
" n.y = sin(r1*10.0+2.05)*0.5+0.5;\n" +
" n.z = sin(r1*10.0-2.05)*0.5+0.5;\n" +
" color = n*r3;\n" +
" }\n" +
" gl_FragColor = vec4(color.x, color.y, color.z, 1.0);" +
"}";
canvas = document.getElementById('c1');
gl = canvas.getContext('webgl');
vertshader = gl.createShader(gl.VERTEX_SHADER);
fragshader = gl.createShader(gl.FRAGMENT_SHADER);
shaderProgram = gl.createProgram();
gl.shaderSource(vertshader, VSHADER_SOURCE);
gl.compileShader(vertshader);
var infov = gl.getShaderInfoLog(vertshader);
gl.shaderSource(fragshader, FSHADER_SOURCE + KERNEL);
gl.compileShader(fragshader);
var infof = gl.getShaderInfoLog(fragshader);
gl.attachShader(shaderProgram, vertshader);
gl.attachShader(shaderProgram, fragshader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
var info = gl.getProgramInfoLog(shaderProgram);
throw 'Could not compile WebGL program. \n\n' + infov + infof + info;
}
glposition = gl.getAttribLocation(shaderProgram, 'position');
glright = gl.getUniformLocation(shaderProgram, 'right');
glforward = gl.getUniformLocation(shaderProgram, 'forward');
glup = gl.getUniformLocation(shaderProgram, 'up');
glorigin = gl.getUniformLocation(shaderProgram, 'origin');
glx = gl.getUniformLocation(shaderProgram, 'x');
gly = gl.getUniformLocation(shaderProgram, 'y');
gllen = gl.getUniformLocation(shaderProgram, 'len');
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.vertexAttribPointer(glposition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(glposition);
gl.viewport(0, 0, 1024, 1024);
draw();
window.requestAnimationFrame(ontimer);
document.getElementById("kernel").value = KERNEL;
document.getElementById("btn").addEventListener("click", function () {
var state = this.innerText == "CONFIG";
this.innerText = state ? "HIDE" : "CONFIG";
document.getElementById("config").style.display = state ? "inline" : "none";
});
document.getElementById("apply").addEventListener("click", function () {
KERNEL = document.getElementById("kernel").value;
gl.shaderSource(fragshader, FSHADER_SOURCE + KERNEL);
gl.compileShader(fragshader);
var infof = gl.getShaderInfoLog(fragshader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
var info = gl.getProgramInfoLog(shaderProgram);
alert(infof + info);
}
glposition = gl.getAttribLocation(shaderProgram, 'position');
glright = gl.getUniformLocation(shaderProgram, 'right');
glforward = gl.getUniformLocation(shaderProgram, 'forward');
glup = gl.getUniformLocation(shaderProgram, 'up');
glorigin = gl.getUniformLocation(shaderProgram, 'origin');
glx = gl.getUniformLocation(shaderProgram, 'x');
gly = gl.getUniformLocation(shaderProgram, 'y');
gllen = gl.getUniformLocation(shaderProgram, 'len');
});
document.getElementById("cancle").addEventListener("click", function () {
document.getElementById("kernel").value = KERNEL;
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment