Exploding Image

scalf's picture

I have been searching around and have not found a reliable way to make a picture explode into pieces.

I have tried the Image Texturing Properties Grid.qtz file that comes with QC but that is not very flexible.

Does anyone know of a way to have images/videos explode into pieces or particles?

Would it be better to start with a particle system or a sprite, or other?

Thanks

cybero's picture
Re: Exploding Image

What about exploding a textured 3d Grid using the Kineme 3D Explode patch? See Kineme 3D example compositions.

dust's picture
Re: Exploding Image

yeah k3d has a nice explode patch. the new example lets you blow explode just an area if you want. of course this is all possible all ready stock. see my kinect exploder.

http://kineme.net/forum/Discussion/DevelopingCompositions/kinectexplosion

i did this with the kinect but with the principles will work with any cam or picture.

step 1: write a cl kernel with an image input.

step 2: declare your thread id's

 int          tid_x = get_global_id(0),
           tid_y = get_global_id(1),
            indx = tid_y * get_global_size(0) + tid_x;

step 3: create variable to store the image as well as make grid to read in the image.

float4 storeImage;
 
int2 pos = (int2)(tid_x, tid_y);
 
sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
 
storeImage = read_imagef(Img, smp, pos);

step 4: create your mesh so you can map your image to it. notice the z component is set to zero for a flat image.

vertex = (float4)((float)tid_x/get_global_size(0)-0.5, 1.-(float)tid_y/get_global_size(1)-0.5, 0.0, 1.);

step 5: create some global inputs to simulate explosion. no constants just a simple float4. in your kernel declaration at the top make the simple inputs like float4 g, float4 v, float4 vt, float4 timeStep, float4 halfStep; g= gravity v = init velocities vt = terminal velocity or drag parameter. timeStep = ∆t or delta time. you can forget the half step as it is just (stepTime*stepTime). these should all give you 4d inputs to your kernel or xyzw components for each. this just makes things easier, you will see it makes for less code in the end. meaning you will not have to break up the problem into smaller components. you can just make some working variables and keep everything in 3d even though your just dealing with an image. this is so your explosion can explode in 3d.

__kernel void read_image(__rd image2d_t Img, __global float4 *mesh, __global float4 *colors, float4 g, float4 timeStep, float4 halfTime, float4 v, float4 vt, __global const float4 *vel)

step 6: set up your working variables to integrate. this is just a basic simulation but remember force is dependent on 4 things. position, velocity, acceleration, and time. to solve these types of simulations you need to use a euler or in this case a euler richardson. the euler richardson being more accurate as there is an extra mid step involved. so make your working variables with a working mid step. a = accel, p = pos, amid = accel at mid point, pmid = pos at mid point, vmid = vel at mid point.

float4 a, p,vmid,amid, pmid; 

step 7: assign your vertex grid from above to the position working variable.

p = vertex;

step 8: this is the part that will make or break your explosion. for each vertex you want a random velocity making things fly in all directions. to do this its best to create a simple java script that has a min and max value for your initial velocities stored into a structure that you then map to the simulation. here is js patch that will create your random velocities. make sure to set its count to your image pixel width times your images pixel height. i suggest working with a small image at first.

//java script not cl code
 
 
var _s = []
 
function normalize(p)
{
   var norm = Math.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
   return new Array(p[0]/norm, p[1]/norm, p[2]/norm);
}
 
function (__structure s) main (__index count, __number vMin[3], __number vMax[3])
{
   var result = new Object();
   for (var i=0; i<count; ++i) {
      var v = []
      v[0] = Math.random()*2-1
      v[1] = Math.random()*2-1
      v[2] = Math.random()*2-1
 
      v = normalize(v)
      var rx = Math.random()*(vMax[0]-vMin[0])+vMin[0];
      var ry = Math.random()*(vMax[1]-vMin[1])+vMin[1];
      var rz = Math.random()*(vMax[2]-vMin[2])+vMin[2];
      v = [v[0]*rx, v[1]*ry, v[2]*rz]
 
      v[3] = 1.
      _s[i] = v
   }
 
   result.s = _s
   return result;
}

step 9: assign the random velocities from the js patch to your. float4 variables in cl.

v = vel[indx];

step 10: finally run the euler richardson simulation and output your mesh and colors.

   p = vertex;
   v = vel[indx];
 
   a = -g*((float4)(1.f)-v/vt);
 
 
   vmid = v + a * timeStep * halfTime;
 
   pmid = p + v * timeStep * halfTime;
   amid = -g*((float4)(1.f)-vmid/vt);
 
 
   v += amid * timeStep;
   p += vmid * timeStep;
 
   mesh[indx] = p;
   colors[indx] = storeImage;

then just use a mesh creator to assign your color to your mesh. then fiddle with the point size. more than likely you will want to set the gravity to a negative y number so things fall down etc.. also to simulate the explosion you will need to feed in a ∆t or delta time. i suggest maybe setting up a multiplexor with 2 inputs one for 0 time and one for ∆t. that would be like input 1 = 0 and input 2 = .01. hook that up to the kernels ∆t input. now when you flip the multiplexers source index explosion will happen.

refer to the link above to see working kinect example. all thats left to do is take a background image shot this is so that when the particle explodes you will still have your background. more or less this is so if you can explode a video of your self. for that effect you need a frame without you in it. ;)

the whole kernel looks something like this. like i said above using your float4 inputs makes for shorter code.

//Dustin O'Connor Physics Explosion
 
__kernel void read_image(__rd image2d_t Img, __global float4 *mesh, __global float4 *colors, float4 g, float4 timeStep, float4 halfTime, float4 v, float4 vt, __global const float4 *vel)
{
    int       tid_x = get_global_id(0),
            tid_y = get_global_id(1),
            indx = tid_y * get_global_size(0) + tid_x;
 
 
       float4 storeImage;
       int2   pos = (int2)(tid_x, tid_y);
       sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
 
       storeImage = read_imagef(Img, smp, pos);
 
 
       vertex = (float4)((float)tid_x/get_global_size(0)-0.5, 1.-(float)tid_y/get_global_size(1)-0.5, 0.0, 1.);
 
      float4 a, p,vmid,amid, pmid; 
 
    p = vertex;
   v = vel[indx];
 
   a = -g*((float4)(1.f)-v/vt);
 
 
   vmid = v + a * timeStep * halfTime;
 
   pmid = p + v * timeStep * halfTime;
   amid = -g*((float4)(1.f)-vmid/vt);
 
 
   v += amid * timeStep;
   p += vmid * timeStep;
 
   mesh[indx] = p;
   colors[indx] = storeImage;
 
 
}

scalf's picture
Re: Exploding Image

That was quite in depth!

Thank you very much for the example