Hi again.

It now works!!!
Let me see if I have this right though:

the RIOHandler function is forcing the DOD of the
output from makeStrip to the full size of the input
image.
Without this, the size of the image returned by
imageStrip would be limited by the size defined in the
Crop filter following it, resulting in the entire
image being squeezed into a 1-pixel line (which is
clearly going to screw things up).

The RIOHandler is not needed when the xy_pixellate
function is called because it's ROI should be the same
size as its output DOD, and it's not being followed my
a function that will result in a change to its
dimensions.

Just checking I understand what's going on. Please let
me know if I'm completely off-beam.


Thanks again for your very thorough explanation. Sorry
I'm a bit slow picking this stuff up. My experiments
with Quartz Composer are my first forays into the
wonderful world of realtime video effects, so I'm
picking stuff up as I go along. I'm really excited my
the possibilities, however.

I must admit though, I do often feel the Quartz
Composer documentation is a little.. sparse,
especially on the programmable patches (GLSL, Core
Image Filter and JavaScript). Not being a programmer
by training (but having some informal experience of
coding in a variety of languages), I don't always pick
up on the specialist terms used. However, some things
just don't seem to be documented at all.

Anyway, thanks once again,

alx






--- Kevin Quennesson <[EMAIL PROTECTED]> wrote:

> Dear Alex,
> 
> CoreImage compiles all kernels internally to one,
> and will try to be  
> the most efficient by processing the less pixels
> possible.
> If you crop your image at the end to (0., 0., 100.,
> 1.), why would  
> CoreImage upload your whole input image? It will
> actually only upload  
> the region (0., 0., 100., 1.) of that image, and you
> will get a  
> "wrong" result as you "makeStrip" kernel requires
> the whole input  
> image to generate a (0., 0., 100., 1.) image.
> 
> ROI are the way you tell a kernel that it needs a
> different region in  
> the input image (ROI) than the region which is
> processed at the output  
> (DOD).
> For consistent results you must define a ROI
> whenever for an output  
> pixel (x.y) you are fetching pixel in the input
> image different from  
> (x,y).
> 
> For your particular issue, a easy fix is to pass as
> the userInfo of  
> the ROI function your DOD and make the ROI function
> simply return that  
> DOD. This means that you need the following changes:
> 
> -------------
> //First, add at the beginning of script:
> 
> function myROIFunction (samplerIndex, dstRect, info)
> {
>       return info;
> }
> 
> makeStrip.ROIHandler = myROIFunction;
> 
> //Then, pass dodRect as userInfo for makeStrip call:
> 
> imageStrip = makeStrip.apply(dodRect, dodRect,
> imagePixellated,  
> CellWidth, CellHeight, CellNum, Cols);
> -------------
> 
> However this will not work for big images that
> requires tiling as  
> dodRect will be bigger than maximum texture size of
> the GPU.
> In that case the ROI function will be called
> multiple times to process  
> tiles of your dodRect, which will be given in the
> dstRect argument.
> In that case you must return the region of the input
> image needed to  
> process only the dstRect: you'll use the info =
> dodRect argument and  
> will return the appropriate subregion.
> 
> Marc, <rdar://5558266> is a different issue.
> 
> Kevin
> 
> On Dec 12, 2007, at 5:05 AM, Alex Drinkwater wrote:
> 
> >> // KERNEL
> >>
> >> // SUPPORTING FUNCTIONS
> >>
> >> // Used by makeStrip (returns coord of pixel to
> be
> >> sampled)
> >> vec2 sampleHere(vec2 xy, float cellWidth, float
> >> cellHeight, float cols)
> >> {
> >>    // Calculate Row and Column for current
> iteration
> >>    float rowNum = ceil(xy.x / cols);
> >>    float colNum = xy.x - ((rowNum - 1.0) * cols);
> >>    // Calculate position of pixel to copy
> >>    xy.x = colNum * cellWidth;
> >>    xy.y = rowNum * cellHeight;
> >>    
> >>    // Return coord for sampler
> >>    return xy;
> >> }
> >>
> >> // MAIN KERNEL FUNCTIONS (RETURN IMAGES)
> >>
> >> // Pixellates image with exact dimensions for
> pixel
> >> tiles' width and height
> >> kernel vec4 xy_pixellate(sampler Image, float
> >> CellWidth, float CellHeight)
> >> {
> >>    // Current pixel location
> >>    vec2 xy = destCoord();
> >>    // Left and right of tile
> >>    float x1 = floor(xy.x / CellWidth) * CellWidth;
> >>    float x2 = (ceil(xy.x / CellWidth)) * CellWidth;
> >>    // Top and bottom of tile
> >>    float y1 = (floor(xy.y / CellHeight) *
> CellHeight);
> >>    float y2 = (ceil(xy.y / CellHeight)) *
> CellHeight;
> >>    
> >>    // Average left and right pixels
> >>    vec4 avgX = (sample(Image,
> samplerTransform(Image,
> >> vec2(x1, y1)))+(sample(Image,
> >> samplerTransform(Image,
> >> vec2(x2, y1))))) / 2.0;
> >>    
> >>    // Average top and bottom pixels
> >>    vec4 avgY = (sample(Image,
> samplerTransform(Image,
> >> vec2(x1, y1)))+(sample(Image,
> >> samplerTransform(Image,
> >> vec2(x1, y2))))) / 2.0;
> >>    // Centre pixel
> >>    vec4 avgC = sample(Image,
> samplerTransform(Image,
> >> vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))));
> >>    // Average the averages + centre
> >>    vec4 outPix = (avgX+avgY+avgC) / 3.0;
> >>    
> >>    // Output
> >>    return outPix;
> >> }
> >>
> >> // Creates 1-pixel-high strip from input image
> >> kernel vec4 makeStrip(sampler Image, float
> >> CellWidth,
> >> float CellHeight, float CellNum, float Cols)
> >> {
> >>    // Current pixel position
> >>    vec2 xy = destCoord();
> >>    vec2 samplePos = (xy.x > CellNum) ?
> vec2(0.0,0.0) :
> >> (xy.y > 10.0) ? vec2(0.0,0.0) : sampleHere(xy,
> >> CellWidth, CellHeight, Cols);
> >>    
> >>    // Output
> >>    return sample(Image, samplerTransform(Image,
> >> vec2(samplePos)));
> >> }
> >>
> >>
> >> // JAVASCRIPT
> >>
> >> function __image main(__image Image, __number
> Rows,
> >> __number Cols)
> >> {
> >>    // CREATE CONTROL VALUES
> >>    
> >>    // Input image dimensions
> >>    var Width = Image.extent.width;
> >>    var Height = Image.extent.height;
> >>    // Dimensions of Pixellation cells
> >>    var CellWidth = Width / (Math.ceil(Rows));
> >>    var CellHeight = Height / (Math.ceil(Cols));
> >>    // Total number of cells
> >>    var CellNum = Rows * Cols;
> >>    // DOD rect
> >>    var dodRect = new Vec(0.0, 0.0, Width, Height);
> >>    
> >>    
> >>    // IMAGE OPERATIONS
> >>    
> >>    // Pixellate image
> >>    imagePixellated = xy_pixellate.apply(dodRect,
> null,
> >> Image, CellWidth, CellHeight);
> >>    // Create strip
> >>    imageStrip = makeStrip.apply(dodRect, null,
> >> imagePixellated, CellWidth, CellHeight, CellNum,
> >> Cols);
> >>    // Crop
> >>    imageCropped = Filter.Crop(imageStrip, new
> Vec(0.0,
> >> 0.0, CellNum, 1.0));
> >>    // Output
> >>    return imageCropped;
> >> }
> >>
> >>
> >>
> >> Anything obvious jump out as still being wrong?
> >>
> >> Cheers again for your advice,
> >>
> >> Alex
> >>
> >> --- Kevin Quennesson <[EMAIL PROTECTED]>
> wrote:
> 
=== message truncated ===



      __________________________________________________________
Sent from Yahoo! Mail - a smarter inbox http://uk.mail.yahoo.com

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to