problems with superimposed gratings created by Alpha blending

Hi,

I'm using the alpha blending function in psychtoolbox to superimpose two gratings.
The gratings I'm using were created by "CreateProceduralSineGrating", backgroundColorOffset was set to [0.5,0.5,0.5,0], the blending function was Screen('BlendFunction', win, GL_SRC_ALPHA, GL_ONE). I choose this blending function because it's what they used in the "AdditiveBlendingForLinearSuperpositionTutorial" demo.
However, I'm confused about two things:
First, I cannot use a contrast higher than 0.5 for the component gratings. If the contrast exceeds 0.5, the color seems to get reversed and the superimposed gratings look weird.
Secondly, I think the visible contrast of the superimposed gratings is lower than that of its component gratings. So my question is, is there a way to find out what the exact contrast of the new stimulus is?

p.s. I also tried the Screen('BlendFunction', win, GL_ONE, GL_ONE) function as was mentioned in some earlier posts, however, the superimposed grating created was not what I expected.



Qing
Type:

Screen BlendFunction?

at the command line and press enter.

This gives details about blending.

There are also a number of other posts detailing how blend functions and gratings work. So you can search there also.




--- In psychtoolbox@yahoogroups.com, "yuqingpsy" wrote:
>
> Hi,
>
> I'm using the alpha blending function in psychtoolbox to superimpose two gratings.
> The gratings I'm using were created by "CreateProceduralSineGrating", backgroundColorOffset was set to [0.5,0.5,0.5,0], the blending function was Screen('BlendFunction', win, GL_SRC_ALPHA, GL_ONE). I choose this blending function because it's what they used in the "AdditiveBlendingForLinearSuperpositionTutorial" demo.
> However, I'm confused about two things:
> First, I cannot use a contrast higher than 0.5 for the component gratings. If the contrast exceeds 0.5, the color seems to get reversed and the superimposed gratings look weird.
> Secondly, I think the visible contrast of the superimposed gratings is lower than that of its component gratings. So my question is, is there a way to find out what the exact contrast of the new stimulus is?
>
> p.s. I also tried the Screen('BlendFunction', win, GL_ONE, GL_ONE) function as was mentioned in some earlier posts, however, the superimposed grating created was not what I expected.
>
>
>
> Qing
>
--- In psychtoolbox@yahoogroups.com, "yuqingpsy" wrote:
>
> Hi,
>
> I'm using the alpha blending function in psychtoolbox to superimpose two gratings.
> The gratings I'm using were created by "CreateProceduralSineGrating", backgroundColorOffset was set to [0.5,0.5,0.5,0], the blending function was Screen('BlendFunction', win, GL_SRC_ALPHA, GL_ONE). I choose this blending function because it's what they used in the "AdditiveBlendingForLinearSuperpositionTutorial" demo.
> However, I'm confused about two things:
> First, I cannot use a contrast higher than 0.5 for the component gratings. If the contrast exceeds 0.5, the color seems to get reversed and the superimposed gratings look weird.
> Secondly, I think the visible contrast of the superimposed gratings is lower than that of its component gratings. So my question is, is there a way to find out what the exact contrast of the new stimulus is?
>

Use Screen('BlendFunction', win, GL_ONE, GL_ONE) with gratings created via CreateProceduralSineGrating, or for gabors created via CreateProceduralGabor, so the alpha values of the grating are completely ignored and the system simply adds up the color values of drawn pixels - a classic superposition. You must also setup the onscreen window properly for this. It must use a floating point framebuffer for superposition to work correctly. ProceduralGarboriumDemo is a good starting point that shows this, just replace its procedural gabor functions with the procedural grating functions. AdditiveBlendingForLinearSuperpositionTutorial demonstrates the same, but it also demonstrates lots of other advanced things and uses alpha values you shouldn't use here, so using ProceduralGarboriumDemo as a start might be simpler.

Using alpha values with the procedural functions in addition to the contrast values they use gives too many degrees of freedom and just gets confusing.

With alpha blending fixed this way (GL_ONE, GL_ONE), the procedural functions allow you to specify contrast (or more precise: a multiplicative gain), as described in "help CreateProceduralSineGrating". The help tells you exactly the formula by which your given parameters are evaluated into pixel color values.

With a floating point framebuffer whose normalized color/grayscale values range from 0.0 (black) to 1.0 (white) and assuming a gray background of 0.5 (for 50% intensity gray), your useable range is +/- 0.5, that's why your composed gratings must not exceed that, otherwise you'd try to draw gratings which are whiter than white or darker than pitch black -- outside the displayable range. The system would simply show values < 0.0 as 0.0 and > 1.0 as 1.0.

> p.s. I also tried the Screen('BlendFunction', win, GL_ONE, GL_ONE) function as was mentioned in some earlier posts, however, the superimposed grating created was not what I expected.
>

One thing you can always do to check your results is read back a snapshot of the framebuffer via Screen('GetImage', win, [], 'drawBuffer', 1); to get the final composed stimulus within the normalized intensity range 0.0 - 1.0. Reading back 'frontBuffer' after a Screen('Flip') would give you a screenshot of the final framebuffer content after all post-processing operations like gamma correction, stereoscopic display etc. are applied -- assuming you selected such operations via the PsychImaging() command.

Specifying alpha values to modulate the intensity or contrast of drawn pixels is useful for standard drawing commands (FillRect, DrawDots, FillOval, DrawText, ....) or for textures. For the procedural stimuli it is best to leave alpha out of the process and use the controllable stimulus parameters of those stimuli.

-mario
Hi Mario,

Thanks for your detailed reply! Now I got the superimposed grating I want using Screen('BlendFunction', win, GL_ONE, GL_ONE). However, I still have one more question:
When I superimpose two gratings, 'backgroundColorOffset' in "CreateProceduralSineGrating" is set to [0, 0, 0, 0], the superimposed grating looks good (black lines superimposed on grey background), however, since 'backgroundColorOffset' is [0, 0, 0, 0], the background of the component grating is black, instead of grey (which is what I want). So if I want to get a grey background for a single grating, I need to set the 'backgroundColorOffset' as [0.5, 0.5, 0.5, 0]. Now my question is, if I want to get a pair of superimposed grating and common grating with the same contrast (e.g. 0.2), can I use 'backgroundColorOffset' = [0, 0, 0, 0], contrast=0.1 in component gratings to create the superimposed grating, and 'backgroundColorOffset' = [0.5, 0.5, 0.5, 0], contrast=0.2 to create the common grating? Do they have the same contrast ?




Qing

--- In psychtoolbox@yahoogroups.com, "Mario" wrote:
>
>
>
> --- In psychtoolbox@yahoogroups.com, "yuqingpsy" wrote:
> >
> > Hi,
> >
> > I'm using the alpha blending function in psychtoolbox to superimpose two gratings.
> > The gratings I'm using were created by "CreateProceduralSineGrating", backgroundColorOffset was set to [0.5,0.5,0.5,0], the blending function was Screen('BlendFunction', win, GL_SRC_ALPHA, GL_ONE). I choose this blending function because it's what they used in the "AdditiveBlendingForLinearSuperpositionTutorial" demo.
> > However, I'm confused about two things:
> > First, I cannot use a contrast higher than 0.5 for the component gratings. If the contrast exceeds 0.5, the color seems to get reversed and the superimposed gratings look weird.
> > Secondly, I think the visible contrast of the superimposed gratings is lower than that of its component gratings. So my question is, is there a way to find out what the exact contrast of the new stimulus is?
> >
>
> Use Screen('BlendFunction', win, GL_ONE, GL_ONE) with gratings created via CreateProceduralSineGrating, or for gabors created via CreateProceduralGabor, so the alpha values of the grating are completely ignored and the system simply adds up the color values of drawn pixels - a classic superposition. You must also setup the onscreen window properly for this. It must use a floating point framebuffer for superposition to work correctly. ProceduralGarboriumDemo is a good starting point that shows this, just replace its procedural gabor functions with the procedural grating functions. AdditiveBlendingForLinearSuperpositionTutorial demonstrates the same, but it also demonstrates lots of other advanced things and uses alpha values you shouldn't use here, so using ProceduralGarboriumDemo as a start might be simpler.
>
> Using alpha values with the procedural functions in addition to the contrast values they use gives too many degrees of freedom and just gets confusing.
>
> With alpha blending fixed this way (GL_ONE, GL_ONE), the procedural functions allow you to specify contrast (or more precise: a multiplicative gain), as described in "help CreateProceduralSineGrating". The help tells you exactly the formula by which your given parameters are evaluated into pixel color values.
>
> With a floating point framebuffer whose normalized color/grayscale values range from 0.0 (black) to 1.0 (white) and assuming a gray background of 0.5 (for 50% intensity gray), your useable range is +/- 0.5, that's why your composed gratings must not exceed that, otherwise you'd try to draw gratings which are whiter than white or darker than pitch black -- outside the displayable range. The system would simply show values < 0.0 as 0.0 and > 1.0 as 1.0.
>
> > p.s. I also tried the Screen('BlendFunction', win, GL_ONE, GL_ONE) function as was mentioned in some earlier posts, however, the superimposed grating created was not what I expected.
> >
>
> One thing you can always do to check your results is read back a snapshot of the framebuffer via Screen('GetImage', win, [], 'drawBuffer', 1); to get the final composed stimulus within the normalized intensity range 0.0 - 1.0. Reading back 'frontBuffer' after a Screen('Flip') would give you a screenshot of the final framebuffer content after all post-processing operations like gamma correction, stereoscopic display etc. are applied -- assuming you selected such operations via the PsychImaging() command.
>
> Specifying alpha values to modulate the intensity or contrast of drawn pixels is useful for standard drawing commands (FillRect, DrawDots, FillOval, DrawText, ....) or for textures. For the procedural stimuli it is best to leave alpha out of the process and use the controllable stimulus parameters of those stimuli.
>
> -mario
>