3D Generative Ribbons

July 30th, 2012

I spent few hours to port a 3d Ribbons Processing example to Openframeworks, it turned out pretty great, especially combined with ofxFX.

Here is the source code, if somebody wants to play around!

Perlin Noise and GLSL

June 21st, 2012

After reading this post on Creative Applications and then going to Inigo Quilez’s website and reading his post about warping, I decided to have some fun with GLSL, Perlin Noise and Openframeworks. The results are just beautiful:

I am just posting a small code example I did, if somebody wants to take things further or just play around.

Openframeworks Draw Code:

    ofBackground(0, 0, 0);
    shader.begin();
    shader.setUniform1f("time", ofGetFrameNum() * 0.001);
    ofRect(0,0,1024,768);
    shader.end();

Vertex Shader:

uniform float time;

void main() {
     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment Shader:

uniform float time;

vec4 mod289(vec4 x)
{
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x)
{
    return mod289(((x*34.0)+1.0)*x);
}

vec4 taylorInvSqrt(vec4 r)
{
    return 1.79284291400159 - 0.85373472095314 * r;
}

vec2 fade(vec2 t) {
    return t*t*t*(t*(t*6.0-15.0)+10.0);
}

// Classic Perlin noise
float cnoise(vec2 P)
{
    vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
    vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
    Pi = mod289(Pi); // To avoid truncation effects in permutation
    vec4 ix = Pi.xzxz;
    vec4 iy = Pi.yyww;
    vec4 fx = Pf.xzxz;
    vec4 fy = Pf.yyww;
    
    vec4 i = permute(permute(ix) + iy);
    
    vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
    vec4 gy = abs(gx) - 0.5 ;
    vec4 tx = floor(gx + 0.5);
    gx = gx - tx;
    
    vec2 g00 = vec2(gx.x,gy.x);
    vec2 g10 = vec2(gx.y,gy.y);
    vec2 g01 = vec2(gx.z,gy.z);
    vec2 g11 = vec2(gx.w,gy.w);
    
    vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
    g00 *= norm.x;  
    g01 *= norm.y;  
    g10 *= norm.z;  
    g11 *= norm.w;  
    
    float n00 = dot(g00, vec2(fx.x, fy.x));
    float n10 = dot(g10, vec2(fx.y, fy.y));
    float n01 = dot(g01, vec2(fx.z, fy.z));
    float n11 = dot(g11, vec2(fx.w, fy.w));
    
    vec2 fade_xy = fade(Pf.xy);
    vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
    float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
    return 2.3 * n_xy;
}

// Classic Perlin noise, periodic variant
float pnoise(vec2 P, vec2 rep)
{
    vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
    vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
    Pi = mod(Pi, rep.xyxy); // To create noise with explicit period
    Pi = mod289(Pi);        // To avoid truncation effects in permutation
    vec4 ix = Pi.xzxz;
    vec4 iy = Pi.yyww;
    vec4 fx = Pf.xzxz;
    vec4 fy = Pf.yyww;
    
    vec4 i = permute(permute(ix) + iy);
    
    vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
    vec4 gy = abs(gx) - 0.5 ;
    vec4 tx = floor(gx + 0.5);
    gx = gx - tx;
    
    vec2 g00 = vec2(gx.x,gy.x);
    vec2 g10 = vec2(gx.y,gy.y);
    vec2 g01 = vec2(gx.z,gy.z);
    vec2 g11 = vec2(gx.w,gy.w);
    
    vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
    g00 *= norm.x;  
    g01 *= norm.y;  
    g10 *= norm.z;  
    g11 *= norm.w;  
    
    float n00 = dot(g00, vec2(fx.x, fy.x));
    float n10 = dot(g10, vec2(fx.y, fy.y));
    float n01 = dot(g01, vec2(fx.z, fy.z));
    float n11 = dot(g11, vec2(fx.w, fy.w));
    
    vec2 fade_xy = fade(Pf.xy);
    vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
    float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
    return 2.3 * n_xy;
}

float fbm(vec2 P, int octaves, float lacunarity, float gain)
{
	float sum = 0.0;
	float amp = 1.0;
    vec2 pp = P;
    
	int i;
	
	for(i = 0; i < octaves; i+=1)
	{
        amp *= gain; 
		sum += amp * cnoise(pp);
        pp *= lacunarity;
    }
	return sum;

}


float pattern(in vec2 p) {
    float l = 2.5;
    float g = 0.4;
    int oc = 10;
    
    vec2 q = vec2( fbm( p + vec2(0.0,0.0),oc,l,g),fbm( p + vec2(5.2,1.3),oc,l,g));
    vec2 r = vec2( fbm( p + 4.0*q + vec2(1.7,9.2),oc,l,g ), fbm( p + 4.0*q + vec2(8.3,2.8) ,oc,l,g));
    return fbm( p + 4.0*r ,oc,l,g);    
}

float pattern2( in vec2 p, out vec2 q, out vec2 r , in float time)
{
    float l = 2.3;
    float g = 0.4;
    int oc = 10; 
    
    q.x = fbm( p + vec2(time,time),oc,l,g);
    q.y = fbm( p + vec2(5.2*time,1.3*time) ,oc,l,g);
    
    r.x = fbm( p + 4.0*q + vec2(1.7,9.2),oc,l,g );
    r.y = fbm( p + 4.0*q + vec2(8.3,2.8) ,oc,l,g);
    
    return fbm( p + 4.0*r ,oc,l,g);
}

void main() {
    
    vec2 q = gl_FragCoord.xy / vec2(640.0,480.0);
    vec2 p = -1.0 + 2.0 * q;
    vec2 qq;
    vec2 r;
    float color = pattern2(p,qq,r,time);
    
    vec4 c = vec4(color,color,color,color);
    c *= 3.5;
    
    gl_FragColor = c;
}

FLORA – Interactive Installation

May 28th, 2012

Here is a short documentary of the installation we did for the Burgas Contemporary Festival 2012. The installation utilize Openframeworks for receiving and sending motion sensor data, Resolume for visualisation and MadMapper + Syphon for spreading and mapping the whole content over the building.

Color Couches

April 10th, 2012

Color Couches is just a proof of concept for a recent application I have been doing. It uses Node.js to bridge a connection between your mobile phone browser and an Openframeworks application.

The player is the white rectangle and it’s controlled from a simple interface made with JavaScript from a Mobile browser. The browsers sends data to a Node.js server through Socket.io, then the server sends Osc signals to an Openframeworks application, which handles the game logic and sends the visuals to MadMapper through Syphon. This easily can be played from like hundred devices at the same time.

3D Metaballs

December 9th, 2011

Since, I started to play around with Metaballs and Marching Cubes, I really wanted a very clean and simple example done in OpenFrameworks, so here I am sharing my own. This is just the very basics of implementing Marching Cubes, I am sure it could be optimized.

Edit (11/12/2011): Added calculation of the vertex normals, using interpolation between the gradient vectors for every vertex of the cubes. This way I could get really smooth images like this one:

Resources:

https://github.com/kamend/3D-Metaballs-with-Marching-Cubes
http://www.angelfire.com/linux/myp/MCAdvanced/MCImproved.html

Kinect Cloth in OpenFrameworks

December 2nd, 2011

After playing with Cloth Physics for a while, I decided to re-produce the Kinect+Cloth hack by Victor Martins (pixelnerve.com/v/) and here is the result:

The source code is a little bit messy, but you will get the point.

2D MetaBalls with OpenFrameworks

November 28th, 2011

I have been playing around with 2D Metaballs, so here is very short and dirty demo.

Source: here

And here is another example of drawing 2D Metaballs, but with using a prepared texture with a gradient ball with alpha. I could draw hundreds of balls inside a FBO and use the alpha channel as influence value, the glBlendFunc take care of all calculations. The results is something like this:

Source: here

Point Sprites in OpenFrameworks

November 16th, 2011

Since, I could not find any tutorial on using GL_POINT_SPRITES in OF007, I decided to write one. In short, you could use ofVboMesh with setMode(OF_PRIMITIVE_POINTS) to draw point sprites using a texture by your choice, but have in mind that the texture has to be power-of-two sized, so before loading your images you must call ofDisableArbTex();

Here is a short code demo:

#include "testApp.h"

const int numParticles = 300000;

//--------------------------------------------------------------
void testApp::setup(){
	
	// setup
	ofSetLogLevel(OF_LOG_VERBOSE);
    
    
    mesh.clear();
    mesh.setMode(OF_PRIMITIVE_POINTS);
    for(int i=0;i<numParticles;i++) {

	ofVec2f p = ofVec2f(ofRandom(0,ofGetWidth()),ofRandom(0,ofGetHeight()));
	mesh.addVertex(p);
	mesh.addColor(ofColor(ofRandom(0,255),ofRandom(0,255),ofRandom(0,255)));
	
	}
    
   
    ofDisableArbTex();
    texture.loadImage("sprite1.png");
    
    glPointSize(20);
	

}

//--------------------------------------------------------------
void testApp::update(){
    for(int i=0;i<numParticles;i++) {
        ofVec2f p = mesh.getVertex(i);
        
        p.x += ofRandomf() * 10;
        p.y += ofRandomf() * 10;
        
        mesh.setVertex(i, p);
    }
}

//--------------------------------------------------------------
void testApp::draw(){
    ofBackground(0, 0, 0);
    
    ofEnableAlphaBlending();
    ofEnablePointSprites();
    texture.getTextureReference().bind();
    mesh.drawFaces();

    ofDisablePointSprites();
}