1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
function ProceduralColorGratingDemo(color1,color2,baseColor)
% ProceduralColorGratingDemo() -- demo color grating procedural shader
% stimuli
%
%
% This demo shows how to use procedural color gratings. Color gratings
% have two color sources, rather than one. They are a useful stimulus
% class for e.g. understanding opponenet color channels. The standard PTB
% grating shader cannot generate this class of grating. The procedural
% shader can generate sinusoidal or square wave gratings, and you can set a
% radial aperture.
%
%
% Optional Inputs are:
% color1 -- the first color of the grating, default is red [1 0 0 1]
% color2 -- the second color of the grating, default is green [0 1 0 1]
% baseColor -- the base color from which color1 and color2 are blended
% depending on contrast. Normally this would be set to your background
% color in PTB; default in this demo is the background color [0.5 0.5 0.5 1].
%
% History:
% 01/03/2020 initial version (Ian Andolina)
if ~exist('color1','var') || isempty(color1)
color1 = [1 0 0 1];
end
if ~exist('color2','var') || isempty(color2)
color2 = [0 1 0 1];
end
if ~exist('baseColor','var') || isempty(baseColor)
baseColor = [0.5 0.5 0.5 1];
end
% Setup defaults and unit color range:
PsychDefaultSetup(2);
% Disable synctests for this quick demo:
oldSyncLevel = Screen('Preference', 'SkipSyncTests', 2);
% Select screen with maximum id for output window:
screenid = max(Screen('Screens'));
% Open a fullscreen, onscreen window with gray background. Enable 32bpc
% floating point framebuffer via imaging pipeline on it, if this is possible
% on your hardware while alpha-blending is enabled. Otherwise use a 16bpc
% precision framebuffer together with alpha-blending.
PsychImaging('PrepareConfiguration');
PsychImaging('AddTask', 'General', 'FloatingPoint32BitIfPossible');
[win, winRect] = PsychImaging('OpenWindow', screenid, baseColor);
% Query frame duration: We use it later on to time 'Flips' properly for an
% animation with constant framerate:
ifi = Screen('GetFlipInterval', win);
% Enable alpha-blending
Screen('BlendFunction', win, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
% default x + y size
virtualSize = 512;
% radius of the disc edge
radius = floor(virtualSize / 2);
% Build a procedural texture, we also keep the shader as we will show how to
% modify it (though not as efficient as using parameters in drawtexture)
texture = CreateProceduralColorGrating(win, virtualSize, virtualSize,...
color1, color2, radius);
% These settings are the parameters passed in directly to DrawTexture
% angle
angle = 45;
% phase
phase = 0;
% spatial frequency
frequency = 0.03;
% contrast
contrast = 0.5;
% sigma < 0 is a sinusoid.
sigma = -1.0;
% Preperatory flip
showTime = 3;
vbl = Screen('Flip', win);
tstart = vbl + ifi; %start is on the next frame
while vbl < tstart + showTime
% Draw a message
Screen('DrawText', win, 'Standard Color Sinusoidal Grating', 10, 10, [1 1 1]);
% Draw the shader texture with parameters
Screen('DrawTexture', win, texture, [], [],...
angle, [], [], baseColor, [], [],...
[phase, frequency, contrast, sigma]);
vbl = Screen('Flip', win, vbl + 0.5 * ifi);
phase = phase - 15;
end
%--- now we switch to a square wave grating using sigma >= 0
% if sigma is 0 then the squarewave is not smoothed, but if it is > 0 then
% hermite interpolation smoothing in +-sigma of the edge is performed.
sigma = 0.1;
% Preperatory flip
vbl = Screen('Flip', win);
tstart = vbl + ifi; %start is on the next frame
while vbl < tstart + showTime
% Draw a message
Screen('DrawText', win, 'Standard Color Squarewave Grating', 10, 10, [1 1 1]);
% Draw the shader texture with parameters
Screen('DrawTexture', win, texture, [], [],...
angle, [], [], baseColor, [], [],...
[phase, frequency, contrast, sigma]);
vbl = Screen('Flip', win, vbl + 0.5 * ifi);
phase = phase - 15;
end
%--- Lets make a Blue/Yellow colour shader
Screen('Close',texture);
texture = CreateProceduralColorGrating(win, virtualSize,...
virtualSize, [0 0 1 1], [1 1 0 1], radius);
% Preperatory flip
vbl = Screen('Flip', win);
tstart = vbl + ifi; %start is on the next frame
while vbl < tstart + showTime
% Draw a message
Screen('DrawText', win, 'Blue-Yellow Color Squarewave Grating', 10, 10, [1 1 1]);
% Draw the shader texture with parameters
Screen('DrawTexture', win, texture, [], [],...
angle, [], [], baseColor, [], [],...
[phase, frequency, contrast, sigma]);
vbl = Screen('Flip', win, vbl + 0.5 * ifi);
phase = phase - 15;
end
%--- now we change the baseColor to show its effect on the grating
baseColor = [0.2 0.0 0.2 1];
% Preperatory flip
vbl = Screen('Flip', win);
tstart = vbl + ifi; %start is on the next frame
while vbl < tstart + showTime
%draw the background with the same baseColor
Screen('FillRect',win, baseColor);
% Draw a message
Screen('DrawText', win, 'Blue-Yellow Grating modifying the base color', 10, 10, [1 1 1]);
% Draw the shader texture with parameters
Screen('DrawTexture', win, texture, [], [],...
angle, [], [], baseColor, [], [],...
[phase, frequency, contrast, sigma]);
vbl = Screen('Flip', win, vbl + 0.5 * ifi);
phase = phase - 15;
end
% Close onscreen window, release all resources:
sca;
% Restore old settings for sync-tests:
Screen('Preference', 'SkipSyncTests', oldSyncLevel);
|