I'm having a weird problem with HLSL where I can't access any element of the array StructuredBuffers other than element 0

I’m having a weird problem with HLSL where I can’t access any element of the array StructuredBuffers other than element 0.
It works fine and everything is showing up right in glsl, but when I try it in hlsl it’s only using the first element in each buffer.

Checked renderdoc and the const buffer is working correctly, so the StructuredBuffers should be getting the right index.
Also in renderdoc the StructuredBuffers arrays always show they are using the first element, even when the const buffer is showing that it’s giving another index.
Texture work fine, if you hard code the index number. Is there something I’m missing in the binding notation?

Tried hard coding one of the buffers to see if makes a difference, and still shows the element 0 mesh, but not the element 1 mesh.
I’m working vulkan in that makes any difference.

This is the vertex shader.

#include "MeshProperties.hlsli"
struct SceneProperties
{
    uint MeshIndex;
};

struct VSInput
{
    [[vk::location(0)]] float3 Position : POSITION0;
    [[vk::location(1)]] float2 UV : TEXCOORD0;
    [[vk::location(2)]] float3 Normal : NORMAL0;
    [[vk::location(3)]] float3 Tangent : POSITION1;
    [[vk::location(4)]] float3 BiTangent : POSITION2;
    [[vk::location(5)]] float3 Color : COLOR0;
};

struct VSOutput
{
    float4 Pos : SV_POSITION;
    [[vk::location(0)]] float3 WorldPos : POSITION0;
    [[vk::location(1)]] float2 UV : TEXCOORD0;
    [[vk::location(2)]] float3 Normal : NORMAL0;
    [[vk::location(3)]] float3 Tangent : POSITION1;
    [[vk::location(4)]] float3 BiTangent : POSITION2;
    [[vk::location(5)]] float3 Color : COLOR0;
};

[[vk::push_constant]] SceneProperties sceneProperties;
[[vk::binding(0)]] StructuredBuffer<MeshProperties> meshPropertiesBuffer;
[[vk::binding(1)]] StructuredBuffer<float4x4> ModelTransformBuffer;

VSOutput main(VSInput input)
{
    VSOutput output = (VSOutput) 0;
    
    output.WorldPos = mul(ModelTransformBuffer[sceneProperties.MeshIndex], float4(input.Position, 1.0)).xyz;//sceneProperties.MeshIndex seems to always be 0, even when it's hardcoded as [1] for testing.
    output.Pos = mul(sceneProperties.proj, mul(sceneProperties.view, float4(output.WorldPos, 1.0)));
    output.Color = input.Color;
 
    return output;
}

PixelShader, doubt there’s any important info in there but just in case:

struct VSOutput
{
    [[vk::location(0)]] float3 WorldPos : POSITION0;
    [[vk::location(1)]] float2 UV : TEXCOORD0;
    [[vk::location(2)]] float3 Normal : NORMAL0;
    [[vk::location(3)]] float3 Tangent : POSITION1;
    [[vk::location(4)]] float3 BiTangent : POSITION2;
    [[vk::location(5)]] float3 Color : COLOR0;
};

float4 main(VSOutput input) : SV_TARGET
{
    return float4(1.0f, 1.0f, 0.0f, 1.0f);
}

And the working glsl vertex shader since I was trying translate the glsl to the hlsl shader that isn’t working.

layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aUV;
layout (location = 3) in vec3 aTangent;
layout (location = 4) in vec3 aBitangent;
layout (location = 5) in vec3 aColor;

layout(location = 0) out vec3 FragPos;
layout(location = 1) out vec2 UV;
layout(location = 2) out vec3 Normal;
layout(location = 3) out vec3 Tangent;
layout(location = 4) out vec3 BiTangent;
layout(location = 5) out vec3 Color;

layout(binding = 0) buffer MeshPropertiesBuffer { MeshProperties meshProperties; } meshBuffer[];
layout(binding = 1) buffer TransformBuffer { mat4 transform; } transformBuffer[];

layout(push_constant) uniform SceneData
{
    uint MeshIndex;
} sceneData;

void main() {

  gl_Position = sceneData.proj * 
                  sceneData.view *                
                  transformBuffer[sceneData.MeshIndex].transform * 
                  vec4(inPosition, 1.0);
    Color = aColor;
    UV = aUV;
}

Someone else was asking to see the how the binding works, so I figured I’d show it here too.
Basically I get the bindings like this for each type. Since I’m talking about since I used transform buffer as the main problem I’ll just show that binding. The other StructuredBuffers are using the same type of binding logic. It works perfectly in glsl.

std::vector<VkDescriptorBufferInfo> GLTFSceneManager::GetGameObjectTransformBuffer()
{
	std::vector<VkDescriptorBufferInfo>	TransformPropertiesBuffer;
	if (GameObjectList.size() == 0)
	{
		VkDescriptorBufferInfo nullBuffer;
		nullBuffer.buffer = VK_NULL_HANDLE;
		nullBuffer.offset = 0;
		nullBuffer.range = VK_WHOLE_SIZE;
		TransformPropertiesBuffer.emplace_back(nullBuffer);
	}
	else
	{
		for (auto& gameObject : GameObjectList)
		{
			VkDescriptorBufferInfo TransformBufferInfo = {};
			TransformBufferInfo.buffer = gameObject->GetGameObjectTransformMatrixBuffer().buffer;
			TransformBufferInfo.offset = 0;
			TransformBufferInfo.range = VK_WHOLE_SIZE;
			TransformPropertiesBuffer.emplace_back(TransformBufferInfo);
		}
	}

	return TransformPropertiesBuffer;
}
std::vector<VkDescriptorBufferInfo> Mesh::UpdateMeshTransformBuffer()
{
	std::vector<VkDescriptorBufferInfo> TransformDescriptorList;
	VkDescriptorBufferInfo transformMatrixPropertiesBufferInfo = {};
	transformMatrixPropertiesBufferInfo.buffer = MeshTransformBuffer.GetBuffer();
	transformMatrixPropertiesBufferInfo.offset = 0;
	transformMatrixPropertiesBufferInfo.range = VK_WHOLE_SIZE;
	TransformDescriptorList.emplace_back(transformMatrixPropertiesBufferInfo);
	TransformMatrixBuffer = TransformDescriptorList;
	return TransformMatrixBuffer;
}

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.