Chromatic drifting, vibrating and static gratings

Hi,

I'm fairly new to Matlab and psychtoolbox so I've come here to ask for help. I have been able to make striped gratings with drifting and vibrating lines, but I'm unable to manipulate the colour channels to change the chromaticities of the lines.

I've modified the channels to enable manipulation but I'm not sure if that's correct

"Screen('BlendFunction', w, GL_SRC_ALPHA, GL_ZERO,[1 1 1 1]);".

If I set them all to 1 then the grating turns white, but turning off all channels aprt from one I can get a colour. However, I am unable to manipulate this colour when drawing the texture to the screen:


Here's a copy of the current code, sorry if it's a bit messy. It's been modified from the drift demos provided.

Hopefully someone will have experience in doing this or can help me out!
Thanks!





function stripes(pattern_type);

if nargin<1
pattern_type=3;
end;

f=0.025

cyclespersecond=10;

angle=90;

movieDurationSecs=15 ; % Abort demo after 5 seconds.
texsize=300; % Half-Size of the grating image.


try

AssertOpenGL;

screens=Screen('Screens');
screenNumber=max(screens);

% Find the color values which correspond to white and black.
white=WhiteIndex(screenNumber);
black=BlackIndex(screenNumber);
gray=(white+black)/2;
if round(gray)==white
gray=black;
end
inc=white-gray;
% Open a double buffered fullscreen window and draw a gray background
% to front and back buffers:
[w screenRect]=Screen('OpenWindow',screenNumber, 0,[],32,2);
Screen('BlendFunction', w, GL_SRC_ALPHA, GL_ZERO,[1 1 1 1]);
Screen('FillRect',w, gray);

% This is the beginning of the stimulus repetition
StimulusSequence=[1 2 3 3 2 1 3 1 2 2 1 3 2 3 1 3 2 1 ];
NumberTrials=size(StimulusSequence)

for presn=1:1:NumberTrials(2);
% Abort demo if any key is pressed:
if KbCheck
break;
end;
pattern_type=StimulusSequence(presn);


% Calculate parameters of the grating:
p=ceil(1/f); % pixels/cycle
fr=f*2*pi;
visiblesize=2*texsize+1;
contrast=0.1;

% Create one single static grating image:
[x,y]=meshgrid(-texsize:texsize + p, -texsize:texsize);
%grating=gray + inc*(cos(fr*x));
grating1=white%+ inc.*contrast.*ceil(cos(fr*x)*0.999999999);
% Store grating in texture:
gratingtex1=Screen('MakeTexture', w, grating1);
Screen('DrawTexture', w, gratingtex1, [], [], [], [], [], [0 255 0]);

% Create one single static grating image:
[x,y]=meshgrid(-texsize:texsize + p, -texsize:texsize);
%grating=gray + inc*(cos(fr*x));
grating2=gray+ inc.*contrast.*ceil(cos(fr*x)*0.999999999);
% Store grating in texture:
gratingtex2=Screen('MakeTexture', w, grating2);
Screen('DrawTexture', w, gratingtex2, [], [], [], [], [], [0 255 0]);


priorityLevel=MaxPriority(w);
Priority(priorityLevel);

%Definition of the drawn rectangle on the screen:
dstRect=[0 0 visiblesize-1 visiblesize-1];
dstRect1=[0 0 visiblesize/2-1 visiblesize-1];
dstRect2=[0 0 visiblesize/2-1 visiblesize-1];
dstRect=CenterRect(dstRect, screenRect);
dstRect1=CenterRect(dstRect1, screenRect);
dstRect2=CenterRect(dstRect2, screenRect);
dstRect1=OffsetRect(dstRect1,0,visiblesize/4);
dstRect2=OffsetRect(dstRect2,0,-visiblesize/4);

% Query duration of monitor refresh interval:
ifi=Screen('GetFlipInterval', w);

waitframes = 1;
waitduration = waitframes * ifi;

% Translate requested speed of the grating (in cycles per second)
% into a shift value in "pixels per frame", assuming given
% waitduration: This is the amount of pixels to shift our "aperture" at
% each redraw:
shiftperframe= cyclespersecond * p * waitduration;

% Perform initial Flip to sync us to the VBL and for getting an initial
% VBL-Timestamp for our "WaitBlanking" emulation:
vbl=Screen('Flip', w);
vblendtime = vbl + movieDurationSecs;
i=0;

while(vbl < vblendtime)

% Shift the grating by "shiftperframe" pixels per frame:
t1 = mod(i*shiftperframe,p);
xoffset1=t1;
t2=mod(i*shiftperframe, 2*p);
if pattern_type==2
if t1==t2
st=t1;
else xoffset1=st-mod(i*shiftperframe,p);

end
end
if pattern_type==3
xoffset1=0;
end
xoffset2 = -xoffset1;

i=i+1;

% Define shifted srcRect that cuts out the properly shifted rectangular
% area from the texture:
srcRect1=[xoffset1 0 xoffset1 + visiblesize visiblesize];

% Draw grating texture, rotated by "angle":
Screen('DrawTexture', w, gratingtex1, srcRect1, dstRect1, angle);

% Define shifted srcRect that cuts out the properly shifted rectangular
% area from the texture:
srcRect2=[xoffset2 125 xoffset2 + visiblesize visiblesize];

% Draw grating texture, rotated by "angle":
Screen('DrawTexture', w, gratingtex2, srcRect2, dstRect2, angle);

% Flip 'waitframes' monitor refresh intervals after last redraw.
vbl = Screen('Flip', w, vbl + (waitframes - 0.5) * ifi);

% Abort demo if any key is pressed:
if KbCheck
break;
end;
end;

end;

Priority(0);

Screen('CloseAll');

catch

Screen('CloseAll');
Priority(0);
psychrethrow(psychlasterror);
end %try..catch..
Forget about that Blendfunction thing. What you probably need is to set the optional 'modulateColor' parameter of 'DrawTexture', e.g., setting it to [128, 255, 0, 255] would multiply your red channel with 128/255, leave the green channel as is (255/255 == 1 == identity) and disable blue channel drawing (well, turn its intensity to 0).

So you change chromaticity this way, but this is not the same as changing per-color channel contrast.

For more fine-grained control over contrast etc. with half-way modern graphics cards, look into AdditiveBlendingForLinearSuperpositionTutorial.m

-mario


--- In psychtoolbox@yahoogroups.com, "mscresmethucl" <mscresmethucl@...> wrote:
>
> Hi,
>
> I'm fairly new to Matlab and psychtoolbox so I've come here to ask for help. I have been able to make striped gratings with drifting and vibrating lines, but I'm unable to manipulate the colour channels to change the chromaticities of the lines.
>
> I've modified the channels to enable manipulation but I'm not sure if that's correct
>
> "Screen('BlendFunction', w, GL_SRC_ALPHA, GL_ZERO,[1 1 1 1]);".
>
> If I set them all to 1 then the grating turns white, but turning off all channels aprt from one I can get a colour. However, I am unable to manipulate this colour when drawing the texture to the screen:
>
>
> Here's a copy of the current code, sorry if it's a bit messy. It's been modified from the drift demos provided.
>
> Hopefully someone will have experience in doing this or can help me out!
> Thanks!
>
>
>
>
>
> function stripes(pattern_type);
>
> if nargin<1
> pattern_type=3;
> end;
>
> f=0.025
>
> cyclespersecond=10;
>
> angle=90;
>
> movieDurationSecs=15 ; % Abort demo after 5 seconds.
> texsize=300; % Half-Size of the grating image.
>
>
> try
>
> AssertOpenGL;
>
> screens=Screen('Screens');
> screenNumber=max(screens);
>
> % Find the color values which correspond to white and black.
> white=WhiteIndex(screenNumber);
> black=BlackIndex(screenNumber);
> gray=(white+black)/2;
> if round(gray)==white
> gray=black;
> end
> inc=white-gray;
> % Open a double buffered fullscreen window and draw a gray background
> % to front and back buffers:
> [w screenRect]=Screen('OpenWindow',screenNumber, 0,[],32,2);
> Screen('BlendFunction', w, GL_SRC_ALPHA, GL_ZERO,[1 1 1 1]);
> Screen('FillRect',w, gray);
>
> % This is the beginning of the stimulus repetition
> StimulusSequence=[1 2 3 3 2 1 3 1 2 2 1 3 2 3 1 3 2 1 ];
> NumberTrials=size(StimulusSequence)
>
> for presn=1:1:NumberTrials(2);
> % Abort demo if any key is pressed:
> if KbCheck
> break;
> end;
> pattern_type=StimulusSequence(presn);
>
>
> % Calculate parameters of the grating:
> p=ceil(1/f); % pixels/cycle
> fr=f*2*pi;
> visiblesize=2*texsize+1;
> contrast=0.1;
>
> % Create one single static grating image:
> [x,y]=meshgrid(-texsize:texsize + p, -texsize:texsize);
> %grating=gray + inc*(cos(fr*x));
> grating1=white%+ inc.*contrast.*ceil(cos(fr*x)*0.999999999);
> % Store grating in texture:
> gratingtex1=Screen('MakeTexture', w, grating1);
> Screen('DrawTexture', w, gratingtex1, [], [], [], [], [], [0 255 0]);
>
> % Create one single static grating image:
> [x,y]=meshgrid(-texsize:texsize + p, -texsize:texsize);
> %grating=gray + inc*(cos(fr*x));
> grating2=gray+ inc.*contrast.*ceil(cos(fr*x)*0.999999999);
> % Store grating in texture:
> gratingtex2=Screen('MakeTexture', w, grating2);
> Screen('DrawTexture', w, gratingtex2, [], [], [], [], [], [0 255 0]);
>
>
> priorityLevel=MaxPriority(w);
> Priority(priorityLevel);
>
> %Definition of the drawn rectangle on the screen:
> dstRect=[0 0 visiblesize-1 visiblesize-1];
> dstRect1=[0 0 visiblesize/2-1 visiblesize-1];
> dstRect2=[0 0 visiblesize/2-1 visiblesize-1];
> dstRect=CenterRect(dstRect, screenRect);
> dstRect1=CenterRect(dstRect1, screenRect);
> dstRect2=CenterRect(dstRect2, screenRect);
> dstRect1=OffsetRect(dstRect1,0,visiblesize/4);
> dstRect2=OffsetRect(dstRect2,0,-visiblesize/4);
>
> % Query duration of monitor refresh interval:
> ifi=Screen('GetFlipInterval', w);
>
> waitframes = 1;
> waitduration = waitframes * ifi;
>
> % Translate requested speed of the grating (in cycles per second)
> % into a shift value in "pixels per frame", assuming given
> % waitduration: This is the amount of pixels to shift our "aperture" at
> % each redraw:
> shiftperframe= cyclespersecond * p * waitduration;
>
> % Perform initial Flip to sync us to the VBL and for getting an initial
> % VBL-Timestamp for our "WaitBlanking" emulation:
> vbl=Screen('Flip', w);
> vblendtime = vbl + movieDurationSecs;
> i=0;
>
> while(vbl < vblendtime)
>
> % Shift the grating by "shiftperframe" pixels per frame:
> t1 = mod(i*shiftperframe,p);
> xoffset1=t1;
> t2=mod(i*shiftperframe, 2*p);
> if pattern_type==2
> if t1==t2
> st=t1;
> else xoffset1=st-mod(i*shiftperframe,p);
>
> end
> end
> if pattern_type==3
> xoffset1=0;
> end
> xoffset2 = -xoffset1;
>
> i=i+1;
>
> % Define shifted srcRect that cuts out the properly shifted rectangular
> % area from the texture:
> srcRect1=[xoffset1 0 xoffset1 + visiblesize visiblesize];
>
> % Draw grating texture, rotated by "angle":
> Screen('DrawTexture', w, gratingtex1, srcRect1, dstRect1, angle);
>
> % Define shifted srcRect that cuts out the properly shifted rectangular
> % area from the texture:
> srcRect2=[xoffset2 125 xoffset2 + visiblesize visiblesize];
>
> % Draw grating texture, rotated by "angle":
> Screen('DrawTexture', w, gratingtex2, srcRect2, dstRect2, angle);
>
> % Flip 'waitframes' monitor refresh intervals after last redraw.
> vbl = Screen('Flip', w, vbl + (waitframes - 0.5) * ifi);
>
> % Abort demo if any key is pressed:
> if KbCheck
> break;
> end;
> end;
>
> end;
>
> Priority(0);
>
> Screen('CloseAll');
>
> catch
>
> Screen('CloseAll');
> Priority(0);
> psychrethrow(psychlasterror);
> end %try..catch..
>