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

222 lines
6.5 KiB
Plaintext

// ===== 平台检测 =====
#ifdef __METAL_VERSION__
#define METAL_PLATFORM
#endif
#ifdef SPIRV
#define SPIRV_PLATFORM
#endif
// ===== 基础类型定义 =====
#ifdef METAL_PLATFORM
// Metal类型别名
typealias Texture2D_float = texture2d<float>;
typealias Texture2D_float4 = texture2d<float4>;
typealias RWTexture2D_float4 = texture2d<float4, access::read_write>;
typealias SamplerState = sampler;
// Metal属性包装器
struct MetalAttribute<T> {
T value;
};
#else
// HLSL/SPIR-V使用原生类型
typealias Texture2D_float = Texture2D<float>;
typealias Texture2D_float4 = Texture2D<float4>;
typealias RWTexture2D_float4 = RWTexture2D<float4>;
#endif
// ===== 资源声明辅助函数 =====
// 顶点着色器资源
#ifdef METAL_PLATFORM
#define VERTEX_TEXTURE(Type, Name, Binding) \
[[texture(Binding)]] Type Name
#define VERTEX_SAMPLER(Name, Binding) \
[[sampler(Binding)]] sampler Name
#define VERTEX_STORAGE_TEXTURE(Type, Name, Binding) \
[[texture(Binding)]] texture2d<Type, access::read_write> Name
#define VERTEX_UNIFORM_BUFFER(Type, Name, Binding) \
[[buffer(Binding)]] constant Type& Name
#define VERTEX_STORAGE_BUFFER(Type, Name, Binding) \
[[buffer(Binding)]] device Type* Name
#else
#define VERTEX_TEXTURE(Type, Name, Binding) \
[[vk::binding(Binding, 0)]] \
Type Name : register(t##Binding, space0)
#define VERTEX_SAMPLER(Name, Binding) \
[[vk::binding(Binding, 0)]] \
SamplerState Name : register(s##Binding, space0)
#define VERTEX_STORAGE_TEXTURE(Type, Name, Binding) \
[[vk::binding(Binding, 0)]] \
RWTexture2D<Type> Name : register(t##Binding, space0)
#define VERTEX_UNIFORM_BUFFER(Type, Name, Binding) \
[[vk::binding(Binding, 1)]] \
ConstantBuffer<Type> Name : register(b##Binding, space1)
#define VERTEX_STORAGE_BUFFER(Type, Name, Binding) \
[[vk::binding(Binding, 0)]] \
RWStructuredBuffer<Type> Name : register(t##Binding, space0)
#endif
// 片元着色器资源
#ifdef METAL_PLATFORM
#define FRAGMENT_TEXTURE(Type, Name, Binding) \
[[texture(Binding)]] Type Name
#define FRAGMENT_SAMPLER(Name, Binding) \
[[sampler(Binding)]] sampler Name
#define FRAGMENT_STORAGE_TEXTURE(Type, Name, Binding) \
[[texture(Binding)]] texture2d<Type, access::read_write> Name
#define FRAGMENT_UNIFORM_BUFFER(Type, Name, Binding) \
[[buffer(Binding)]] constant Type& Name
#define FRAGMENT_STORAGE_BUFFER(Type, Name, Binding) \
[[buffer(Binding)]] device Type* Name
#else
#define FRAGMENT_TEXTURE(Type, Name, Binding) \
[[vk::binding(Binding, 2)]] \
Type Name : register(t##Binding, space2)
#define FRAGMENT_SAMPLER(Name, Binding) \
[[vk::binding(Binding, 2)]] \
SamplerState Name : register(s##Binding, space2)
#define FRAGMENT_STORAGE_TEXTURE(Type, Name, Binding) \
[[vk::binding(Binding, 2)]] \
RWTexture2D<Type> Name : register(t##Binding, space2)
#define FRAGMENT_UNIFORM_BUFFER(Type, Name, Binding) \
[[vk::binding(Binding, 3)]] \
ConstantBuffer<Type> Name : register(b##Binding, space3)
#define FRAGMENT_STORAGE_BUFFER(Type, Name, Binding) \
[[vk::binding(Binding, 2)]] \
RWStructuredBuffer<Type> Name : register(t##Binding, space2)
#endif
// ===== 更灵活的Slang风格接口方案 =====
// 定义资源接口
interface IShaderResources {
// 这里可以定义通用的资源访问方法
}
// 顶点着色器资源包装器
struct VertexResources : IShaderResources {
// 根据目标平台选择不同的实现
#ifdef METAL_PLATFORM
struct Textures {
[[texture(0)]] texture2d<float> tex0;
[[texture(1)]] texture2d<float> tex1;
};
struct Samplers {
[[sampler(0)]] sampler samp0;
[[sampler(1)]] sampler samp1;
};
struct Uniforms<T> {
[[buffer(0)]] constant T& data;
};
#else
struct Textures {
[[vk::binding(0, 0)]] Texture2D tex0 : register(t0, space0);
[[vk::binding(1, 0)]] Texture2D tex1 : register(t1, space0);
};
struct Samplers {
[[vk::binding(0, 0)]] SamplerState samp0 : register(s0, space0);
[[vk::binding(1, 0)]] SamplerState samp1 : register(s1, space0);
};
struct Uniforms<T> {
[[vk::binding(0, 1)]] ConstantBuffer<T> data : register(b0, space1);
};
#endif
}
// 片元着色器资源包装器
struct FragmentResources : IShaderResources {
#ifdef METAL_PLATFORM
struct Textures {
[[texture(0)]] texture2d<float> tex0;
[[texture(1)]] texture2d<float> tex1;
};
struct Samplers {
[[sampler(0)]] sampler samp0;
[[sampler(1)]] sampler samp1;
};
struct Uniforms<T> {
[[buffer(0)]] constant T& data;
};
#else
struct Textures {
[[vk::binding(0, 2)]] Texture2D tex0 : register(t0, space2);
[[vk::binding(1, 2)]] Texture2D tex1 : register(t1, space2);
};
struct Samplers {
[[vk::binding(0, 2)]] SamplerState samp0 : register(s0, space2);
[[vk::binding(1, 2)]] SamplerState samp1 : register(s1, space2);
};
struct Uniforms<T> {
[[vk::binding(0, 3)]] ConstantBuffer<T> data : register(b0, space3);
};
#endif
}
// ===== 使用示例 =====
/*
// 定义统一数据结构
struct MyVertexUniforms {
float4x4 mvpMatrix;
float4 color;
};
struct MyFragmentUniforms {
float4 tintColor;
float opacity;
};
// 顶点着色器
VERTEX_TEXTURE(Texture2D, vertexTexture, 0);
VERTEX_SAMPLER(vertexSampler, 0);
VERTEX_UNIFORM_BUFFER(MyVertexUniforms, vertexUniforms, 0);
// 或者使用结构化方式
VertexResources::Textures vertTextures;
VertexResources::Samplers vertSamplers;
VertexResources::Uniforms<MyVertexUniforms> vertUniforms;
// 片元着色器
FRAGMENT_TEXTURE(Texture2D, fragmentTexture, 0);
FRAGMENT_SAMPLER(fragmentSampler, 0);
FRAGMENT_UNIFORM_BUFFER(MyFragmentUniforms, fragmentUniforms, 0);
// 着色器函数
[shader("vertex")]
float4 vertexMain(float3 position : POSITION) : SV_Position {
float4 color = vertexTexture.Sample(vertexSampler, float2(0.5, 0.5));
return mul(vertexUniforms.mvpMatrix, float4(position, 1.0));
}
[shader("fragment")]
float4 fragmentMain(float2 uv : TEXCOORD0) : SV_Target {
float4 color = fragmentTexture.Sample(fragmentSampler, uv);
return color * fragmentUniforms.tintColor * fragmentUniforms.opacity;
}
*/