Closed jo-hnny closed 4 years ago
Sorry about the slow response. I haven't forgotten! Expect an answer from me early next week.
@johnny19941216 You should be able to achieve this with the TransitionNode
. If you write your own shader, then you can specify a single image input and adjust the effect to any property defined in customDescription.properties
, e.g. the mix
property populated by the TransitionNode
.
Here is an example - essentially the TransitionNode and EffectNode examples merged - where a single image is transitioned from its default colour to sepia:
// This an unmodified copy of the `TransitionNode` example vertexShader
const vertexShader = `
attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main() {
gl_Position = vec4(vec2(2.0,2.0)*a_position-vec2(1.0, 1.0), 0.0, 1.0);
v_texCoord = a_texCoord;
}`;
/**
* This is the `EffectNode` and `TransitionNode` `fragmentShader` examples merged,
* where a single input (`u_image`) is transitioned to sepia using the `mix`
* property provided by the `transitionNode`.
*/
const fragmentShader = `
precision mediump float;
uniform sampler2D u_image;
uniform float mix;
uniform vec3 inputMix;
uniform vec3 outputMix;
varying vec2 v_texCoord;
varying float v_mix;
void main(){
vec4 color_a = texture2D(u_image, v_texCoord);
vec4 color_b = texture2D(u_image, v_texCoord);
float mono = color_b[0]*inputMix[0] + color_b[1]*inputMix[1] + color_b[2]*inputMix[2];
color_b[0] = mono * outputMix[0];
color_b[1] = mono * outputMix[1];
color_b[2] = mono * outputMix[2];
color_a[0] *= (1.0 - mix);
color_a[1] *= (1.0 - mix);
color_a[2] *= (1.0 - mix);
color_a[3] *= (1.0 - mix);
color_b[0] *= mix;
color_b[1] *= mix;
color_b[2] *= mix;
color_b[3] *= mix;
gl_FragColor = color_a + color_b;
}`;
var customDescription = {
title: "Time-Based-Transition",
description: "Transition from normal to sepia.",
vertexShader,
fragmentShader,
properties: {
mix: { type: "uniform", value: 0.0 },
inputMix: { type: "uniform", value: [0.4, 0.6, 0.2] },
outputMix: { type: "uniform", value: [1.0, 1.0, 1.0] }
},
inputs: ["u_image"]
};
// Setup the video context
var canvas = document.getElementById("canvas");
var ctx = new VideoContext(canvas);
// Create an image node that plays for 5 seconds
var imageNode = ctx.image("https://source.unsplash.com/random/1280x720");
imageNode.start(0);
imageNode.stop(5);
// Create the effect node
var customEffect = ctx.transition(customDescription);
// Give a sepia tint to the monochrome output (note how shader description properties are automatically bound to the JavaScript object).
customEffect.outputMix = [1.25, 1.18, 0.9];
/**
* Setup the transition. This will change the "mix" property of the node from 0.0 to 1.0.
* Transition mix value from 0.0 to 1.0 at time = 1 over a period of 3 seconds to time = 4.
*/
customEffect.transition(1.0, 4.0, 0.0, 1.0, "mix");
// Connect videoNode to the "image_u" input of the processing node
imageNode.connect(customEffect);
customEffect.connect(ctx.destination);
// Start playback
ctx.play();
CodeSandbox: https://codesandbox.io/embed/tender-meitner-edmxo
I want to generate a special effect that changes over time. and only one image input