continue docs

This commit is contained in:
Gaëtan Renaudeau 2015-10-01 12:29:46 +02:00
parent 8271600843
commit abef910821
11 changed files with 276 additions and 17 deletions

View File

@ -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)

View File

@ -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)*.
---

View File

@ -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 `<GL.View>` 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 <GL.View
{...rest}
shader={shaders.helloGL}
/>;
}
}
```
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).

View File

@ -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 <GL.View
{...rest}
shader={shaders.saturation}
width={width}
height={height}
uniforms={{ factor, image }}
/>;
}

View File

@ -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 <GL.View
{...rest}
shader={shaders.hueRotate}
width={width}
height={height}
uniforms={{ hue }}>
<GL.Uniform name="tex">{children}</GL.Uniform>
</GL.View>;
@ -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 <GL.View
{...rest}
shader={shaders.hueRotate}
uniforms={{ hue, tex }}
/>;
}
}
```
> Remember that you can totally avoid to use `GL.Uniform` and give everything to `uniforms` props.

View File

@ -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 <GL.View
{...rest}
shader={shaders.helloGL}
width={width}
height={height}
uniforms={{ value }}
/>;
}

View File

@ -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 <GL.View
{...rest}
shader={shaders.blur1D}
width={width}
height={height}
uniforms={{
direction,
resolution: [ width, height ]
}}>
<GL.Uniform name="t">{children}</GL.Uniform>
</GL.View>;
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 :
<Blur1D {...rest} width={width} height={height} direction={directionForPass(p, factor, passes)}>
{rec(p-1)}
</Blur1D>;
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
<Blur factor={0.5} passes={2} width={w} height={h}>{any}</Blur>
```
- Medium blur:
```html
<Blur factor={2} passes={4} width={w} height={h}>{any}</Blur>
```
- Powerful blur:
```html
<Blur factor={20} passes={6} width={w} height={h}>{any}</Blur>
```

BIN
docs/examples/8.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

40
docs/examples/8.md Normal file
View File

@ -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
<Blur
autoRedraw
eventsThrough
visibleContent
width={256}
height={160}
factor={factor}>
<HueRotate hue={-switch1 + 2 * switch2 + 4 * switch3}>
<View style={{ width: 256, height: 160, padding: 10 }}>
<SliderIOS style={{ height: 80 }} maximumValue={2} onValueChange={factor => this.setState({ factor })} />
<View style={{ height: 60, flexDirection: "row", alignItems: "center" }}>
<SwitchIOS style={{flex:1}} value={switch1} onValueChange={switch1 => this.setState({ switch1 })} />
<SwitchIOS style={{flex:1}} value={switch2} onValueChange={switch2 => this.setState({ switch2 })} />
<SwitchIOS style={{flex:1}} value={switch3} onValueChange={switch3 => this.setState({ switch3 })} />
</View>
<ProgressViewIOS progress={factor} style={{height: 10, marginTop: 8, flex:1}} />
</View>
</HueRotate>
</Blur>
```
### 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.

BIN
docs/examples/9.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 MiB

105
docs/examples/9.md Normal file
View File

@ -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
<Colorify width={256} height={190} colorScale={colorScales[colorScale]} disableLinearInterpolation={disableLinearInterpolation}>
http://i.imgur.com/iPKTONG.jpg
</Colorify>
```
![](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 <GL.View
shader={shaders.colorify}
width={width}
height={height}
uniforms={{ image, legend }}
opaque={false}
>
<GL.Uniform name="colorScale" disableLinearInterpolation={disableLinearInterpolation}>
{colorScale}
</GL.Uniform>
</GL.View>;
}
}
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).