
<!DOCTYPE html>
<html>
<head>
    <title>Shader Example</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>

    <script type="x-shader/x-fragment" id="fragmentShader">
      
        #define LOOK 1
        
        mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
        {
          vec3 cw = normalize(ta-ro);
          vec3 cp = vec3(sin(cr), cos(cr),0.0);
          vec3 cu = normalize( cross(cw,cp) );
          vec3 cv = normalize( cross(cu,cw) );
            return mat3( cu, cv, cw );
        }
        
        float noise( in vec3 x )
        {
            vec3 p = floor(x);
            vec3 f = fract(x);
          f = f*f*(3.0-2.0*f);
        
        #if NOISE_METHOD==0
            x = p + f;
            return textureLod(iChannel2,(x+0.5)/32.0,0.0).x*2.0-1.0;
        #endif
        #if NOISE_METHOD==1
          vec2 uv = (p.xy+vec2(37.0,239.0)*p.z) + f.xy;
            vec2 rg = textureLod(iChannel0,(uv+0.5)/256.0,0.0).yx;
          return mix( rg.x, rg.y, f.z )*2.0-1.0;
        #endif    
        #if NOISE_METHOD==2
            ivec3 q = ivec3(p);
          ivec2 uv = q.xy + ivec2(37,239)*q.z;
          vec2 rg = mix(mix(texelFetch(iChannel0,(uv           )&255,0),
                      texelFetch(iChannel0,(uv+ivec2(1,0))&255,0),f.x),
                  mix(texelFetch(iChannel0,(uv+ivec2(0,1))&255,0),
                      texelFetch(iChannel0,(uv+ivec2(1,1))&255,0),f.x),f.y).yx;
          return mix( rg.x, rg.y, f.z )*2.0-1.0;
        #endif    
        }
        
        #if LOOK==0
        float map( in vec3 p, int oct )
        {
          vec3 q = p - vec3(0.0,0.1,1.0)*iTime;
            float g = 0.5+0.5*noise( q*0.3 );
            
          float f;
            f  = 0.50000*noise( q ); q = q*2.02;
            #if USE_LOD==1
            if( oct>=2 ) 
            #endif
            f += 0.25000*noise( q ); q = q*2.23;
            #if USE_LOD==1
            if( oct>=3 )
            #endif
            f += 0.12500*noise( q ); q = q*2.41;
            #if USE_LOD==1
            if( oct>=4 )
            #endif
            f += 0.06250*noise( q ); q = q*2.62;
            #if USE_LOD==1
            if( oct>=5 )
            #endif
            f += 0.03125*noise( q ); 
            
            f = mix( f*0.1-0.75, f, g*g ) + 0.1;
            return 1.5*f - 0.5 - p.y;
        }
        
        const int kDiv = 1; // make bigger for higher quality
        const vec3 sundir = normalize( vec3(-1.0,0.0,-1.0) );
        
        vec4 raymarch( in vec3 ro, in vec3 rd, in vec3 bgcol, in ivec2 px )
        {
            // bounding planes	
            const float yb = -3.0;
            const float yt =  0.6;
            float tb = (yb-ro.y)/rd.y;
            float tt = (yt-ro.y)/rd.t;
        
            // find tigthest possible raymarching segment
            float tmin, tmax;
            if( ro.y>yt )
            {
                // above top plane
                if( tt<0.0 ) return vec4(0.0); // early exit
                tmin = tt;
                tmax = tb;
            }
            else
            {
                // inside clouds slabs
                tmin = 0.0;
                tmax = 60.0;
                if( tt>0.0 ) tmax = min( tmax, tt );
                if( tb>0.0 ) tmax = min( tmax, tb );
            }
            
            // dithered near distance
            float t = tmin + 0.1*texelFetch( iChannel1, px&1023, 0 ).x;
            
            // raymarch loop
          vec4 sum = vec4(0.0);
            for( int i=0; i<190*kDiv; i++ )
            {
               // step size
               float dt = max(0.05,0.02*t/float(kDiv));
        
               // lod
               #if USE_LOD==0
               const int oct = 5;
               #else
               int oct = 5 - int( log2(1.0+t*0.5) );
               #endif
               
               // sample cloud
               vec3 pos = ro + t*rd;
               float den = map( pos,oct );
               if( den>0.01 ) // if inside
               {
                   // do lighting
                   float dif = clamp((den - map(pos+0.3*sundir,oct))/0.3, 0.0, 1.0 );
                   vec3  lin = vec3(0.65,0.65,0.75)*1.1 + 0.8*vec3(1.0,0.6,0.3)*dif;
                   vec4  col = vec4( mix( vec3(1.0,0.95,0.8), vec3(0.25,0.3,0.35), den ), den );
                   col.xyz *= lin;
                   // fog
                   col.xyz = mix(col.xyz,bgcol, 1.0-exp2(-0.075*t));
                   // composite front to back
                   col.w    = min(col.w*8.0*dt,1.0);
                   col.rgb *= col.a;
                   sum += col*(1.0-sum.a);
               }
               // advance ray
               t += dt;
               // until far clip or full opacity
               if( t>tmax || sum.a>0.99 ) break;
            }
        
            return clamp( sum, 0.0, 1.0 );
        }
        
        vec4 render( in vec3 ro, in vec3 rd, in ivec2 px )
        {
          float sun = clamp( dot(sundir,rd), 0.0, 1.0 );
        
            // background sky
            vec3 col = vec3(0.76,0.75,0.86);
            col -= 0.6*vec3(0.90,0.75,0.95)*rd.y;
          col += 0.2*vec3(1.00,0.60,0.10)*pow( sun, 8.0 );
        
            // clouds    
            vec4 res = raymarch( ro, rd, col, px );
            col = col*(1.0-res.w) + res.xyz;
            
            // sun glare    
          col += 0.2*vec3(1.0,0.4,0.2)*pow( sun, 3.0 );
        
            // tonemap
            col = smoothstep(0.15,1.1,col);
         
            return vec4( col, 1.0 );
        }
        
        #else
        
        
        float map5( in vec3 p )
        {    
            vec3 q = p - vec3(0.0,0.1,1.0)*iTime;    
            float f;
            f  = 0.50000*noise( q ); q = q*2.02;    
            f += 0.25000*noise( q ); q = q*2.03;    
            f += 0.12500*noise( q ); q = q*2.01;    
            f += 0.06250*noise( q ); q = q*2.02;    
            f += 0.03125*noise( q );    
            return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
        }
        float map4( in vec3 p )
        {    
            vec3 q = p - vec3(0.0,0.1,1.0)*iTime;    
            float f;
            f  = 0.50000*noise( q ); q = q*2.02;    
            f += 0.25000*noise( q ); q = q*2.03;    
            f += 0.12500*noise( q ); q = q*2.01;   
            f += 0.06250*noise( q );    
            return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
        }
        float map3( in vec3 p )
        {
            vec3 q = p - vec3(0.0,0.1,1.0)*iTime;    
            float f;
            f  = 0.50000*noise( q ); q = q*2.02;    
            f += 0.25000*noise( q ); q = q*2.03;    f += 0.12500*noise( q );    
            return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
        }
        float map2( in vec3 p )
        {    
            vec3 q = p - vec3(0.0,0.1,1.0)*iTime;    
            float f;
            f  = 0.50000*noise( q ); 
            q = q*2.02;    f += 0.25000*noise( q );;    
            return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
        }
        
        const vec3 sundir = vec3(-0.7071,0.0,-0.7071);
        
        #define MARCH(STEPS,MAPLOD) for(int i=0; i<STEPS; i++) { vec3 pos = ro + t*rd; if( pos.y<-3.0 || pos.y>2.0 || sum.a>0.99 ) break; float den = MAPLOD( pos ); if( den>0.01 ) { float dif = clamp((den - MAPLOD(pos+0.3*sundir))/0.6, 0.0, 1.0 ); vec3  lin = vec3(1.0,0.6,0.3)*dif+vec3(0.91,0.98,1.05); vec4  col = vec4( mix( vec3(1.0,0.95,0.8), vec3(0.25,0.3,0.35), den ), den ); col.xyz *= lin; col.xyz = mix( col.xyz, bgcol, 1.0-exp(-0.003*t*t) ); col.w *= 0.4; col.rgb *= col.a; sum += col*(1.0-sum.a); } t += max(0.06,0.05*t); }
        
        vec4 raymarch( in vec3 ro, in vec3 rd, in vec3 bgcol, in ivec2 px )
        {    
            vec4 sum = vec4(0.0);    
            float t = 0.05*texelFetch( iChannel1, px&255, 0 ).x;    
            MARCH(40,map5);    
            MARCH(40,map4);    
            MARCH(30,map3);    
            MARCH(30,map2);    
            return clamp( sum, 0.0, 1.0 );
        }
        
        vec4 render( in vec3 ro, in vec3 rd, in ivec2 px )
        {
            // background sky         
            float sun = clamp( dot(sundir,rd), 0.0, 1.0 );    
            vec3 col = vec3(0.6,0.71,0.75) - rd.y*0.2*vec3(1.0,0.5,1.0) + 0.15*0.5;    
            col += 0.2*vec3(1.0,.6,0.1)*pow( sun, 8.0 );    
            // clouds        
            vec4 res = raymarch( ro, rd, col, px );    
            col = col*(1.0-res.w) + res.xyz;        
            // sun glare        
            col += vec3(0.2,0.08,0.04)*pow( sun, 3.0 );    
            return vec4( col, 1.0 );
        }
        
        #endif
        
        void mainImage( out vec4 fragColor, in vec2 fragCoord )
        {
            vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y;
            vec2 m =                iMouse.xy      /iResolution.xy;
        
            // camera
            vec3 ro = 4.0*normalize(vec3(sin(3.0*m.x), 0.8*m.y, cos(3.0*m.x))) - vec3(0.0,0.1,0.0);
          vec3 ta = vec3(0.0, -1.0, 0.0);
            mat3 ca = setCamera( ro, ta, 0.07*cos(0.25*iTime) );
            // ray
            vec3 rd = ca * normalize( vec3(p.xy,1.5));
            
            fragColor = render( ro, rd, ivec2(fragCoord-0.5) );
        }
        
    </script>

    <script>
        // Get the shader code from the script tag
        var fragmentShaderCode = document.getElementById("fragmentShader").textContent;

        // Initialize WebGL context
        var canvas = document.getElementById("canvas");
        var gl = canvas.getContext("webgl");
        if (!gl) {
            console.error("WebGL is not supported.");
            return;
        }

        // Create shader program
        var vertexShaderCode = `
            void main() {
                gl_Position = vec4(0, 0, 0, 1);
            }
        `;

        var vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertexShader, vertexShaderCode);
        gl.compileShader(vertexShader);

        var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader, fragmentShaderCode);
        gl.compileShader(fragmentShader);

        var program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        // Set up the vertex buffer
        var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
        gl.enableVertexAttribArray(positionAttributeLocation);
        gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

        // Set up the resolution uniform
        var resolutionUniformLocation = gl.getUniformLocation(program, "iResolution");
        gl.uniform2f(resolutionUniformLocation, canvas.width, canvas.height);

        // Set up other uniforms and variables here

        // Render loop
        function render() {
            gl.viewport(0, 0, canvas.width, canvas.height);
            gl.clearColor(0, 0, 0, 1);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

            // Call the render function again on the next frame
            requestAnimationFrame(render);
        }

        // Start the render loop
        render();
    </script>
</body>
</html>исправь ошибки