How to handle material textures when deferred shading?

67 views Asked by At

I am trying to implement deferred shading to replace my traditional forward shading.
My current forward lighting implementation works as follow.

For each mesh I bind his material, textures and I render. Pixel shader look like this:

struct MaterialStruct
{
    float4 baseColor;
    float4 specularColor;
    int type;

    bool hasBaseColorTex;
    bool hasSpecularColorTex;
    bool hasNormalTex;
};

cbuffer MaterialCB : register(b0)
{
    MaterialStruct Material;
};

// Textures here ---------------------------------------------
Texture2D baseColorTex : register(t0);
Texture2D specularColorTex : register(t1);
Texture2D normalTex : register(t2);
//------------------------------------------------------------4

struct VS_OUTPUT
{
    float4 position: SV_POSITION;
    float3 worldPosition : POSITION;
    float3 normal : NORMAL;
    float2 texCoord: TEXCOORD;
};

float4 main(VS_OUTPUT input) : SV_TARGET
{
    float4 pixelColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
    // .....
    return pixelColor;
}

CPP side i have:

__declspec(align(16)) struct DX12Material
{
    DirectX::XMFLOAT4 baseColor;
    DirectX::XMFLOAT4 specularColor;
    INT type;

    BOOL hasBaseColorTex;
    BOOL hasSpecularColorTex;
    BOOL hasNormalTex;
};

struct MaterialCB
{
    DX12Material material;
};

But now i want to implement deferred shading(and later raytracing). To do so i need to have access to all materials and textures at once. I first use a structured buffer of materials intead of a single constant buffer.

HLSL side:

StructuredBuffer<MaterialStruct> sceneMaterials : register(t0);

Now where to put the textures? I had two idea.

IDEA 1

Directly put the texture inside the material struct. So:

struct MaterialStruct
{
    float4 baseColor;
    float4 specularColor;
    int type;

    bool hasBaseColorTex;
    bool hasSpecularColorTex;
    bool hasNormalTex;

    Texture2D baseColorTex;
    Texture2D specularColorTex;
    Texture2D normalTex;
};  

This compiles. But what to put CPP side?

__declspec(align(16)) struct DX12Material
{
    DirectX::XMFLOAT4 baseColor;
    DirectX::XMFLOAT4 specularColor;
    INT type;

    BOOL hasBaseColorTex;
    BOOL hasSpecularColorTex;
    BOOL hasNormalTex;

    /* What to put here? */
};

IDEA 2

Use a Texture2DArray for each texture. HLSL side:

struct MaterialStruct
{
    float4 baseColor;
    float4 specularColor;
    int type;

    int baseColorTexIndex;
    int specularColorTexIndex;
    int normalTexIndex;
};  

StructuredBuffer<MaterialStruct> sceneMaterials : register(t0);

Texture2DArray baseColorTexs : register(t1);
Texture2DArray specularColorTexs : register(t2);
Texture2DArray normalTexs : register(t3);

What is the proper way to go?

0

There are 0 answers