2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FragmentShaderを表示するreactコンポーネントの作り方

Last updated at Posted at 2020-07-30

fragmentshader.jpeg

概要

CRAでプロジェクトを作成、プロジェクトにPackageを入れて、↑を表示するシンプルなReactコンポーネントの作成を行います。

環境

  • Mac
  • yarn/npx (CRAのグローバルインストールは非推奨のため)
  • TypeScript 3.5+ (オプション)

CRAでベースアプリを作成

# npxの場合
$ npx create-react-app myshader

# yarnの場合
$ yarn create react-app myshader


# npx & typescriptを利用する場合
$ npx create-react-app myshader --template typescript

# yarn & typescriptを利用する場合
$ yarn create react-app myshader --template typescript

大抵の場合は必要ないですが、一応CRAがちゃんとコードを生成している事を確認しておきます。

$ cd myshader

# yarn
$ yarn start

# npm
$ npm start

[TypeScriptの場合]
cra.png

react-vfxをインストール

react-vfxをインストールします。
併せて、styled-componentsも入れておきます。CSSやSCSSまたはSASSが好きな方はインストールしなくても全く問題ないです。
ちなみ、react-vfxはtsで書かれているので、@typesファイルのインストールは不要です。

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

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

コンポーネントを作成

一番最初の画像を表示するためのシンプルなコンポーネントを作成していきます。
名前はなんでも良いのですが、今回は分かりやすくMyShader.tsxとしました。
本当はフォルダを作るべきなんですが、目的はreact-vfxを試す事なので、src直下に作りました。

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;

コード自体は非常にシンプルで、react-vfxをインポート
import * as VFX from "react-vfx";
FragmentShaderをリテラル内に記述して、metalという変数を定義
インポートしたvfxのコンポーネントを使って、metal(FragmentShader)をロード

Contentは表示するためだけのものなので、普通にCSSを書いて、インポートする方がstyled-componentsを使うより簡単かつ楽だと思います。

あとはこれをApp.tsxもしくはApp.jsにインポートして、を記述したのちに、アプリを起動すれば、FragmentShaderで記述されたアニメーションが表示されます。

ちなみに、metalの部分にShaderToyのコードを移植して、変数名等を修正すれば、簡単に色々なモノを試せます。ただし、公開する場合はライセンスに気をつける必要があります。

react-vfxサンプルページ

react-vfx自体もエフェクトを持っているので、Shaderを書かなくても面白いエフェクトをページに簡単に加える事ができます。
https://amagi.dev/react-vfx/

[text]
Screen Shot 2020-07-30 at 2.06.53 AM.png

repo:https://github.com/koji/typescript/tree/master/shadereact
レポジトリを試す場合は下記を実行すれば、動きます。

$ cd shaderreact
$ yarn
$ yarn start

Dev.toに投稿したポストを日本語にして投稿してみました。
元の記事
https://dev.to/kojikanao/use-fragmentshader-with-reactjs-easily-react-vfx-52lm

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?