前言
程序员也是人,当然也会心动的。而且想想明天就周六,能不心动嘛。那么程序员的心动到底是啥样的,看图
效果展示
image
其实和其他人没啥区别
正文
1.概述
前边一直在说片元着色器,片元着色器中的顶点,法线等等一系列可以用in导入的参数到底是从哪里来的呢,看过顶点着色器的可能会知道,他是在顶点着色器中out导出的。下面借助这个心动的效果,简单说一下顶点着色器
2.实现
Effect代码:
CCEffect %{
techniques:
- name: opaque
passes:
- vert: general-vs:vert # builtin header
frag: unlit-fs:frag
properties: &props
mainTexture: { value: white }
mainColor: { value: [1, 1, 1, 1], editor: { type: color } }
- name: transparent
passes:
- vert: unlit-vs:vert # builtin header
frag: unlit-fs:frag
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha
blendSrcAlpha: src_alpha
blendDstAlpha: one_minus_src_alpha
rasterizerState:
cullMode: none
properties: *props
}%
CCProgram unlit-vs %{
precision highp float;
#include <input-standard>
#include <cc-global>
#include <cc-local-batch>
in vec3 a_color;
in vec2 a_texCoord;
#if HAS_SECOND_UV
in vec2 a_texCoord1;
#endif
out vec3 v_position;
out vec3 v_normal;
out vec3 v_tangent;
out vec3 v_bitangent;
out vec2 v_uv;
out vec2 v_uv1;
out vec3 v_color;
vec4 vert () {
StandardVertInput In;
CCVertInput(In);
mat4 matWorld, matWorldIT;
CCGetWorldMatrixFull(matWorld, matWorldIT);
v_position = (matWorld * In.position).xyz;
v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);
v_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);
v_bitangent = cross(v_normal, v_tangent) * In.tangent.w; // note the cross order
v_uv = a_texCoord;
#if HAS_SECOND_UV
v_uv1 = a_texCoord1;
#endif
v_color = a_color;
v_position += v_normal*abs(sin(cc_time.x*10.0))/5.0*-1.0;
return cc_matProj * (cc_matView)*vec4(v_position,1.0);
}
}%
CCProgram unlit-fs %{
precision highp float;
#include <output>
in vec2 v_uv;
uniform sampler2D mainTexture;
uniform Constant {
vec4 mainColor;
};
in vec3 v_position;
in vec3 v_normal;
vec4 frag () {
vec4 col=texture(mainTexture, v_uv);
return CCFragOutput(mainColor*col);
}
}%
2.1 代码说明
- 声明顶点着色器入口函数
之前咱们一直用的是引擎默认自带的顶点着色器,现在开始咱们就开始自己按照自己的需求编辑顶点着色器
- 声明顶点着色器入口函数
vert: unlit-vs:vert # builtin header
frag: unlit-fs:frag
- 2.顶点着色器实现
CCProgram unlit-vs %{
precision highp float;
#include <input-standard>
#include <cc-global>
#include <cc-local-batch>
in vec3 a_color;
in vec2 a_texCoord;
#if HAS_SECOND_UV
in vec2 a_texCoord1;
#endif
//out 声明可以在外部(片元着色器)引入的参数
out vec3 v_position;
out vec3 v_normal;
out vec3 v_tangent;
out vec3 v_bitangent;
out vec2 v_uv;
out vec2 v_uv1;
out vec3 v_color;
vec4 vert () {
//声明StandardVertInput类型的参数 并且对其就行赋值
//通过看官方代码,可以法线StandardVertInput包含了三个参数
//struct StandardVertInput {
// highp vec4 position; 顶点
// vec3 normal; 法线
// vec4 tangent; 切线
//}
StandardVertInput In;
CCVertInput(In);
//下面六行代码,是多获得的顶点,法线,切线的坐标进行了转化
//需要注意的In里边的这三个属性所拿到的坐标是相对于模型本身的,
//想要将模型渲染到屏幕上,需要经过三部转化
//自身坐标(转)世界坐标(转)视图坐标
mat4 matWorld, matWorldIT;
CCGetWorldMatrixFull(matWorld, matWorldIT);
v_position = (matWorld * In.position).xyz;
v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);
v_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);
v_bitangent = cross(v_normal, v_tangent) * In.tangent.w; // note the cross order
v_uv = a_texCoord;
#if HAS_SECOND_UV
v_uv1 = a_texCoord1;
#endif
v_color = a_color;
//这一行代码对模型的大小变化进行控制
//在原顶点坐标的基础上使其延法线方向延伸
v_position += v_normal*abs(sin(cc_time.x*10.0))/5.0*-1.0;
return cc_matProj * (cc_matView)*vec4(v_position,1.0);
}
}%