1
0
mirror of https://github.com/psychopy/psychojs.git synced 2025-05-10 18:50:54 +00:00

wgl1 shaders for gratingStim;

This commit is contained in:
lgtst 2022-10-06 19:40:31 +01:00
parent 24c08055a0
commit 8eee61cf4e
15 changed files with 550 additions and 3 deletions

View File

@ -28,6 +28,21 @@ import radRampShader from "./shaders/radRampShader.frag";
import raisedCosShader from "./shaders/raisedCosShader.frag";
import radialStim from "./shaders/radialShader.frag";
import defaultQuadVertWGL1 from "./shaders/wgl1/defaultQuad.vert";
import imageShaderWGL1 from "./shaders/wgl1/imageShader.frag";
import sinShaderWGL1 from "./shaders/wgl1/sinShader.frag";
import sqrShaderWGL1 from "./shaders/wgl1/sqrShader.frag";
import sawShaderWGL1 from "./shaders/wgl1/sawShader.frag";
import triShaderWGL1 from "./shaders/wgl1/triShader.frag";
import sinXsinShaderWGL1 from "./shaders/wgl1/sinXsinShader.frag";
import sqrXsqrShaderWGL1 from "./shaders/wgl1/sqrXsqrShader.frag";
import circleShaderWGL1 from "./shaders/wgl1/circleShader.frag";
import gaussShaderWGL1 from "./shaders/wgl1/gaussShader.frag";
import crossShaderWGL1 from "./shaders/wgl1/crossShader.frag";
import radRampShaderWGL1 from "./shaders/wgl1/radRampShader.frag";
import raisedCosShaderWGL1 from "./shaders/wgl1/raisedCosShader.frag";
import radialStimWGL1 from "./shaders/wgl1/radialShader.frag";
/**
* Grating Stimulus.
*
@ -253,6 +268,125 @@ export class GratingStim extends VisualStim
}
};
static #SHADERSWGL1 = {
imageShader: {
shader: imageShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
sin: {
shader: sinShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
sqr: {
shader: sqrShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
saw: {
shader: sawShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
tri: {
shader: triShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uPeriod: 1.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
sinXsin: {
shader: sinXsinShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
sqrXsqr: {
shader: sqrXsqrShaderWGL1,
uniforms: {
uFreq: 1.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
circle: {
shader: circleShaderWGL1,
uniforms: {
uRadius: 1.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
gauss: {
shader: gaussShaderWGL1,
uniforms: {
uA: 1.0,
uB: 0.0,
uC: 0.16,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
cross: {
shader: crossShaderWGL1,
uniforms: {
uThickness: 0.2,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
radRamp: {
shader: radRampShaderWGL1,
uniforms: {
uSqueeze: 1.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
raisedCos: {
shader: raisedCosShaderWGL1,
uniforms: {
uBeta: 0.25,
uPeriod: 0.625,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
},
radialStim: {
shader: radialStimWGL1,
uniforms: {
uFreq: 20.0,
uPhase: 0.0,
uColor: [1., 1., 1.],
uAlpha: 1.0
}
}
};
/**
* Default size of the Grating Stimuli in pixels.
*
@ -533,9 +667,21 @@ export class GratingStim extends VisualStim
2
);
geometry.addIndex([0, 1, 2, 0, 2, 3]);
const vertexSrc = defaultQuadVert;
const fragmentSrc = GratingStim.#SHADERS[shaderName].shader;
const uniformsFinal = Object.assign({}, GratingStim.#SHADERS[shaderName].uniforms, uniforms);
let vertexSrc;
let fragmentSrc;
let uniformsFinal;
if (this._win._renderer.context.webGLVersion >= 2)
{
vertexSrc = defaultQuadVert;
fragmentSrc = GratingStim.#SHADERS[shaderName].shader;
uniformsFinal = Object.assign({}, GratingStim.#SHADERS[shaderName].uniforms, uniforms);
}
else
{
vertexSrc = defaultQuadVertWGL1;
fragmentSrc = GratingStim.#SHADERSWGL1[shaderName].shader;
uniformsFinal = Object.assign({}, GratingStim.#SHADERSWGL1[shaderName].uniforms, uniforms);
}
const shader = PIXI.Shader.from(vertexSrc, fragmentSrc, uniformsFinal);
return new PIXI.Mesh(geometry, shader);
}

View File

@ -0,0 +1,26 @@
/**
* Circle Shape.
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates a filled circle shape with sharp edges.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uRadius;
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]
float s = (1. - step(uRadius, length(uv * 2. - 1.))) * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,28 @@
/**
* Cross Shape.
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates a filled cross shape with sharp edges.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uThickness;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vUvs;
float sx = step(uThickness, length(uv.x * 2. - 1.));
float sy = step(uThickness, length(uv.y * 2. - 1.));
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
float s = (1. - sx * sy) * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,13 @@
precision mediump float;
attribute vec2 aVertexPosition;
attribute vec2 aUvs;
varying vec2 vUvs;
uniform mat3 translationMatrix;
uniform mat3 projectionMatrix;
void main() {
vUvs = aUvs;
gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
}

View File

@ -0,0 +1,32 @@
/**
* Gaussian Function.
* https://en.wikipedia.org/wiki/Gaussian_function
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates a 2d Gaussian image as if 1d Gaussian graph was rotated arount Y axis and observed from above.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
uniform float uA;
uniform float uB;
uniform float uC;
uniform vec3 uColor;
uniform float uAlpha;
#define M_PI 3.14159265358979
void main() {
vec2 uv = vUvs;
float c2 = uC * uC;
float x = length(uv - .5);
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
float g = uA * exp(-pow(x - uB, 2.) / c2 * .5) * 2. - 1.;
gl_FragColor = vec4(vec3(g) * uColor * .5 + .5, 1.) * uAlpha;
}

View File

@ -0,0 +1,29 @@
/**
* 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
*/
precision mediump float;
varying vec2 vUvs;
#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 = texture2D(uTex, vec2(uv.x * uFreq + uPhase, uv.y));
s.xyz = s.xyz * 2. - 1.;
gl_FragColor = vec4(s.xyz * uColor * .5 + .5, s.a) * uAlpha;
}

View File

@ -0,0 +1,27 @@
/**
* Radial Ramp.
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d radial ramp image.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
uniform float uSqueeze;
uniform vec3 uColor;
uniform float uAlpha;
#define M_PI 3.14159265358979
void main() {
vec2 uv = vUvs;
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
float s = (1. - length(uv * 2. - 1.) * uSqueeze) * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,35 @@
/**
* Radial grating.
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d radial grating image. Based on https://www.shadertoy.com/view/wtjGzt
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
uniform float uFreq;
uniform float uPhase;
uniform vec3 uColor;
uniform float uAlpha;
#define M_PI 3.14159265358979
#define PI2 2.* M_PI
float aastep(float x) { // --- antialiased step(.5)
float w = fwidth(x); // pixel width. NB: x must not be discontinuous or factor discont out
return smoothstep(.7,-.7,(abs(fract(x-.25)-.5)-.25)/w); // just use (offseted) smooth squares
}
void main() {
vec2 uv = vUvs * 2. - 1.;
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
float v = uFreq * atan(uv.y, uv.x) / 6.28;
float s = aastep(v) * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,38 @@
/**
* Raised-cosine.
* https://en.wikipedia.org/wiki/Raised-cosine_filter
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d raised-cosine image as if 1d raised-cosine graph was rotated around Y axis and observed from above.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uBeta;
uniform float uPeriod;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vUvs;
float absX = length(uv * 2. - 1.);
float edgeArgument1 = (1. - uBeta) / (2. * uPeriod);
float edgeArgument2 = (1. + uBeta) / (2. * uPeriod);
float frequencyFactor = (M_PI * uPeriod) / uBeta;
float s = .5 * (1. + cos(frequencyFactor * (absX - edgeArgument1)));
if (absX <= edgeArgument1) {
s = 1.;
} else if (absX > edgeArgument2) {
s = 0.;
}
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
s = s * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,29 @@
/**
* Sawtooth wave.
* https://en.wikipedia.org/wiki/Sawtooth_wave
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d sawtooth wave image as if 1d sawtooth graph was extended across Z axis and observed from above.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uFreq;
uniform float uPhase;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vUvs;
float s = uFreq * uv.x + uPhase;
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
s = mod(s, 1.) * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,27 @@
/**
* Sine wave.
* https://en.wikipedia.org/wiki/Sine_wave
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d sine wave image as if 1d sine graph was extended across Z axis and observed from above.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uFreq;
uniform float uPhase;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vUvs - .25;
float s = sin((uFreq * uv.x + uPhase) * 2. * M_PI);
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,30 @@
/**
* Sine wave multiplied by another sine wave.
* https://en.wikipedia.org/wiki/Sine_wave
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates an image of two 2d sine waves multiplied with each other.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
#define PI2 2.* M_PI
uniform float uFreq;
uniform float uPhase;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vec2(vUvs.x - .25, vUvs.y * -1. - .25);
float sx = sin((uFreq * uv.x + uPhase) * PI2);
float sy = sin((uFreq * uv.y + uPhase) * PI2);
float s = sx * sy;
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,27 @@
/**
* Square wave.
* https://en.wikipedia.org/wiki/Square_wave
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d square wave image as if 1d square graph was extended across Z axis and observed from above.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uFreq;
uniform float uPhase;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vUvs - .25;
float s = sign(sin((uFreq * uv.x + uPhase) * 2. * M_PI));
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,30 @@
/**
* Square wave multiplied by another square wave.
* https://en.wikipedia.org/wiki/Square_wave
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates an image of two 2d square waves multiplied with each other.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
#define PI2 2.* M_PI
uniform float uFreq;
uniform float uPhase;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vec2(vUvs.x - .25, vUvs.y * -1. - .25);
float sx = sign(sin((uFreq * uv.x + uPhase) * PI2));
float sy = sign(sin((uFreq * uv.y + uPhase) * PI2));
float s = sx * sy;
// it's important to convert to [0, 1] while multiplying to uColor, not before, to preserve desired coloring functionality
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}

View File

@ -0,0 +1,30 @@
/**
* Triangle wave.
* https://en.wikipedia.org/wiki/Triangle_wave
*
* @author Nikita Agafonov
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
* @license Distributed under the terms of the MIT License
* @description Creates 2d triangle wave image as if 1d triangle graph was extended across Z axis and observed from above.
* @usedby GratingStim.js
*/
precision mediump float;
varying vec2 vUvs;
#define M_PI 3.14159265358979
uniform float uFreq;
uniform float uPhase;
uniform float uPeriod;
uniform vec3 uColor;
uniform float uAlpha;
void main() {
vec2 uv = vUvs;
float s = uFreq * uv.x + uPhase;
// converting first to [-1, 1] space to get the proper color functionality
// then back to [0, 1]
s = (2. * abs(s / uPeriod - floor(s / uPeriod + .5))) * 2. - 1.;
gl_FragColor = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
}