topical media & game development

talk show tell print

graphic-flex-image-effects-12-source-funhouseMirror.pbk / pbk



  <languageVersion : 1.0;>
  
  kernel FunhouseMirror
  <   namespace : "com.bobs27";
      vendor : "Todd Yard";
      version : 1;
      description : "Distorts image like a warped funhouse mirror.";
  >
  {
      input image4 source;
      output pixel4 result;
  
      parameter int warpBeginX
      <
          minValue:       0;
          maxValue:       1024;
          defaultValue:   0;
          description:    "The start of the image warp on the x axis.";
      >;
  
      parameter int warpEndX
      <
          minValue:       0;
          maxValue:       1024;
          defaultValue:   512;
          description:    "The end of the image warp on the x axis.";
      >;
  
      parameter float warpRatioX
      <
          minValue:       0.0;
          maxValue:       1.0;
          defaultValue:   0.5;
          description:    "The percent of the curved warp distortion weighted towards the beginning on the x axis.";
      >;
  
      parameter float distortionX
      <
          minValue:       0.0;
          maxValue:       1.0;
          defaultValue:   0.5;
          description:    "The amount of distortion to apply on the x axis.";
      >;
  
      parameter int warpBeginY
      <
          minValue:       0;
          maxValue:       1024;
          defaultValue:   0;
          description:    "The start of the image warp on the y axis.";
      >;
  
      parameter int warpEndY
      <
          minValue:       0;
          maxValue:       1024;
          defaultValue:   512;
          description:    "The end of the image warp on the y axis.";
      >;
  
      parameter float warpRatioY
      <
          minValue:       0.0;
          maxValue:       1.0;
          defaultValue:   0.5;
          description:    "The percent of the curved warp distortion weighted towards the beginning on the y axis.";
      >;
  
      parameter float distortionY
      <
          minValue:       0.0;
          maxValue:       1.0;
          defaultValue:   0.5;
          description:    "The amount of distortion to apply on the y axis.";
      >;
  
      void
      evaluatePixel()
      {
          float2 coord = outCoord();
          int firstHalf;
  
          // only run this if we have distortion to apply on x axis
          if (distortionX > 0.0) {
              int x = int(coord.x);
              float tX;
              float fullWarpX = float(warpEndX - warpBeginX);
              // only run this if pixel is within full warp range
              if (x > warpBeginX && x < warpEndX) {
                  // find difference between pixel position and beginning of effect
                  tX = float(x - warpBeginX);
                  firstHalf = 0;
                  // this means we are in first half of effect
                  if (tX/fullWarpX <= warpRatioX) {
                      // we need to know the ration of just first half of effect
                      fullWarpX *= warpRatioX;
                      firstHalf = 1;
                  } else {
                      // we need to know the ration of second half of effect
                      fullWarpX = fullWarpX-(fullWarpX*warpRatioX);
                      // determine distance of pixel from end of effect
                      tX = float(warpEndX - x);
                  }
                  // taken from Robert Penner's easing equations
                  tX /= (fullWarpX/2.0);
                  if (tX < 1.0) {
                      tX = (fullWarpX/2.0)*tX*tX;
                  } else {
                      tX = -(fullWarpX/2.0)*((--tX)*(tX - 2.0) - 1.0);
                  }
                  // for first half of effect, add translation to beginning position of warp effect
                  if (firstHalf == 1) {
                      tX += float(warpBeginX);
                  // otherwise subtract it from end of effect
                  } else {
                      tX = float(warpEndX) - tX; 
                  }
                  // final pixel position is interpolated between original and transformed position based on distortion amount
                  coord.x = mix(coord.x, tX, distortionX);
              }
          }
          
          // only run this if we have distortion to apply on y axis
          if (distortionY > 0.0) {
              int y = int(coord.y);
              float tY;
              float fullWarpY = float(warpEndY - warpBeginY);
              // only run this if pixel is within full warp range
              if (y > warpBeginY && y < warpEndY) {
                  // find difference between pixel position and beginning of effect
                  tY = float(y - warpBeginY);
                  firstHalf = 0;
                  // this means we are in first half of effect
                  if (tY/fullWarpY <= warpRatioY) {
                      // we need to know the ration of just first half of effect
                      fullWarpY *= warpRatioY;
                      firstHalf = 1;
                  } else {
                      // we need to know the ration of second half of effect
                      fullWarpY = fullWarpY-(fullWarpY*warpRatioY);
                      // determine distance of pixel from end of effect
                      tY = float(warpEndY - y);
                  }
                  // taken from Robert Penner's easing equations
                  tY /= (fullWarpY/2.0);
                  if (tY < 1.0) {
                      tY = (fullWarpY/2.0)*tY*tY;
                  } else {
                      tY = -(fullWarpY/2.0)*((--tY)*(tY - 2.0) - 1.0);
                  }
                  // for first half of effect, add translation to beginning position of warp effect
                  if (firstHalf == 1) {
                      tY += float(warpBeginY);
                  // otherwise subtract it from end of effect
                  } else {
                      tY = float(warpEndY) - tY; 
                  }
                  // final pixel position is interpolated between original and transformed position based on distortion amount
                  coord.y = mix(coord.y, tY, distortionY);
              }
          }
          
          result = sampleNearest(source, coord);
      }
  }
  


(C) Æliens 18/6/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.