Page 1 of 1

Prism GLSL TOP

PostPosted: Tue Feb 28, 2012 7:54 pm
by keithlostracco
I was working in AfterEffects today and noticed an effect called Prism that is basically a radial blur that changes color for each iteration of the blur. So I thought of modifying the radial blur that comes with Touch to do the same thing. I am able to change the color but I'm having difficulty getting the colour cycle through all the different hues for each cycle. I'm wondering if someone might have some ideas on how to edit the code to make this happen. Below is an image of the Prism effect from After Effects. In the component posted is a couple of modified radial blur shaders where I'm trying to emulate the same thing. I think I might have to incorporate the the HSV adjust code in the bottom shader to do what I would like but I hoping there is an easier way.

Re: Prism GLSL TOP

PostPosted: Tue Feb 28, 2012 8:07 pm
by malcolm
Ya I think you'll need to convert from RGB to HSV and back to RGB to do a color shift easily. The HSV shaders in TD are all assembly, not GLSL, so the my source for those won't help you. There are lots of articles that tell you the algorithm to convert between them (HSV To RGB is easy, RGB to HSV takes a little more) which you can use to code up a GLSL solution. It's a pretty simple algorithm.

Re: Prism GLSL TOP

PostPosted: Tue Feb 28, 2012 8:27 pm
by keithlostracco
Thanks Malcolm, I thought that was the case. Actually I did find a GLSL HSV adjust shader that I'll incorporate into the prism shader.

thanks

Re: Prism GLSL TOP

PostPosted: Wed Feb 29, 2012 4:12 am
by keithlostracco
So I've been able to get some RGB to HSV and HSV to RGB code happening but still have a small problem. At first I found an HSL adjust shader and used that code. I could get the Hue to rotate but not a different Hue on each iteration.

Then I found some formula's online for RGB to HSV and HSV to RGB and wrote my own shader so I would understand it better and then incorporated my shader into the radial blur shader and again have the same problem. I'm trying to use the "i" variable inside a for loop to change the hue on each iteration but it just changes the hue for all the iterations. I put the whole RGB-HSV,HSV_RGB code inside of the for loop which I think is right but I just can't get the hue to change to a new value in each iteration. Here is the shader;

Code: Select all
uniform sampler2D sInput1;
uniform float Hue;
uniform float Sat;
uniform float Value;


uniform float BlurStart;
uniform float BlurWidth;
uniform vec2 Center;
uniform float nSamples;
uniform vec3 ColorOffset;

vec3 changeC = ColorOffset;

void main()
{
 
   vec4 finalColor;
   vec4 c = vec4(0.0);
   vec3 grey= vec3(0.0);
   vec4 color = vec4(0.0);
   float alpha = 0.0;

   for(int i=0; i<int(nSamples); i++)
   {

      float cMax, cMin;
       float D;
   
       float H, S, V;
       float vR, vG, vB;
      float dR,dG,dB;

      float scale = BlurStart + BlurWidth*(float(i)/(nSamples-1.0));
      c = texture2D(sInput1, gl_TexCoord[0].st*scale + Center);
     
      //convert to single color
      float luma = (c.r+c.g+c.b)/3;   
      grey = vec3(luma);
      if (luma > 0.10)
      {
         alpha = 1.0;
      }
      else
      {
         alpha = 0.0;
      }
         
      color += vec4(grey * changeC,alpha);

       vR = color.r;
       vG = color.g;
       vB = color.b;

      // convert to HSV

       cMax = max(vR,max(vG,vB));
       cMin = min(vR,min(vG,vB));
      D = cMax - cMin;

      V= cMax;

      if (D == 0.0)
      {
         H = 0.0;
         S = 0.0;
      }
      else
      {
         S = D/cMax;
   
         dR = (((cMax-vR)/6)+(D/2))/D;
         dG = (((cMax-vG)/6)+(D/2))/D;
         dB = (((cMax-vB)/6)+(D/2))/D;

         if (vR==cMax) H = dB-dG;
         else if (vG==cMax) H = (1/3)+dR-dB;
         else if (vB==cMax) H = (2/3)+dG-dR;
   
         if (H<0) H += 1;
         if (H>1) H -= 1;
      }

      H += Hue + (float(i)/(nSamples));
      S *= Sat;
      V *= Value;



      // convert to RGB
   
      float R,G,B;
      float vh,vi,vr,vg,vb,v1,v2,v3;

      if (S == 0)
      {
         R = V;
         B = V;
      }
      else
      {
         vh = H*6;
         if (vh==6) vh=0;
         vi = int(vh);
         v1 = V * (1-S);
         v2 = V * (1-S*(vh-vi));
         v3 = V * (1-S*(1-(vh-vi)));
   
         if     (vi == 0) { vr = V ; vg = v3; vb = v1;}
         else if (vi == 1) { vr = v2; vg = V ; vb = v1;}
         else if (vi == 2) { vr = v1; vg = V ; vb = v3;}
         else if (vi == 3) { vr = v1; vg = v2; vb = V ;}
         else if (vi == 4) { vr = v3; vg = v1; vb = V ;}
         else            { vr = V ; vg = v1; vb = v2;}

         R = vr;
         G = vg;
         B = vb;

         finalColor= vec4(R,G,B,1.0);   
   

      }
   }

finalColor /= nSamples;
gl_FragColor = finalColor;
   
}


I'm also getting two warnings both stating that the "H" and "finalColor" variables might be being used before they are being declared. I've tried declaring them earlier but nothing seems to work. Any suggestions?

Thanks
Keith

Re: Prism GLSL TOP

PostPosted: Tue Mar 06, 2012 12:30 am
by keithlostracco
I've come to the conclusion that with the way the original radial blur shader works it would be impossible to do a hue shift to each "layer" of the image. At first I didn't really understand how the shader worked but now I'm pretty sure of what's happening.
Code: Select all
for(int i=0; i<int(nSamples); i++)
{
   float scale = BlurStart + BlurWidth*(float(i)/(nSamples-1));
   color = texture2D(sInput1, gl_TexCoord[0].st*scale + Center);
   c += color;   
}
c /= (nSamples);
gl_FragColor = c;

For every pixel (fragment) it samples another pixel determined by the offset and scale and then repeats (with offset tex coord) the process for the number of samples specified. For each iteration it adds each sample's rgba to the previous samples and finally draws the summed (divided by the number of samples) color of all the pixels sampled. So basically there are no separate layers to apply any color shifts to. There are just single pixels with new colors. If you want to shift one pixel's color by a set amount you have to shift them all, unless you incorporate the texcoordinates of each of the pixels but that won't really relate the perceived "layers".

I think to do this I would need to do a color shift to the whole image (with the tex coord transform) and then write that layer to memory, then shift the next layer and add it to the previous layer(summed layers) in memory.

I don't really have any experience writing to texture memory are a there any suggestions? Is it possible with a shader to store a texture and recall it? Also please correct me if I'm wrong about any of the above.

thanks
Keith

Re: Prism GLSL TOP

PostPosted: Wed Mar 07, 2012 9:43 pm
by malcolm
You'll want to use multiple TOPs to create your layers than combine them. That's storing and recalling a texture essentially.

Re: Prism GLSL TOP

PostPosted: Thu Mar 08, 2012 1:15 am
by keithlostracco
Thanks Malcolm that is the conclusion I came to the other day.