Commit 77367906 authored by Gaëtan Renaudeau's avatar Gaëtan Renaudeau

more transitions from glsl-transitions

parent c749a382
## Run the example
```
npm install
```
Then open AdvancedEffects.xcodeproj with XCode and run the application.
## Developing with the example
```
npm install react-native
npm install ../.. # everytime the lib code changes
```
(also make sure a `npm install` has been called on the root directory of gl-react-native).
......@@ -31,7 +31,7 @@
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://192.168.0.26:8081/index.ios.bundle"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"];
/**
* OPTION 2
......@@ -43,7 +43,7 @@
* see http://facebook.github.io/react-native/docs/runningondevice.html
*/
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
//jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"AdvancedEffects"
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6,8 +6,9 @@
"start": "node_modules/react-native/packager/packager.sh"
},
"dependencies": {
"react-native": "^0.9.0",
"gl-react-native": "0.0.x"
"gl-react-native": "0.0.x",
"glsl-transitions": "^2015.8.17",
"react-native": "^0.9.0"
},
"devDependencies": {
"eslint": "^1.1.0",
......
......@@ -46,13 +46,13 @@ class Intro extends React.Component {
opaque={false}
uniforms={{
time: time,
freq: 12 - 9 * Math.sin(time / 7),
amp: 0.04 - 0.03 * Math.cos(time / 4),
freq: 20 - 14 * Math.sin(time / 7),
amp: 0.05 - 0.03 * Math.cos(time / 4),
colorSeparation: 0.02,
moving: 1
}}>
<GL.Target uniform="texture" style={{ justifyContent: "center" }}>
<Text style={{ color: "#00BDF3", fontSize: 24, letterSpacing: -2.0 }}>
<Text style={{ color: "#00BDF3", fontSize: 32, letterSpacing: -1.0 }}>
GL REACT NATIVE
</Text>
<View style={{ flex: 1, flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
......
const React = require("react-native");
const GL = require("gl-react-native");
const TransitionGenerator = require("./TransitionGenerator");
const Transition = require("./Transition");
const shaders = GL.Shaders.create({
transitionDirectionalWipe: {
frag: `
precision highp float;
varying vec2 uv;
uniform sampler2D from;
uniform sampler2D to;
uniform float progress;
uniform vec2 direction;
uniform float smoothness;
const vec2 center = vec2(0.5, 0.5);
void main() {
vec2 v = normalize(direction);
v /= abs(v.x)+abs(v.y);
float d = v.x * center.x + v.y * center.y;
float m = smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d-0.5+progress*(1.+smoothness)));
gl_FragColor = mix(texture2D(to, uv), texture2D(from, uv), m);
}
`
},
transitionRandomSquares: {
frag: `
precision highp float;
varying vec2 uv;
uniform sampler2D from;
uniform sampler2D to;
uniform float progress;
uniform ivec2 size;
uniform float smoothness;
float rand (vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main() {
float r = rand(floor(vec2(size) * uv));
float m = smoothstep(0.0, -smoothness, r - (progress * (1.0 + smoothness)));
gl_FragColor = mix(texture2D(from, uv), texture2D(to, uv), m);
}
`
},
transitionWind: {
frag: `
precision highp float;
varying vec2 uv;
uniform sampler2D from, to;
uniform float progress;
uniform float size;
float rand (vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main() {
float r = rand(vec2(0, uv.y));
float m = smoothstep(0.0, -size, uv.x*(1.0-size) + size*r - (progress * (1.0 + size)));
gl_FragColor = mix(texture2D(from, uv), texture2D(to, uv), m);
}
`
}
});
const shaders = GL.Shaders.create(TransitionGenerator.shaders);
class Slideshow extends React.Component {
constructor (props) {
super(props);
this._currentTransition = -1;
}
render () {
const { duration, width, height, time, images } = this.props;
const slide = time / duration;
......@@ -70,7 +17,18 @@ class Slideshow extends React.Component {
let transitionFrom = images[Math.floor(slide) % images.length];
let transitionTo = images[Math.floor(slide+1) % images.length];
let transitionShader, transitionUniforms;
const currentTransition = Math.floor(slide);
if (currentTransition !== this._currentTransition) {
this._currentTransition = currentTransition;
const { name, uniforms } = TransitionGenerator.random();
this._shader = shaders[name];
this._uniforms = uniforms;
}
const transitionShader = this._shader;
const transitionUniforms = this._uniforms;
/*
switch (Math.floor(slide/4) % 3) {
case 0:
transitionShader = shaders.transitionRandomSquares;
......@@ -94,6 +52,7 @@ class Slideshow extends React.Component {
};
break;
}
*/
return <Transition
width={width}
......
......@@ -4,6 +4,7 @@ const GL = require("gl-react-native");
class Transition extends React.Component {
render () {
const { width, height, shader, progress, from, to, uniforms } = this.props;
const scale = React.PixelRatio.get();
return <GL.View
shader={shader}
style={{ width, height }}
......@@ -12,7 +13,8 @@ class Transition extends React.Component {
progress,
from,
to,
...uniforms
...uniforms,
resolution: [ width * scale, height * scale ]
}}
/>;
}
......
const GlslTransitions = require("glsl-transitions");
const byName = {};
GlslTransitions.forEach(function (t) {
byName[t.name] = t;
});
const transitions = [
[ "cube", function () {
return { persp: 0.9 - Math.random()*Math.random(), unzoom: Math.random()*Math.random() };
} ],
"undulating burn out",
[ "CrossZoom", function () {
return { strength: 0.5 * Math.random() };
} ],
"glitch displace",
"crosshatch",
"PageCurl",
[ "Mosaic", function () {
const dx = Math.round(Math.random() * 6 - 3), dy = Math.round(Math.random() * 6 - 3);
if (dx===0 && dy===0) dy = -1;
return { endx: dx, endy: dy };
} ],
[ "DoomScreenTransition", function () {
return {
barWidth: Math.round(6 + 20 * Math.random()),
amplitude: 2 * Math.random(),
noise: 0.5 * Math.random(),
frequency: Math.random()
};
} ],
[ "colourDistance", function () {
return { interpolationPower: 6 * Math.random() };
} ],
[ "swap", function () {
return { depth: 1 + 4 * Math.random(), perspective: 0.9 + Math.random() * Math.random() };
} ],
[ "doorway", function () {
return { perspective: Math.random() * Math.random(), depth: 1 + 10 * Math.random() * Math.random() };
} ],
"Star Wipe",
"pinwheel",
[ "Slide", function () {
const choices = [
{ translateX: 0, translateY: -1 },
{ translateX: 0, translateY: 1 },
{ translateX: -1, translateY: 0 },
{ translateX: 1, translateY: 0 }
];
return choices[Math.floor(choices.length * Math.random())];
} ],
"SimpleFlip",
"TilesScanline",
"Dreamy",
"Swirl",
"HSVfade",
[ "burn", function () {
return { color: [0,0,0].map(Math.random) };
} ],
"Radial",
[ "ripple", function () {
return {
amplitude: 200 * Math.random(),
speed: 200 * Math.random()
};
} ],
"morph",
["ButterflyWaveScrawler", function () {
return {
amplitude: Math.random(),
waves: 100 * Math.random() * Math.random(),
colorSeparation: 0.8 * Math.random() * Math.random()
};
} ],
[ "flash", function () {
return { flashIntensity: 4 * Math.random() };
} ],
[ "randomsquares", function () {
const size = Math.round(4 + 30 * Math.random());
return {
size: [ size, size ],
smoothness: Math.random()
};
} ],
[ "flyeye", function () {
return {
size: Math.random() * Math.random(),
zoom: 200 * Math.random() * Math.random(),
colorSeparation: 0.8 * Math.random() * Math.random()
};
} ],
"squeeze",
[ "directionalwipe", function () {
const angle = Math.random() * 2 * Math.PI;
return {
direction: [ Math.cos(angle), Math.sin(angle) ]
};
} ],
"circleopen",
[ "wind", function () {
return { size: 0.5 * Math.random() };
} ],
[ "fadecolor", function () {
return { color: [0,0,0].map(Math.random) };
} ]
].map(function (obj) {
let name, genUniforms;
if (typeof obj === "string")
name = obj;
else {
name = obj[0];
genUniforms = obj[1];
}
if (!(name in byName)) throw new Error("no transition called "+name);
const t = byName[name];
return {
transition: t,
name: name,
genUniforms: function () {
return genUniforms ? {
...t.uniforms,
...genUniforms()
} : t.uniforms;
}
};
});
function random () {
const i = Math.floor(Math.random() * transitions.length);
const t = transitions[i];
const uniforms = t.genUniforms && t.genUniforms() || {};
return {
name: t.name,
uniforms: uniforms
};
}
const shaders = {};
transitions.forEach(function (o) {
shaders[o.name] = { frag: o.transition.glsl };
});
module.exports = {
shaders: shaders,
random: random
};
......@@ -10,25 +10,29 @@ varying vec2 uv;
uniform float time;
uniform float amp;
uniform float freq;
uniform float colorSeparation;
uniform sampler2D texture;
uniform float moving;
const vec2 center = vec2(0.5);
uniform vec2 finger;
vec2 lookup (vec2 offset) {
vec2 lookup (vec2 offset, float amp2) {
return mod(
uv + amp * vec2(cos(freq*(uv.x+offset.x)+time),sin(freq*(uv.y+offset.x)+time)) + vec2(moving * time/10.0, 0.0),
uv + amp2 * amp * vec2(cos(freq*(uv.x+offset.x)+time),sin(freq*(uv.y+offset.x)+time)) + vec2(moving * time/10.0, 0.0),
vec2(1.0));
}
void main() {
float dist = distance(uv, finger);
float amp2 = pow(1.0 - dist, 2.0);
float colorSeparation = 0.1 * amp2;
float a = atan(uv.y-finger.y, uv.x-finger.x);
vec2 delta = vec2(cos(a), sin(a));
gl_FragColor = vec4(
vec3(
texture2D(texture, lookup(vec2(colorSeparation))).r,
texture2D(texture, lookup(vec2(-colorSeparation))).g,
texture2D(texture, lookup(vec2(0.0))).b),
1.0-min(1.0, pow(1.9 * distance(uv, center), 4.0) + 0.5 * pow(distance(fract(50.0 * uv.y), 0.5), 2.0)));
texture2D(texture, lookup(colorSeparation * delta, amp2)).r,
texture2D(texture, lookup(-colorSeparation * delta, amp2)).g,
texture2D(texture, lookup(vec2(0.0), amp2)).b),
1.0-min(0.95, pow(1.8 * distance(uv, finger), 4.0) + 0.5 * pow(distance(fract(50.0 * uv.y), 0.5), 2.0)));
}
`
}
......@@ -36,19 +40,36 @@ void main() {
class Vignette extends React.Component {
constructor (props) {
super(props);
this.onResponderMove = this.onResponderMove.bind(this);
this.state = {
finger: [0.5, 0.5]
};
}
onResponderMove (evt) {
const { width, height } = this.props;
const { locationX, locationY } = evt.nativeEvent;
this.setState({ finger: [locationX/width, 1-locationY/height] });
}
render () {
const { width, height, time, i, source } = this.props;
const { finger } = this.state;
return <GL.View
onStartShouldSetResponder={() => true}
onMoveShouldSetResponder={() => true}
onResponderMove={this.onResponderMove}
shader={shaders.imageVignette}
style={{ width, height }}
opaque={false}
uniforms={{
time: time,
freq: (10+i)*(1+Math.sin(0.7*time + i)),
freq: 10 + 2 * Math.sin(0.7*time + i),
texture: source,
amp: 0.02 + Math.max(0, 0.05*i*Math.cos(time + 2*i)),
colorSeparation: 0.03,
moving: 0
amp: 0.05 + Math.max(0, 0.03*i*Math.cos(time + 2*i)),
moving: 0,
finger: finger
}}
/>;
}
......
......@@ -15,9 +15,11 @@ const Shaders = {
invariant(typeof obj === "object", "config must be an object");
const result = {};
for (let key in obj) {
// TODO : validate first
const shader = obj[key];
invariant(typeof shader === "object" && typeof shader.frag === "string",
"invalid shader given to Shaders.create(). A valid shader is a { frag: String }");
const id = _uid ++;
GLShadersRegistry.register(id, obj[key]);
GLShadersRegistry.register(id, shader);
result[key] = id;
}
return result;
......
......@@ -13,13 +13,11 @@
],
"author": "Project September <tech@projectseptember.com>",
"license": "MIT",
"devDependencies": {
"react-native": "^0.9.0"
},
"peerDependencies": {
"react-native": "^0.9.0"
},
"dependencies": {
"invariant": "^2.1.0"
"invariant": "^2.1.0",
"react-native": "^0.9.0"
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment