diff --git a/docs/README.md b/docs/README.md index bb61ccb..d7db68c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,5 +13,7 @@ * [Touch Responsive](/docs/examples/5.md) * [Animation](/docs/examples/6.md) * [Blur (2-Pass)](/docs/examples/7.md) + * [Blur+Hue over UI](/docs/examples/8.md) + * [Texture from array](/docs/examples/9.md) * [Advanced Effects Examples](/docs/examples/advancedeffects.md) * [Sharing code across gl-react and gl-react-native](/docs/universal.md) diff --git a/docs/api/View.md b/docs/api/View.md index ee3c320..9658b37 100644 --- a/docs/api/View.md +++ b/docs/api/View.md @@ -86,7 +86,7 @@ A texture uniform value can be one of these formats: - an image URL (String). - an Object with an `uri` image URL. This is React Native format (same format as the `source` prop of `React.Image`). `require("image!localImage")` is also supported. - Virtual DOM of any content to be rasterized, see [GL.Uniform][Uniform.md] for more information. -- **(only in gl-react)**: a `ndarray` image data value. This allows to gives computed value as a texture. +- **(only in gl-react)**: a `ndarray` image data value. This allows to gives computed value as a texture. *For more information on accepted `ndarray` formats, checkout [gl-texture2d documentation](https://github.com/stackgl/gl-texture2d#var-tex--createtexturegl-array)*. --- diff --git a/docs/examples/1.md b/docs/examples/1.md index 3d624cc..14c37fe 100644 --- a/docs/examples/1.md +++ b/docs/examples/1.md @@ -52,3 +52,23 @@ A GL component is implemented in 2 parts: - first, you need to implement a fragment shader in GLSL (OpenGL Shading Language). Give it to `GL.Shaders.create` and you have a backed object in return (like `StyleSheet.create`). - second, you can render a `` and pass-in the shader you have defined previously. **Do not forget to give a width and height**. + +### Improved version + +Now, we can rewrite this code to make it more "generic" like this: + +```js +... + +class HelloGL extends GL.Component { + render () { + const { ...rest } = this.props; + return ; + } +} +``` + +That way, we not only allow `width` and `height` to flow in `GL.View` but any other props (we will see later the power of this). diff --git a/docs/examples/2.md b/docs/examples/2.md index b81ca84..06f1cba 100644 --- a/docs/examples/2.md +++ b/docs/examples/2.md @@ -40,11 +40,10 @@ void main () { class Saturation extends GL.Component { render () { - const { width, height, factor, image } = this.props; + const { factor, image, ...rest } = this.props; return ; } diff --git a/docs/examples/3.md b/docs/examples/3.md index 84f0285..c53e991 100644 --- a/docs/examples/3.md +++ b/docs/examples/3.md @@ -66,11 +66,10 @@ void main() { class HueRotate extends GL.Component { render () { - const { width, height, hue, children } = this.props; + const { hue, children, ...rest } = this.props; return {children} ; @@ -81,3 +80,23 @@ class HueRotate extends GL.Component { The `GL.Uniform` describes which texture uniform is used for the rasterization of its children content. > Note how powerful it is to **compose** React Components that way. + +### Improved version + +Here is an even more concise way of writing your component. + +```js +... +class HueRotate extends GL.Component { + render () { + const { hue, children: tex, ...rest } = this.props; + return ; + } +} +``` + +> Remember that you can totally avoid to use `GL.Uniform` and give everything to `uniforms` props. diff --git a/docs/examples/6.md b/docs/examples/6.md index e9b2daa..f45c723 100644 --- a/docs/examples/6.md +++ b/docs/examples/6.md @@ -46,12 +46,11 @@ class HelloGL extends GL.Component { requestAnimationFrame(loop); } render () { - const { width, height } = this.props; + const { ...rest } = this.props; const { value } = this.state; return ; } diff --git a/docs/examples/7.md b/docs/examples/7.md index e2eef2d..3f5d738 100644 --- a/docs/examples/7.md +++ b/docs/examples/7.md @@ -19,17 +19,18 @@ and stack it into these 2 passes. ```js class Blur1D extends GL.Component { render () { - const { width, height, direction, children } = this.props; + const { width, height, direction, children: t, ...rest } = this.props; return - {children} - ; + resolution: [ width, height ], + t + }} + />; } } ``` @@ -52,9 +53,9 @@ class Blur extends GL.Component { In this simple example, `Blur` has 2 passes: one on X dimension, then one on Y dimension. -For a more advanced (4-Pass) example, see [Examples/Blur](https://github.com/ProjectSeptemberInc/gl-react/tree/master/Examples/Blur). +### 4-pass -**Extract:** +(Used in [Examples/Blur](https://github.com/ProjectSeptemberInc/gl-react/tree/master/Examples/Blur)) ```js class Blur4Pass extends GL.Component { @@ -75,3 +76,77 @@ class Blur4Pass extends GL.Component { } } ``` + +### N-pass + +(Used in [Examples/VideoBlur](https://github.com/ProjectSeptemberInc/gl-react/tree/master/Examples/VideoBlur)) + +```js +const React = require("react"); +const GL = require("gl-react"); +const { + PropTypes +} = React; +const Blur1D = require("./Blur1D"); + +const NORM = Math.sqrt(2)/2; + +function directionForPass (p, factor, total) { + const f = factor * p / total; + switch (p%4) { + case 0: return [f,0]; + case 1: return [0,f]; + case 2: return [f*NORM,f*NORM]; + case 3: return [f*NORM,-f*NORM]; + } + return p%2 ? [f,0] : [0,f]; +} + +class Blur extends GL.Component { + render () { + const { width, height, factor, children, passes, ...rest } = this.props; + + const rec = p => p <= 0 ? children : + + {rec(p-1)} + ; + + return rec(passes); + } +} + +Blur.defaultProps = { + passes: 2 +}; + +Blur.propTypes = { + width: PropTypes.number, + height: PropTypes.number, + factor: PropTypes.number.isRequired, + children: PropTypes.any.isRequired, + passes: PropTypes.number +}; + +module.exports = Blur; +``` + + +**Usages:** + +- Small blur: + +```html +{any} +``` + +- Medium blur: + +```html +{any} +``` + +- Powerful blur: + +```html +{any} +``` diff --git a/docs/examples/8.gif b/docs/examples/8.gif new file mode 100644 index 0000000..e679db4 Binary files /dev/null and b/docs/examples/8.gif differ diff --git a/docs/examples/8.md b/docs/examples/8.md new file mode 100644 index 0000000..f037522 --- /dev/null +++ b/docs/examples/8.md @@ -0,0 +1,40 @@ +# Blur+Hue over UI + +> This example is only available in `gl-react-native`. +Implementing it in `gl-react` would be possible if reimplementing the whole UI in a Canvas. However, we can't do it by just using DOM like we can easily use Views in `gl-react-native`. + +![](8.gif) + +## Implementation + +```html + + + + + + this.setState({ factor })} /> + + this.setState({ switch1 })} /> + this.setState({ switch2 })} /> + this.setState({ switch3 })} /> + + + + + + +``` + +### autoRedraw, eventsThrough and visibleContent + +These 3 props are essential to make this example work: +- `autoRedraw` makes the view continously re-render *(and in an efficient way, the render loop is implemented in Objective-C. in `gl-react` context, it is also a bit more performant)*. In our example, we need to do that because we **can't observe UI animation changes** (like when I smoothly move the switch) so we just assume the UI always changes and needs a redraw. +- `eventsThrough` allows to make touch events going through the GL view: we don't want our effect layer to respond for those events but the underlying content with the slider and switches. +- `visibleContent` prevents the content (our view with the slider and switches) to be hidden. When used with `eventsThrough`, it makes the content intercepting the events. diff --git a/docs/examples/9.gif b/docs/examples/9.gif new file mode 100644 index 0000000..4945319 Binary files /dev/null and b/docs/examples/9.gif differ diff --git a/docs/examples/9.md b/docs/examples/9.md new file mode 100644 index 0000000..1197c66 --- /dev/null +++ b/docs/examples/9.md @@ -0,0 +1,105 @@ +# Texture from array + +> This example is only available in `gl-react`. `ndarray` support is not easy to bring for `gl-react-native` but [feel free to help in this issue](https://github.com/ProjectSeptemberInc/gl-react-native/issues/14). + +```html + + http://i.imgur.com/iPKTONG.jpg + +``` + +![](9.gif) + +## Implementation + +This specific `Colorify` component both display the image and the bottom "gradient bar" that renders the color scale applied. + +```js +const React = require("react"); +const GL = require("gl-react"); + +const shaders = GL.Shaders.create({ + colorify: { + frag: ` +precision highp float; +varying vec2 uv; +uniform sampler2D image; +uniform sampler2D colorScale; // used as a lookup texture +uniform float legend; + +float monochrome (vec3 c) { + return 0.2125 * c.r + 0.7154 * c.g + 0.0721 * c.b; +} + +void main () { + vec4 imgC = texture2D(image, uv / vec2(1.0, 1.0 - legend) - vec2(0.0, legend)); + vec4 scaleC = texture2D(colorScale, vec2(monochrome(imgC.rgb), 0.5)); + float legendArea = step(uv.y, legend); + gl_FragColor = step(uv.y, legend - 0.02) * texture2D(colorScale, uv) + + step(legend, uv.y) * vec4(scaleC.rgb, imgC.a * scaleC.a); +} + ` + } +}); + +class Colorify extends React.Component { + render () { + const { width, height, children: image, colorScale, legend, disableLinearInterpolation } = this.props; + return + + {colorScale} + + ; + } +} + +Colorify.defaultProps = { + legend: 0.06 +}; +``` + +The `colorScale` uniform that this component takes is a N x 1 image where `x` position is used as a color scale lookup. + +The `disableLinearInterpolation` option in `GL.Uniform` allows to disable the default linear interpolation that creates a nice smoothing in the lookup of `texture2D`. + +Here is the equivalent way using `uniforms` props: + +```js +{ colorScale: { value: colorScale, opts: { disableLinearInterpolation } } } +``` + +### colorScales + +Here is an extract of the colorScales collection: + +```js +const colorScales = { + classical: ndarray(new Float64Array([ + 0, 0, 1, // blue + 0.1, 0.7, 1, // cyan + 0.4, 1, 0.4, // light green + 1, 0.6, 0, // orange + 1, 0, 0 // red + ]), [5, 1, 3]), + + reversedMonochrome: ndarray(new Float64Array([ + 1, 1, 1, + 0.1, 0.2, 0.3 + ]), [2, 1, 3]), + + opacityFading: ndarray(new Float64Array([ + 1, + 0 + ]), [2, 1, 1]), + + Spectral: ndarray(new Float64Array([0.62,0.00,0.26,0.84,0.24,0.31,0.96,0.43,0.26,0.99,0.68,0.38,1.00,0.88,0.55,1.00,1.00,0.75,0.90,0.96,0.60,0.67,0.87,0.64,0.40,0.76,0.65,0.20,0.53,0.74,0.37,0.31,0.64]), [11,1,3]), +}; +``` + +For more information on accepted `ndarray` formats, checkout [gl-texture2d documentation](https://github.com/stackgl/gl-texture2d#var-tex--createtexturegl-array).