Monday, December 24, 2018

c++ - Cbuffer Padding Error



In my cbuffer in DirectX, I send 2 variables over to my HLSL shader called Light & Roughness. If I remove the Roughness variable my program compiles fine but as soon as I introduce Roughness I get the error: Exception thrown at 0x00007FFDDEFA0030 (d3d11.dll) in Eagle Engine.exe: 0xC0000005: Access violation reading location 0x00000000000000C0.


On the HLSL side the light variable contains it's defined value that was set in C++ and works fine without Roughness. If anyone could help me that would be great, I've included the necessary code below.


effects.fx


#include "Common.hlsl"

struct Light
{
float3 dir;
float4 ambient;
float4 diffuse;

};

cbuffer cbPerFrame
{
Light light;
float Roughness;
};

cbuffer cbPerObject
{

float4x4 WVP;
float4x4 World;
};

Texture2D ObjTexture;
SamplerState ObjSamplerState
{
Filter = ANISOTROPIC;
MaxAnisotropy = 16;
AddressU = Wrap;

AddressV = Wrap;
};

struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 TexCoord : TEXCOORD;
float3 normal : NORMAL;
};


float3 DirectDiffuseBRDF(float3 diffuseAlbedo, float nDotL)
{
return (diffuseAlbedo * nDotL);
}

VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD, float3 normal : NORMAL)
{
VS_OUTPUT output;

output.Pos = mul(inPos, WVP);


output.normal = mul(normal, World);

output.TexCoord = inTexCoord;

return output;
}

float4 PS(VS_OUTPUT input) : SV_TARGET
{

input.normal = normalize(input.normal);

float4 textureColor = ObjTexture.Sample(ObjSamplerState, input.TexCoord);

float nDotL = saturate(dot(input.normal, light.dir));

float3 diffuseLighting = textureColor * light.ambient * light.diffuse * Roughness;
diffuseLighting += saturate(DirectDiffuseBRDF(textureColor, nDotL));

return float4(diffuseLighting, textureColor.a);

}

In my Main.cpp


constbuffPerFrame.light = light;
constbuffPerFrame.Roughness = 1.0f;

devcon->UpdateSubresource(cbPerFrameBuffer, 0, NULL, &constbuffPerFrame, 0, 0);
devcon->PSSetConstantBuffers(0, 1, &cbPerFrameBuffer);

Header.h



struct Light
{
Light()
{
ZeroMemory(this, sizeof(Light));
}
XMFLOAT3 dir;
float pad;
XMFLOAT4 ambient;
XMFLOAT4 diffuse;

XMFLOAT4 specular;
};

struct cbPerFrame
{
Light light;
float Roughness;
};

Light light;

cbPerFrame constbuffPerFrame;

Answer



You are not padding after the roughness in the C++ side structure. You need to add 3 more floats of padding after roughness so that the buffer size is a multiple of 16 bytes.


On MSDN you can read a more complete explanation.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...