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 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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue