mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 18:50:54 +00:00
Merge branch '2022.2.0' of github.com:apitiot/psychojs into 2022.2.0
This commit is contained in:
commit
bd1148fb63
@ -14,6 +14,7 @@ import { to_pixiPoint } from "../util/Pixi.js";
|
|||||||
import * as util from "../util/Util.js";
|
import * as util from "../util/Util.js";
|
||||||
import { VisualStim } from "./VisualStim.js";
|
import { VisualStim } from "./VisualStim.js";
|
||||||
import defaultQuadVert from "./shaders/defaultQuad.vert";
|
import defaultQuadVert from "./shaders/defaultQuad.vert";
|
||||||
|
import imageShader from "./shaders/imageShader.frag";
|
||||||
import sinShader from "./shaders/sinShader.frag";
|
import sinShader from "./shaders/sinShader.frag";
|
||||||
import sqrShader from "./shaders/sqrShader.frag";
|
import sqrShader from "./shaders/sqrShader.frag";
|
||||||
import sawShader from "./shaders/sawShader.frag";
|
import sawShader from "./shaders/sawShader.frag";
|
||||||
@ -60,12 +61,21 @@ export class GratingStim extends VisualStim
|
|||||||
* Shader source code is later used for construction of shader programs to create respective visual stimuli.
|
* Shader source code is later used for construction of shader programs to create respective visual stimuli.
|
||||||
* @name module:visual.GratingStim.#SHADERS
|
* @name module:visual.GratingStim.#SHADERS
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
|
*
|
||||||
|
* @property {Object} imageShader - Renders provided image with applied effects (coloring, phase, frequency).
|
||||||
|
* @property {String} imageShader.shader - shader source code for the image based grating stimuli.
|
||||||
|
* @property {Object} imageShader.uniforms - default uniforms for the image based shader.
|
||||||
|
* @property {float} imageShader.uniforms.uFreq=1.0 - how much times image repeated within grating stimuli.
|
||||||
|
* @property {float} imageShader.uniforms.uPhase=0.0 - offset of the image along X axis.
|
||||||
|
* @property {float} imageShader.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
|
*
|
||||||
* @property {Object} sin - Creates 2d sine wave image as if 1d sine graph was extended across Z axis and observed from above.
|
* @property {Object} sin - Creates 2d sine wave image as if 1d sine graph was extended across Z axis and observed from above.
|
||||||
* {@link https://en.wikipedia.org/wiki/Sine_wave}
|
* {@link https://en.wikipedia.org/wiki/Sine_wave}
|
||||||
* @property {String} sin.shader - shader source code for the sine wave stimuli
|
* @property {String} sin.shader - shader source code for the sine wave stimuli
|
||||||
* @property {Object} sin.uniforms - default uniforms for sine wave shader
|
* @property {Object} sin.uniforms - default uniforms for sine wave shader
|
||||||
* @property {float} sin.uniforms.uFreq=1.0 - frequency of sine wave.
|
* @property {float} sin.uniforms.uFreq=1.0 - frequency of sine wave.
|
||||||
* @property {float} sin.uniforms.uPhase=0.0 - phase of sine wave.
|
* @property {float} sin.uniforms.uPhase=0.0 - phase of sine wave.
|
||||||
|
* @property {float} sin.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} sqr - Creates 2d square wave image as if 1d square graph was extended across Z axis and observed from above.
|
* @property {Object} sqr - Creates 2d square wave image as if 1d square graph was extended across Z axis and observed from above.
|
||||||
* {@link https://en.wikipedia.org/wiki/Square_wave}
|
* {@link https://en.wikipedia.org/wiki/Square_wave}
|
||||||
@ -73,6 +83,7 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {Object} sqr.uniforms - default uniforms for square wave shader
|
* @property {Object} sqr.uniforms - default uniforms for square wave shader
|
||||||
* @property {float} sqr.uniforms.uFreq=1.0 - frequency of square wave.
|
* @property {float} sqr.uniforms.uFreq=1.0 - frequency of square wave.
|
||||||
* @property {float} sqr.uniforms.uPhase=0.0 - phase of square wave.
|
* @property {float} sqr.uniforms.uPhase=0.0 - phase of square wave.
|
||||||
|
* @property {float} sqr.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} saw - Creates 2d sawtooth wave image as if 1d sawtooth graph was extended across Z axis and observed from above.
|
* @property {Object} saw - Creates 2d sawtooth wave image as if 1d sawtooth graph was extended across Z axis and observed from above.
|
||||||
* {@link https://en.wikipedia.org/wiki/Sawtooth_wave}
|
* {@link https://en.wikipedia.org/wiki/Sawtooth_wave}
|
||||||
@ -80,6 +91,7 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {Object} saw.uniforms - default uniforms for sawtooth wave shader
|
* @property {Object} saw.uniforms - default uniforms for sawtooth wave shader
|
||||||
* @property {float} saw.uniforms.uFreq=1.0 - frequency of sawtooth wave.
|
* @property {float} saw.uniforms.uFreq=1.0 - frequency of sawtooth wave.
|
||||||
* @property {float} saw.uniforms.uPhase=0.0 - phase of sawtooth wave.
|
* @property {float} saw.uniforms.uPhase=0.0 - phase of sawtooth wave.
|
||||||
|
* @property {float} saw.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} tri - Creates 2d triangle wave image as if 1d triangle graph was extended across Z axis and observed from above.
|
* @property {Object} tri - Creates 2d triangle wave image as if 1d triangle graph was extended across Z axis and observed from above.
|
||||||
* {@link https://en.wikipedia.org/wiki/Triangle_wave}
|
* {@link https://en.wikipedia.org/wiki/Triangle_wave}
|
||||||
@ -88,6 +100,7 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {float} tri.uniforms.uFreq=1.0 - frequency of triangle wave.
|
* @property {float} tri.uniforms.uFreq=1.0 - frequency of triangle wave.
|
||||||
* @property {float} tri.uniforms.uPhase=0.0 - phase of triangle wave.
|
* @property {float} tri.uniforms.uPhase=0.0 - phase of triangle wave.
|
||||||
* @property {float} tri.uniforms.uPeriod=1.0 - period of triangle wave.
|
* @property {float} tri.uniforms.uPeriod=1.0 - period of triangle wave.
|
||||||
|
* @property {float} tri.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} sinXsin - Creates an image of two 2d sine waves multiplied with each other.
|
* @property {Object} sinXsin - Creates an image of two 2d sine waves multiplied with each other.
|
||||||
* {@link https://en.wikipedia.org/wiki/Sine_wave}
|
* {@link https://en.wikipedia.org/wiki/Sine_wave}
|
||||||
@ -95,6 +108,7 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {Object} sinXsin.uniforms - default uniforms for shader
|
* @property {Object} sinXsin.uniforms - default uniforms for shader
|
||||||
* @property {float} sinXsin.uniforms.uFreq=1.0 - frequency of sine wave (both of them).
|
* @property {float} sinXsin.uniforms.uFreq=1.0 - frequency of sine wave (both of them).
|
||||||
* @property {float} sinXsin.uniforms.uPhase=0.0 - phase of sine wave (both of them).
|
* @property {float} sinXsin.uniforms.uPhase=0.0 - phase of sine wave (both of them).
|
||||||
|
* @property {float} sinXsin.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} sqrXsqr - Creates an image of two 2d square waves multiplied with each other.
|
* @property {Object} sqrXsqr - Creates an image of two 2d square waves multiplied with each other.
|
||||||
* {@link https://en.wikipedia.org/wiki/Square_wave}
|
* {@link https://en.wikipedia.org/wiki/Square_wave}
|
||||||
@ -102,12 +116,14 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {Object} sqrXsqr.uniforms - default uniforms for shader
|
* @property {Object} sqrXsqr.uniforms - default uniforms for shader
|
||||||
* @property {float} sqrXsqr.uniforms.uFreq=1.0 - frequency of sine wave (both of them).
|
* @property {float} sqrXsqr.uniforms.uFreq=1.0 - frequency of sine wave (both of them).
|
||||||
* @property {float} sqrXsqr.uniforms.uPhase=0.0 - phase of sine wave (both of them).
|
* @property {float} sqrXsqr.uniforms.uPhase=0.0 - phase of sine wave (both of them).
|
||||||
|
* @property {float} sqrXsqr.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} circle - Creates a filled circle shape with sharp edges.
|
* @property {Object} circle - Creates a filled circle shape with sharp edges.
|
||||||
* @property {String} circle.shader - shader source code for filled circle.
|
* @property {String} circle.shader - shader source code for filled circle.
|
||||||
* @property {Object} circle.uniforms - default uniforms for shader.
|
* @property {Object} circle.uniforms - default uniforms for shader.
|
||||||
* @property {float} circle.uniforms.uRadius=1.0 - Radius of the circle. Ranges [0.0, 1.0], where 0.0 is circle so tiny it results in empty stim
|
* @property {float} circle.uniforms.uRadius=1.0 - Radius of the circle. Ranges [0.0, 1.0], where 0.0 is circle so tiny it results in empty stim
|
||||||
* and 1.0 is circle that spans from edge to edge of the stim.
|
* and 1.0 is circle that spans from edge to edge of the stim.
|
||||||
|
* @property {float} circle.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} gauss - Creates a 2d Gaussian image as if 1d Gaussian graph was rotated arount Y axis and observed from above.
|
* @property {Object} gauss - Creates a 2d Gaussian image as if 1d Gaussian graph was rotated arount Y axis and observed from above.
|
||||||
* {@link https://en.wikipedia.org/wiki/Gaussian_function}
|
* {@link https://en.wikipedia.org/wiki/Gaussian_function}
|
||||||
@ -116,18 +132,21 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {float} gauss.uniforms.uA=1.0 - A constant for gaussian formula (see link).
|
* @property {float} gauss.uniforms.uA=1.0 - A constant for gaussian formula (see link).
|
||||||
* @property {float} gauss.uniforms.uB=0.0 - B constant for gaussian formula (see link).
|
* @property {float} gauss.uniforms.uB=0.0 - B constant for gaussian formula (see link).
|
||||||
* @property {float} gauss.uniforms.uC=0.16 - C constant for gaussian formula (see link).
|
* @property {float} gauss.uniforms.uC=0.16 - C constant for gaussian formula (see link).
|
||||||
|
* @property {float} gauss.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} cross - Creates a filled cross shape with sharp edges.
|
* @property {Object} cross - Creates a filled cross shape with sharp edges.
|
||||||
* @property {String} cross.shader - shader source code for cross shader
|
* @property {String} cross.shader - shader source code for cross shader
|
||||||
* @property {Object} cross.uniforms - default uniforms for shader
|
* @property {Object} cross.uniforms - default uniforms for shader
|
||||||
* @property {float} cross.uniforms.uThickness=0.2 - Thickness of the cross. Ranges [0.0, 1.0], where 0.0 thickness makes a cross so thin it becomes
|
* @property {float} cross.uniforms.uThickness=0.2 - Thickness of the cross. Ranges [0.0, 1.0], where 0.0 thickness makes a cross so thin it becomes
|
||||||
* invisible and results in an empty stim and 1.0 makes it so thick it fills the entire stim.
|
* invisible and results in an empty stim and 1.0 makes it so thick it fills the entire stim.
|
||||||
|
* @property {float} cross.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} radRamp - Creates 2d radial ramp image.
|
* @property {Object} radRamp - Creates 2d radial ramp image.
|
||||||
* @property {String} radRamp.shader - shader source code for radial ramp shader
|
* @property {String} radRamp.shader - shader source code for radial ramp shader
|
||||||
* @property {Object} radRamp.uniforms - default uniforms for shader
|
* @property {Object} radRamp.uniforms - default uniforms for shader
|
||||||
* @property {float} radRamp.uniforms.uSqueeze=1.0 - coefficient that helps to modify size of the ramp. Ranges [0.0, Infinity], where 0.0 results in ramp being so large
|
* @property {float} radRamp.uniforms.uSqueeze=1.0 - coefficient that helps to modify size of the ramp. Ranges [0.0, Infinity], where 0.0 results in ramp being so large
|
||||||
* it fills the entire stim and Infinity makes it so tiny it's invisible.
|
* it fills the entire stim and Infinity makes it so tiny it's invisible.
|
||||||
|
* @property {float} radRamp.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*
|
*
|
||||||
* @property {Object} raisedCos - Creates 2d raised-cosine image as if 1d raised-cosine graph was rotated around Y axis and observed from above.
|
* @property {Object} raisedCos - Creates 2d raised-cosine image as if 1d raised-cosine graph was rotated around Y axis and observed from above.
|
||||||
* {@link https://en.wikipedia.org/wiki/Raised-cosine_filter}
|
* {@link https://en.wikipedia.org/wiki/Raised-cosine_filter}
|
||||||
@ -135,14 +154,25 @@ export class GratingStim extends VisualStim
|
|||||||
* @property {Object} raisedCos.uniforms - default uniforms for shader
|
* @property {Object} raisedCos.uniforms - default uniforms for shader
|
||||||
* @property {float} raisedCos.uniforms.uBeta=0.25 - roll-off factor (see link).
|
* @property {float} raisedCos.uniforms.uBeta=0.25 - roll-off factor (see link).
|
||||||
* @property {float} raisedCos.uniforms.uPeriod=0.625 - reciprocal of the symbol-rate (see link).
|
* @property {float} raisedCos.uniforms.uPeriod=0.625 - reciprocal of the symbol-rate (see link).
|
||||||
|
* @property {float} raisedCos.uniforms.uAlpha=1.0 - value of the alpha channel.
|
||||||
*/
|
*/
|
||||||
static #SHADERS = {
|
static #SHADERS = {
|
||||||
|
imageShader: {
|
||||||
|
shader: imageShader,
|
||||||
|
uniforms: {
|
||||||
|
uFreq: 1.0,
|
||||||
|
uPhase: 0.0,
|
||||||
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
|
}
|
||||||
|
},
|
||||||
sin: {
|
sin: {
|
||||||
shader: sinShader,
|
shader: sinShader,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uFreq: 1.0,
|
uFreq: 1.0,
|
||||||
uPhase: 0.0,
|
uPhase: 0.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sqr: {
|
sqr: {
|
||||||
@ -150,7 +180,8 @@ export class GratingStim extends VisualStim
|
|||||||
uniforms: {
|
uniforms: {
|
||||||
uFreq: 1.0,
|
uFreq: 1.0,
|
||||||
uPhase: 0.0,
|
uPhase: 0.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
saw: {
|
saw: {
|
||||||
@ -158,7 +189,8 @@ export class GratingStim extends VisualStim
|
|||||||
uniforms: {
|
uniforms: {
|
||||||
uFreq: 1.0,
|
uFreq: 1.0,
|
||||||
uPhase: 0.0,
|
uPhase: 0.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tri: {
|
tri: {
|
||||||
@ -167,7 +199,8 @@ export class GratingStim extends VisualStim
|
|||||||
uFreq: 1.0,
|
uFreq: 1.0,
|
||||||
uPhase: 0.0,
|
uPhase: 0.0,
|
||||||
uPeriod: 1.0,
|
uPeriod: 1.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sinXsin: {
|
sinXsin: {
|
||||||
@ -175,7 +208,8 @@ export class GratingStim extends VisualStim
|
|||||||
uniforms: {
|
uniforms: {
|
||||||
uFreq: 1.0,
|
uFreq: 1.0,
|
||||||
uPhase: 0.0,
|
uPhase: 0.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sqrXsqr: {
|
sqrXsqr: {
|
||||||
@ -183,14 +217,16 @@ export class GratingStim extends VisualStim
|
|||||||
uniforms: {
|
uniforms: {
|
||||||
uFreq: 1.0,
|
uFreq: 1.0,
|
||||||
uPhase: 0.0,
|
uPhase: 0.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
circle: {
|
circle: {
|
||||||
shader: circleShader,
|
shader: circleShader,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uRadius: 1.0,
|
uRadius: 1.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
gauss: {
|
gauss: {
|
||||||
@ -199,21 +235,24 @@ export class GratingStim extends VisualStim
|
|||||||
uA: 1.0,
|
uA: 1.0,
|
||||||
uB: 0.0,
|
uB: 0.0,
|
||||||
uC: 0.16,
|
uC: 0.16,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cross: {
|
cross: {
|
||||||
shader: crossShader,
|
shader: crossShader,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uThickness: 0.2,
|
uThickness: 0.2,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
radRamp: {
|
radRamp: {
|
||||||
shader: radRampShader,
|
shader: radRampShader,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uSqueeze: 1.0,
|
uSqueeze: 1.0,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
raisedCos: {
|
raisedCos: {
|
||||||
@ -221,7 +260,8 @@ export class GratingStim extends VisualStim
|
|||||||
uniforms: {
|
uniforms: {
|
||||||
uBeta: 0.25,
|
uBeta: 0.25,
|
||||||
uPeriod: 0.625,
|
uPeriod: 0.625,
|
||||||
uColor: [1., 1., 1.]
|
uColor: [1., 1., 1.],
|
||||||
|
uAlpha: 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -469,11 +509,11 @@ export class GratingStim extends VisualStim
|
|||||||
* @name module:visual.GratingStim#_getPixiMeshFromPredefinedShaders
|
* @name module:visual.GratingStim#_getPixiMeshFromPredefinedShaders
|
||||||
* @function
|
* @function
|
||||||
* @protected
|
* @protected
|
||||||
* @param {String} funcName - name of the shader function. Must be one of the SHADERS
|
* @param {String} shaderName - name of the shader. Must be one of the SHADERS
|
||||||
* @param {Object} uniforms - a set of uniforms to supply to the shader. Mixed together with default uniform values.
|
* @param {Object} uniforms - a set of uniforms to supply to the shader. Mixed together with default uniform values.
|
||||||
* @return {Pixi.Mesh} Pixi.Mesh object that represents shader and later added to the scene.
|
* @return {Pixi.Mesh} Pixi.Mesh object that represents shader and later added to the scene.
|
||||||
*/
|
*/
|
||||||
_getPixiMeshFromPredefinedShaders (funcName = "", uniforms = {}) {
|
_getPixiMeshFromPredefinedShaders (shaderName = "", uniforms = {}) {
|
||||||
const geometry = new PIXI.Geometry();
|
const geometry = new PIXI.Geometry();
|
||||||
geometry.addAttribute(
|
geometry.addAttribute(
|
||||||
"aVertexPosition",
|
"aVertexPosition",
|
||||||
@ -492,8 +532,8 @@ export class GratingStim extends VisualStim
|
|||||||
);
|
);
|
||||||
geometry.addIndex([0, 1, 2, 0, 2, 3]);
|
geometry.addIndex([0, 1, 2, 0, 2, 3]);
|
||||||
const vertexSrc = defaultQuadVert;
|
const vertexSrc = defaultQuadVert;
|
||||||
const fragmentSrc = GratingStim.#SHADERS[funcName].shader;
|
const fragmentSrc = GratingStim.#SHADERS[shaderName].shader;
|
||||||
const uniformsFinal = Object.assign({}, GratingStim.#SHADERS[funcName].uniforms, uniforms);
|
const uniformsFinal = Object.assign({}, GratingStim.#SHADERS[shaderName].uniforms, uniforms);
|
||||||
const shader = PIXI.Shader.from(vertexSrc, fragmentSrc, uniformsFinal);
|
const shader = PIXI.Shader.from(vertexSrc, fragmentSrc, uniformsFinal);
|
||||||
return new PIXI.Mesh(geometry, shader);
|
return new PIXI.Mesh(geometry, shader);
|
||||||
}
|
}
|
||||||
@ -509,9 +549,7 @@ export class GratingStim extends VisualStim
|
|||||||
setPhase (phase, log = false) {
|
setPhase (phase, log = false) {
|
||||||
this._setAttribute("phase", phase, log);
|
this._setAttribute("phase", phase, log);
|
||||||
if (this._pixi instanceof PIXI.Mesh) {
|
if (this._pixi instanceof PIXI.Mesh) {
|
||||||
this._pixi.shader.uniforms.uPhase = phase;
|
this._pixi.shader.uniforms.uPhase = -phase;
|
||||||
} else if (this._pixi instanceof PIXI.TilingSprite) {
|
|
||||||
this._pixi.tilePosition.x = -phase * (this._size_px[0] * this._pixi.tileScale.x) / (2 * Math.PI)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,8 +585,21 @@ export class GratingStim extends VisualStim
|
|||||||
this._setAttribute("color", colorObj, log);
|
this._setAttribute("color", colorObj, log);
|
||||||
if (this._pixi instanceof PIXI.Mesh) {
|
if (this._pixi instanceof PIXI.Mesh) {
|
||||||
this._pixi.shader.uniforms.uColor = colorObj.rgbFull;
|
this._pixi.shader.uniforms.uColor = colorObj.rgbFull;
|
||||||
} else if (this._pixi instanceof PIXI.TilingSprite) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines how visible the stimulus is relative to background.
|
||||||
|
*
|
||||||
|
* @name module:visual.GratingStim#setOpacity
|
||||||
|
* @public
|
||||||
|
* @param {number} [opacity=1] opacity - The value should be a single float ranging 1.0 (opaque) to 0.0 (transparent).
|
||||||
|
* @param {boolean} [log= false] - whether of not to log
|
||||||
|
*/
|
||||||
|
setOpacity (opacity = 1, log = false) {
|
||||||
|
this._setAttribute("opacity", opacity, log);
|
||||||
|
if (this._pixi instanceof PIXI.Mesh) {
|
||||||
|
this._pixi.shader.uniforms.uAlpha = opacity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,13 +615,6 @@ export class GratingStim extends VisualStim
|
|||||||
this._setAttribute("SF", sf, log);
|
this._setAttribute("SF", sf, log);
|
||||||
if (this._pixi instanceof PIXI.Mesh) {
|
if (this._pixi instanceof PIXI.Mesh) {
|
||||||
this._pixi.shader.uniforms.uFreq = sf;
|
this._pixi.shader.uniforms.uFreq = sf;
|
||||||
} else if (this._pixi instanceof PIXI.TilingSprite) {
|
|
||||||
// tileScale units are pixels, so converting function frequency to pixels
|
|
||||||
// and also taking into account possible size difference between used texture and requested stim size
|
|
||||||
this._pixi.tileScale.x = (1 / sf) * (this._pixi.width / this._pixi.texture.width);
|
|
||||||
// since most functions defined in SHADERS assume spatial frequency change along X axis
|
|
||||||
// we assume desired effect for image based stims to be the same so tileScale.y is not affected by spatialFrequency
|
|
||||||
this._pixi.tileScale.y = this._pixi.height / this._pixi.texture.height;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,11 +651,9 @@ export class GratingStim extends VisualStim
|
|||||||
*/
|
*/
|
||||||
setInterpolate (interpolate = false, log = false) {
|
setInterpolate (interpolate = false, log = false) {
|
||||||
this._setAttribute("interpolate", interpolate, log);
|
this._setAttribute("interpolate", interpolate, log);
|
||||||
if (this._pixi instanceof PIXI.Mesh) {
|
if (this._pixi instanceof PIXI.Mesh && this._pixi.shader.uniforms.uTex instanceof PIXI.Texture) {
|
||||||
|
this._pixi.shader.uniforms.uTex.baseTexture.scaleMode = interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST;
|
||||||
} else if (this._pixi instanceof PIXI.TilingSprite) {
|
this._pixi.shader.uniforms.uTex.baseTexture.update();
|
||||||
this._pixi.texture.baseTexture.scaleMode = interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST;
|
|
||||||
this._pixi.texture.baseTexture.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,6 +675,8 @@ export class GratingStim extends VisualStim
|
|||||||
if (this._needPixiUpdate)
|
if (this._needPixiUpdate)
|
||||||
{
|
{
|
||||||
this._needPixiUpdate = false;
|
this._needPixiUpdate = false;
|
||||||
|
let shaderName;
|
||||||
|
let shaderUniforms;
|
||||||
let currentUniforms = {};
|
let currentUniforms = {};
|
||||||
if (typeof this._pixi !== "undefined")
|
if (typeof this._pixi !== "undefined")
|
||||||
{
|
{
|
||||||
@ -651,25 +695,28 @@ export class GratingStim extends VisualStim
|
|||||||
|
|
||||||
if (this._tex instanceof HTMLImageElement)
|
if (this._tex instanceof HTMLImageElement)
|
||||||
{
|
{
|
||||||
this._pixi = PIXI.TilingSprite.from(this._tex, {
|
shaderName = "imageShader";
|
||||||
scaleMode: this._interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST,
|
let shaderTex = PIXI.Texture.from(this._tex, {
|
||||||
width: this._size_px[0],
|
wrapMode: PIXI.WRAP_MODES.REPEAT,
|
||||||
height: this._size_px[1]
|
scaleMode: this._interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST
|
||||||
});
|
});
|
||||||
this.setPhase(this._phase);
|
shaderUniforms = {
|
||||||
this.setSF(this._SF);
|
uTex: shaderTex,
|
||||||
|
uFreq: this._SF,
|
||||||
|
uPhase: this._phase,
|
||||||
|
uColor: this._color.rgbFull
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._pixi = this._getPixiMeshFromPredefinedShaders(
|
shaderName = this._tex;
|
||||||
this._tex,
|
shaderUniforms = {
|
||||||
Object.assign({
|
uFreq: this._SF,
|
||||||
uFreq: this._SF,
|
uPhase: this._phase,
|
||||||
uPhase: this._phase,
|
uColor: this._color.rgbFull
|
||||||
uColor: this._color.rgbFull
|
};
|
||||||
}, currentUniforms)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
this._pixi = this._getPixiMeshFromPredefinedShaders(shaderName, Object.assign(shaderUniforms, currentUniforms));
|
||||||
this._pixi.pivot.set(this._pixi.width * 0.5, this._pixi.width * 0.5);
|
this._pixi.pivot.set(this._pixi.width * 0.5, this._pixi.width * 0.5);
|
||||||
this._pixi.filters = [this._adjustmentFilter];
|
this._pixi.filters = [this._adjustmentFilter];
|
||||||
|
|
||||||
@ -712,7 +759,7 @@ export class GratingStim extends VisualStim
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._pixi.zIndex = this._depth;
|
this._pixi.zIndex = this._depth;
|
||||||
this._pixi.alpha = this.opacity;
|
this.opacity = this._opacity;
|
||||||
|
|
||||||
// set the scale:
|
// set the scale:
|
||||||
const displaySize = this._getDisplaySize();
|
const displaySize = this._getDisplaySize();
|
||||||
|
@ -17,11 +17,12 @@ out vec4 shaderOut;
|
|||||||
#define M_PI 3.14159265358979
|
#define M_PI 3.14159265358979
|
||||||
uniform float uRadius;
|
uniform float uRadius;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs;
|
||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
float s = (1. - step(uRadius, length(uv * 2. - 1.))) * 2. - 1.;
|
float s = (1. - step(uRadius, length(uv * 2. - 1.))) * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ out vec4 shaderOut;
|
|||||||
#define M_PI 3.14159265358979
|
#define M_PI 3.14159265358979
|
||||||
uniform float uThickness;
|
uniform float uThickness;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs;
|
||||||
@ -25,5 +26,5 @@ void main() {
|
|||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
float s = (1. - sx * sy) * 2. - 1.;
|
float s = (1. - sx * sy) * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ uniform float uA;
|
|||||||
uniform float uB;
|
uniform float uB;
|
||||||
uniform float uC;
|
uniform float uC;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
#define M_PI 3.14159265358979
|
#define M_PI 3.14159265358979
|
||||||
|
|
||||||
@ -29,5 +30,5 @@ void main() {
|
|||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
float g = uA * exp(-pow(x - uB, 2.) / c2 * .5) * 2. - 1.;
|
float g = uA * exp(-pow(x - uB, 2.) / c2 * .5) * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(g) * uColor * .5 + .5, 1.);
|
shaderOut = vec4(vec3(g) * uColor * .5 + .5, 1.) * uAlpha;
|
||||||
}
|
}
|
||||||
|
31
src/visual/shaders/imageShader.frag
Normal file
31
src/visual/shaders/imageShader.frag
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Image shader.
|
||||||
|
*
|
||||||
|
* @author Nikita Agafonov
|
||||||
|
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
|
||||||
|
* @license Distributed under the terms of the MIT License
|
||||||
|
* @description Renders passed in image with applied effects.
|
||||||
|
* @usedby GratingStim.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
in vec2 vUvs;
|
||||||
|
out vec4 shaderOut;
|
||||||
|
|
||||||
|
#define M_PI 3.14159265358979
|
||||||
|
uniform sampler2D uTex;
|
||||||
|
uniform float uFreq;
|
||||||
|
uniform float uPhase;
|
||||||
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = vUvs;
|
||||||
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
|
// then back to [0, 1]
|
||||||
|
vec4 s = texture(uTex, vec2(uv.x * uFreq + uPhase, uv.y));
|
||||||
|
s.xyz = s.xyz * 2. - 1.;
|
||||||
|
shaderOut = vec4(s.xyz * uColor * .5 + .5, s.a) * uAlpha;
|
||||||
|
}
|
@ -15,6 +15,7 @@ in vec2 vUvs;
|
|||||||
out vec4 shaderOut;
|
out vec4 shaderOut;
|
||||||
uniform float uSqueeze;
|
uniform float uSqueeze;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
#define M_PI 3.14159265358979
|
#define M_PI 3.14159265358979
|
||||||
|
|
||||||
@ -23,5 +24,5 @@ void main() {
|
|||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
float s = (1. - length(uv * 2. - 1.) * uSqueeze) * 2. - 1.;
|
float s = (1. - length(uv * 2. - 1.) * uSqueeze) * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ out vec4 shaderOut;
|
|||||||
uniform float uBeta;
|
uniform float uBeta;
|
||||||
uniform float uPeriod;
|
uniform float uPeriod;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs;
|
||||||
@ -35,5 +36,5 @@ void main() {
|
|||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
s = s * 2. - 1.;
|
s = s * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ out vec4 shaderOut;
|
|||||||
uniform float uFreq;
|
uniform float uFreq;
|
||||||
uniform float uPhase;
|
uniform float uPhase;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs;
|
||||||
@ -26,5 +27,5 @@ void main() {
|
|||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
s = mod(s, 1.) * 2. - 1.;
|
s = mod(s, 1.) * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,11 @@ out vec4 shaderOut;
|
|||||||
uniform float uFreq;
|
uniform float uFreq;
|
||||||
uniform float uPhase;
|
uniform float uPhase;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs - .25;
|
||||||
float s = sin((uFreq * uv.x + uPhase) * 2. * M_PI);
|
float s = sin((uFreq * uv.x + uPhase) * 2. * M_PI);
|
||||||
// it's important to convert to [0, 1] while multiplication to uColor, not before, to preserve desired coloring functionality
|
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,13 @@ out vec4 shaderOut;
|
|||||||
uniform float uFreq;
|
uniform float uFreq;
|
||||||
uniform float uPhase;
|
uniform float uPhase;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vec2(vUvs.x - .25, vUvs.y * -1. - .25);
|
||||||
float sx = sin((uFreq * uv.x + uPhase) * PI2);
|
float sx = sin((uFreq * uv.x + uPhase) * PI2);
|
||||||
float sy = sin((uFreq * uv.y + uPhase) * PI2);
|
float sy = sin((uFreq * uv.y + uPhase) * PI2);
|
||||||
float s = sx * sy;
|
float s = sx * sy;
|
||||||
// it's important to convert to [0, 1] while multiplication to uColor, not before, to preserve desired coloring functionality
|
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,11 @@ out vec4 shaderOut;
|
|||||||
uniform float uFreq;
|
uniform float uFreq;
|
||||||
uniform float uPhase;
|
uniform float uPhase;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs - .25;
|
||||||
float s = sign(sin((uFreq * uv.x + uPhase) * 2. * M_PI));
|
float s = sign(sin((uFreq * uv.x + uPhase) * 2. * M_PI));
|
||||||
// it's important to convert to [0, 1] while multiplication to uColor, not before, to preserve desired coloring functionality
|
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,13 @@ out vec4 shaderOut;
|
|||||||
uniform float uFreq;
|
uniform float uFreq;
|
||||||
uniform float uPhase;
|
uniform float uPhase;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vec2(vUvs.x - .25, vUvs.y * -1. - .25);
|
||||||
float sx = sign(sin((uFreq * uv.x + uPhase) * PI2));
|
float sx = sign(sin((uFreq * uv.x + uPhase) * PI2));
|
||||||
float sy = sign(sin((uFreq * uv.y + uPhase) * PI2));
|
float sy = sign(sin((uFreq * uv.y + uPhase) * PI2));
|
||||||
float s = sx * sy;
|
float s = sx * sy;
|
||||||
// it's important to convert to [0, 1] while multiplication to uColor, not before, to preserve desired coloring functionality
|
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ uniform float uFreq;
|
|||||||
uniform float uPhase;
|
uniform float uPhase;
|
||||||
uniform float uPeriod;
|
uniform float uPeriod;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
|
uniform float uAlpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = vUvs;
|
vec2 uv = vUvs;
|
||||||
@ -27,5 +28,5 @@ void main() {
|
|||||||
// converting first to [-1, 1] space to get the proper color functionality
|
// converting first to [-1, 1] space to get the proper color functionality
|
||||||
// then back to [0, 1]
|
// then back to [0, 1]
|
||||||
s = (2. * abs(s / uPeriod - floor(s / uPeriod + .5))) * 2. - 1.;
|
s = (2. * abs(s / uPeriod - floor(s / uPeriod + .5))) * 2. - 1.;
|
||||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user