cc3.x(cocos creator3.x)的着色器demo有点少,而且讲的不是很清晰,我这种业余自学小白学的真的很艰难,不过好赖算是啃的差不多了,所以有了这则小记,权当备忘录了。
首先顶点着色器,上一段代码:
CCProgram vs %{
precision highp float;
#include <particle-common>
in vec3 a_position;
in vec4 a_color;
in vec2 a_texCoord;
vec4 vs_main() {
vec4 pos = vec4(a_position.x,a_position.y,a_position.z, 1);
pos = cc_matWorld * pos;
pos = cc_matViewProj * pos;
color = a_color;
uv = a_texCoord;
return pos;
}
}%
in vec3 a_position; in vec4 a_color; in vec2 a_texCoord; 这仨是固定写法,而这个变量名咋来的呢,可以在mesh里找到它,struct是网格的结构,在参数里有五个值,包括顶点坐标,顶点法线,顶点切线,还有uv,其中texCoord就是该顶点在纹理上的uv坐标,至于texCoord1我也不是很清楚。 通过关键字in+参数名,就可以把需要的顶点信息引入进顶点着色器,顶点着色器所处理的顶点就是模型的顶点,这里输出的是该点在屏幕上的坐标,如果它是一个3D环境内的点,则需要通过两次变换来映射到观察空间,即pos = cc_matWorld * pos; pos = cc_matViewProj * pos; ,要注意的是,模型顶点坐标的坐标值是模型(本地)空间下的。
可见,顶点着色器的作用是计算顶点在屏幕上的位置,在2d环境下,想要将一张图片绘制成3d的效果(即透视效果),则需要修改图片顶点绘制到屏幕上的位置,使其具有一种近大远小的效果,它也可以用来实现扭曲效果等等。
而片元着色器则是用来处理像素的,在最初,我以为它是用来处理一个三角面片的,其实是像素,来一段代码:
CCProgram fs %{
precision mediump float;
#include <output>
in vec4 color;
in vec2 uv;
uniform Constant {
vec4 mainColor;
};
float getDistance(vec2 p1, vec2 p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
uniform sampler2D mainTexture;
vec4 fs_main () {
vec4 col= texture(mainTexture,uv);
return color*col;
}
}%
在这里,in vec4 color; in vec2 uv; 是用来引入顶点着色器的输出值的,在顶点着色器的代码段中color = a_color; uv = a_texCoord;即为赋值过程。
但是!这里有一点要格外注意,在片元着色器中,由于处理的是单个像素,因此,uv和color并不是顶点的值,而是依据顶点的uv与color所计算出的这一个像素的uv和color值,片元着色器的工作就是依据这些信息,来计算出这个像素的最终颜色。
此外,顶点与片元着色器均可以引入自定义的外部变量,因此,片元着色器的处理过程可以是这样的:拿到像素的uv坐标后,通过混合法线贴图,粗糙度贴图,色彩贴图等,计算出像素的基本颜色,再按照需求(如果有的话)混合当前像素的color(此值依赖顶点颜色计算),如果有需要的话,还可以根据uv与指定点的距离,对色彩进行二次处理,又或者弱/强化某个通道的值(rgb)。
但是,以上计算的并不包括光照,如果要进行光照计算,则需要依赖cc提供的函数来进行处理:
StandardSurface s;
surf(s);
vec4 color = CCStandardShading(s);
return CCFragOutput(color);
这里需要自己写一个生成StandardSurface的函数surf,在StandardSurface中要处理的包括光照,反射率,pbr流程等等,最终通过输出一个固定结构,来调用CCStandardShading计算最终颜色,我没有仔细的看,如果有需求再细学。
(注:cc有提供一个基础材质,里面使用的effect中包括一个写好的surf函数,可以通过修改它来实现一些基本需求)
|