mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
added coloring support for image based Gratings; added proper opacity support;
This commit is contained in:
parent
49e645f280
commit
51d57083a3
@ -14,6 +14,7 @@ import { to_pixiPoint } from "../util/Pixi.js";
|
||||
import * as util from "../util/Util.js";
|
||||
import { VisualStim } from "./VisualStim.js";
|
||||
import defaultQuadVert from "./shaders/defaultQuad.vert";
|
||||
import imageShader from "./shaders/imageShader.frag";
|
||||
import sinShader from "./shaders/sinShader.frag";
|
||||
import sqrShader from "./shaders/sqrShader.frag";
|
||||
import sawShader from "./shaders/sawShader.frag";
|
||||
@ -60,6 +61,13 @@ export class GratingStim extends VisualStim
|
||||
* Shader source code is later used for construction of shader programs to create respective visual stimuli.
|
||||
* @name module:visual.GratingStim.#SHADERS
|
||||
* @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 {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}
|
||||
* @property {String} sin.shader - shader source code for the sine wave stimuli
|
||||
@ -137,12 +145,22 @@ export class GratingStim extends VisualStim
|
||||
* @property {float} raisedCos.uniforms.uPeriod=0.625 - reciprocal of the symbol-rate (see link).
|
||||
*/
|
||||
static #SHADERS = {
|
||||
imageShader: {
|
||||
shader: imageShader,
|
||||
uniforms: {
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
sin: {
|
||||
shader: sinShader,
|
||||
uniforms: {
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
sqr: {
|
||||
@ -150,7 +168,8 @@ export class GratingStim extends VisualStim
|
||||
uniforms: {
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
saw: {
|
||||
@ -158,7 +177,8 @@ export class GratingStim extends VisualStim
|
||||
uniforms: {
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
tri: {
|
||||
@ -167,7 +187,8 @@ export class GratingStim extends VisualStim
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uPeriod: 1.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
sinXsin: {
|
||||
@ -175,7 +196,8 @@ export class GratingStim extends VisualStim
|
||||
uniforms: {
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
sqrXsqr: {
|
||||
@ -183,14 +205,16 @@ export class GratingStim extends VisualStim
|
||||
uniforms: {
|
||||
uFreq: 1.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
circle: {
|
||||
shader: circleShader,
|
||||
uniforms: {
|
||||
uRadius: 1.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
gauss: {
|
||||
@ -199,21 +223,24 @@ export class GratingStim extends VisualStim
|
||||
uA: 1.0,
|
||||
uB: 0.0,
|
||||
uC: 0.16,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
cross: {
|
||||
shader: crossShader,
|
||||
uniforms: {
|
||||
uThickness: 0.2,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
radRamp: {
|
||||
shader: radRampShader,
|
||||
uniforms: {
|
||||
uSqueeze: 1.0,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
raisedCos: {
|
||||
@ -221,7 +248,8 @@ export class GratingStim extends VisualStim
|
||||
uniforms: {
|
||||
uBeta: 0.25,
|
||||
uPeriod: 0.625,
|
||||
uColor: [1., 1., 1.]
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -469,11 +497,11 @@ export class GratingStim extends VisualStim
|
||||
* @name module:visual.GratingStim#_getPixiMeshFromPredefinedShaders
|
||||
* @function
|
||||
* @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.
|
||||
* @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();
|
||||
geometry.addAttribute(
|
||||
"aVertexPosition",
|
||||
@ -492,8 +520,8 @@ export class GratingStim extends VisualStim
|
||||
);
|
||||
geometry.addIndex([0, 1, 2, 0, 2, 3]);
|
||||
const vertexSrc = defaultQuadVert;
|
||||
const fragmentSrc = GratingStim.#SHADERS[funcName].shader;
|
||||
const uniformsFinal = Object.assign({}, GratingStim.#SHADERS[funcName].uniforms, uniforms);
|
||||
const fragmentSrc = GratingStim.#SHADERS[shaderName].shader;
|
||||
const uniformsFinal = Object.assign({}, GratingStim.#SHADERS[shaderName].uniforms, uniforms);
|
||||
const shader = PIXI.Shader.from(vertexSrc, fragmentSrc, uniformsFinal);
|
||||
return new PIXI.Mesh(geometry, shader);
|
||||
}
|
||||
@ -509,9 +537,7 @@ export class GratingStim extends VisualStim
|
||||
setPhase (phase, log = false) {
|
||||
this._setAttribute("phase", phase, log);
|
||||
if (this._pixi instanceof PIXI.Mesh) {
|
||||
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)
|
||||
this._pixi.shader.uniforms.uPhase = -phase;
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,8 +573,21 @@ export class GratingStim extends VisualStim
|
||||
this._setAttribute("color", colorObj, log);
|
||||
if (this._pixi instanceof PIXI.Mesh) {
|
||||
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 +603,6 @@ export class GratingStim extends VisualStim
|
||||
this._setAttribute("SF", sf, log);
|
||||
if (this._pixi instanceof PIXI.Mesh) {
|
||||
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,12 +639,11 @@ export class GratingStim extends VisualStim
|
||||
*/
|
||||
setInterpolate (interpolate = false, log = false) {
|
||||
this._setAttribute("interpolate", interpolate, log);
|
||||
if (this._pixi instanceof PIXI.Mesh) {
|
||||
|
||||
} else if (this._pixi instanceof PIXI.TilingSprite) {
|
||||
this._pixi.texture.baseTexture.scaleMode = interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST;
|
||||
this._pixi.texture.baseTexture.update();
|
||||
if (this._pixi === undefined || !this._pixi.shader.uniforms.uTex) {
|
||||
return;
|
||||
}
|
||||
this._pixi.shader.uniforms.uTex.baseTexture.scaleMode = interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST;
|
||||
this._pixi.shader.uniforms.uTex.baseTexture.update();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -633,6 +664,8 @@ export class GratingStim extends VisualStim
|
||||
if (this._needPixiUpdate)
|
||||
{
|
||||
this._needPixiUpdate = false;
|
||||
let shaderName;
|
||||
let shaderUniforms;
|
||||
let currentUniforms = {};
|
||||
if (typeof this._pixi !== "undefined")
|
||||
{
|
||||
@ -651,25 +684,28 @@ export class GratingStim extends VisualStim
|
||||
|
||||
if (this._tex instanceof HTMLImageElement)
|
||||
{
|
||||
this._pixi = PIXI.TilingSprite.from(this._tex, {
|
||||
scaleMode: this._interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST,
|
||||
width: this._size_px[0],
|
||||
height: this._size_px[1]
|
||||
shaderName = "imageShader";
|
||||
let shaderTex = PIXI.Texture.from(this._tex, {
|
||||
wrapMode: PIXI.WRAP_MODES.REPEAT,
|
||||
scaleMode: this._interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST
|
||||
});
|
||||
this.setPhase(this._phase);
|
||||
this.setSF(this._SF);
|
||||
shaderUniforms = {
|
||||
uTex: shaderTex,
|
||||
uFreq: this._SF,
|
||||
uPhase: this._phase,
|
||||
uColor: this._color.rgbFull
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
this._pixi = this._getPixiMeshFromPredefinedShaders(
|
||||
this._tex,
|
||||
Object.assign({
|
||||
uFreq: this._SF,
|
||||
uPhase: this._phase,
|
||||
uColor: this._color.rgbFull
|
||||
}, currentUniforms)
|
||||
);
|
||||
shaderName = this._tex;
|
||||
shaderUniforms = {
|
||||
uFreq: this._SF,
|
||||
uPhase: this._phase,
|
||||
uColor: this._color.rgbFull
|
||||
};
|
||||
}
|
||||
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.filters = [this._adjustmentFilter];
|
||||
|
||||
@ -712,7 +748,7 @@ export class GratingStim extends VisualStim
|
||||
}
|
||||
|
||||
this._pixi.zIndex = this._depth;
|
||||
this._pixi.alpha = this.opacity;
|
||||
this.opacity = this._opacity;
|
||||
|
||||
// set the scale:
|
||||
const displaySize = this._getDisplaySize();
|
||||
|
@ -17,11 +17,12 @@ out vec4 shaderOut;
|
||||
#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.;
|
||||
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
|
||||
uniform float uThickness;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
@ -25,5 +26,5 @@ void main() {
|
||||
// converting first to [-1, 1] space to get the proper color functionality
|
||||
// then back to [0, 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 uC;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
#define M_PI 3.14159265358979
|
||||
|
||||
@ -29,5 +30,5 @@ void main() {
|
||||
// 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.;
|
||||
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;
|
||||
uniform float uSqueeze;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
#define M_PI 3.14159265358979
|
||||
|
||||
@ -23,5 +24,5 @@ void main() {
|
||||
// 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.;
|
||||
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 uPeriod;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
@ -35,5 +36,5 @@ void main() {
|
||||
// converting first to [-1, 1] space to get the proper color functionality
|
||||
// then back to [0, 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 uPhase;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
@ -26,5 +27,5 @@ void main() {
|
||||
// converting first to [-1, 1] space to get the proper color functionality
|
||||
// then back to [0, 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 uPhase;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
vec2 uv = vUvs - .25;
|
||||
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
|
||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
||||
// 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) * uAlpha;
|
||||
}
|
||||
|
@ -20,12 +20,13 @@ out vec4 shaderOut;
|
||||
uniform float uFreq;
|
||||
uniform float uPhase;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
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 multiplication to uColor, not before, to preserve desired coloring functionality
|
||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
||||
// 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) * uAlpha;
|
||||
}
|
||||
|
@ -19,10 +19,11 @@ out vec4 shaderOut;
|
||||
uniform float uFreq;
|
||||
uniform float uPhase;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
vec2 uv = vUvs - .25;
|
||||
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
|
||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
||||
// 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) * uAlpha;
|
||||
}
|
||||
|
@ -20,12 +20,13 @@ out vec4 shaderOut;
|
||||
uniform float uFreq;
|
||||
uniform float uPhase;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
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 sy = sign(sin((uFreq * uv.y + uPhase) * PI2));
|
||||
float s = sx * sy;
|
||||
// it's important to convert to [0, 1] while multiplication to uColor, not before, to preserve desired coloring functionality
|
||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0);
|
||||
// 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) * uAlpha;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ uniform float uFreq;
|
||||
uniform float uPhase;
|
||||
uniform float uPeriod;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs;
|
||||
@ -27,5 +28,5 @@ void main() {
|
||||
// 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.;
|
||||
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