Use FragmentShader with Reactjs Easily ~react-vfx~
Tags: react, javascript, fragmentshader, typescript
Published: 2019-12-30 23:02:37

There are some options to use Shaders with javascript/typescript.
I just saw an npm package that allows me to use fragment shader easily.
I'm using `typescript`, but in this case I don't really use ts lol.

{% github https://github.com/fand/react-vfx %}


In this post, I will show you how to use react-vfx for displaying `FragmentShaders`. 


## Steps
#### Step1. Create a new react app by create-react-app
#### Step2. Install `react-vfx`
#### Step3. Create a new component for FragmentShader
#### Step4. Run the app

### Step1 Create react app
In this case, we will use `create-react-app`. If you have a template, you can use it. 

Here is one thing you should know about `create-react-app`

>If you've previously installed create-react-app globally via npm install -g create-react-app, we recommend you uninstall the package using npm uninstall -g create-react-app to ensure that npx always uses the latest version.
Global installs of create-react-app are no longer supported.

If you install `react-create-app` globally, I recommend you to uninstall it since it may prevent you to create a new react app(Actually my case didn't create an app properly just generate package.json and a couple of files)

```zsh
$ npx create-react-app myshader --template typescript
# or I used yarn since I have switched a package manager from npm to yarn
$ yarn create react-app myshader --template typescript
```
If you don't want to use `Typescript` try the following.
```bash
$ npx create-react-app myshader
# or
$ yarn create react-app myshader
```


This isn't necessary, but I prefer to run before adding a component.

```zsh
$ yarn start
```

You will see this.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/11pdkcu1q89wxz3id0cr.png)


### Step2 Install react-vfx
```
# using styled-components
$ yarn add react-vfx styled-components
$ yarn add -D @types/styled-components <-- if you use typescript

# or
$ npm install react-vfx styled-components
$ npm install -D @types/styled-components <-- if you use typescript
```

### Step3 Create component
In this case, I created a new file, MyShader.tsx under `src`. If you are using js, the file's extension should be `.jsx`

```ts
import React from "react";
import * as VFX from "react-vfx";
import styled from "styled-components";

const Content = styled.div`
  width: 100vw;
  height: 100vh;
`;

const metal = `
uniform vec2 resolution;
uniform float time;
void main()
{
    vec2 coord = gl_FragCoord.xy / resolution.xy;
    vec2 st = coord;
    vec3 line = vec3(0.0);

    coord *= 4.;

    float len;

    for (int i = 0; i < 15; i++) {
        len = length(vec2(coord.x, coord.y));
        coord.x += cos(coord.y + sin(len)) + cos(time * .07) * 0.2;
        coord.y += sin(coord.x + cos(len)) + sin(time * 0.1);
    }

    len *= cos(len * 0.4);

    len -= 10.;

    for (float i = 0.0; i < 5.0; i++) {
        len += 0.11 / abs(mod(st.x, 1.09 * i) * 200.) * 1.;
    }

    vec3 color = vec3(cos(len + 0.2) * 1.15, cos(len + 0.1), cos(len - 0.05));

    gl_FragColor = vec4(color, 1.0);
}
`;

const MyShader: React.FC = () => {
  return (
    <>
      <VFX.VFXProvider>
        <VFX.VFXSpan shader={metal}>
          <Content></Content>
        </VFX.VFXSpan>
      </VFX.VFXProvider>
    </>
  );
}

export default MyShader;
```

As you can see the code is very simple except Fragment shader.

Import packages and create a styled tag, Content and write a Fragment Shader, `metal`. Then add `react-vfx`.

Actually, I tried the following. But it didn't render the content properly. Haven't checked the exact issue lol. 
```ts
const MyShader: React.FC = () => {
  return (
    <>
      <VFX.VFXProvider>
        <VFX.VFXSpan shader={metal}>
        </VFX.VFXSpan>
      </VFX.VFXProvider>
    </>
  );
}
```


### Step4 Run app

```zsh
$ yarn start
```

If everything works well, you will see the following. (Actually, what you will see is an animation.)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/2jho9wo9scmuqhn03ixl.png)


I use threejs to use fragment shader which is pretty good since threejs has nice samples so I just need to modify shader part and threejs input's part. However, with `typescript` the setup is a little bit troublesome to me. But, `react-vfx` is very handy since it is written in `typescript` so I don't need to install any @type file for it. I will use this for updating my portfolio site.


I pushed my sample code.
https://github.com/koji/typescript/tree/master/shadereact

Also, you can find out some nice samples on the creator's site.
https://amagi.dev/react-vfx/