Should range based fog use length(vec4) or length(vec3)? - opengl

I've been working on a simple range-based distance fog based on this tutorial. The tutorial uses length(viewSpace) to get the distance of a fragment to the camera, however viewSpace is vec4 meaning that the w component will factor into the length. Why is this useful? Is it even correct?

I think you've spotted a bug. I think that viewSpace.w will always be 1 (assuming standard world and view matrices), so the behaviour is reasonably consistent at least.
The author of the shaders has probably just tuned his parameters with the bug in place, so it's not doing any real harm for him, and any performance impact will be negligible, but you'd be better off changing viewSpace to a vec3 IMO.

Related

generate vertices using geometry shader(GLSL)

recently I'm trying to implement an algorithm to generate vine in real time. I kinda know how to do it on cpu, but I want to use GPU to accomplish this. I was thinking of geometry shader, but it looks like geometry shader executes in primitive scale, meaning it will perform the exact same functionality on every primitive, which is not what I expect.
Here is conceptually how my vine growing algorithm works. pick any point on an object mesh as the root point, the vine growing algorithm generates a series of points(representing the vine) according to previous points produced. Positions of points are influenced by such factors as gravity, adhesion and distance to triangle faces. Every point must be in the same side as the normal of triangle face.
How can I do this on GPU? Thanks a lot.
If you want to do something like this, that doesn't map well to the regular rendering pipeline, in glsl; your best bet is to use compute shaders (if you don't need to implement this in glsl, you may also want to take a look at OpenCL or CUDA as possible alternatives, though note that CUDA in vendor-locked to NVIDIA GPUs) in this case you can use it to generate the vine geometry using whatever method you had planned; then render the vines as normal in a second pass.
Note that this is only a good idea if your vine generation algorithm maps well to the massively parallel nature of a GPU. If your algorithm is inherently serial, then using the CPU to generate the geometry will likely yield better results.

OpenGL: Easy way of stopping light at vertexes?

I have a scene built in OpenGL. When my light is in the center of the room, the outside of the room is lit. Is there any easy way to make OpenGl stop the lighting at vertexes, or will it require complex calculations. Here are pictures of my crappy, quick scene showing the lighting as it is when asking this question:
Essentially, you want the walls of the room to cast a shadow. That's what you want when you want the exterior part of the object not to be lit.
Shadowing in graphics, is generally a pretty hard problem. There are a lot of good, and a lot of fast, solutions, but not both -- any one solution is going to be a tradeoff between the two. SIGGRAPH is full of all sorts of papers from Really Smart People trying to solve this problem.
If you want something quick and dirty, shadow mapping is not terribly difficult (at least the simple kind), but it is imprecise. You'll see artifacts along the intersections of your object and the walls, for one. For precision, stencil shadows will work, but you'll have hard-edged shadows.
One solution here would probably be to author the geometry in a way, that objects don't protrude outside walls (or separate them into inside/outside parts). Then render the interior and exterior with different lights.
You wouldn't have the problem if everything would cast shadows on everything.
If the lights are static, you might want to consider pre-calculating (baking) the lighting (together with shadows). You can do this in many 3D packages, and from a programming perspective this might be the simplest solution.
If you had a general solution for real-time rendering shadows for every light, that would also solve your problem, but that is a challenging task, and it might also not be the optimal thing to do, if you want to maintain good frame-rates.
If you want to learn about real-time shadow rendering, I recommend looking at shadow maps - they are generally the solution used in most games today. Note that for a point light you would need to render the shadow map for 6 sides of a cube-map. For practical purposes you should really consider which lights really need to cast shadows, and make some kind of trade-off.

Modifying an image with OpenGL?

I have a device to acquire XRay images. Due to some technical constrains, the detector is made of heterogeneous pixel size and multiple tilted and partially overlapping tiles. The image is thus distorted. The detector geometry is known precisely.
I need a function converting these distorted images into a flat image with homogeneous pixel size. I have already done this by CPU, but I would like to give a try with OpenGL to use the GPU in a portable way.
I have no experience with OpenGL programming, and most of the information I could find on the web was useless for this use. How should I proceed ? How do I do this ?
Image size are 560x860 pixels and we have batches of 720 images to process. I'm on Ubuntu.
OpenGL is for rendering polygons. You might be able to do multiple passes and use shaders to get what you want but you are better off re-writing the algorithm in OpenCL. The bonus then would be you have something portable that will even use multi core CPUs if no graphics accelerator card is available.
Rather than OpenGL, this sounds like a CUDA, or more generally GPGPU problem.
If you have C or C++ code to do it already, CUDA should be little more than figuring out the types you want to use on the GPU and how the algorithm can be tiled.
If you want to do this with OpengGL, you'd normally do it by supplying the current data as a texture, and writing a fragment shader that processes that data, and set it up to render to a texture. Once the output texture is fully rendered, you can retrieve it back to the CPU and write it out as a file.
I'm afraid it's hard to do much more than a very general sketch of the overall flow without knowing more about what you're doing -- but if (as you said) you've already done this with CUDA, you apparently already have a pretty fair idea of most of the details.
At heart what you are asking here is "how can I use a GPU to solve this problem?"
Modern GPUs are essentially linear algebra engines, so your first step would be to define your problem as a matrix that transforms an input coordinate < x, y > to its output in homogenous space:
For example, you would represent a transformation of scaling x by ½, scaling y by 1.2, and translating up and left by two units as:
and you can work out analogous transforms for rotation, shear, etc, as well.
Once you've got your transform represented as a matrix-vector multiplication, all you need to do is load your source data into a texture, specify your transform as the projection matrix, and render it to the result. The GPU performs the multiplication per pixel. (You can also write shaders, etc, that do more complicated math, factor in multiple vectors and matrices and what-not, but this is the basic idea.)
That said, once you have got your problem expressed as a linear transform, you can make it run a lot faster on the CPU too by leveraging eg SIMD or one of the many linear algebra libraries out there. Unless you need real-time performance or have a truly immense amount of data to process, using CUDA/GL/shaders etc may be more trouble than it's strictly worth, as there's a bit of clumsy machinery involved in initializing the libraries, setting up render targets, learning the details of graphics development, etc.
Simply converting your inner loop from ad-hoc math to a well-optimized linear algebra subroutine may give you enough of a performance boost on the CPU that you're done right there.
You might find this tutorial useful (it's a bit old, but note that it does contain some OpenGL 2.x GLSL after the Cg section). I don't believe there are any shortcuts to image processing in GLSL, if that's what you're looking for... you do need to understand a lot of the 3D rasterization aspect and historical baggage to use it effectively, although once you do have a framework for inputs and outputs set up you can forget about that and play around with your own algorithms in shader code relatively easily.
Having being doing this sort of thing for years (initially using Direct3D shaders, but more recently with CUDA) I have to say that I entirely agree with the posts here recommending CUDA/OpenCL. It makes life much simpler, and generally runs faster. I'd have to be pretty desperate to go back to a graphics API implementation of non-graphics algorithms now.

Setting ModelView matrix using rotate, translate, etc.. vs setting manual matrix

When setting the ModelView matrix you normally go through several transformations from the identity matrix. for example:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(270.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(-rect.size.height / 2, -rect.size.width / 2, 0.0f);
Instead of doing those operations one after the other (assume there are more than two), wouldn't it be more efficient to simply pre-calculate the resulting matrix and set the ModelView matrix to this manual matrix?
Sure, as long as the transformation isn't going to change. If, for example, the user can move and rotate your objects with the mouse then you are going to have to keep recalculating your matrix. In that case you may as well let OpenGL do it for you.
Also, unless you are having performance problems I would tend to not worry about efficiency and just stick with whichever way is going to keep your code simpler, which is probably to specify individual transformations.
Although I'm not entirely certain, Jeff Lamarche's excellent "OpenGL from the Ground Up" tutorials seem to indicate that the matrix multiplications occur on the CPU anyways. See tutorial number 7.
If you're still trying to get things going as fast as possible, his article has some code which uses the iPhone's vector processors (think SSE1/2/3/4 on a desktop) to speed up the code by 7 times (from 0.7% of runtime to 0.1% on Shark).
However, the performance increase may not be worth it, especially in terms of code readability. If you want your code to go as fast as possible, do it, but if not, consider keeping the library transformations so that others can figure out what's going on in your code. Everybody who does OpenGL on iPhone is going to recognize glTranslatef(x,y,z), but maybe not mTranslate(worldview, makeMat(...))

Does it make sense to use own mipmap creation algorithm for OpenGL textures?

I was wondering if the quality of texture mipmaps would be better if I used my own algorithm for pre-generating them, instead of the built-in automatic one. I'd probably use a slow but pretty algorithm, like Lanczos resampling.
Does it make sense? Will I get any quality gain on modern graphics cards?
There are good reasons to generate your own mipmaps. However, the quality of the downsampling is not one of them.
Game and graphic programmers have experimented with all kinds of downsampling algorithms in the past. In the end it turned out that the very simple "average four pixels"-method gives the best results. Also more advanced methods are in theory mathematical more correct they tend to take a lot of sharpness out of the mipmaps. This gives a flat look (Try it!).
For some (to me not understandable) reason the simple average method seems to have the best tradeoff between antialiasing and keeping the mipmaps sharp.
However, you may want to calculate your mipmaps with gamma-correction. OpenGL does not do this on it's own. This can make a real visual difference, especially for darker textures.
Doing so is simple. Instead of averaging four values together like this:
float average (float a, float b, float c, float d)
{
return (a+b+c+d)/4
}
Do this:
float GammaCorrectedAverage (float a, float b, float c, float d)
{
// assume a gamma of 2.0 In this case we can just square
// the components.
return sqrt ((a*a+b*b+c*c+d*d)/4)
}
This code assumes your color components are normalized to be in the range of 0 to 1.
What is motivating you to try? Are the mipmaps you have currently being poorly generated? (i.e. have you looked?) Bear in mind your results will often still be (tri)linearly interpolated anyway, so between that an motion there are often steeply diminishing returns to improved resampling.
It depends on the kind of assets you display. Lanczos filter gets closer to ideal low-pass filter and the results are noticeable if you compare the mip maps side by side. Most people will mistake aliasing for sharpness - again it depends whether your assets tend to contain high frequencies - I've definitely seen cases where box filter was not a good option. But since the mip map is then linearly interpolated anyway the gain might not be that noticeable. There is another thing to mention - most people use box filter and pass the output as an input into the next stage - in this way you lose both precision and visual energy (although gamma will help this one). If you can come up with code that uses arbitrary filter (mind you that most of them are separable into two passes) you would typically scale the filter kernel itself and produce mip map levels from the base texture, which is a good thing.
As an addition to this question, I have found that some completely different mipmapping (rather than those simply trying to achieve best down-scaling quality, like Lanczos filtering) algorithms have good effects on certain textures.
For instance, on some textures that are supposed to represent high-frequency information, I have tried using an algorithm that simply takes one random pixel of the four that are being considered for each iteration. The results depend much on the texture and what it is supposed to convey, but I have found that it gives great effect on some; not least for ground textures.
Another one I've tried is taking the most deviating of the four pixels to preserve contrasts. It has even fewer uses, but they do exist.
As such, I've implemented the option to choose mipmapping algorithm per texture.
EDIT: I thought I might provide some examples of the differences in practice. Here's a piece of grass texture on the ground, the leftmost picture being with standard average mipmapping, and the rightmost being with randomized mipmapping:
I hope the viewer can appreciate how much "apparent detail" is lost in the averaged mipmap, and how much flatter it looks for this kind of texture.
Also for reference, here are the same samples with 4× anisotropic filtering turned on (the above being tri-linear):
Anisotropic filtering makes the difference less pronounced, but it's still there.