加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
index.html 5.39 KB
一键复制 编辑 原始数据 按行查看 历史
cyl 提交于 2022-12-08 21:08 . 1.0.0
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="icon" type="image/svg+xml" href="/vite.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform float iTime;
uniform vec2 iResolution;
varying vec2 vUv;
const float END = 20.;
const float ep = 0.001;
mat2 rot(float a){
return mat2(cos(a), -sin(a), sin(a), cos(a));
}
float cube(vec3 p, float b, float r){
vec3 d = abs(p) - b;
return length(max(d,0.0)) - r + min(max(d.x,max(d.y,d.z)),0.0);
}
float sphere(vec3 p, float r){
return length(p) - r;
}
float plane( vec3 p, vec4 n )
{
return dot(p,n.xyz) + n.w;
}
float light(vec3 p){
vec3 move = 1.5*vec3(cos(iTime)*sin(iTime), sin(iTime)*sin(iTime), cos(iTime));
vec3 p_ = p - move; p_.xy *= rot(iTime * 3.); p_.zy *= rot(iTime * 2.);
return min(cube(p_, .17, 0.), sphere(p + move, .2));
}
float obj(vec3 p){
p.xy *= rot(iTime * .3);
float cube = cube(p, .5, .5);
vec3 shook = .4*vec3(sin(iTime*3.), cos(iTime*4.), sin(iTime*2.));
float sphere = sphere(p + shook, .4);
return max(cube, -sphere);
}
float mirror(vec3 p){
float ripples = 0.1*sin(3.*length(p.xz) - iTime*pow(abs(sin(iTime*0.1)*0.5), 4.));
//return plane(p, vec4(0.,1.,0., 1.1)) + ripples;
return cube(p + vec3(0., 3., 0.), 1.7, 0.3) + ripples;
}
float SDscene(vec3 p){
float obj = obj(p);
float mirror = mirror(p);
float light = light(p);
float d = min(min(obj, mirror), light);
return d;
}
vec3 SDnormal(vec3 p){
//Calculates the normal vector of SDscene
return normalize(vec3(
SDscene(vec3(p.x+ep,p.y,p.z))-SDscene(vec3(p.x-ep,p.y,p.z)),
SDscene(vec3(p.x,p.y+ep,p.z))-SDscene(vec3(p.x,p.y-ep,p.z)),
SDscene(vec3(p.x,p.y,p.z+ep))-SDscene(vec3(p.x,p.y,p.z-ep))
));
}
float depth(vec3 ro, vec3 rd, float sig, inout float min_l){
//Returns depth from ro given raydirection
int max=300;
vec3 p;
float dist=0., d;
for (int i=0; i<max; i++){
p = ro + dist*rd;
d = SDscene(p)*sig;
if (light(p) < min_l){ min_l = light(p);}
if (abs(d)<ep){
return dist;
}
dist += d;
if (dist > END){
return END;
}
}
}
void ray_mirror(inout vec3 ro, inout vec3 rd, inout float d, inout float min_l){
int Nmax = 15, count = 0;
while (count < Nmax){
ro -= rd*ep*5.;
rd = normalize(reflect(rd, SDnormal(ro)));
d = depth(ro, rd, 1., min_l);
ro += d*rd;
if (mirror(ro) > ep){break;}
count += 1;
}
}
void ray_obj(inout vec3 ro, inout vec3 rd, inout float Dglass, inout float d, inout float min_l){
int Nmax = 15, count = 0, count2 = 0;
vec3 p, rd_;
while (count < Nmax){
//Go into glass
ro += rd * ep*10.;
rd = normalize(refract(rd, SDnormal(ro), 0.6));
d = depth(ro, rd, -1., min_l);
ro += rd * d;
Dglass += d;
//internal refraction
rd_ = refract(rd, -SDnormal(ro), 1.5);
while (length(rd_) < 0.0001 && count2 < Nmax){
rd = normalize(reflect(rd, -SDnormal(ro)));
d = depth(ro, rd, -1., min_l);
ro += d*rd;
Dglass += d;
rd_ = refract(rd, -SDnormal(ro), 1.5);
count2 += 1;
}
if (length(rd_) > 0.0001){rd = normalize(rd_);}
ro += rd * ep*10.;
d = depth(ro, rd, 1., min_l);
ro += rd * d;
if (obj(ro) > ep){break;}
//if (mirror(ro) > ep){ break;}
count += 1;
}
}
void fresnel(vec3 ro, vec3 rd, inout float refl, inout float refr){
float b = ((1. - 1.5)/(1. + 1.5));
float r0 = b*b;
refl = r0 + (1. - r0)*pow((1. - abs(dot(SDnormal(ro), normalize(rd)))), 5.);
refr = 1.-refl;
//refl = .5; refr = .5;
}
void render(in vec2 uv, inout vec3 col){
//Camera
float ScreenSize = 4.;
float shake = 0.3*sin(.3*iTime);
float zoom = 2.5;
float k = 0.4;
float osc = sin(iTime*.3); //3.5 + 2.*osc*osc
vec3 ro = 6.*vec3(sin(k*iTime), shake, cos(k*iTime)) + vec3(0.,2.,0.);
vec3 lookat = vec3(0,0,0);
vec3 fw = normalize(lookat - ro);
vec3 r = normalize(cross(vec3(0,1.,0), fw));
vec3 up = normalize(cross(fw,r));
vec3 scrC = ro + (zoom)*fw;
vec3 scrP = scrC + (uv.x*r + uv.y*up) * ScreenSize;
vec3 rd = normalize(scrP - ro);
float Dglass, min_l = END;
float d = depth(ro, rd, 1., min_l);
ro += d*rd;
vec3 ro_, rd_;
float refl, refr;
int Nmax = 15, count;
while (count < Nmax){
//hits background
//hit light
if (light(ro) < ep){
col += vec3(1.);
break;
}
//hit obj
else if (obj(ro) < ep){
ray_obj(ro, rd, Dglass, d, min_l);
}
//hit mirror
else if (mirror(ro) < ep){
ray_mirror(ro, rd, d, min_l);
}
else{d = END;}
count += 1;
}
}
void main()
{
vec2 R = iResolution.xy;
vec2 uv = (vUv - .5*R)/R.x;
vec3 col;
render(uv, col);
gl_FragColor = vec4( col, 1.0 );
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
precision mediump float;
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script type="module" src="/src/main.js"></script>
</body>
</html>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化