Skip to content

Instantly share code, notes, and snippets.

@mikkamikka
Created November 3, 2013 23:50
Show Gist options
  • Select an option

  • Save mikkamikka/7296136 to your computer and use it in GitHub Desktop.

Select an option

Save mikkamikka/7296136 to your computer and use it in GitHub Desktop.
A Pen by Mika Chernov.
<script id="effectShader" type="x-shader/x-fragment">
#ifdef GL_ES
precision highp float;
#endif
uniform vec2 resolution;
uniform float time;
uniform sampler2D tex0;
uniform vec2 mouse;
//uniform vec4 color;
//Function to draw a line, taken from the watch shader
float line(vec2 p, vec2 a, vec2 b, float thickness )
{
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
return 1.0 - smoothstep(thickness*0.2, thickness * 1.0, length(pa - ba * h));
}
void main(void)
{
vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;
float gt = floor(time * 60.0) * 0.05;
//Calculate the next two points
vec2 point1 = vec2(sin(gt * 0.19), cos(gt * 0.29));
vec2 point2 = vec2(cos(gt * 0.39), sin(gt * 0.45));
vec2 delta = vec2(1.5,1.5);
vec4 col = texture2D(tex0,uv);
float aspect = resolution.x/resolution.y;
float dx = 0.008;
float dy = dx * aspect;
vec4 v0 = texture2D( tex0, uv );
vec4 v1 = texture2D( tex0, uv + vec2( 0.0, dy ) );
vec4 v2 = texture2D( tex0, uv + vec2( dx, 0.0 ) );
vec4 v3 = texture2D( tex0, uv + vec2( 0.0, -dy ) );
vec4 v4 = texture2D( tex0, uv + vec2( -dx, 0.0 ) );
vec4 v5 = texture2D( tex0, uv + vec2( dx, dy ) );
vec4 v6 = texture2D( tex0, uv + vec2( -dx, -dy ) );
vec4 v7 = texture2D( tex0, uv + vec2( dx, -dy ) );
vec4 v8 = texture2D( tex0, uv + vec2( -dx, dy ) );
vec4 s = v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
if ( v0.x >= 0.0 ) {
//if ( s.x < 1.0 || s.x > 2.0 )
//col = vec4( 1.0, 0.0, 0.0, 1 );
//else
//col = vec4( 0.0, 1.0, 1.0, 1 );
}
//else {
// if ( s.x == 3.0 )
// col = vec4( 0.5, 0.5, 1.0, 1.0 ); }
col.x *= 0.0+0.5*sin(1.9*time);
col.y *= 0.0+0.5*cos(1.7*time);
col.z *= 0.0+0.5*sin(1.5*time);
col.w *= 0.0+0.5*sin(1.3*time);
col.xyz += line(uv, vec2(-0.0,-0.0) + col.xy * 4.0 , vec2(-0.0,-0.0) + col.zw * 4.0, 0.2);
//col.rgb += line(uv, point1, point2, 0.3);
//col.rgb -= line(uv, point2, point1, 0.05);
//gl_FragColor = clamp(color, 0.0, 1.0);
gl_FragColor = vec4(col.xyz, 1.0);
}
</script>

Light beamer

Sketch with procedural texture generation and drawing a graphical primitive using shader

A Pen by Mika Chernov on CodePen.

License.

"use strict";
var mouse = {
down: false,
button: 1,
x: 0, y: 0, px: 0, py: 0
};
// Define an Effect class for handling interaction with OpenGL and drawing to a quad.
function Effect(gl,xres,yres)
{
this.mGLContext = gl;
this.mQuadVBO = null;
this.mProgram = null;
this.mTexture = null;
var vertices = new Float32Array([ -1., -1., 1., -1., -1., 1., 1., -1., 1., 1., -1., 1.]);
this.mQuadVBO = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.mQuadVBO);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
}
// Compiles GLSL code and sends it to the GPU.
Effect.prototype.NewShader = function(shaderCode)
{
var gl = this.mGLContext;
var tmpProgram = gl.createProgram();
var vs = gl.createShader(gl.VERTEX_SHADER);
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vs, "attribute vec2 pos;void main(){gl_Position=vec4(pos.x,pos.y,0.0,1.0);}");
gl.shaderSource(fs, shaderCode);
gl.compileShader(vs);
gl.compileShader(fs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
{ var infoLog = gl.getShaderInfoLog(vs);
gl.deleteProgram( tmpProgram );
return "VS ERROR: " + infoLog;;
}
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
{ var infoLog = gl.getShaderInfoLog(fs);
gl.deleteProgram( tmpProgram );
return "FS ERROR: " + infoLog;
}
gl.attachShader(tmpProgram, vs);
gl.attachShader(tmpProgram, fs);
gl.deleteShader(vs);
gl.deleteShader(fs);
gl.linkProgram(tmpProgram);
if( this.mProgram != null )
gl.deleteProgram( this.mProgram );
this.mProgram = tmpProgram;
}
// Resize the effect window.
Effect.prototype.SetSize = function(xres,yres)
{
this.mXres = xres;
this.mYres = yres;
}
// This method creates the XOR texture and binds it to the GL context associated with the Effect.
Effect.prototype.BindTexture = function()
{
var textureCanvas = document.createElement('canvas');
textureCanvas.width = 256;
textureCanvas.height = 256;
var ctx = textureCanvas.getContext("2d");
var idata = ctx.getImageData(0, 0, 256, 256);
var i = 0;
for( var x = 0 ; x < 256 ; ++x ) {
for( var y = 0 ; y < 256 ; ++y ) {
idata.data[i++]=( Math.sin(x|y)*300 );
idata.data[i++]=( Math.cos(x|y)*300 );
idata.data[i++]=( Math.sin(x|y)*255 );
idata.data[i++]=( Math.sin(x|y)*255 );
}
}
//var myimage = new Image();
//myimage.onload = function() {
// ctx.drawImage(myimage, 0, 0);
// }
//myimage.src = 'http://i647.photobucket.com/albums/uu200/dasheekyplus/texture.png';
ctx.putImageData( idata, 0, 0 );
var gl = this.mGLContext;
var texture = gl.createTexture();
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureCanvas); // This is the important line!
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
this.mTexture = texture;
}
// Draws a single quad using the fragment shader we specified by calling NewShader.
Effect.prototype.Paint = function(time)
{
var gl = this.mGLContext;
gl.viewport( 0, 0, this.mXres, this.mYres );
gl.useProgram(this.mProgram);
var l1 = gl.getAttribLocation(this.mProgram, "pos");
var l2 = gl.getUniformLocation(this.mProgram, "time");
var l3 = gl.getUniformLocation(this.mProgram, "resolution");
var l4 = gl.getUniformLocation(this.mProgram, "color");
var l5 = gl.getUniformLocation(this.mProgram, "mouse");
var t0 = gl.getUniformLocation(this.mProgram, "tex0");
gl.bindBuffer(gl.ARRAY_BUFFER, this.mQuadVBO);
if( l2!=null ) gl.uniform1f(l2, time);
if( l3!=null ) gl.uniform2f(l3, this.mXres, this.mYres);
//var color = new Float32Array([0, 1, 0, 1]);
gl.uniform4f(l4, mouse.x/1000.0, mouse.y/1000, 1 - mouse.x/1000.0 , 1.0);
gl.uniform2f(l5, -1+mouse.x/100.0, 1-mouse.y/100.0);
gl.vertexAttribPointer(l1, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(l1);
if( t0!=null ) { gl.uniform1i(t0, 0 );
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.mTexture); }
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.disableVertexAttribArray(l1);
}
// Request animation frame browser-specific bindings and fallback.
if ( !window.requestAnimationFrame ) {
window.requestAnimationFrame = ( function() {
return window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function ( callback, element ) {
window.setTimeout( callback, 1000 / 100 );
};
} )();
}
// Create the canvas element, compile the shader code, and bind the texture to the context.
document.write("<canvas id='x'></canvas>");
var glCanvas = document.getElementById("x");
var glContext = glCanvas.getContext("experimental-webgl");
var effect = new Effect( glContext, glCanvas.width, glCanvas.height );
effect.NewShader( document.getElementById( 'effectShader' ).textContent );
effect.BindTexture();
// Specify a canvas scale and handle window resize.
var scaleDown = 1;
function onWindowResize() {
//glCanvas.width = window.innerWidth / scaleDown;
//glCanvas.height = window.innerHeight / scaleDown;
//glCanvas.style.width = window.innerWidth + 'px';
//glCanvas.style.height = window.innerHeight + 'px';
var width = 800, height = 800;
glCanvas.width = width / scaleDown;
glCanvas.height = height / scaleDown;
glCanvas.style.width = width + 'px';
glCanvas.style.height = height + 'px';
glContext.viewport( 0, 0, glCanvas.width, glCanvas.height );
effect.SetSize( glCanvas.width, glCanvas.height );
}
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
// Main loop.
var t0 = (new Date()).getTime();
function animate() {
effect.Paint( ((new Date()).getTime()-t0)/1000 );
requestAnimationFrame( animate );
}
animate();
window.onload = function() {
x.onmousedown = function(e) {
if (e.which == 1) {
} else if (e.which == 3) {
mouse.down = true; }
e.preventDefault(); };
x.onmouseup = function(e) {
if (e.which == 3) { mouse.down = false; }
e.preventDefault(); };
x.onmousemove = function(e) {
var rect = this.getBoundingClientRect();
mouse.x = e.clientX - rect.left;
mouse.y = e.clientY - rect.top;
};
};
html,body{ margin:0px; overflow:hidden; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment