Search code examples
glslbuffershadervulkanimgui

UBO value changes value when passed to shader


I am trying to update the value of a uniform variable within my shader using an ImGui slider however the value I pass in is correct on the CPU side but when its at the GPU it becomes a negative value. I give an example of how I am setting this all up where someVal is the value being passed to the GPU which represents the radius value in the image I show (Naming was changed to help make things slightly clearer). This is what I am currently doing

static float ImGuiAdjustVal = 0.02f;

ImGui::SliderFloat("value: ", &ImGuiAdjustVal, 0.0f, 5.0f);

struct UniformObject {

    alignas(4) float someVal;
};

// update uniforms function

UniformObject ub{};
ub.someVal = ImGuiAdjustVal;

// both show same result and slider is able to adjust the value. The value just incorrectly makes it to the shader
std::cout << "Value: " << ImGuiAdjustVal << std::endl;
std::cout << "Sending to GPU" << ub.someVal << std::endl;

void* data;
vkMapMemory(device, uniformBufferMem[currentImage], 0, sizeof(ub), 0, &data);
memcpy(data, &ub, sizeof(ub));
vkUnmapMemory(device, uniformBufferMem[currentImage]);

// in my shader
layout(std140, binding = 1) uniform UniformObject {
  
    float someVal;
}ub;

float exampleProperty = ub.someVal;

In renderDoc my value is showing as becoming -0.00295 instead of the set value of 0.02 enter image description here

If I adjust the value using the ImGui::Slider the value will update in the print statements but the value will remain -0.00295 in the GPU. I have tested this by using the slider to change the value and capturing a frame in renderDoc to see if the value changed. However, the value remained -0.00295 as mentioned.


Solution

  • I was taking in an array of samples which was set to 64 but in my shader I had set it to 32. This caused my other variables to receive weird values.

    struct UBOStruct {
        alignas(16) vec3 samples[64];
        alignas(4) float radius;
    }
    
    // shader 
    layout(std140, binding = 1) uniform UBOStruct {
       vec4 samples[32];
       float radius;
    
    }ubo;
    

    The solution is to ensure all your values are being taken in correctly

    struct UBOStruct {
       alignas(16) vec3 samples[64];
       alignas(4) float radius;
    }
    
    // shader 
    layout(std140, binding = 1) uniform UBOStruct {
       vec4 samples[64];
       float radius;
    
    }ubo;