-
-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for floating point textures to OpenGL #724
Comments
Created by: REAS @codeanticode will know the answer |
Created by: codeanticode Hi @AmnonOwed, it is not currently possible to define a floating point texture through Processing's API, the internal format can only be normal RGB or RGBA (i.e.: 1 byte per channel). Quickly inspecting the code, seems like it shouldn't be too difficult to add GL.GL_RGBA32F or GL.GL_RGB32F as fp formats, but this would probably require an additional hint, or some other method to signal to the renderer that the user wishes to use fp textures. |
Created by: AmnonOwed Hey guys, Thanks for the quick response. Would be great to add this functionality. I think the two options to let the user set this would be either a) per renderer or b) per texture. With regard to these two options: a) per renderer b) per texture I think option a (per renderer) is most in line with the current Processsing API. So it would make sense to implement this option. The only question I would have then: can you use the global renderer setting, to set different formats for different textures in one sketch? So for example set / keep most textures to 1 byte per channel, but set one texture to 32FLOAT. I guess this could be possible by switching the global format setting back and forth at strategic points in the sketch? Not sure how this currently works for textureWrap() etc. |
Created by: benfry @codeanticode Can this be done inside begin/endPGL? If so, we should probably close. Seems akin to adding CMYK support instead of just RGB since it touches so many parts of the API. |
Created by: timseverien Any update on this? Floating point textures are great for GPGPU. |
Created by: codeanticode Hi, as mentioned earlier, this would require adding a bunch of new API to the core. I'm happy to have a more specific discussion, but this kind of functionality seems more suitable to incorporate through a contributed library... have you looked at PixelFlow, it goes pretty far in terms of GPGPU, and I believe it uses FP textures. |
Created by: timseverien Thanks for the link! PixelFlow seems to provide a lot of built-in GPGPU shaders, but I was unable to find utilities to use a custom shader. I'll have a more thorough look when I have more time.
Because Processing supports shaders, I think Processing should also provide the ability to choose how data is transferred to the GPU. The latter is essential for many projects. I was stoked finding out Processing supports shaders, and it feels counter-intuitive to download a library to work around this limitation. Nonetheless, I enjoy Processing a lot and am grateful of all your efforts. Anyway, I like @AmnonOwed per-renderer approach. How about |
Created by: cacheflowe The more I've been using shaders for advanced feedback & particle techniques, the more I've run into this need. I didn't quite realize why my calculations were suffering until an OpenGL expert suggested that I might not be using a 32-bit texture for storage & computation. That explained my limitation of |
Created by: timseverien Eventually I did manage to use PixelFlow to achieve what I couldn't with processing using the following code: import com.jogamp.opengl.GL;
import com.thomasdiewald.pixelflow.java.DwPixelFlow;
import com.thomasdiewald.pixelflow.java.dwgl.DwGLSLProgram;
import com.thomasdiewald.pixelflow.java.dwgl.DwGLTexture;
DwPixelFlow context;
PGraphics2D canvas; // A PGraphics object to render the data to
// Two shaders: one to update data, one to visualise data to screen
DwGLSLProgram shader;
DwGLSLProgram shaderScreen;
// An object containing two frame buffer objects (textures) I can swap
DwGLTexture.TexturePingPong buffer = new DwGLTexture.TexturePingPong();
void setup() {
context = new DwPixelFlow(this);
canvas = (PGraphics2D) createGraphics(512, 512, P2D);
shader = context.createShader("my-shader.glsl");
shaderScreen = context.createShader("my-shader-screen.glsl");
buffer.resize(context, GL.GL_RGBA32F, 512, 512, GL.GL_RGBA, GL.GL_FLOAT, GL.GL_NEAREST, GL.GL_REPEAT, 4, 1);
}
// Draw shader output to buffer.dest, where buffer.src acts as input data
void update() {
context.begin();
context.beginDraw(buffer.dest);
shader.begin();
shader.uniformTexture("uTexture", buffer.src);
shader.drawFullScreenQuad();
shader.end();
context.endDraw();
context.end();
buffer.swap();
}
void draw() {
update();
// Render data to PGraphics object with a shader to visualise data
context.begin();
context.beginDraw(canvas);
shaderScreen.begin();
shaderScreen,uniformTexture("uTexture", buffer.src);
shaderScreen.drawFullScreenQuad();
shaderScreen.end();
context.endDraw();
context.end();
// Render PGraphics object to screen
image(canvas, 0, 0);
} Resources:
|
Created by: codeanticode @timseverien thanks for posting your solution, it sounds like the floating texture support in PixelFlow can be nicely integrated with the core API. Do you think this makes adding FP texture support in the code superfluous? Perhaps we should write a tutorial about these advanced techniques... I wanted to write a follow up to the intro PShader tutorial for a long time, but never get the chance to do it :-) |
Created by: cacheflowe I did some research and just got 32-bit textures working as a proof-of-concept with very minimal changes. In PJOGL, where textures are created, I overrode the
That's it! This change allows shaders to work as they do in WebGL and other 32-bit GLSL contexts (like Shadertoy), where textures can be used as high-precision vec4 float data! This allows for proper GPU particles and feedback effects, and would probably benefit most shaders' fidelity. I've obviously just broken the intent of the PJOGL code, but I think there's the potential of adding a 32-bit texture option without much extra work. I'll try to think of a way to make this a reality, but I feel that someone like @codeanticode would have a good opinion on how to make this possible. Perhaps a toggle in Speaking to the previous question about PixelFlow's 32-bit support, you have to switch wholesale into the PixelFlow rendering techniques, and lose the option of using much of Processing's core functionality (this is my experience - I could be wrong). I think adding the 32-bit option into Processing's core would be a huge step forward. |
Created by: cacheflowe After further testing, I found some new info:
If anyone wants to try my recompiled |
Created by: cacheflowe I'm in way over my head on this, but after seeing another performance hit while using a different camera library, I'm wondering if the realtime conversion between OpenGL texture formats could be causing the slowdown. But perhaps it's something else. I'll keep investigating towards a real implementation of this feature. Maybe it's a lot more involved than I'd hoped 😬 Any advice on OpenGL texture formats and how they interplay in PGL would be very welcome. https://www.khronos.org/opengl/wiki/Pixel_Transfer |
Created by: cacheflowe I've revisited this after some conceptual direction from @benfry and arrived at a much simpler distillation that has little-to-no impact on the core. By overriding just a couple of things in
It was suggested that this could be built as a library, but this is a much more minimal addition than I expected. I'd love to hear opinions about how this might get integrated as an option for creating PGraphics instances - I'm happy to go down either core or library route, depending on informed opinions. This code above would be a really easy pull request. Some more info on what I'm doing (and I'll try to put together some complete examples), when you're creating a 32-bit texture to use as data, and manipulating each pixel in a shader to move a particle, you want to prep the PGraphics with the following configuration to have it behave properly. Otherwise, you'll get some funky artifacts:
Someone who's familiar with even more advanced shader techniques might have further additions or tweaks to OpenGL formats & specific texture/data configuration, but this example has been really helpful for my use-cases. |
Created by: benfry Much nicer solution! That looks simple enough that adding a |
Created by: Beervangeer Hi @cacheflowe , i would love to try this. I want to pass float texture data like @timseverien between shaders through processing. Do I have to rebuild from source to use your solution? Or can I add this constant and class extension in a different way? |
Created by: cacheflowe @Beervangeer - I never had the time/brainpower to get this submitted to the Processing core as a real solution, but I refined it within my own codebase in a way that's relatively easy to use and doesn't break the ways you'd normally use PGraphics and PShader objects. I wrapped up the code above into a class that mimics the Processing API as best as I could. You can add the class below that will create a PGraphics instance with an underlying 32-bit float texture. Then just call
|
Created by: jeremydouglass @benfry @sampottinger would a hint() for this be a incorporate-able in Processing3? or would it instead be a potential Processing4 feature? |
Created by: Beervangeer @cacheflow, thank you very much for creating this class! I tried it out, but I got a error on the static functions createGraphics and newDataPG. It says these methods cannot be declared static, because they can only be declared in a static or top level type. When I turn the new PGraphics32 calss into a static class, the error goes away. It seems I can still load a shader and draw it to screen with image(). Also when I use the PGRaphics32 I get this error: OpenGL error 1282 at bot endDraw(): I attached the project if you are interested. Its simple fluid simulation with two shaders, one for calculations the other for displaying. |
Created by: cacheflowe @Beervangeer A couple of lines in the
|
Created by: lindemeier
For others with the same issue (static class): |
Created by: stmaccarelli Hello everyone. |
Created by: sampottinger Hello! It may make sense to move this over to the Processing 4 repo. Things are pretty quiet on the |
Created by: SableRaf @sampottinger Done! Let me know if you need any more support from me on this. |
Created by: aphid91 The PGraphics32 class has been a life saver! Be very careful with newPG.noSmooth() as it can have some strange effects on texture lookups, even when using something like texelFetch() that should only care about individual pixels. See my comment here: processing/processing#5363 |
Created by: AmnonOwed
I'm packing data in a texture (PImage) to send to a fragment shader. I'm running into the limitations of the 32bit RGBA format that seems to be the default for every texture in Processing. It's causing banding effects in my output. Switching to floating point textures will most likely solve these problems, because of the increased accuracy.
I have searched high and low (all the forums, the source code, the issue list), but I cannot find a way to use floating points textures in Processing. Is this possible? If not, I would like to post this issue as a feature request.
The text was updated successfully, but these errors were encountered: