Visual element objects

Visual elements include visual stimuli as well as elements that use other kinds of screen-based functionality like mouse. They all have the properties below setting visual options and transformations.

Input properties
Record properties
All visual elements

position
depth
nn_eyes
rotation

flipHorz
flipVert

colorMask

alpha
intensity

contrastMult
convolution
shader
filterOrder
filterGrayscale
filterResolutionMult
filterGamma

channelResolution

backColor

addDisplay

All elements
start
end

startBuffer
endBuffer

syncExperiment
preload
vary
staircase

All objects
info
report

position
depth

Default: position = screen center
Default: depth = 0 (doesn't matter if element won't overlap with other elements)

position is a vector [x y] setting element position on screen (deg). + = right⁠/⁠down (like Western text and matrix indexing), <cd>[0 0]<cd> = screen center. Typically elements center at this point, but see element type documentation for exceptions.

depth is a number setting element layering on screen. + = backward, − = forward. Absolute values don’t matter, only relative. You can ignore depth for element displays that won’t overlap.

To set drift or movement, you can use property vary.

Examples

element.position = [2 0]

→ 2 deg right from screen center

element.position = {[-400 -400], <cdsm>"px"<cdsm>}

→ 400 px left and up from screen center

nn_eyes

Default: show on both eyes

If you turn on stereo display (screen object property stereo) use this property to set whether the element shows on left eye (<cd>1<cd>), right eye (<cd>2<cd>), or both eyes (a vector <cd>[1 2]<cd>). The other position properties above apply as usual within each eye.

rotation

Default: no rotation

Element orientation clockwise (from +x to +y screen axis, with +y down) about position (deg).

flipHorz
flipVert

Defaults: don't flip

<cd>true<cd>/<cd>false<cd>: flip element horizontally/vertically. Note if you want to flip the whole display for the experiment, use screen object properties flipHorz, flipVert instead.

colorMask

Default: normal

A 1×3 vector with numbers between 0–1 scaling RGB components in the element display. e.g. <cd>[1 0 0]<cd> = remove all green and blue color from the display. In the case of a pixel that is pure white (RGB = <cd>[1 1 1]<cd>), colorMask is equivalent to setting its RGB color.

Often you can set color directly in a type-specific property (e.g. color) instead. colorMask is useful for elements where the image(s) are read from a file or data and color can't be set directly, e.g. in picture or movie elements. Another difference is that colorMask is usually adjustable (so you can apply property vary or an adjuster element to it) whereas type-specific color properties often are not.

alpha

Default: no additional transparency

A number between 0–1 applying transparency to the element. 0 = fully transparent (invisible), 1 = no additional transparency.

Regardless of this property some elements have transparent background and/or parts of their display with some level of transparency, often settable by other properties—see specific element type documentation. alpha multiplies in additional transparency at the level of the whole element.

intensity

Default: normal

A number ≥ 0 multiplying the RGB intensity of the element. < 1 = decrease brightness, 1 = normal, > 1 = increase brightness. Note often you can set brightness more directly through type-specific properties setting color.

contrastMult

Default: normal

A number ≥ 0 multiplying the contrast of the element, assuming a mean intensity of 0.5 (50%). < 1 = decrease contrast, 1 = normal, > 1 = increase contrast.

Or a vector [mult mean] if you want to use a different mean intensity value. (Currently PsychBench cannot automatically detect actual mean intensity values for use with this property.)

The transformation at each pixel is:

<cd>rgb = (rgb-mean)*mult+mean<cd>

convolution

Default: no convolution

You can apply one of various types of blur or any other convolution filter using this property. convolution is a further struct that can have the following fields. You can omit fields (or leave them = <cd>[]<cd>) to leave them at default.

Note if you use convolution, PsychBench needs to fill any transparent parts of the element background with an opaque color to blend with. It also pads the element display borders with this color. By default fill color is same as trial background color, so in most use cases this doesn't matter. If you want to use a different color, specify it in property backColor below.

type
size
sigma

Default: no generated kernel

type is a string <cdsm>"average"<cdsm>, <cdsm>"disk"<cdsm>, or <cdsm>"gaussian"<cdsm> to tell PsychBench to use a symmetric convolution kernel of that type. You then need to set size and other parameters in further fields below:

size is width of the symmetric kernel. Convolution is applied at the resolution the element shows at on screen. As such, kernel size is a distance on screen, so by default it’s in deg units as usual. The resulting size will round up to an odd integer number of px on screen. Note if you want to set size in px units, you can use <cdm>{value, <cdm><cdsm>"unit"<cdsm><cdm>}<cdm> form directly in the field, e.g. convolution.size = <cdm>{value, <cdm><cdsm>"px"<cdsm><cdm>}<cdm>.

sigma (type = <cdsm>"gaussian"<cdsm> only): This is standard deviation of the Gaussian. Again this is a distance on screen, by default in deg but you can specify other units like px directly in the field if you want.

For type = <cdsm>"gaussian"<cdsm> only, you can set either size or sigma and the other will default to size = 4 × sigma. You can also set both if you want a different ratio.

Note if you use filterResolutionMult below to apply the convolution at a resolution lower than screen resolution, PsychBench will automatically scale size and sigma down. So, always set them assuming convolution at screen resolution.

type requires the MATLAB Image Processing Toolbox.

kernel

Default: no custom kernel

If you don’t have the Image Processing Toolbox or want to use a different kernel than one of the above, you can directly specify any kernel as a 2D matrix in kernel instead. Specifically this is a correlation kernel like those generated by fspecial (it will be rotated 180 deg at application to implement convolution). Pixels in the kernel correspond to pixels at screen resolution. Like a MATLAB image matrix, rows correspond to height and columns to width. The kernel must be an odd integer number of px wide and high (not necessarily symmetric). If the kernel is separable, you can use a 1×2 cell array containing x and y kernels for greater efficiency.

Note if you use filterResolutionMult below to apply the convolution at a resolution lower than screen resolution, PsychBench does not scale your custom kernel down. You must set it assuming convolution at the lower resolution.

shader

Default: no custom shaders

You can apply custom visual transformations using one or more GLSL shaders. shader is a further struct that can have the following fields. You can omit fields (or leave them = <cd>[]<cd>) to leave them at default. You can apply multiple shaders separately by making shader a struct array, e.g. <cd>shader(1).fileName = <cd> ..., <cd>shader(2).fileName = <cd>... , to run in that order.

fileName

A string or array of strings that are text files containing GLSL shader code, one file per shader. If multiple files then the shaders will be linked into a single program in that order.

setupCode
setupVars

Defaults: no additional setup code

PsychBench automatically loads and links the shader(s) in fileName using Psychtoolbox LoadGLSLProgramFromFiles and adds them to a GL operator using AddToGLOperator. However, typically the shader(s) need some setup code between loading/linking and adding, e.g. setting uniforms, making auxiliary textures, etc. You can set setupCode to a string that is the name of a MATLAB script containing this code. The script can reference the variable n_shader which will contain the pointer to the loaded/linked shader program. It can optionally make variables blitterConfig and n_lutTexture which will go to inputs of AddToGLOperator, and nn_glTextures which is a row vector containing OpenGL texture numbers for any auxiliary textures the setup code opens so PsychBench can close them later.

setupVars: You can provide further inputs to the setup code in this field. This is a further struct containing any number of fields with any names containing anything you want. This struct will be available to the setup code in a variable called vars.

Example

An example of a shader and some setup code for it which reproduces property contrastMult above is in <><PsychBench folder><>/docs/demos. Other open source shader files can also be found in <><PsychBench folder><>/core/elementWithScreen. Many more can be found in folders in Psychtoolbox.

filterOrder
filterGrayscale
filterResolutionMult
filterGamma

Default: filterOrder = intensitycontrastMultconvolution → custom shaders in shader
Default:
filterGrayscale = don't assume grayscale element display
Default:
filterResolutionMult = filter at screen resolution
Default: filterGamma = apply filters to standard gamma-encoded RGB

Properties intensity, contrastMult, convolution, shader, above are implemented as GLSL shaders that run on your graphics hardware. The properties below affect all of them.
filterOrder: If you enable more than one of these filters, the default order they apply in is listed above. You can set filterOrder if you want to use a different order. This is an array of strings that can include any of <cds>"intensity"<cds>, <cds>"contrastMult"<cds>, <cds>"convolution"<cds>, <cds>"shader"<cds>, <cds>"shader(1)"<cds>, <cds>"shader(2)"<cds>, ... in any order.
filterGrayscale: <cd>true<cd>/<cd>false<cd>: assume grayscale element display. If the element is grayscale, setting this = <cd>true<cd> makes the filter operation(s) faster since then they only need to be calculated once for each pixel, not for each RGB pixel component. This can help avoid dropped frames if you have a dynamic stimulus where PsychBench needs to re-filter at each frame of animation and you have some combination of computationally intensive filter / large stimulus / high screen resolution / slow system. Note if the element is not grayscale and you set filterGrayscale = <cd>true<cd>, it will appear grayscale but with distorted brightness, so don't do that. filterGrayscale doesn't apply to custom shaders you set in shader above—for these you can implement any grayscale treatment directly in your shader code.
filterResolutionMult lets you apply these filters at a lower resolution than the element shows at on screen. This is a number between 0–1 that is fraction of screen resolution to use, e.g. 0.5 = half screen resolution, 1 = screen resolution. The filter result is then scaled up to screen resolution for display. filterResolutionMult < 1 makes the filter operation(s) faster, similar to filterGrayscale above. However it may come at a cost of reduced image quality.
filterGamma applies a gamma decoding before any intensity, contrastMult, convolution, shader and then its inverse (re-encoding) after them and before display. You can use this to apply these filters to a representation that models the physical luminance the element will produce as opposed to its standard gamma-encoded RGB, assuming the filterGamma you set correctly models the total mapping from gamma-encoded RGB → luminance for your display (note this total mapping is generally not just your graphics card's gamma table—see screen object gamma for more information). For example, you could use filterGamma with a blur convolution to simulate reduced visual acuity at the eye. filterGamma is ignored if no convolution filters are applied.

filterGamma can be one number for simple power law gamma decoding/re-encoding (e.g. the standard 2.2). Or it can be an n×3 matrix with columns corresponding to RGB color channels, rows corresponding to input intensities (e.g. for 1024 rows: 0, 1/1024, 2/1024, ... 1), and numbers = output intensities between 0–1.

filterGamma doesn't change the gamma decoding that is actually applied element displays—for that add a screen object and set its property gamma. You can also mix using filterGamma with screen gamma.

channelResolution

Default: 8 bits

Intensity resolution of each pixel channel (R, G, B, A) for the element display before being drawn to the experiment window (bits). Typically you can leave this at default 8 bits (256 levels) since final displayed channel resolution is limited by your graphics hardware. However, if needed you can set this to 16 or 32 bits for higher precision in pre-window processing.

Not all graphics hardware supports even pre-window channel resolutions > 8 bits, more specifically that and alpha blending at the same time. If yours doesn't, you will see warnings from Psychtoolbox in the MATLAB command window and you would need to upgrade your graphics hardware.

Example

If an element display has low dynamic range at low levels (e.g. levels 15–20 out of 256 at 8 bits) and you apply a filter like intensity that scales it up, e.g. ×10 to 150–200, the quantization would become easily visible since it would be distributed across much more of the dynamic range of the screen. To avoid this you could set the element's channel resolution = 16 or 32 bits such that the same initial range would be quantized into 6,144 or 100,663,296 levels, which would still look smooth when scaled up.

backColor

Default: no override, background depends on element type, generally transparent or = opaque trial background color

Usually you can ignore this property.

A 1×3 RGB vector with numbers between 0–1, or the string <cds>"opaque"<cds> to take whatever the opaque trial background color is. This property overrides the element's background with an opaque (or different opaque) color. Default background depends on element type but is generally either transparent (RGBA <cd>[0 0 0 0]<cd>) or = trial background color. The most common reason to set this property is for an element where default background is transparent and that is causing artifacts in its display. These are very unusual corner cases but possible for some element types—see specific type documentation.

addDisplay

Default: no additive blending → display occludes or blends normally with whatever is behind it

<cd>true<cd>/<cd>false<cd>: If = <cd>true<cd> then instead of the usual occluding or blending, the element display's pixel values will add to pixel values behind it on screen (including negative pixel values subtract). For most elements this doesn't make sense to do. However, some elements support it—see element type documentation. For example, if you set addDisplay = <cd>true<cd> for a noise element then instead of simply showing a noise patch, it will add noise to whatever is behind it on screen, typically another element.

Notes: Use property depth above to put the element above the other element(s) you want to add to.

Not all graphics hardware supports this, more specifically this and alpha blending at the same time. If yours doesn't, all element displays will occlude and you will see warnings from Psychtoolbox in the MATLAB command window. On some systems making a screen object and setting its property bufferChannelResolution to <cds>"16i"<cds> will work in this case. Otherwise you would need to upgrade your graphics hardware.

Technical

If you enable this property, PsychBench enables a signed experiment window frame buffer (default 16 bit floating point) and unclamps pre-display pixel values. These can also be set independently in screen object properties bufferChannelResolution and clampChannels, but if you set addDisplay for any element in the experiment then PsychBench does it automatically so you don't need to. However, you can additionally set screen bufferChannelResolution if you want to change the type of signed frame buffer it uses.

Input properties
Record properties

PsychBench uses record properties to record information during experiments. You can't set record properties but you can see them in experiment results using input property report.

All elements
startTime
endTime
duration
n_startFrame
n_endFrame
startLatencyBufferable
endLatencyBufferable

trigger
triggerTime
d_triggerTime
numTriggers

syncTime