222 lines
6.5 KiB
Plaintext
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;
|
|
}
|
|
*/
|