vue-glsl 是一个基于vue3的片段着色器组件,使用的是webGL 1.0(移动端webGL 2.0不支持),并支持多webGLProgram项目。
组件支持shadertoyCode;
# install dependices
`npm install`
# examples
`npm run serve`
# build component
`npm run build-lib`First, install vue-glsl using either npm.
npm i vue-glsl --saveInstanciate 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>gl-canvas
包含了canvas创建,以及webGL环境配置,当gl-canvas被销毁时,requestAnimationFrame也将被销毁。
| Props | default | describe |
|---|---|---|
width |
null |
用于设置canvas的宽度,不设置宽高会自动读取父级的宽高。 |
height |
null |
用于设置canvas的高度,不设置宽高会自动读取父级的宽高。 |
paused |
false |
用于控制监听器的运行,设置true可以暂停运行,防止后台渲染,避免不必要的性能损耗。 |
code |
'' |
公共片段着色器代码,多webGLProgram时会自动拼接在每个webGLProgram的fragmentShader中。 |
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和当作frameBuffer的id使用。 |
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>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数据 |
gl-vec3
WebGLUniform组件,当有vec3类型的uniform传入时,用此组件,必须是 gl-program 的子组件。
| Props | Type | describe |
|---|---|---|
name |
string |
WebGLUniform名字 |
value |
number[3] |
vec3类型的WebGLUniform数据 |
gl-vec4
WebGLUniform组件,当有vec4类型的uniform传入时,用此组件,必须是 gl-program 的子组件。
| Props | Type | describe |
|---|---|---|
name |
string |
WebGLUniform名字 |
value |
number[4] |
vec4类型的WebGLUniform数据 |
gl-mat2
WebGLUniform组件,当有mat2类型的uniform传入时,用此组件,必须是 gl-program 的子组件。
| Props | Type | describe |
|---|---|---|
name |
string |
WebGLUniform名字 |
value |
number[4] |
mat2类型的WebGLUniform数据 |
gl-mat3
WebGLUniform组件,当有mat3类型的uniform传入时,用此组件,必须是 gl-program 的子组件。
| Props | Type | describe |
|---|---|---|
name |
string |
WebGLUniform名字 |
value |
number[9] |
mat3类型的WebGLUniform数据 |
gl-mat4
WebGLUniform组件,当有mat4类型的uniform传入时,用此组件,必须是 gl-program 的子组件。
| Props | Type | describe |
|---|---|---|
name |
string |
WebGLUniform名字 |
value |
number[16] |
mat4类型的WebGLUniform数据 |
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会被其覆盖 |
<string>imageURL:本地图片链接地址。
<HTMLImageElement>imageObj|<HTMLVideoElement>videoObj|<HTMLCanvasElement>canvasObj:可以传入Image\|Video\|Canvas对象(video对象没测,但是理论上可以的),比如展示跨域image时,自行传入image对象,效果同imageURL;
<string>webGLProgramName:当项目为多WebGLProgram时,value值可设置为gl-program的name值,可以把该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;
