Possible to render procedural texture to another texture?

Wondering if it is possible to render a procedural texture to an intermediate image texture rather than straight to screen? When I using DrawTexture to draw a procedural texture to another texture it seems to copy the procedure but not render. In case helpful, a specific e.g. is in the following toy code--if it actually drew the final image when drawing the procedural texture to an intermediate texture I would expect the result of the two passes to be the same (but they aren't). Thanks!


p.s. unrelated but a little bug report: CreateProceduralGabor throws an unexpected error if you pass non-integer dimension values to it when using the Oculus Rift (not when using a standard screen).


clear all

clc

 

try

    w = PsychImaging('OpenWindow', 0, [0 0 0]);

    Screen('ColorRange', w, 1.0, [], 1);

    

    o = Screen('OpenOffscreenWindow', w, [0 0 0 0]);

 

   %[gaborid, gaborrect] = CreateProceduralGabor(windowPtr, width, height [, nonSymmetric=0][, backgroundColorOffset =(0,0,0,0)][, disableNorm=0][, contrastPreMultiplicator=1][, validModulationRange=[-2,2]])

    g = CreateProceduralGabor(w, 400, 400, [], [0.5 0.5 0.5 0], 1, 0.5);

 

    

    %DRAW TO INTERMEDIATE TEXTURE WITH NO BLENDING, THEN DRAW THAT TEXTURE TO SCREEN WITH BLENDING

    %---

   %Screen('DrawTexture', windowPointer, texturePointer [,sourceRect] [,destinationRect] [,rotationAngle] [, filterMode] [, globalAlpha] [, modulateColor] [, textureShader] [, specialFlags], [phase, freq, sc, contrast, aspectratio, 0, 0, 0]);

    Screen('BlendFunction', o, 'GL_ONE', 'GL_ZERO');

    Screen('BlendFunction', w, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');

    Screen('DrawTexture', o, g, [], [], 45, [], [], [], [], kPsychDontDoRotation, [0 0.023 100 1 1 0 0 0])

    Screen('DrawTexture', w, o)

 

    Screen('Flip', w);

        

    WaitSecs(5)

    %---

    

    

    %DRAW STRAIGHT TO SCREEN WITH NO BLENDING

    %---    

    Screen('BlendFunction', w, 'GL_ONE', 'GL_ZERO');

    Screen('DrawTexture', w, g, [], [], 45, [], [], [], [], kPsychDontDoRotation, [0 0.023 100 1 1 0 0 0])

 

    Screen('Flip', w);

        

    WaitSecs(5)

    %---

 

    

    sca    

catch X

    sca

    rethrow(X)

end



Sorry, just getting back to this now.

Oh that makes sense. I didn't realize the gabor pattern was also in the alpha channel--I had assumed the alpha channel had a uniform 1 in it so that the gabor patch was simply drawn to the offscreen texture like a regular RGB picture would be. That explains a lot of confusion I've been having.

If I wanted to draw the gabor as a regular RGB picture with a uniform 1 in the alpha channel, but to an otherwise fully transparent texture, would the simplest way be something like the following?

ow = Screen('OpenOffscreenWindow', <onscreen window ptr>, [0 0 0 0])
g = CreateProceduralGabor(...)
Screen('BlendFunction', ow, [], [], [1 1 1 0]);
Screen('DrawTexture', ow, g, ...)
Screen('BlendFunction', ow, [], [], [0 0 0 1]);
Screen('FillRect', ow, [0 0 0 1], <same rect on "ow" as gabor was drawn to>)

Or is there a more direct way?

As for the "bug", sorry, I didn't describe it accurately in my first message. It may not be a bug and it's not a huge deal. The SetOpenGLTexture line in CreateProceduralGabor will not tolerate non-integer gabor width/height input to CreateProceduralGabor (for any screen, not just for Oculus--forget I mentioned Oculus). At least at a glance this seems out of keeping with the general behaviour of other PTB drawing functions of accepting non-integer px positions or dimensions at their inputs. So I thought it might be a "bug", kind of. Maybe there's a reason behind it, though.
XX---In PSYCHTOOLBOX@yahoogroups.com, <hollandgh@...> wrote :

Sorry, just getting back to this now.

Oh that makes sense. I didn't realize the gabor pattern was also in the alpha channel--I had assumed the alpha channel had a uniform 1 in it so that the gabor patch was simply drawn to the offscreen texture like a regular RGB picture would be. That explains a lot of confusion I've been having.


If I wanted to draw the gabor as a regular RGB picture with a uniform 1 in the alpha channel, but to an otherwise fully transparent texture, would the simplest way be something like the following?

ow = Screen('OpenOffscreenWindow', <onscreen window ptr>, [0 0 0 0])
g = CreateProceduralGabor(...)
Screen('BlendFunction', ow, [], [], [1 1 1 0]);
Screen('DrawTexture', ow, g, ...)
Screen('BlendFunction', ow, [], [], [0 0 0 1]);
Screen('FillRect', ow, [0 0 0 1], <same rect on "ow" as gabor was drawn to>)

Or is there a more direct way?

-> You can set the 'backgroundColorOffset' in CreateProceduralGabor to [0,0,0,1] to always add a constant alpha value of 1 to whatever the Gabor functions provides, and then in 'DrawTexture' set 'globalAlpha' to 0, or the 'modulateColor' to [1,1,1,0] to multiply all alpha values from the Gabor function with zero, so Alphaout(x,y) = 1 + Gaboralpha(x,y) * 0 = 1.

Not sure why you need an offscreen window though? Any specific experimental reasons for that indirection? Drawing procedural gabors is very fast, and going through that indirection of drawing them to an offscreen window, then that to the onscreen window would probably diminish much of the speed/flexibility advantage of using them in the first place?

As for the "bug", sorry, I didn't describe it accurately in my first message. It may not be a bug and it's not a huge deal. The SetOpenGLTexture line in CreateProceduralGabor will not tolerate non-integer gabor width/height input to CreateProceduralGabor (for any screen, not just for Oculus--forget I mentioned Oculus). At least at a glance this seems out of keeping with the general behaviour of other PTB drawing functions of accepting non-integer px positions or dimensions at their inputs. So I thought it might be a "bug", kind of. Maybe there's a reason behind it, though.

-> That width and height is the size of the area of input pixel locations / input (x,y) locations across which the Gabor function is evaluated and then drawn. The same size as a regular texture would be if you stored an image of a Gabor in it. The difference is just that a regular texture statically stores one color value per texel, whereas the color values for the texels of procedural textures are computed on the fly given all input parameters. You can't specify fractional sizes of textures, regardless if fixed or procedural.

-mario

Oh, I had not noticed it's not possible to specify fractional sizes for regular textures either (e.g. using Screen MakeTexture). I had assumed it was just because it's possible to input fractional px values for many drawing functions (e.g. source and target rects input to DrawTexture) and PTB takes care of rounding automatically for them. I do find that a very useful feature since by the time px values get to these functions they've often been through some computation that leaves them non-integer and, at least ideally, I want to round only at the end. So without the auto-rounding feature in many PTB functions I'd end up putting round commands right at their inputs a lot of the time.

As for the gabor question, originally I was looking into drawing gabors to an intermediate texture because I wanted to do another transformation on them before the final draw. As it turns out I don't have to, so I can draw them directly now. Still good I asked, though, because now I understand that there's a gabor pattern in the alpha channel too, which had been causing me some trouble since I have alpha blending on for another draw operation.

Thanks!