Skip to content

Instantly share code, notes, and snippets.

@pexavc
Last active February 2, 2022 08:12
Show Gist options
  • Save pexavc/4ca60bd507907f04b23f976a73a3b261 to your computer and use it in GitHub Desktop.
Save pexavc/4ca60bd507907f04b23f976a73a3b261 to your computer and use it in GitHub Desktop.
Test webGL shaders from a single html file using GLSL Canvas. Enter the raw shader code into the text box and click submit. A super light-weight alternative to shader toy.
<!DOCTYPE html>
<html>
<head>
<meta property="og:image" content="https://gateway.ipfs.io/ipfs/QmQt9J74g3daLLG12nTH4VpUMst3Y51uCcSYCgkWbyppSA" /><meta name="description" content="Lightweight shader toy."><title>Marble Shader Toy</title>
<meta name="viewport" content="width=device-width">
<meta name="keywords" content="shader, generator">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<style>
@import url('https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400&display=swap');
@import url('https://fonts.googleapis.com/css?family=Playfair+Display:400,400i,700,700i,900,900i');
.container {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.containerData {
display: flex;
justify-content: center;
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
.codeContainer {
display: flex;
justify-content: center;
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: 2;
overflow: hidden;
}
#canvas2 {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.slideAnim {
animation-name: slide;
animation-duration: 2s;
animation-fill-mode: forwards;
/*New content */
-webkit-animation-fill-mode: forwards;
}
@keyframes slide {
from {
opacity: 1.0;
}
to {
opacity: 0.0;
}
}
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
<script type="text/javascript">
function compile() {
localStorage.clear();
let t = document.getElementById('shaderCode').value;
var name = localStorage.getItem("name");
if (name !== null) t = name;
let oCT = document.getElementById("canvas2");
oCT.parentNode.removeChild(oCT);
let cT = document.getElementById("canvasContainer");
cT.innerHTML = "<canvas id='canvas2' class='glslCanvas' data-fragment='"+t+"' width='631px' height='631px'></canvas>";
localStorage.setItem("name", t);
return true;
}
var index = 0;
function refreshScript (src) {
console.log(index);
var scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.src = src + '?' + index++;
document.getElementsByTagName('body')[0].prepend(scriptElement);
}
window.onload = function() {
var t = localStorage.getItem("name");
if (t !== null) {
let oCT = document.getElementById("canvas2");
oCT.parentNode.removeChild(oCT);
let cT = document.getElementById("canvasContainer");
cT.innerHTML = "<canvas id='canvas2' class='glslCanvas' data-fragment='"+t+"' width='631px' height='631px'></canvas>";
}
}
</script>
</head>
<body>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js">
</script>
<div class="containerToTHEContainerheh">
<div id="canvasContainer" class="containerData">
<canvas id="canvas2" class="glslCanvas" data-fragment="" width="631px" height="631px"></canvas>
</div>
<div class="codeContainer">
<form onsubmit="return compile()">
<textarea id="shaderCode" rows="5" cols="60" name="text" placeholder="Enter text"></textarea>
<br/>
<input type="submit" value="compile"/>
</form>
</div>
</div>
</body>
</html>
@pexavc
Copy link
Author

pexavc commented Feb 2, 2022

Example shader:

precision highp float;
uniform vec2 u_resolution;
uniform float u_time;
uniform vec2 u_position;
                
const float cloudscale = 2.1;
const float speed = .20;
const float clouddark = 0.5;
const float cloudlight = 0.9;
const float cloudcover = 0.7;
const float cloudalpha = 100.0;
const float skytint = 0.5;
const vec3 skycolour1 = vec3(0.9, 0.1, 10.6);
const vec3 skycolour2 = vec3(0.4, 1.1, 01.0);

const mat2 m = mat2( 1.9,  1.2, -1.2,  0.9 );

vec2 hash( vec2 p ) {
    p = vec2(dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)));
    return -1.0 + 2.0*fract(sin(p)*43758.5453123);
}

float noise( in vec2 p ) {
    const float K1 = 0.366025404; // (sqrt(3)-1)/2;
    const float K2 = 0.211324865; // (3-sqrt(3))/6;
    vec2 i = floor(p + (p.x+p.y)*K1);   
    vec2 a = p - i + (i.x+i.y)*K2;
    vec2 o = (a.x>a.y) ? vec2(1.0,0.0) : vec2(0.0,1.0); //vec2 of = 0.5 + 0.5*vec2(sign(a.x-a.y), sign(a.y-a.x));
    vec2 b = a - o + K2;
    vec2 c = a - 1.0 + 2.0*K2;
    vec3 h = max(0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
    vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
    return dot(n, vec3(70.0));  
}

float fbm(vec2 n) {
    float total = 0.0, amplitude = 0.5;
    for (int i = 0; i < 7; i++) {
        total -= noise(n) * amplitude;
        n = m * n;
        amplitude *= 0.5;
    }
    return total;
}

// -----------------------------------------------

void main() {
    vec2 p = gl_FragCoord.xy / u_resolution.xy;
    vec2 uv = p*vec2(u_resolution.x/u_resolution.y,1.0);    
    float time = u_time * speed;
    float q = fbm(uv * cloudscale * 0.5);
    
    //ridged noise shape
    float r = 0.0;
    uv *= cloudscale;
    uv -= q - time;
    float weight = 0.8;
    for (int i=0; i<8; i++){
        r += abs(weight*noise( uv ));
        uv = m*uv + time;
        weight *= 0.7;
    }
    
    //noise shape
    float f = 0.0;
    uv = p*vec2(u_resolution.x/u_resolution.y,1.0);
    uv *= cloudscale;
    uv -= q - time;
    weight = 0.9;
    for (int i=0; i<8; i++){
        f += weight*noise( uv );
        uv = m*uv + time;
        weight *= 0.6;
    }
    
    f *= r + f;
    
    //noise colour
    float c = 0.0;
    time = u_time * speed * 2.0;
    uv = p*vec2(u_resolution.x/u_resolution.y,1.0);
    uv *= cloudscale*2.0;
    uv -= q - time;
    weight = 0.4;
    for (int i=0; i<7; i++){
        c += weight*noise( uv );
        uv = m*uv + time;
        weight *= .6;
    }
    
    //noise ridge colour
    float c1 = 0.0;
    time = u_time * speed * 3.0;
    uv = p*vec2(u_resolution.x/u_resolution.y,1.0);
    uv *= cloudscale*3.0;
    uv -= q - time;
    weight = 0.1;
    for (int i=0; i<7; i++){
        c1 += abs(weight*noise( uv ));
        uv = m*uv + time;
        weight *= 0.2;
    }
    
    c += c1;
    
    vec3 skycolour = mix(skycolour2, skycolour1, (p.x + p.y) * .7);
    vec3 cloudcolour = vec3(9.10, 0.0, 0.0) * clamp((clouddark + cloudlight*c), 0.0, 0.0);
   
    f = cloudcover + cloudalpha*f*r;
    
    vec3 result = mix(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 0.0), clamp(f + c, 0.0, 1.0));
    
    gl_FragColor = vec4( result, 1.0 );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment