[CocosShader]Cocos-Shader结构
·
GLSL:OpenGL Shading Language,是OpenGL的着色语言,是一种基于C语言的高级编程语言,用于描述GPU的渲染管道。
Cocos effect是基于opengl的,使用glsl语法和函数。但是经过了cocos进行封装,所以一般看不到main函数,直接写关键函数即可。点击写好的effect,在Cocos creator属性面板可以看到生成的完整代码。effect一般会有三个部分:
- CCEffect 声明部分
- CCProgram vs 顶点着色器
- CCProgram fs 片段着色器
CCEffect中每个passes都需要指定顶点着色器和片段着色器,一般都是vs:vert和fs:frag两个函数。
创建使用材质与shader
- 创建一个shader
- 创建一个材质–>选择一个shader
- MeshRenderer–>选择一个材质,MeshRenderer–>Mesh–>MeshData模型的网格(形状)–>MeshVertexData–>MeshIndexData
cocos-shader结构
shader是代码,是算法,有数据,那shader的数据哪里来?
- 顶点shader数据需要从渲染管道里获取数据
- CPU要传递数据给顶点shader和片段shader
- 顶点shader的数据传递给片段shader
GLSL-顶点shader
- attribute:顶点属性,用于从缓冲区中读取数据,如位置、法线、颜色等。修饰的变量是从渲染管道获取的数据给顶点shader
- uniform:全局变量,用于向顶点着色器传递数据,如摄像机位置、光源位置、光源颜色等。修饰的变量都是CPU传递给shader的数据
- varying:顶点着色器输出到片段着色器的变量,用于向片段着色器传递数据。修饰的变量是顶点着色器输出到片段着色器的数据,顶点shader要定义一次,片段shader也到定义一次,才能使用一次
GLSL-片段shader
- varying:顶点着色器输出到片段着色器的变量,用于向片段着色器传递数据。修饰的变量是顶点着色器输出到片段着色器的数据,顶点shader要定义一次,片段shader也到定义一次,才能使用一次
- uniform:全局变量,用于向片段着色器传递数据,如摄像机位置、光源位置、光源颜色等。修饰的变量都是CPU传递给shader的数据
- texture:纹理,用于从贴图中读取数据,如贴图颜色、法线、深度等。修饰的变量是从贴图中读取的数据
- gl_FragColor:片段着色器输出的颜色,用于渲染到屏幕上。
shi CCEffect %{
techniques:
- passes:#渲染管道,可以有多个
- vert: vs:vert #顶点shader,入口函数名vert
frag: fs:frag #片段shader,入口函数名frag
blendState:#混合状态
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha
blendDstAlpha: one_minus_src_alpha
rasterizerState:#光栅化状态
cullMode: none # 剔除模式(none/front/back)
fillMode: solid # 填充模式(solid/wireframe)
depthBias: 0.0 # 深度偏移值
slopeScaleDepthBias: 0.0 # 斜率缩放深度偏移
properties:
# 着色器中需要同步定义一个 ‘uniform center’,该属性可在编辑器的属性检查器中进行配置
center: { value: [0.5, 0.5], editor: { tooltip: '模糊中心点' } }
# 着色器中需要同步定义一个 ‘uniform strength’,该属性可在编辑器的属性检查器中进行配置
strength: { value: 0.03, editor: { tooltip: '模糊强度' } }
}%
CCProgram vs %{
precision highp float; // precision精度声明 高highp、中mediump、低lowp
#include <cc-global>
//attribute 渲染管道传递给你的
in vec3 a_position; //输入变量,三维,顶点位置数据-世界坐标
in vec2 a_texCoord; //输入变量,二维,顶点纹理坐标,当前顶点对应的纹理位置
in vec4 a_color; //输入变量,四维,顶点颜色
in vec3 a_normal; //输入变量,三维,顶点法线
out vec2 v_uv0; //输出变量,二维,纹理坐标
vec4 vert () {
vec4 pos = vec4(a_position, 1);
#剪切空间坐标 = 投影矩阵 * 世界坐标
//通过 MVP 乘以空间顶点,得到裁剪空间 (clip space) 坐标并返回
pos = cc_matViewProj * pos;
v_uv0 = a_texCoord;
return pos;
}
}%
CCProgram fs %{
precision highp float;
in vec2 v_uv0;
#pragma builtin(local)
layout(set = 2, binding = 10) uniform sampler2D cc_spriteTexture;
//定义文件里写的属性可以这样获取
uniform Properties {
vec2 center;
float strength;
};
// 获取径向模糊颜色
vec4 getRadialBlurColor(vec2 coord) {
// 偏移
vec2 offset = coord.xy - center;
// 采样次数
const int samples = 10;
// 强度
float perStrength = strength / float(samples - 1);
// 采样
vec4 color = vec4(0.0);
for(int i = 0; i < samples; i++) {
vec2 uv = offset * (1.0 + (float(i) * perStrength)) + center;
color += texture(cc_spriteTexture, uv);
}
color /= float(samples);
// 完成
return color;
}
vec4 frag () {
vec4 o = vec4(1, 1, 1, 1);
o *= getRadialBlurColor(v_uv0);
return o;// 固定返回绿色的 RGBA 色值
}
}%
更多推荐
所有评论(0)