328 lines
11 KiB
Plaintext
328 lines
11 KiB
Plaintext
// =============================================================================
|
||
// 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
|