This post is actually reporting on something that happened a while ago (in fact, over a year ago, around the time when I unsuccessfully tried to restart my blog), but I think is still worth bringing it up now, as my blog is finally up and running again :-) So back then, Jason Fletcher, Science Visualizer & Live Presenter at the Charles Hayden Planetarium at the Boston Museum of Science and author of The Full Dome Blog, gave myself and a few other lucky fellows a tour of the planetarium and allowed us to play with his real-time setup to project on the dome with a single computer running Blendy Dome VJ.
A really cool thing about his setup is that is was really simply to hook up to. In essence, all one needs is a software that applies a fish eye projection on the visuals to project onto the dome, and then outputs it through Syphon.
For example, in Processing this was quite easy to accomplish using the Syphon library and a fish eye shader. The outcome of our experiments can be appreciated in the picture below:
In terms of the Processing code, the important elements to have are the Syphon server to send the frames over to Blendy Dome, and a offscreen PGraphics surface to render the scene to, so it can be then transformed with the fish eye shader:
importcodeanticode.syphon.*;SyphonServerserver;PShaderfisheye;PGraphicscanvas;voidsettings(){size(1920,1920,P3D);PJOGL.profile=1;}voidsetup(){server=newSyphonServer(this,"Processing Syphon");canvas=createGraphics(width,height,P3D);fisheye=loadShader("FishEye.glsl");fisheye.set("aperture",180.0);}voiddraw(){// Draw the scene into the PGraphicscanvas.beginDraw();canvas.background(0);canvas.stroke(255,0,0);canvas.strokeWeight(2);for(inti=-width;i<2*width;i+=50){canvas.line(i,-height,-100,i,2*height,-100);}for(inti=-height;i<2*height;i+=50){canvas.line(-width,i,-100,2*width,i,-100);}canvas.lights();canvas.noStroke();canvas.translate(mouseX,mouseY,200);canvas.rotateX(frameCount*0.01);canvas.rotateY(frameCount*0.01);canvas.box(100);canvas.endDraw();// Apply fish eye transformation on offscreen canvasshader(fisheye);image(canvas,0,0,width,height);// Send over Syphonserver.sendScreen();}
The fish eye shader was inspired by the “Angular Fisheye à la Bourke” sketch from Jonathan Cremieux, as shown in the OpenProcessing website, and uses the inverse transform of the angular fisheye as explained in Paul Bourke’s website:
uniformsampler2Dtexture;uniformmat4texMatrix;varyingvec4vertColor;varyingvec4vertTexCoord;uniformfloataperture;constfloatPI=3.1415926535;voidmain(void){floatapertureHalf=0.5*aperture*(PI/180.0);// This factor ajusts the coordinates in the case that// the aperture angle is less than 180 degrees, in which// case the area displayed is not the entire half-sphere.floatmaxFactor=sin(apertureHalf);// The st factor takes into account the situation when non-pot// textures are not supported, so that the maximum texture// coordinate to cover the entire image might not be 1.vec2stFactor=vec2(1.0/abs(texMatrix[0][0]),1.0/abs(texMatrix[1][1]));vec2pos=(2.0*vertTexCoord.st*stFactor-1.0);floatl=length(pos);if(l>1.0){gl_FragColor=vec4(0,0,0,1);}else{floatx=maxFactor*pos.x;floaty=maxFactor*pos.y;floatn=length(vec2(x,y));floatz=sqrt(1.0-n*n);floatr=atan(n,z)/PI;floatphi=atan(y,x);floatu=r*cos(phi)+0.5;floatv=r*sin(phi)+0.5;gl_FragColor=texture2D(texture,vec2(u,v)/stFactor)*vertColor;}}