Last active
February 2, 2022 08:12
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
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
Make sure to use these headers in your shader code. Simply put them at the top of your text input.
These are provided values. Frag colors and coords should also be changed (if needed) as so
gl_FragCoord
,gl_FragColor
.Always leave your main function empty like so
void main() {
.Enjoy!