小小宇宙观测站edit icon

作者:
用户fkxIv10
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
md
README.md
现在支持上传本地图片了!
index.html
            
            <!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- 引入 css 文件 -->
  <link rel="stylesheet" href="./style.css">
  <!-- 引入 js 文件 -->
  <script src="./index.js"></script>
</head>

<body>
  <canvas id="canvas"></canvas>
  <textarea id="codeEditor" class="editor" spellcheck="false" autocorrect="off" autocapitalize="off" translate="no" oninput="render()"></textarea>
  <pre id="error"></pre>
  <div id="indicator"></div>
  <div id="controls">
    <div class="controls">
      <input id="btnToggleView" class="icon" type="checkbox" name="toggleView" onclick="toggleView()">
      <input id="btnToggleResolution" class="icon" type="checkbox" name="toggleResolution" onchange="toggleResolution()">
      <input id="btnReset" class="icon" type="checkbox" name="reset" onclick="reset()">
    </div>
  </div>
  <script type="x-shader/x-fragment">#version 300 es
/*********
* made by Matthias Hurrle (@atzedent)
*/
precision highp float;
out vec4 O;
uniform float time;
uniform vec2 resolution;
uniform vec2 touch;
uniform int pointerCount;
#define mouse (touch/R)
#define P pointerCount
#define FC gl_FragCoord.xy
#define R resolution
#define T time
#define N normalize
#define S smoothstep
#define SE(v,a) S(a+1./MN,a-1./MN,v)
#define TAU radians(360.)
#define MN min(R.x,R.y)
#define rot(a) mat2(cos((a)-vec4(0,11,33,0)))
#define hue(a) (.5+.5*sin(TAU*(a)+vec3(1,2,3)))
#define procd (T*.1)
#define scene int(floor(mod(procd, 11.)))
#define light sqrt(S(.0,.0125,sin(-1.57+6.28318*fract(procd))*.5+.5))
#define sc (P>0?-1:scene)
vec3 watermark() {
    vec3 col=vec3(0);
    float rel=R.x/R.y;
    vec2 z=FC/R;
    z.x*=rel;
    z.x-=rel;
    z+=vec2(.1,-.1);
    float j=.025, id=round(z.y/j);
    z.y-=clamp(round(z.y/j),-1.,1.)*j;
    float rect=step(max(abs(z.x),abs(z.y)),.01);
    return mix(col,sqrt(rect*hue(id/(TAU/2.))),.5);
}
float rnd(vec2 p) {
    p=fract(p*vec2(12.9898,78.233));
    p+=dot(p,p+34.56);
    return fract(p.x*p.y);
}
float rnd(vec3 p) {
    p=fract(p*vec3(12.9898,78.233,156.345));
    p+=dot(p,p+34.56);
    return fract(p.x*p.y*p.z);
}
float noise(vec2 p) {
    vec2 i=floor(p), u=S(i,i+1.,p), k=vec2(1,0);
    float
    a=rnd(i),
    b=rnd(i+k),
    c=rnd(i+k.yx),
    d=rnd(i+k.xx);
    return mix(mix(a,b,u.x),mix(c,d,u.x),u.y);
}
float fbm(vec2 p) {
    float f=.0;
    mat2 m=mat2(1.6,1.2,-1.2,1.6);
    f+=.5000*noise(p); p*=m;
    f+=.2500*noise(p); p*=m;
    f+=.1250*noise(p); p*=m;
    f+=.0625*noise(p);
    return f;
}
float noise3(vec3 p) {
    vec3 s=vec3(7,157,113), i=floor(p);
    vec4 h=dot(i,s)+vec4(0,s.yz,s.y+s.z);
    p-=i; 
    p=p*p*(3.-2.*p);
    h=mix(fract(sin(h)*43758.5453),fract(sin(h+s.x)*43758.5453),p.x);
    h.xy=mix(h.xz,h.yw,p.y);
    return mix(h.x,h.y,p.z); 
}
float fbm (vec3 p) {
    float t=.0, a = 1., h = .0;
    for (int i=0; i++<8;) {
        t+=a*noise3(p);
        p*=2.;
        h+=a;
        a/=2.;
    }
    return t/h;
}
vec3 blackbody(float a) {
    vec3 col=clamp(vec3(
        56100000.*pow(a,-1.5)+148.,
        a>6500. ? 35200000.*pow(a,-1.5)+184. : 100.04*log(a)-623.6,
        194.18*log(a)-1448.6
    ),0.,255.)/255.;
    if (a<1000.) col*=a/1000.;
    return col;
}
vec3 star(vec2 uv, float a) {
    return blackbody(a*(1.-length(uv)));
}
float ftor(vec3 p, vec3 s, float r) {
    vec2 c=vec2(length(p.xz)-s.x-s.z,p.y)+r;
    c=abs(c)-s.zy;
    return length(max(c,.0))+min(.0,max(c.x,c.y))-r;
}
vec2 pmod(vec2 p, float n) {
    float a=atan(p.x,p.y), b=TAU/n;
    return p*rot(round(a/b)*b);
}
float mat=.0;
float map(vec3 p, bool z) {
    p.z-=1.45;
    p.y-=.2;
    vec3 q=p;
    p.xz*=rot(p.y*TAU/14.-T*.4);
    p.x-=.5;
    p.xz*=.25;
    vec3 st=p; float k=.125, r=.05;
    st.y=mod(p.y+.5,1.)-.5;
    p.y=fract(p.y)-.5;
    q.y=abs(abs(q.y)-.2)-.2;
    float a=min(length(st+vec3(0,0,k))-r,length(p-vec3(0,0,k))-r),
    b=ftor(q,vec3(1.35,.1,.125),1e-3);
    mat=z?a<b?.0:1.:mat;
    return min(a,b);
}
float map(vec3 p) { return map(p,false); }
bool march(inout vec3 p, vec3 rd, out float dd) {
    for (int i; i++<400;) {
        float d=map(p,true);
        if (abs(d)<1e-3) return true;
        if (dd>40.) return false;
        p+=rd*d;
        dd+=d;
    }
}
vec3 norm(vec3 p) {
    float h=1e-3; vec2 k=vec2(-1,1);
    return N(
        k.xyy*map(p+k.xyy*h)+
        k.yxy*map(p+k.yxy*h)+
        k.yyx*map(p+k.yyx*h)+
        k.xxx*map(p+k.xxx*h)
    );
}
vec3 dir(vec2 uv, vec3 p, vec3 t, float z) {
    vec3 up=vec3(0,1,0),
    f=N(t-p),
    r=N(cross(up,f)),
    u=N(cross(f,r));
    return N(mat3(r,u,f)*vec3(uv,z));
}
void cam(inout vec3 p) {
    float yz=-mouse.y*6.3+3.14, xz=3.14-mouse.x*6.3;
    switch (sc) {
        case 0:
            yz=-.0;
            xz=-.78;
            break;
        case 1:
            yz=-.0;
            xz=-.0;
            break;
        case 2:
            yz=-.05;
            xz=cos(T*.2)*sin(T*.2);
            break;
        case 3:
            yz=-.0;
            xz=-2.4;
            break;
        case 4:
            yz=.05;
            xz=-2.4+.5*cos(TAU/4.+T*.05)*sin(T*.05);
            break;
        case 5:
            yz=.1;
            xz=.618;
            break;
        case 6:
            yz=-.3-.2*cos(T*.2);
            xz=-.4-.1*cos(T*.2);
            break;
        case 7:
            yz=.25;
            xz=.2-.2*cos(T*.2);
            break;
        case 8:
            yz=-.125;
            xz=.4;
            break;
        case 9:
            yz=.2*cos(T*.05);
            xz=3.8-.2*sin(T*.05);
            break;
        case 10:
            yz=-.3;
            xz=.1;
            break;
    }
    p.yz*=rot(yz);
    p.xz*=rot(xz);
}
vec3 sky(vec2 p) {
    p.x-=.17;
    p*=500.;
    vec2 id=floor(p), gv=fract(p)-.5;
    float n=rnd(id), d=length(gv), f=S(3e-2*n,1e-3*n,d*d);
    if (n<.95) return vec3(0);
    return hue(.1+TAU*rnd(id))*f+f*.6;
}
float shadow(vec3 p, vec3 lp) {
    float shd=1., maxd=length(lp-p);
    vec3 l=N(lp-p);
    for (float i=1e-3; i<maxd;) {
        float d=map(p+l*i);
        if (d<1e-3) {
            shd=.0;
            break;
        }
        shd=min(shd,128.*d/i);
        i+=d;
    }
    return shd;
}
float calcAO(vec3 p, vec3 n) {
    float occ=.0, sca=.5;
    for (float i=.0; i<5.; i++) {
        float
        h=.01+i*.09,
        d=map(p+h*n);
        occ+=(h-d)*sca;
        sca*=.7;
        if (occ>.35) break;
    }
    return clamp(1.-3.*occ,.0,1.)*(.5+.5*n.y);
}
vec3 render(vec2 uv) {
    vec3 col=vec3(0),
    p=vec3(0),
    rd=dir(uv,p,vec3(0,0,1),sc==3||sc==9?.2:1.2);
    cam(p); cam(rd);
    float dd;
    if (march(p,rd,dd)) {
        vec3 n=norm(p), lp=vec3(0,1,5.), l=N(lp-p);
        float dif=clamp(dot(l,n),.0,1.), spe=pow(clamp(dot(reflect(rd,n),l),.0,1.),32.),
        fre=pow(clamp(1.+dot(rd,n),.0,1.),5.),
        ao=calcAO(p,rd), shd=shadow(p+n*5e-3,lp),
        pat=fbm(p*2.);
        col+=.08+.5*dif*shd*ao;
        col=mix(vec3(1,.9,.8)*spe*ao,col,fre);
        col+=mat<1.?spe:.0;
        col=mat>.0?mix(vec3(mix(-.05,.0,rnd(p))),col,pat):sqrt(col)*hue(-p.y*TAU);
    } else {
        vec2 sn=vec2(atan(rd.x,rd.z),atan(length(rd.xz),rd.y))/TAU;
        col=3.*sky(sn*2.)+2.*sky(sn*1.5)+.65*sky(sn*2.2);
        col+=.5*sky(sn*3.)+.65*sky(1.+sn*3.2);
        vec2 s1v=(sn-vec2(0,.2))*100., s2v=(sn-vec2(.1,.25))*200.;
        vec3 s1=star(s1v,4000.-3900.*fbm(sn*356.)), s2=star(s2v,800.);
        col=min(col,length(s1v)-1.);
        col=min(col,length(s2v)-1.);
        col=max(s1,col);
        col=max(s2,col);
        s1v*=1.-fbm(s1v*1.4);
        col+=.1*pow(3e-1/clamp(1e-3+dot(s1v,s1v),.0,1.),1.6)*vec3(1,.6,.5);
        float s2f=.6*fbm(s2v*2.1);
        s2v*=1.-s2f;
        vec3 s2c=mix(vec3(.2,.7,.75),mix(vec3(1.5,1.2,.1),vec3(.2,1.2,1),s2f),s2f);
        col+=.1*pow(2e-1/clamp(4e-2+dot(s2v,s2v),.0,1.),1.8)*s2c;
        vec2 g1=vec2(1.6,2)*5.*(sn-vec2(0,.28));
        g1*=rot(-.78)*(1.-fbm(g1*1.2));
        float g1x=exp(-abs(3.*g1.x)), g1y=exp(-abs(10.*g1.y));
        col=min(col,pow(42.*dot(g1,g1),4.));
        col=max(
            blackbody(mix(100.,2000.,g1x*g1y))*pow(g1y*g1x,1.2)*.5,
            col
        );
        col+=.1*sqrt(3e-3/clamp(1e-5+dot(g1,g1),.0,1.));
        vec2 g2=vec2(1,2)*5.*(sn-vec2(.38,.28));
        float g2f=fbm(g2*4.4);
        g2*=rot(-1.4)*2.*g2f;
        col=min(col,pow(42.*dot(g2,g2),4.));
        float g2x=exp(-abs(2.*g2.x)), g2y=exp(-abs(10.*g2.y));
        col=max(
            blackbody(mix(300.,1500.,g2x*g2y))*g2y*g2x,
            col
        );
        col+=.2*pow(3e-3/clamp(1e-3+dot(g2,g2),.0,1.),1.2);
        vec3 g2c=mix(vec3(.2,1.7,1.65),mix(vec3(1.5,1.2,.1),vec3(2.2,1.2,1),g2f),g2f*g2f);
        col+=.1*pow(12e-2/clamp(9e-2+dot(g2,g2),.0,1.),8.)*g2c;
    }
    col+=exp(dd*1e-4)*vec3(.5,.8,1)*.2;
    return col;
}
void main() {
    vec2 uv=(FC-.5*R)/MN;
    if (T>2. && P==0) {
        float f=(.5+.5*sin(.1*TAU*T-TAU/3.+.5*rnd(round((FC/MN)*4.))))*30.;
        uv/=tanh(f);
    }
    vec3 col=mix(vec3(0),render(uv),min(time*.3,1.)*(P>0?1.:light*light));
    col=tanh(col*col);
    col=sqrt(col);
    uv=FC/R*2.-1.;
    uv*=.9;
    uv*=uv*uv*uv;
    col=mix(col,vec3(0),dot(uv,uv));
    col=max(col,.08);
    col=max(col,watermark());
    O=vec4(col,dot(col,vec3(.21,.71,.07)));
}</script>
</body>

</html>
        
预览
控制台