2D 自定义渐变 shader 的思路是利用 UV 坐标在片元着色器里 mix 两个颜色。下面给一个完整的做法。
第一步:创建 .shader 文件
在 IDE 的 assets 目录下新建一个 gradient2d.shader,内容如下:
Shader3D Start
{
type: Shader3D,
name: Gradient2D,
shaderType: D2_TextureSV,
attributeMap: {
a_posuv: [0, Vector4],
a_attribColor: [1, Vector4],
a_attribFlags: [2, Vector4],
a_customs: [3, Vector4]
},
uniformMap: {
u_startColor: { type: Color, default: [1, 0, 0, 1] },
u_endColor: { type: Color, default: [0, 0, 1, 1] },
u_angle: { type: Float, default: 0 }
},
shaderPass: [
{
VS: gradientVS,
FS: gradientFS
}
]
}
Shader3D End
GLSL Start
#defineGLSL gradientVS
#define SHADER_NAME GradientVS
#include "Sprite2DVertex.glsl";
void main() {
vertexInfo info;
getVertexInfo(info);
v_texcoordAlpha = info.texcoordAlpha;
v_color = info.color;
v_useTex = info.useTex;
v_useClip = info.useClip;
v_customs = info.customs;
gl_Position = getPosition(info.pos);
}
#endGLSL
#defineGLSL gradientFS
#define SHADER_NAME GradientFS
#if defined(GL_FRAGMENT_PRECISION_HIGH)
precision highp float;
#else
precision mediump float;
#endif
#include "Sprite2DFrag.glsl";
uniform vec4 u_startColor;
uniform vec4 u_endColor;
uniform float u_angle;
void main() {
clip();
vec4 texColor = getSpriteTextureColor();
float rad = u_angle * 3.14159265 / 180.0;
vec2 dir = vec2(cos(rad), sin(rad));
float t = clamp(dot(v_texcoordAlpha.xy, dir), 0.0, 1.0);
vec4 gradColor = mix(u_startColor, u_endColor, t);
texColor *= gradColor;
setglColor(texColor);
}
#endGLSL
GLSL End
关键点:shaderType: D2_TextureSV 表示这是给 Sprite/Graphics 用的 2D shader,顶点格式和内置 Sprite2DTexture 一致。v_texcoordAlpha.xy 就是 UV 坐标,用来做渐变插值。u_angle 控制渐变方向(0 = 左→右,90 = 上→下)。
第二步:使用
在 IDE 中基于这个 shader 创建一个 .lmat 材质文件,调整 startColor / endColor / angle 参数。然后在代码里:
// 加载 shader 和图片
let sp = new Laya.Sprite();
sp.loadImage("res/your-image.png");
Laya.stage.addChild(sp);
Laya.loader.load("res/gradient2d.shader").then(() => {
let mat = new Laya.Material();
mat.setShaderName("Gradient2D");
sp.graphics.material = mat;
sp.graphics.useSpriteState = false;
});
也可以直接在 IDE 属性面板里把材质拖给 Sprite 的 material 字段,不用写代码。
如果不需要图片纹理、只要纯色渐变填充一个矩形,可以先 sp.graphics.drawRect(0, 0, width, height, "#ffffff") 画一个白色矩形,再挂这个材质,渐变色就会乘上去。
以上由AI自动回复,仅供参考。