着色器第二章 uniforms
本页面代码来自:https://thebookofshaders.com/03/?lan=ch
着色器部分如果想要会变化,那么就需要变量
按照书中的demo, 有一个unifrom float u_time
这个值相当于调用着色器的地方给着色器传了一个值叫做u_time
, 用来记录当前时间
首先先编写一个自定义组件, 用来给着色器进行赋值
我这里取名为ShaderTimerHelper.ts
定义ShaderTimerHelper来进行传递值
const {ccclass, property, executeInEditMode} = cc._decorator;
@ccclass
@executeInEditMode
export default class ShaderTimerHelper extends cc.Component {
private material:cc.Material = null;
private time:number = 0;
protected onLoad () {
let sprite = this.node.getComponent(cc.Sprite);
if (!sprite) {
return;
}
this.material = sprite.getMaterial(0);
}
protected update(dt:number):void{
if(!this.material) return;
this.time += dt;
this.material.effect.setProperty('u_time', this.time);
}
}
代码片段中 onLoad
部分, 我们将节点中sprite渲染组件中的材质取出来
代码片段中的update
方法中,将定义的time时间进行累加,并将时间传递给材质
第一个demo,一个根据时间来变换的红黑shader
新建一个材质shader_03_01_uniform.effect
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: vs
frag: fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
texture: { value: white }
# 定义自定义属性u_time 用来接受属性的传递
u_time: { value: 0.0 }
}%
CCProgram vs %{
precision highp float;
#include <cc-global>
#include <cc-local>
in vec3 a_position;
in vec4 a_color;
out vec4 v_color;
#if USE_TEXTURE
in vec2 a_uv0;
out vec2 v_uv0;
#endif
void main () {
vec4 pos = vec4(a_position, 1);
#if CC_USE_MODEL
pos = cc_matViewProj * cc_matWorld * pos;
#else
pos = cc_matViewProj * pos;
#endif
#if USE_TEXTURE
v_uv0 = a_uv0;
#endif
v_color = a_color;
gl_Position = pos;
}
}%
CCProgram fs %{
precision highp float;
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D texture;
#endif
//引用u_time值到着色器中使用
uniform Timer{
float u_time;
};
void main () {
float r = abs(sin(u_time));
gl_FragColor = vec4(r, 0., 0., 1.);
}
}%
这里 unifroms的第一个demo就完成了,可以实现一个根据时间进行红黑变换的着色器
gl_FragCoord 根据屏幕位置实现一个颜色渐变效果
编写一个传递u_resolution
的组件
const {ccclass, property, executeInEditMode} = cc._decorator;
@ccclass
@executeInEditMode
export default class ShaderTimerHelper extends cc.Component {
private material:cc.Material = null;
protected onLoad () {
let sprite = this.node.getComponent(cc.Sprite);
if (!sprite) {
return;
}
this.material = sprite.getMaterial(0);
// 用来传递 demo 中 u_resolution 值 这个值被初始化之后就不会变化,所以只用在onLoad阶段传递一次即可
let csize = this.node.getContentSize();
this.material.effect.setProperty('u_resolution', [csize.width, csize.height]);
}
}
新建一个材质shader_03_02_uniform.effect
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: vs
frag: fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
texture: { value: white }
u_resolution: {
value: [100.0, 100.0],
editor: {
tooltip: "纹理尺寸px(宽 x 高)"
}
}
}%
CCProgram vs %{
precision highp float;
#include <cc-global>
#include <cc-local>
in vec3 a_position;
in vec4 a_color;
out vec4 v_color;
#if USE_TEXTURE
in vec2 a_uv0;
out vec2 v_uv0;
#endif
void main () {
vec4 pos = vec4(a_position, 1);
#if CC_USE_MODEL
pos = cc_matViewProj * cc_matWorld * pos;
#else
pos = cc_matViewProj * pos;
#endif
#if USE_TEXTURE
v_uv0 = a_uv0;
#endif
v_color = a_color;
gl_Position = pos;
}
}%
CCProgram fs %{
precision highp float;
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D texture;
#endif
uniform Rsolution{
vec2 u_resolution;
};
void main () {
vec2 st = gl_FragCoord.xy / u_resolution;
gl_FragColor = vec4(st.x, st.y, 0., 1.);
}
}%
到这里, 书中的着色器 uniforms部分demo就编写完成了
最新评论