vue-glsl

A simple WebGL components for fragment shader. Can be used with Shadertoys codes

Usage no npm install needed!

<script type="module">
  import vueGlsl from 'https://cdn.skypack.dev/vue-glsl';
</script>

README

vue-glsl

vue-glsl 是一个基于vue3的片段着色器组件,使用的是webGL 1.0(移动端webGL 2.0不支持),并支持多webGLProgram项目。

组件支持shadertoyCode;

Screenshots

screenshot

Install and Usage

# install dependices
 `npm install`

# examples
`npm run serve`

# build component
`npm run build-lib`

Quickstart

First, install vue-glsl using either npm.

npm i vue-glsl --save

Instanciate and tell Vue about the plugin

import {createApp} from 'vue'
import glsl from 'vue-glsl'
import App from './App.vue'
createApp(App).use(glsl).mount('#app');

Then use the components !

<template>
  <div id="app">
    <gl-canvas @update="glslUpdate">
      <gl-program name="main" :code="shaderCode">
        <gl-float name="u_light" :value="light" />
      </gl-program>
    </gl-canvas>
  </div>
</template>

<script lang="ts">
const shader=`
void main() {
    vec2 uv = gl_FragCoord.xy/iResolution.xy;
    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
    gl_FragColor = vec4(col*u_light,1.0);
}`;
export default {
  data(){
    return{
      light:0,
      shaderCode:shader,
    }
  },
  methods:{
    glslUpdate(tickData: {
      iResolution: number[],
      iTime: number,
      iTimeDelta: number,
      iFrame: number,
      iMouse: number[],
      iDate: number[],
    }){
      //console.log(tickData);
      this.light = (Math.sin(tickData.iTime)+1)/2;
    }
  }
};
</script>
<style>
#app{
  position: absolute;
  top: 0;left: 0;
  padding: 0;margin: 0;
  width: 100%;height: 100%;
  background: #000;
  overflow: hidden;
}
</style>

API

gl-canvas

包含了canvas创建,以及webGL环境配置,当gl-canvas被销毁时,requestAnimationFrame也将被销毁。


Props default describe
width null 用于设置canvas的宽度,不设置宽高会自动读取父级的宽高。
height null 用于设置canvas的高度,不设置宽高会自动读取父级的宽高。
paused false 用于控制监听器的运行,设置true可以暂停运行,防止后台渲染,避免不必要的性能损耗。
code '' 公共片段着色器代码,多webGLProgram时会自动拼接在每个webGLProgramfragmentShader中。
style '' clearColor设置为透明的,如果想给canvas加一个背景的话,设置其样式就好了

监听方法

update:
在每一次绘制时会触发该方法供vue做js操作,返回数据为当前帧的一些内置变量。

用法:
<gl-canvas :paused="false" @update="canvasUpdate">
  <!-- ... -->
</gl-canvas>
<script lang="ts">
  export default{
    // ...
    methods:{
      canvasUpdate(tickData:{
        iResolution :number[];  // viewport resolution (in pixels)
        iTime       :number;    // shader playback time (in seconds)
        iTimeDelta  :number;    // render time (in seconds)
        iFrame      :number;    // shader playback frame
        iMouse      :number[];  // mouse pixel coords. xy: current (if MLB down), zw: click
        iDate       :number[];  // (year, month, day, time in seconds)
      }){
        // ...
      }
    }
  }
</script>
gl-program

webGLProgram的创建操作,必须是 gl-canvas 的子组件。


Props default describe
name 'main' 当有多个program时,此属性必须设置,用来区分webGLProgram和当作frameBufferid使用。
code '' 当前webGLProgram的片段着色器代码,会自动拼接gl-canvas中的公共code

用法:

<gl-canvas>
  <gl-program name="buffer0" :code="bufferCode0"></gl-program>
  <gl-program name="main" :code="mainCode"></gl-program>
</gl-canvas>

WebGLUniform组件


gl-int

WebGLUniform组件,当有int类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number int类型的WebGLUniform数据

用法:

<gl-canvas>
  <gl-program name="main" :code="mainCode">
    <gl-int name="u_int0" :value="u_int0">
  </gl-program>
</gl-canvas>
<script>
  export default{
    data(){
      return{
        u_int0:0,
        mainCode:`
void main(){
gl_FragColor = vec4(vec3(u_int0),1);
}
        `,
      }
    }
  }
</script>
gl-float

WebGLUniform组件,当有float类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number float类型的WebGLUniform数据

用法:

<gl-canvas>
  <gl-program name="main" :code="mainCode">
    <gl-float name="u_float0" :value="u_float0">
  </gl-program>
</gl-canvas>
<script>
  export default{
    data(){
      return{
        u_float0:.5,
        mainCode:`
void main(){
gl_FragColor = vec4(vec3(u_float0),1);
}
        `,
      }
    }
  }
</script>
gl-vec2

WebGLUniform组件,当有vec2类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number[2] vec2类型的WebGLUniform数据

用法同上,类型为vec2数据;

gl-vec3

WebGLUniform组件,当有vec3类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number[3] vec3类型的WebGLUniform数据

用法同上,类型为vec3数据;

gl-vec4

WebGLUniform组件,当有vec4类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number[4] vec4类型的WebGLUniform数据

用法同上,类型为vec4数据;

gl-mat2

WebGLUniform组件,当有mat2类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number[4] mat2类型的WebGLUniform数据

用法同上,类型为mat2数据;

gl-mat3

WebGLUniform组件,当有mat3类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number[9] mat3类型的WebGLUniform数据

用法同上,类型为mat3数据;

gl-mat4

WebGLUniform组件,当有mat4类型的uniform传入时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value number[16] mat4类型的WebGLUniform数据

用法同上,类型为mat4数据;

gl-image

WebGLUniform组件,当用到纹理时,用此组件,必须是 gl-program 的子组件。


Props Type describe
name string WebGLUniform名字
value imageURL\|imageObj\|videoObj\|canvasObj\|webGLProgramName\|textureCubeData 用于传入当前WebGLProgram纹理的数据
repeat 0\|1\|2 可以省略,2d纹理有效,0(默认):gl.CLAMP_TO_EDGE 1:gl.REPEAT 2:gl.MIRRORED_REPEAT
repeatX 0\|1\|2 同上,但是若有repeat会被其覆盖
repeatY 0\|1\|2 同上,但是若有repeat会被其覆盖

value 取值;

<string>imageURL:本地图片链接地址。

<HTMLImageElement>imageObj|<HTMLVideoElement>videoObj|<HTMLCanvasElement>canvasObj:可以传入Image\|Video\|Canvas对象(video对象没测,但是理论上可以的),比如展示跨域image时,自行传入image对象,效果同imageURL;

<string>webGLProgramName:当项目为多WebGLProgram时,value值可设置为gl-programname值,可以把该frameBuffer引入纹理(除mainwebGLProgram外,其他webGLProgram均可当作纹理对象,原因是mainwebGLProgram要作为主frameBuffer渲染出来);

<object>textureCubeData:用于添加立方体贴图,并包含以下数据:
| Props | Type | describe | | :-------- | :-----: | :----------- | | front | imageURL\|imageObj\|videoObj\|canvasObj | 本地图片链接地址或者Image\|Video\|CanvasHTML对象,最好为2^n的正方形尺寸 | | back | imageURL\|imageObj\|videoObj\|canvasObj | 本地图片链接地址或者Image\|Video\|CanvasHTML对象,最好为2^n的正方形尺寸 | | left | imageURL\|imageObj\|videoObj\|canvasObj | 本地图片链接地址或者Image\|Video\|CanvasHTML对象,最好为2^n的正方形尺寸 | | right | imageURL\|imageObj\|videoObj\|canvasObj | 本地图片链接地址或者Image\|Video\|CanvasHTML对象,最好为2^n的正方形尺寸 | | top | imageURL\|imageObj\|videoObj\|canvasObj | 本地图片链接地址或者Image\|Video\|CanvasHTML对象,最好为2^n的正方形尺寸 | | bottom | imageURL\|imageObj\|videoObj\|canvasObj | 本地图片链接地址或者Image\|Video\|CanvasHTML对象,最好为2^n的正方形尺寸 |

用法:

<gl-canvas>
  <gl-program name="buffer0" :code="bufferCode0">
  </gl-program>
  <gl-program name="main" :code="mainCode">
    <gl-image name="u_image0" :value="u_image0">
    <gl-image name="u_image1" value="buffer0">
  </gl-program>
</gl-canvas>
<script>
  export default{
    data(){
      return{
        u_image0:require('../assets/image0.png'),
        //bufferCode0:...
        mainCode:`
void main(){
vec2 uv = gl_FragCoord.xy/iResolution.xy;
gl_FragColor = texture2D(u_image0,uv)+texture2D(u_image1,uv);
}
        `,
      }
    }
  }
</script>

uniform内置变量 内支持变量(glsl中自动追加下列数据,供片段着色器直接使用)
type name describe
uniform vec3 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform float iTimeDelta; // render time (in seconds)
uniform int iFrame; // shader playback frame
uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click
uniform vec4 iDate; // (year, month, day, time in seconds)

用法:

gl-image示例中已经用到了iResolution;