Skip to content

Latest commit

 

History

History
94 lines (83 loc) · 4.05 KB

File metadata and controls

94 lines (83 loc) · 4.05 KB

Colorful

Demonstrates the use of shader binding

The Pixel Shader

cbuffer Args : register(b0)
{
    float time;
} 

[shader("pixel")]
float4 Pixel(Varying input) : SV_Target
{
    return float4(input.Uv, (cos(time) + 1) * 0.5, 1);
}

2 LoadResources

var modules = await LoadShaderModules("Shader", [ShaderStage.Vertex, ShaderStage.Pixel]);

// Defines the shader layout. 
// This rhi does not provide shader compilation and reflection related features, and needs to be provided by the user.
ShaderLayout = Device.CreateShaderLayout(
    [
        new()
        {
            Id = 0,                                         // The ID of the binding point. different stages and scopes can be repeated. 
            Scope = 0,                                      // The Id Scope
            Slot = 0,                                       // Dx: hlsl register; Vk: binding or push const offset when View is Constants
            Space = 0,                                      // Dx: hlsl space; Vk: binding set
            Count = 1,                                      // The size of the array, must >= 1, or == 1 when View is StaticSampler, or num of 32 bit value when view is Constants
            Format = GraphicsFormat.Unknown,                // The format
            Stage = ShaderStage.Pixel,                      // Can only be bound to a single shader stage
            View = ShaderLayoutItemView.Cbv,                // View type, Cbv Srv Uav Sampler Constants
            Type = ShaderLayoutItemType.ConstantBuffer,     // Resource type, use hlsl style, ConstantBuffer StructureBuffer Texture2D etc
            UavAccess = ResourceAccess.Unknown,             // Used to distinguish read and write behaviors during uav access
        }
    ]
);
// Define the bind group layout and binding layout
BindingLayout = Device.CreateBindingLayout(
    ShaderLayout, [
        // A binding layout has multiple binding group layouts, and a binding group can be shared among multiple bindings.
        // A typical usage is to extract shared binding groups for bindings shared by all materials,
        // and separate binding groups for bindings unique to each material, and split static and dynamic bindings into different binding groups.
        BindGroupLayout = Device.CreateBindGroupLayout(
            [
                new()
                {
                    Id = 0,                                         // Same to Id in ShaderLayout
                    Scope = 0,                                      // Same to Scope in ShaderLayout
                    Count = 1,                                      // Must be >= Count in ShaderLayout
                    StaticSamplerIndex = 0,                         // Index if View is StaticSampler
                    Format = GraphicsFormat.Unknown,                // Must same to Format in ShaderLayout
                    Stages = ShaderStageFlags.Pixel,                // Allow multiple stages
                    View = ShaderLayoutItemView.Cbv,                // Must same to View in ShaderLayout
                    Type = ShaderLayoutItemType.ConstantBuffer,     // Must same to Type in ShaderLayout
                    UavAccess = ResourceAccess.Unknown,             // If in shader layout is ResourceAccess.Unknown, then use this
                }
            ]
        )
    ], Name: Name
);

Shader = Device.CreateShader(modules, ShaderLayout);
Pipeline = Device.CreateGraphicsShaderPipeline(Shader, new() { .. Omitted here }, BindingLayout, Name: Name);

// Create argument buffer
ArgBuffer = Device.CreateBuffer(
    new()
    {
        Purpose = ResourcePurpose.ConstantBuffer,
        Size = sizeof(float),
    },
    Name: "Args"
);

// Create Binding
BindGroup = Isolate.CreateBindGroup(BindGroupLayout, [new(0, ArgBuffer)]);
Binding = Isolate.CreateBinding(BindingLayout, [new(0, BindGroup)]);

3 Render

// Write time data
cmd.Upload(ArgBuffer, [(float)time.Total.TotalSeconds]);
using var render = cmd.Render([new(Output, new Color(0.83f, 0.8f, 0.97f, 1f))]);
render.Draw(Pipeline, 4, Binding: Binding);