Files
SDL3Test/shaders/common_2d.slang
daiqingshuang b532ce2f24 测试代码
2025-06-06 18:26:22 +08:00

328 lines
11 KiB
Plaintext
Raw Permalink 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.
// =============================================================================
// SDL 2D Shader Common Definitions
// 全局变量和通用功能定义
// =============================================================================
#ifndef SDL_2D_COMMON_H
#define SDL_2D_COMMON_H
// =============================================================================
// 平台检测和资源绑定宏
// =============================================================================
#ifdef METAL_TARGET
// Metal使用统一索引空间
#define BIND_VERTEX_TEXTURE(slot) register(t##slot)
#define BIND_VERTEX_SAMPLER(slot) register(s##slot)
#define BIND_VERTEX_BUFFER(slot) register(b##slot)
#define BIND_VERTEX_STORAGE(slot) register(u##slot)
#define BIND_PIXEL_TEXTURE(slot) register(t##slot)
#define BIND_PIXEL_SAMPLER(slot) register(s##slot)
#define BIND_PIXEL_BUFFER(slot) register(b##slot)
#define BIND_PIXEL_STORAGE(slot) register(u##slot)
#else
// Vulkan/DirectX 使用分离空间
#define BIND_VERTEX_TEXTURE(slot) register(t##slot, space0)
#define BIND_VERTEX_SAMPLER(slot) register(s##slot, space0)
#define BIND_VERTEX_BUFFER(slot) register(b##slot, space1)
#define BIND_VERTEX_STORAGE(slot) register(u##slot, space0)
#define BIND_PIXEL_TEXTURE(slot) register(t##slot, space2)
#define BIND_PIXEL_SAMPLER(slot) register(s##slot, space2)
#define BIND_PIXEL_BUFFER(slot) register(b##slot, space3)
#define BIND_PIXEL_STORAGE(slot) register(u##slot, space2)
#endif
// =============================================================================
// 数学常量
// =============================================================================
static const float PI = 3.14159265359;
static const float TWO_PI = 6.28318530718;
static const float HALF_PI = 1.57079632679;
static const float INV_PI = 0.31830988618;
static const float EPSILON = 1e-6;
static const float GAMMA = 2.2;
static const float INV_GAMMA = 0.454545;
// =============================================================================
// 标准2D顶点格式
// =============================================================================
struct Vertex2D {
float2 position; // 位置
float2 texCoord; // 纹理坐标
float4 color; // 顶点颜色
};
struct VertexShaderOutput {
float4 clipPos : SV_Position;
float2 texCoord : TEXCOORD0;
float4 color : TEXCOORD1;
float2 worldPos : TEXCOORD2; // 世界空间位置(用于特效)
};
// =============================================================================
// 全局Uniform缓冲区结构
// =============================================================================
// 场景级别的全局数据
struct SceneGlobals {
float4x4 viewProjection; // 视图投影矩阵
float4x4 invViewProjection; // 逆视图投影矩阵
float2 screenSize; // 屏幕尺寸
float2 invScreenSize; // 1.0 / 屏幕尺寸
float time; // 当前时间(秒)
float deltaTime; // 帧时间
float2 _padding0;
};
// 每个绘制调用的数据
struct DrawCallData {
float4x4 modelMatrix; // 模型矩阵
float4 tintColor; // 色调
float4 uvTransform; // UV变换 (offset.xy, scale.xy)
float2 pivot; // 旋转中心点
float rotation; // 旋转角度(弧度)
float _padding1;
};
// 材质参数
struct MaterialParams {
float4 baseColor; // 基础颜色
float opacity; // 不透明度
float brightness; // 亮度
float contrast; // 对比度
float saturation; // 饱和度
float hue; // 色相偏移
float bloomIntensity; // 泛光强度
float2 distortionAmount; // 扭曲程度
};
// 特效参数
struct EffectParams {
float4 glowColor; // 发光颜色
float glowSize; // 发光大小
float shadowSoftness; // 阴影柔和度
float shadowDistance; // 阴影距离
float shadowAngle; // 阴影角度
float4 gradientColors[4]; // 渐变颜色最多4个
float gradientStops[4]; // 渐变停止点
float noiseScale; // 噪声缩放
float noiseIntensity; // 噪声强度
float2 _padding2;
};
// =============================================================================
// 全局资源声明宏
// =============================================================================
// 顶点着色器全局资源
#define DECLARE_VERTEX_GLOBALS \
ConstantBuffer<SceneGlobals> g_scene : BIND_VERTEX_BUFFER(0); \
ConstantBuffer<DrawCallData> g_draw : BIND_VERTEX_BUFFER(1);
// 像素着色器全局资源
#define DECLARE_PIXEL_GLOBALS \
ConstantBuffer<SceneGlobals> g_scene : BIND_PIXEL_BUFFER(0); \
ConstantBuffer<MaterialParams> g_material : BIND_PIXEL_BUFFER(1); \
ConstantBuffer<EffectParams> g_effect : BIND_PIXEL_BUFFER(2);
// 标准纹理资源
#define DECLARE_STANDARD_TEXTURES \
Texture2D g_mainTexture : BIND_PIXEL_TEXTURE(0); \
Texture2D g_normalTexture : BIND_PIXEL_TEXTURE(1); \
Texture2D g_maskTexture : BIND_PIXEL_TEXTURE(2); \
Texture2D g_noiseTexture : BIND_PIXEL_TEXTURE(3); \
SamplerState g_linearSampler : BIND_PIXEL_SAMPLER(0); \
SamplerState g_pointSampler : BIND_PIXEL_SAMPLER(1); \
SamplerState g_linearClampSampler : BIND_PIXEL_SAMPLER(2); \
SamplerState g_pointClampSampler : BIND_PIXEL_SAMPLER(3);
// =============================================================================
// 实用函数库
// =============================================================================
// 2D变换函数
float2 rotate2D(float2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return float2(
v.x * c - v.y * s,
v.x * s + v.y * c
);
}
float2 scale2D(float2 v, float2 scale) {
return v * scale;
}
float2 translate2D(float2 v, float2 offset) {
return v + offset;
}
// UV坐标变换
float2 transformUV(float2 uv, float4 uvTransform) {
return uv * uvTransform.zw + uvTransform.xy;
}
// 颜色空间转换
float3 sRGBToLinear(float3 color) {
return pow(color, float3(GAMMA));
}
float3 linearToSRGB(float3 color) {
return pow(color, float3(INV_GAMMA));
}
float4 sRGBToLinear(float4 color) {
return float4(sRGBToLinear(color.rgb), color.a);
}
float4 linearToSRGB(float4 color) {
return float4(linearToSRGB(color.rgb), color.a);
}
// HSV颜色空间
float3 rgbToHSV(float3 rgb) {
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
float4 p = lerp(float4(rgb.bg, K.wz), float4(rgb.gb, K.xy), step(rgb.b, rgb.g));
float4 q = lerp(float4(p.xyw, rgb.r), float4(rgb.r, p.yzx), step(p.x, rgb.r));
float d = q.x - min(q.w, q.y);
float e = EPSILON;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
float3 hsvToRGB(float3 hsv) {
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(hsv.xxx + K.xyz) * 6.0 - K.www);
return hsv.z * lerp(K.xxx, saturate(p - K.xxx), hsv.y);
}
// 颜色调整函数
float3 adjustBrightness(float3 color, float brightness) {
return color * brightness;
}
float3 adjustContrast(float3 color, float contrast) {
return (color - 0.5) * contrast + 0.5;
}
float3 adjustSaturation(float3 color, float saturation) {
float gray = dot(color, float3(0.299, 0.587, 0.114));
return lerp(float3(gray), color, saturation);
}
float3 adjustHue(float3 color, float hueShift) {
float3 hsv = rgbToHSV(color);
hsv.x = frac(hsv.x + hueShift);
return hsvToRGB(hsv);
}
// 混合模式
float3 blendNormal(float3 base, float3 blend, float opacity) {
return lerp(base, blend, opacity);
}
float3 blendMultiply(float3 base, float3 blend, float opacity) {
return lerp(base, base * blend, opacity);
}
float3 blendScreen(float3 base, float3 blend, float opacity) {
return lerp(base, 1.0 - (1.0 - base) * (1.0 - blend), opacity);
}
float3 blendOverlay(float3 base, float3 blend, float opacity) {
float3 result = lerp(
2.0 * base * blend,
1.0 - 2.0 * (1.0 - base) * (1.0 - blend),
step(0.5, base)
);
return lerp(base, result, opacity);
}
// 抗锯齿函数
float smootherstep(float edge0, float edge1, float x) {
x = saturate((x - edge0) / (edge1 - edge0));
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}
// SDF相关函数
float sdCircle(float2 p, float r) {
return length(p) - r;
}
float sdBox(float2 p, float2 b) {
float2 d = abs(p) - b;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}
float sdRoundedBox(float2 p, float2 b, float r) {
float2 q = abs(p) - b + r;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
}
// =============================================================================
// 标准顶点着色器模板
// =============================================================================
#define STANDARD_VERTEX_SHADER(name) \
DECLARE_VERTEX_GLOBALS \
\
[shader("vertex")] \
VertexShaderOutput name(Vertex2D input) { \
VertexShaderOutput output; \
\
float2 pos = input.position; \
\
/* 应用旋转 */ \
if (abs(g_draw.rotation) > EPSILON) { \
pos -= g_draw.pivot; \
pos = rotate2D(pos, g_draw.rotation); \
pos += g_draw.pivot; \
} \
\
/* 应用模型变换 */ \
float4 worldPos = mul(g_draw.modelMatrix, float4(pos, 0.0, 1.0)); \
output.clipPos = mul(g_scene.viewProjection, worldPos); \
output.worldPos = worldPos.xy; \
\
/* UV变换 */ \
output.texCoord = transformUV(input.texCoord, g_draw.uvTransform); \
\
/* 颜色 */ \
output.color = input.color * g_draw.tintColor; \
\
return output; \
}
// =============================================================================
// 标准像素着色器模板
// =============================================================================
#define STANDARD_PIXEL_SHADER(name, code) \
DECLARE_PIXEL_GLOBALS \
DECLARE_STANDARD_TEXTURES \
\
[shader("fragment")] \
float4 name(VertexShaderOutput input) : SV_Target { \
float4 color = g_mainTexture.Sample(g_linearSampler, input.texCoord); \
color *= input.color; \
\
/* 用户代码 */ \
code \
\
/* 应用材质参数 */ \
color.rgb = adjustBrightness(color.rgb, g_material.brightness); \
color.rgb = adjustContrast(color.rgb, g_material.contrast); \
color.rgb = adjustSaturation(color.rgb, g_material.saturation); \
color.rgb = adjustHue(color.rgb, g_material.hue); \
color.a *= g_material.opacity; \
\
return color; \
}
#endif // SDL_2D_COMMON_H