Sun_moves/assets/Shader/fluxay_texture_angle2.effect
2024-05-28 11:38:16 +08:00

173 lines
4.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//扫光-纹理
CCEffect %{
techniques:
- passes:
- vert: vs
frag: fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
texture: { value: white }
u_fluxayTexture: { value: white }
u_time: { value: 0 }
u_scale: { value: 1.0 }
u_angle: { value: 30.0 }
u_uvRotated: { value: 0.0 }
u_uvOffset: { value: [0.0,0.0,1.0,1.0] }
}%
// Vertex Shader(顶点着色器)
// 将顶点从模型空间坐标系统转化到屏幕空间坐标系统
// 顶点着色器分为输入和输出两部分
// 负责的功能是把输入的数据进行矩阵变换位置,计算光照公式生成逐顶点颜⾊,⽣成/变换纹理坐标
// 并且把位置和纹理坐标这样的参数发送到片段着色器
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
// 输入的纹理坐标
// UV坐标原点在左上角u轴是向右v轴是向下范围是0-1
in vec2 a_uv0;
// 输出的纹理坐标
out vec2 v_uv0;
#endif
void main () {
mat4 mvp;
#if CC_USE_MODEL
mvp = cc_matViewProj * cc_matWorld;
#else
mvp = cc_matViewProj;
#endif
v_uv0 = a_uv0;
v_color = a_color;
gl_Position = mvp * vec4(a_position, 1);
}
}%
// Fragment Shader(片段着色器)
// 片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色(RGBA)
CCProgram fs %{
precision highp float;
#include <alpha-test>
#include <texture>
in vec4 v_color;
in vec2 v_uv0;
uniform sampler2D texture;
uniform sampler2D u_fluxayTexture; //流光纹理
// 自定义属性
// 所有非 sampler 的 uniform 都必须以 UBO 形式声明
// UBO 成员声明类型和顺序有严格的校验机制,以排除 GL 标准下隐式布局对齐带来的内存消耗
// u_uvRotated图片是否旋转
// u_uvOffset 图片minx,miny,maxx,maxy
uniform ARGS {
float u_time;
float u_scale;
float u_angle;
float u_uvRotated;
vec4 u_uvOffset;
};
vec2 transformUV(vec2 UV,float angle){
float rotate = (angle * 3.1415926) / 180.0;
vec2 di = vec2(0.5, 0.5); // 旋转的中心位置
//float a = cos(rotate);
mat3 m = mat3(cos(rotate), -sin(rotate), 0.0,sin(rotate), cos(rotate), 0.0,0.0, 0.0, 1.0);
//vec3 uv = vec3(UV.x-di.x,UV.y+di.y, 1.0)* m;
//return vec2(uv.x,uv.y)+vec2(di.x,-di.y);
vec3 uv = vec3(UV.x,UV.y, 1.0)* m;
return vec2(uv.x,uv.y);
}
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
// texture.inc 核心函数
// o = texture2D(texture, v_uv0);
// texture: 纹理v_uv0: 纹理坐标,通过 GLSL 的内建函数 texture2D 来获取纹理上对应UV坐标的颜色(RGBA)
o = texture2D(texture, v_uv0);
#endif
// 纹理颜色和顶点颜色(节点颜色)叠加得到最终颜色
o *= v_color;
// alpha-test.inc 核心函数
// if (color.a < alphaThreshold) discard;
// discard退出片段着色器不执行后面的片段着色操作片段也不会写入帧缓冲区
ALPHA_TEST(o);
//纹理的xMin
float xMin = u_uvOffset.x;
float xWidth = u_uvOffset.z - u_uvOffset.x;
//x 转换成扫光图片上的位置
float x = (v_uv0.x - xMin)/xWidth;
float yMin = u_uvOffset.y;
float yWidth = u_uvOffset.w- u_uvOffset.y;
//y 转换成扫光图片上的位置
float y = (v_uv0.y - yMin)/yWidth;
float angle = u_angle;
if(u_uvRotated >= 1.0)
{
x = (v_uv0.y - yMin)/yWidth;
y = (v_uv0.x - xMin)/xWidth;
angle = -u_angle;
}
// 在底图不透明的地方叠加流光纹理的颜色
if(o.a >= 1.0) {
// 根据时间设置流光纹理的UV
vec2 fluxayUV = vec2(x, y);
x += u_scale;
float time = u_time*(1.0+u_scale);
//if(fluxayUV.x > u_time-u_scale && fluxayUV.x <u_time)
if(o.a >= 1.0)
{
// 获取流光纹理上UV的颜色
fluxayUV.x = (x-time)/ u_scale;
fluxayUV = transformUV(fluxayUV,angle);
vec4 fluxay = texture2D(u_fluxayTexture, fluxayUV);
o.a = fluxay.a;
// 叠加颜色
gl_FragColor = o;
}
else {
o.a = 0.0;
gl_FragColor = o;
}
} else {
o.a = 0.0;
gl_FragColor = o;
}
}
}%