WebGL fbm-mesh
Flowing fbm-noise colour field in a fragment shader (OGL).
WebGL Mesh
How to use it
- Paste the HTML where the backgrounds & webgl should appear. Include the script tags at the top once per page.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- WebGL fbm-mesh · NedDev · eigen werk. -->
<!-- benodigd, één keer per pagina: -->
<script type="module">import * as OGL from "https://esm.sh/ogl@1.0.11"; window.OGL = OGL;</script>
<div class="jouw-container">
<div class="wmesh-root"><canvas class="wmesh-canvas"></canvas><div class="wmesh-copy"><h3>WebGL Mesh</h3></div></div>
</div>/* WebGL fbm-mesh · NedDev · eigen werk. */
.wmesh-root{position:absolute;inset:0;overflow:hidden;background:#05060c}
.wmesh-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.wmesh-copy{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}.wmesh-copy h3{color:#fff;font:800 clamp(2rem,6vw,4rem) 'Boldonse','Switzer',sans-serif;mix-blend-mode:overlay}// WebGL fbm-mesh · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var canvas=root.querySelector('.wmesh-canvas');var renderer,gl;try{renderer=new OGL.Renderer({canvas:canvas,dpr:Math.min(devicePixelRatio,1.5),alpha:false});gl=renderer.gl;}catch(e){return;}
var vertex='attribute vec2 uv;attribute vec2 position;varying vec2 vUv;void main(){vUv=uv;gl_Position=vec4(position,0.,1.);}';
var fragment='precision highp float;varying vec2 vUv;uniform float uTime;uniform vec2 uRes;float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}float noise(vec2 p){vec2 i=floor(p),f=fract(p);float a=hash(i),b=hash(i+vec2(1.,0.)),c=hash(i+vec2(0.,1.)),d=hash(i+vec2(1.,1.));vec2 u=f*f*(3.-2.*f);return mix(a,b,u.x)+(c-a)*u.y*(1.-u.x)+(d-b)*u.x*u.y;}float fbm(vec2 p){float v=0.,a=.5;for(int i=0;i<5;i++){v+=a*noise(p);p*=2.;a*=.5;}return v;}void main(){vec2 uv=vUv;uv.x*=uRes.x/uRes.y;float t=uTime*.08;float n=fbm(uv*2.5+vec2(t,t*.7));float m=fbm(uv*1.7-vec2(t*.6,t));vec3 c1=vec3(.96,.28,.06);vec3 c2=vec3(.1,.1,.14);vec3 c3=vec3(.55,.12,.02);vec3 col=mix(c1,c2,smoothstep(.2,.8,n));col=mix(col,c3,smoothstep(.3,.9,m));col+=.05*fbm(uv*8.+t);gl_FragColor=vec4(col,1.);}';
var program=new OGL.Program(gl,{vertex:vertex,fragment:fragment,uniforms:{uTime:{value:0},uRes:{value:[1,1]}}});var mesh=new OGL.Mesh(gl,{geometry:new OGL.Triangle(gl),program:program});
function resize(){var w=root.clientWidth,h=root.clientHeight;renderer.setSize(w,h);program.uniforms.uRes.value=[gl.canvas.width,gl.canvas.height];}new ResizeObserver(resize).observe(root);resize();
var raf,vis=true;var io=new IntersectionObserver(function(es){es.forEach(function(en){vis=en.isIntersecting;});},{threshold:.05});io.observe(canvas);
(function loop(t){raf=requestAnimationFrame(loop);if(!vis)return;program.uniforms.uTime.value=t*.001;renderer.render({scene:mesh});})(0);
}
init(document.querySelector('.jouw-container'));
More backgrounds & webgl
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →