Shader storage buffer objects in JME

I need the SSBO to cache the results of some computations in the fragment shader, the usage in OpenGL is trivial GPU Buffers: Introduction to OpenGL 4.3 Shader Storage Buffers Objects | Geeks3D but i’m having issues in finding a way to implement it in jmonkey.
Does someone with more knowledge of the internal structure of jmonkey (@Momoko_Fan) have any hint from where i can start?

Not a lot of GPUs support SSBO… If I were you I would think if those computations could be done using OpenGL 3 features. E.g. render to texture, transform feedback, or maybe even the new OpenCL feature in jME 3.2.

Would help to know what you’re trying to do.

Even 6 year old cards support it…

I’m executing some computation on a texture and i’d like to do it once and save the result.
I know there are other, more complex but with better support ways, but the game isn’t worth the candle.

Anyway, now I remembered there is also this Image Load Store - OpenGL Wiki that is better for my purpose and probably easier to implement in jme.

Yeah indeed, if you are targeting gaming audience with a good hardware the support is not an issue, and on top of that, i use it for an optional setting.

What’s the issue with using render-to-texture then?

That’s true, SSBO is supported officially for 6 years old cards.
Consider however that SSBO has only been added to the OpenGL specification in 2012, and drivers might not support it very well yet. Some people also don’t have the latest drivers installed or run on old systems or systems with subpar OpenGL support (e.g. Linux). Some people also have Intel graphics which only started supporting SSBO in 2013. Recently we also had people complain that we require OpenGL 2 support even though OpenGL 2 capable GPUs have been available since 2003.

I’d like to do it transparently inside a material that already exists and find a way that is general and don’t require to write custom code every time i need it.
While from my understanding, to use the render to texture solution, i have to place the texture on a quad, apply the changes, render to texture, apply the new texture to the original material.

Well, i have linux with amd official drivers and opengl 4.3 is supported fine. This could be an issue for people which use Mesa drivers, but they won’t be able to run most games anyway for a reason or another.

This part isn’t true. The texture is updated and you don’t have to touch the original material anymore. For example, I use render to texture to render user interfaces onto curved book pages and I only have to set the texture on those pages once.

1 Like

You will need to modify the shader either way with your custom code, regardless of which approach you choose. Unless you use something like compute shaders, you will still need to render a quad in order to get your shader to actually run.

The shader is already running for rendering the model, i just want to cache some of the many values the shader generates in order to compute them only in the first frame and then retrieve them from said cache if available, otherwise regenerate and cache them.
Pseudocode:

pixel.x=texCoord.x*size.x
pixel.y=texCoord.y*size.y
index=pixel.y*size.x+pixel.x
value=cache[index]
if(value.w==0){
   value.xyz=calcXyz()
   value.w=1
   cache[index]=value
}
useValue(value)

I have reasons to believe this is possible with either ssbo or writable textures.

But i want to clarify my question: i didn’t ask for alternative methods, i didn’t ask if it’s good or not and i didn’t ask informations about how widely this feature is supported.

What i asked is, if someone and in particularly you, since afaik you wrote the core, can kindly share any advice i could use to bind an opengl object that is not supported by jmonkey, to a shader.

If you only need it for you private game and it is not ment to be in a public lib it should be possible quite simple if i remember correctly.

You could bind any buffer to a ssbo block.

glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferID); //Not remembering if needed or not
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, bufferBlock, bufferID);

and then access them in the shader trough the layout qualifiers

layout(std430, binding=0) buffer MyBuffer{
vec4 data[]
} myBuffer

Note that read write oparations on ssbo are incoherent (like with Image Load Store) so you need to setup the memory barriers yourself

1 Like

But then?
I have to bind it to the shader program and i have to do it in the rendering loop afaik, this is the part concerning my issue.

No, with BindBufferBase you bind a buffer to a specific BufferBlockIndex. Now any shader invoked can access that block. You just have to use the layout qualifiers where the binding=X has to match the BufferBlockIndex.

Ok, i will try that thanks