feat(着色器): 添加默认和实例化着色器到场景图示例
添加默认和实例化着色器文件到场景图示例,包括顶点和片段着色器 修改构建脚本自动复制着色器文件到romfs目录
This commit is contained in:
parent
91e3e8fe57
commit
8cd883ede7
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -28,9 +28,25 @@ target("scene_graph_demo")
|
|||
local nacptool = path.join(devkitPro, "tools/bin/nacptool.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
|
||||
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
|
||||
os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs})
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue