feat(着色器): 添加默认和实例化着色器到场景图示例

添加默认和实例化着色器文件到场景图示例,包括顶点和片段着色器
修改构建脚本自动复制着色器文件到romfs目录
This commit is contained in:
ChestnutYueyue 2026-03-03 03:57:19 +08:00
parent 91e3e8fe57
commit 8cd883ede7
6 changed files with 271 additions and 1 deletions

View File

@ -0,0 +1,40 @@
#version 320 es
precision highp float;
// 从顶点着色器输入
in vec2 vTexCoord;
in vec4 vColor;
in vec4 vTintColor;
in float vOpacity;
// 纹理采样器
uniform sampler2D uTexture;
// 输出颜色
out vec4 fragColor;
/**
* @brief
*
*
*/
void main() {
// 采样纹理
vec4 texColor = texture(uTexture, vTexCoord);
// 如果纹理采样结果是黑色或透明,使用白色作为默认值
if (texColor.rgb == vec3(0.0) || texColor.a < 0.01) {
texColor = vec4(1.0, 1.0, 1.0, 1.0);
}
// 混合:纹理 * 顶点颜色 * 色调
fragColor = texColor * vColor * vTintColor;
// 应用透明度
fragColor.a *= vOpacity;
// Alpha 测试:丢弃几乎透明的像素
if (fragColor.a < 0.01) {
discard;
}
}

View File

@ -0,0 +1,48 @@
#version 320 es
precision highp float;
// 全局 UBO (binding = 0) - 每帧更新一次
layout(std140, binding = 0) uniform GlobalUBO {
mat4 uViewProjection;
vec4 uCameraPosition;
float uTime;
float uDeltaTime;
vec2 uScreenSize;
};
// 材质 UBO (binding = 1) - 每物体更新
layout(std140, binding = 1) uniform MaterialUBO {
vec4 uColor;
vec4 uTintColor;
float uOpacity;
float uPadding[3]; // std140 对齐填充
};
// 模型矩阵作为单独的统一变量(每个物体设置)
uniform mat4 uModelMatrix;
// 顶点属性
layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec2 aTexCoord;
layout(location = 2) in vec4 aColor;
// 输出到片段着色器
out vec2 vTexCoord;
out vec4 vColor;
out vec4 vTintColor;
out float vOpacity;
/**
* @brief
*
*
*
*/
void main() {
gl_Position = uViewProjection * uModelMatrix * vec4(aPosition, 0.0, 1.0);
vTexCoord = aTexCoord;
// 混合顶点颜色和材质 UBO 中的颜色
vColor = aColor * uColor;
vTintColor = uTintColor;
vOpacity = uOpacity;
}

View File

@ -0,0 +1,73 @@
#version 320 es
precision highp float;
// 全局 UBO (binding = 0) - 每帧更新一次
layout(std140, binding = 0) uniform GlobalUBO {
mat4 uViewProjection;
vec4 uCameraPosition;
float uTime;
float uDeltaTime;
vec2 uScreenSize;
};
// 材质 UBO (binding = 1) - 每批次更新
layout(std140, binding = 1) uniform MaterialUBO {
vec4 uColor;
vec4 uTintColor;
float uOpacity;
float uPadding[3]; // std140 对齐填充
};
// 顶点属性 (每个顶点)
layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec2 aTexCoord;
layout(location = 2) in vec4 aColor;
// 实例属性 (每个实例) - 使用 location 3-6
layout(location = 3) in vec2 iPosition; // 实例位置
layout(location = 4) in float iRotation; // 实例旋转
layout(location = 5) in vec2 iScale; // 实例缩放
layout(location = 6) in vec4 iColor; // 实例颜色
// 输出到片段着色器
out vec2 vTexCoord;
out vec4 vColor;
out vec4 vTintColor;
out float vOpacity;
/**
* @brief 2D变换矩阵
* @param angle
* @return 2x2旋转矩阵
*/
mat2 rotate2D(float angle) {
float c = cos(angle);
float s = sin(angle);
return mat2(c, -s, s, c);
}
/**
* @brief
*
*
*
*
*/
void main() {
// 应用实例缩放和旋转
vec2 localPos = rotate2D(iRotation) * (aPosition * iScale);
// 应用实例位置偏移
vec2 worldPos = localPos + iPosition;
// 变换到裁剪空间
gl_Position = uViewProjection * vec4(worldPos, 0.0, 1.0);
vTexCoord = aTexCoord;
// 混合顶点颜色、实例颜色和材质颜色
vColor = aColor * iColor * uColor;
vTintColor = uTintColor;
vOpacity = uOpacity;
}

View File

@ -0,0 +1,35 @@
#version 320 es
precision highp float;
// 从顶点着色器输入
in vec2 vTexCoord;
in vec4 vColor;
// 纹理采样器
uniform sampler2D uTexture;
// 输出颜色
out vec4 fragColor;
/**
* @brief
*
*
*/
void main() {
// 采样纹理
vec4 texColor = texture(uTexture, vTexCoord);
// 如果纹理采样结果是黑色或透明,使用白色作为默认值
if (texColor.rgb == vec3(0.0) || texColor.a < 0.01) {
texColor = vec4(1.0, 1.0, 1.0, 1.0);
}
// 混合:纹理 * 顶点颜色
fragColor = texColor * vColor;
// Alpha 测试:丢弃几乎透明的像素
if (fragColor.a < 0.01) {
discard;
}
}

View File

@ -0,0 +1,58 @@
#version 320 es
precision highp float;
// 全局 UBO (binding = 0) - 每帧更新一次
layout(std140, binding = 0) uniform GlobalUBO {
mat4 uViewProjection;
vec4 uCameraPosition;
float uTime;
float uDeltaTime;
vec2 uScreenSize;
};
// 顶点属性
layout(location = 0) in vec2 aPosition; // 基础顶点位置
layout(location = 1) in vec2 aTexCoord; // 基础 UV
layout(location = 2) in vec4 aColor; // 基础颜色
// 实例属性 (每个实例)
layout(location = 3) in vec2 aInstancePos; // 实例位置偏移
layout(location = 4) in float aInstanceRot; // 实例旋转
layout(location = 5) in vec2 aInstanceScale; // 实例缩放
layout(location = 6) in vec4 aInstanceColor; // 实例颜色
layout(location = 7) in vec4 aInstanceUV; // 实例 UV 区域
// 输出到片段着色器
out vec2 vTexCoord;
out vec4 vColor;
/**
* @brief
*
*
*/
void main() {
// 构建旋转矩阵
float cosRot = cos(aInstanceRot);
float sinRot = sin(aInstanceRot);
mat2 rotation = mat2(
cosRot, -sinRot,
sinRot, cosRot
);
// 应用缩放和旋转
vec2 scaledPos = aPosition * aInstanceScale;
vec2 rotatedPos = rotation * scaledPos;
// 应用实例位置偏移
vec2 worldPos = rotatedPos + aInstancePos;
// 计算裁剪空间位置
gl_Position = uViewProjection * vec4(worldPos, 0.0, 1.0);
// 计算 UV 坐标(应用实例 UV 区域)
vTexCoord = aTexCoord * aInstanceUV.zw + aInstanceUV.xy;
// 混合顶点颜色和实例颜色
vColor = aColor * aInstanceColor;
}

View File

@ -28,9 +28,25 @@ target("scene_graph_demo")
local nacptool = path.join(devkitPro, "tools/bin/nacptool.exe") local nacptool = path.join(devkitPro, "tools/bin/nacptool.exe")
local elf2nro = path.join(devkitPro, "tools/bin/elf2nro.exe") local elf2nro = path.join(devkitPro, "tools/bin/elf2nro.exe")
-- 确保 romfs 目录存在
local romfs = path.join(example_dir, "romfs")
if not os.isdir(romfs) then
os.mkdir(romfs)
end
-- 复制着色器文件到 romfs/shader 目录
local shader_source = path.join(example_dir, "../../shader")
local shader_target = path.join(romfs, "shader")
if os.isdir(shader_source) then
if not os.isdir(shader_target) then
os.mkdir(shader_target)
end
os.cp(path.join(shader_source, "*"), shader_target)
print("Copied shaders to romfs: " .. shader_target)
end
if os.isfile(nacptool) and os.isfile(elf2nro) then if os.isfile(nacptool) and os.isfile(elf2nro) then
os.vrunv(nacptool, {"--create", "Scene Graph Demo", "Extra2D Team", "1.0.0", nacp_file}) os.vrunv(nacptool, {"--create", "Scene Graph Demo", "Extra2D Team", "1.0.0", nacp_file})
local romfs = path.join(example_dir, "romfs")
if os.isdir(romfs) then if os.isdir(romfs) then
os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs}) os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs})
else else