Search code examples
shadersfmlfragment-shader

SFML Shaders uniforms: passing my own class


I'm coding simple raytracer on c++ using sfml to draw output images. The problem on CPU was speed, so I decided to use shaders to speed up everything a bit

I am new to GLSL. In the tutorial, it's written, that you can pass some variables to your shader, using shader.setParameter("myvar", 5.f). Then it's written that "setParameter's overloads support all the types provided by SFML"

Okay, so I can pass float, vec2, vec3, vec4, etc.

The question is: can I somehow pass my own class in shader's uniforms?

The problem is that for now, I have to load Scene (class, that represents objects' positions and over things for raytracing) in each pixel's shadering process, and I suppose it can severely slow down everything.


Solution

  • You should be using setUniform instead of setParameter as the latter has been deprecated.

    Although you can't pass a custom class directly to the shader with SFML, you can pass everything at once if you organise/prepare it in a specific way.
    You can pass an array of floats, which should allow you to pass all the information you need in one go. For this, you would use setUniformArray.

    You have other options too but they may involve more preparations.
    If everything you want to pass are sf::Vector2fs, you can pass an array of Glsl::Vec2s.
    For sf::Vector3fs, you can pass an array of Glsl::Vec3s.

    Another way to pass information that is a little more complicated is to use a sf::Texture. You can use a prepared one or use a sf::RenderTexture, draw onto to change its pixels and then use that. This allows you to encode information in the texture's pixels within its colours. You would then use setUniform to send the entire texture to the shader.

    In conclusion, it's likely that all the information you wish to send to the shader is made of multiple floats so you can just send an array of floats directly to the shader.