SceneKit – access destination color in shader modifier for blending - scenekit

Is there a way to access last fragment color (destination color) in Metal shader modifier similar to gl_LastFragData in GLES?
My goal is to perform custom blending using shader modifiers (SceneKit's SCNBlendModes do not suffice in my situation). Currently I'm using SCNTechnique with 3 passes (render the destination, render the source, combine) to achieve this and that seems like a major overkill to me + it is really hard to have several blending groups without introducing new passes.
SCNProgram does not seem like an option for several reasons (I'm using PBR, tessellation/subdivision; I'd rather stick with using techniques for now I guess).
I've tried using #extension GL_EXT_shader_framebuffer_fetch : require as suggested in this answer, but it doesn't work even for GLSL shader modifiers (I'm using Xcode 9.0 and iOS 11).
I've also stumbled upon this wonderful gist that has SceneKit's default metal shader implementation, but it seems that blending is not performed there. Which makes me wonder if that is the reason why I can't find any destination color reference: blending happens somewhere else.
Is SCNProgram is the only way besides the SCNTechnique atrocity?
P.S:
The only mention of gl_LastFragData in the context of Metal that I've found is in chapter 4.8 Programmable Blending of Metal Shading Language Specification which would be helpful if I could somehow access the [[color(0)]] or something similar in shader modifier (if that's even possible).

I just wanted to check that that you hadn't overlooked the fragment entry point?
In the documentation it says: "Use this entry point to change the color of a fragment after all other shading has been performed."
I'm not sure if this is exactly what you mean by accessing the "last fragment color" but thought it might be worth mentioning.
https://developer.apple.com/documentation/scenekit/scnshadermodifierentrypoint/1523342-fragment

Related

SDL_CreateRenderer() vs SDL_CreateSoftwareRenderer()

Does a renderer created with SDL_CreateSoftwareRenderer() behave any differently than one created with SDL_CreateRenderer() using the SDL_RENDERER_SOFTWARE flag?
There are differences on how these two operate, or even their intended use. SDL_CreateSoftwareRenderer creates software renderer drawing to given surface. There is no requirement for this surface to be window surface, you can draw to backbuffer, convert it to texture and feed the result to d3d or opengl renderer.
SDL_CreateRenderer creates renderer for a given window, meaning it is supposed to draw to that window - with some checks, like opengl or vulkan requires window to be created with specific flags. It goes through list of available rendering backends and tries to find the one that matches your flags the best. Eventually if it decides to use software renderer (either nothing else is supported or software is explicitly requested, although there is more than one way to do so - see the last paragraph) it calls more-or-less SDL_CreateSoftwareRenderer(SDL_GetWindowSurface(window)) (not exactly so, but if you'll trace the code it is the same).
flags in SDL_CreateRenderer are not absolute; if a hint says to use direct3d or opengl, your SDL_RENDERER_SOFTWARE will be ignored. SDL_CreateSoftwareRenderer is always software.
Nope! They should behave the same.
SDL2 has quite a list of convenience functions which are equivalent to simply calling another function with a specific set of arguments. For instance, looking at the API listing by name, you'll find that the SDL_LogMessage () function is matched with a variety of other functions that implicitly specify the priority field, like SDL_LogVerbose () or SDL_LogError ().
To some extent, in addition to providing ease-of-use, these combined convenience functions help provide brevity to code while still maintaining clarity. As such, I would advise and advocate for their use when possible!

Representing images as graphs based on pixels using OpenCV's CvGraph

Need to use c for a project and i saw this screenshot in a pdf which gave me the idea
http://i983.photobucket.com/albums/ae313/edmoney777/Screenshotfrom2013-11-10015540_zps3f09b5aa.png
It say's you can treat each pixel of an image as a graph node(or vertex i guess) so i was wondering how
i would do this using OpenCV and the CvGraph set of functions. Im trying to do this to learn about and how
to use graphs in computer vision and i think this would be a good starting point.
I know i can add a vetex to a graph with
int cvGraphAddVtx(CvGraph* graph, const CvGraphVtx* vtx=NULL, CvGraphVtx** inserted_vtx=NULL )
and the documentation says for the above functions vtx parameter
"Optional input argument used to initialize the added vertex (only user-defined fields beyond sizeof(CvGraphVtx) are copied)"
is this how i would represent a pixel as a graph vertex or am i barking up the wrong tree...I would love to learn more about
graphs so if someone could help me by maybe posting code, links, or good ol' fashioned advice...Id be grateful=)
http://vision.csd.uwo.ca/code has an implementation on Mulit-label optimization. GCoptimization.cpp file has a GCoptimizationGridGraph class, which I guess is what you need. I am not a C++ expert, so can't still figure out how it works. I am also looking for some simpler solution.

Advice for Object Detection on Embedded System with no non-standard libraries

I am looking for some advice for a good way to detect either square or circular objects in an image. I currently have a canny edge algorithm running on the original greyscale and I can produce this output:
http://imgur.com/FAwowr1
Now I can see that there is a cubesat in this picture, but what is a good computationally efficient way that the program can see that aswell? I have looked at houghs transform but that seems to be very computation heavy. I have also looked at Harris corner detect, but I feel I would get to many false positives, for I am essentially looking to isolate pictures that contain said cube satellite.
Anyone have any thoughts on some good algorithms to pursue? I am very limited on space so I cannot use any large external libraries like opencv. (This is all in C btw)
Many Thanks!
I would into what is called mathematical morphology
Basically you operate on binary images, so you must find a clever way to threshold them first , the you do operations such as erosion and dilation with some well selected structuring element to extract areas of interest in your image.

How could we get a variable value from GLSL?

I'm doing a project with a lot of calculation and i got an idea is throw pieces of work to GPU, but i wonder whether could we retrieve results from GLSL, if it is posible, how?
GLSL does not provide outputs besides what is placed in the frame buffer.
To program a GPU and get results more conveniently, use CUDA (NVidia only) or OpenCL (cross-platform).
In general, what you want to do is use OpenCL for general-purpose GPU tasks. However, if you are insistent about pretending that OpenGL is not a rendering API...
Framebuffer Objects make it relatively easy to render to multiple outputs. This of course means that you have to structure your processing such that what gets rendered matches what you want. You can render to 32-bit floating-point "images", so you have access to plenty of precision. The biggest difficulty is what I stated: figuring out how to structure your task to match rendering.
It's a bit easier when using transform feedback. This is the ability to write the output of the vertex (or geometry) shader processing to a buffer object. This still requires structuring your tasks into something like rendering, but it's easier because vertex shaders have a strict one-vertex-to-one-vertex mapping. For every input vertex, there is exactly one output. And if you draw GL_POINTS, it's not too difficult to use attributes to pass the data that changes.
Both easier and harder is the use of shader_image_load_store. This is effectively the ability to read/write from/to arbitrary images "whenever you want". I put that last part in quotes because there are lots of esoteric rules about data race conditions: reading from a value written by another shader invocation and so forth. These are not trivial to deal with. You can try to structure your code to avoid them, by not writing to the same image location in the same shader. But in many cases, if you could do that, you could just render to the framebuffer.
Ultimately, it's pretty much impossible to answer this question in the general case, without knowing what exactly you're trying to actually do. How you approach GPGPU through a rendering API depends greatly on exactly what you're trying to compute.

Drawing per-pixel into a backbuffer or texture to display to screen, using opengl - no glDrawPixels()

Basically, I have an array of data (fluid simulation data) which is generated per-frame in real-time from user input (starts in system ram). I want to write the density of the fluid to a texture as an alpha value - I interpolate the array values to result in an array the size of the screen (the grid is relatively small) and map it to a 0 - 255 range. What is the most efficient way (ogl function) to write these values into a texture for use?
Things that have been suggested elsewhere, which I don't think I want to use (please, let me know if I've got it wrong):
glDrawPixels() - I'm under the impression that this will cause an interrupt each time I call it, which would make it slow, particularly at high resolutions.
Use a shader - I don't think that a shader can accept and process the volume of data in the array each frame (It was mentioned elsewhere that the cap on the amount of data they may accept is too low)
If I understand your problem correctly, both solutions are over-complicating the issue. Am I correct in thinking you've already generated an array of size x*y where x and y are your screen resolution, filled with unsigned bytes ?
If so, if you want an OpenGL texture that uses this data as its alpha channel, why not just create a texture, bind it to GL_TEXTURE_2D and call glTexImage2D with your data, using GL_ALPHA as the format and internal format, GL_UNSIGNED_BYTE as the type and (x,y) as the size ?
What makes you think a shader would perfom bad? The whole idea of shaders is about processing huge amounts of data very, very fast. Please use Google on the search phrase "General Purpose GPU computing" or "GPGPU".
Shaders can only gather data from buffers, not scatter. But what they can do is change values in the buffers. This allows for a (fragment) shader to write the locations of *GL_POINT*s, which are then in turn placed on the target pixels of the texture. Shader Model 3 and later GPUs can also access texture samplers from the geometry and vertex shader stages, so the fragment shader part gets really simple then.
If you just have a linear stream of positions and values, just send those to OpenGL through a Vertex Array, drawing *GL_POINT*s, with your target texture being a color attachment for a framebuffer object.
What is the most efficient way (ogl function) to write these values into a texture for use?
A good way would be to try to avoid any unnecessary extra copies. So you could use Pixel Buffer Objects which you map to your address space, and use that to directly generate your data into.
Since you want to update this data per frame, you also want to look for efficient buffer object streaming, so that you don't force implicit synchronizations between the CPU and GPU. An easy way to do that in your scenario would be using a ring buffer of 3 PBOs, which you advance every frame.
Things that have been suggested elsewhere, which I don't think I want to use (please, let me know if I've got it wrong):
glDrawPixels() - I'm under the impression that this will cause an interrupt each time I call it, which would make it slow, particularly at high resolutions.
Well, what the driver does is totally implementation-specific. I don't think that the "cause an interrupt each time" is a useful mental image here. You seem to completely underestimate the work the GL implementation will be doing behind your back. A GL call will not correspond to some command which is sent to the GPU.
But not using glDrawPixels is still a good choice. It is not very efficient, and it has been deprecated and removed from modern GL.
Use a shader - I don't think that a shader can accept and process the volume of data in the array each frame (It was mentioned elsewhere that the cap on the amount of data they may accept is too low)
You got this totally wrong. There is no way to not use a shader. If you're not writing one yourself (e.g. by using old "fixed-function pipeline" of the GL), the GPU driver will provide the shader for you. The hardware implementation for these earlier fixed function stages has been completely superseeded by programmable units - so if you can't do it with shaders, you can't do it with the GPU. And I would strongly recommend to write your own shader (it is the only option in modern GL, anyway).

Resources