Skip to content

Slang Integration

EntropyPortal uses Slang as its primary shading language. Slang provides modern language features (generics, interfaces, modules) while maintaining compatibility with HLSL.

The ShaderCompilerService wraps the Slang API to provide:

  • Async Compilation: Shaders are compiled on background threads using WorkContract.
  • Entry Point Discovery: Automatically finds [shader("vertex")] and [shader("fragment")] entry points.
  • Include Handling: Resolves #include and import across the virtual file system.
graph TD
    Source[Slang Source] --> Compiler[Slang Compiler]
    Compiler -->|Parse| AST[AST w/ Imports]
    AST -->|Generate| Bytecode["SPIR-V / DXIL"]
    AST -->|Reflect| Meta["Reflection Data"]

    Bytecode --> GpuShader
    Meta --> GpuShader

Shaders in EntropyPortal are typically .slang files.

Example.slang
import SceneAttributes;
[shader("vertex")]
float4 vertexMain(float3 position : POSITION) : SV_Position
{
return mul(Scene.viewProjection, float4(position, 1.0));
}
[shader("fragment")]
float4 fragmentMain() : SV_Target
{
return float4(1, 0, 0, 1);
}

The service compiles this into a GpuShader object containing the bytecode for the target API (SPIR-V or DXIL).

EntropyPortal exposes pipeline state directly through Slang User Attributes. This allows shaders to define their own blending, depth, and rasterization state without requiring separate C++ configuration.

From clustered_forward.slang:

#if TRANSPARENT
// Transparent pass: alpha blending enabled, depth write disabled
[Queue("Transparent", 3000)]
[BlendState(BlendFactor.SrcAlpha, BlendFactor.OneMinusSrcAlpha, BlendFactor.One, BlendFactor.OneMinusSrcAlpha)]
[DepthState(0, CompareFunc.GreaterEqual)] // Depth write OFF
#else
// Opaque pass: no blending, depth write enabled
[Queue("Geometry", 2000)]
[BlendState(BlendFactor.One, BlendFactor.Zero, BlendFactor.One, BlendFactor.Zero)]
[DepthState(1, CompareFunc.GreaterEqual)] // Depth write ON
#endif
[Cull(CullMode.Back)]
[shader("fragment")]
float4 fsMain(VSOutput input) : SV_Target {
// ...
}

These attributes are parsed by the ShaderVariantSet during pipeline creation to configure the GpuRenderPipeline.