I have researched and the methods used to make a blooming effects are usually based on having a sharp and blurred image conjoined to give the glow effect. But I want to know how I can make gl_lines(or any line) have brightness. Since in my game I am randomly generating a simple 2D terrain, I wish to make the terrain line segments glow.
Use a fragment shader to calculate the distance from a fragment to the edge and color the fragment with the appropriate color value. You can use a simple control curve to control the radius and intensity anlong of the glow(like in photoshop). It can also be tuned to act like wireframe visualization. The idea is you don't really rasterize points to lines using a draw call, just shade each pixel based on its distance from the corresponding edge.
The difference from using a blur pass is that you will first get better performance, and second - per-pixel control over the glow, you can have non-uniform glow which you cannot get by using blur because it is not really aware of the actual line geometry, it just blindly works on pixels, whereas with edge distance detection you do use the actual geometry data as input without flatting it down to pixels. You can also have stuff like gradient glows, e.g. the glow color is different and changes with the radius.
Related
I have a very simple case. I want to draw the outline of an object, in this case I think they'll only be spheres, but I'd like to not rely on this.
I've found methods such as:
Draw the object to the stencil buffer
Turn on wireframe mode
Draw the object with thick lines
Draw the real object on the top
The problem I have with this method is that my models have a lot of vertices, and this requires me to draw it three times. I'm getting some significant frame rate drops.
Are there other ways to do this? My next guess would be to draw circles on the final render as a post-process effect, seeing as I'm only looking at spheres. But I'd much much rather do this for more than just spheres.
Is there something I can do in an existing shader to outline?
I'd also like the outline to appear when the object is behind others.
I'm using OpenGL 4.3.
I know 3 ways of doing contour rendering:
Using the stencil buffer
The first one is a slightly modified version of the one you described: you first render your object as normal with stencil buffer on, then you slightly scale it and render it plain color where the stencil buffer is not filled. You can find an explanation of this technique here.
Using image processing techniques
The second one is a post-process step, where you look for edges using image processing filters (like the sobel operator) and you compose your rendering with your contour detection result. The good thing with the sobel operator is that it is separable; this means you can do the detection in two 1D passes, which is more efficient that doing one 2D pass.
Using the geometry shader
Last but not least, you can use the geometry shader to extract the silhouette of your mesh. The idea is to use adjacent vertices of a triangle to detect if one edge of this triangle (let call it t0) is a contour.
To do this, for each edge ei of t0:
build a new triangle ti using the vertices of ei and its associated vertex,
compute the normal ni of ti, and the normal n0 of t0, transform them both in view space (the silhouette depends on the point of view),
compute the dot product between n0 and ni. If its value is negative, this means that the normals are in opposite directions and the edge ei is a silhouette edge.
You then build a quad around ei, emit each of its vertices and color them the way you want in the fragment shader.
This is the basic idea of this algorithm. Using only this will result in aliased edges, with holes between them, but this can be improved. You can read this paper, and this blog post for further informations.
In my experience you get good results if you render the outlined object in white (unlit) to a texture as big as the final framebuffer, then draw a framebuffer-sized quad with that texture and have the fragment shader blur or otherwise process it and apply the desired color.
I have an example here
I am trying to create the effect of the water surface thickness with a vertex-fragment shader.
I am in a 3D game environment but It's a scroll view so a "2D" view.
Here is a good tutorial of creating such effect in real 2D using fragment shader.
But this can't be used in my case I think.
For the moment I have only a plane were I apply refraction.
And I want to apply the water thickness effect. But I don't know how to do it.
I am not trying to create some water deformation/displacement using vertex for the moment, this is not the point.
I don't know if it's possible with a simple quad maybe should I use an object like this.
Here are some examples.
Thanks a lot !
[EDIT] Added Rayman water effect to have a better reference of the effect.
I am trying to create 2D Water effect with a vertex-fragment shader on a simple quad.
Your first misconception is thinking in 2D. What you see in your right picture is the interaction of light with a 2 surface in a 3D space. A simple quad will not suffice.
For water you need some surface displacement. You can either simulate this by solving some wave equation. Or you're using a fourier transform based approach. I suggest the second. Next you render your scene "regular" for everything above the water, then "murky and refracted" for everything below the water line. Render both to textures.
Then You render the water surface. When looking at the Air→Water Interface (i.e. from above) use a Fresnel reflection term, i.e. mix between top reflection and see through depending on the angle of incidence, and for a too small angle emulate Brewster reflection. For the Water→Air Interface (i.e. from below) you do similar, only you don't need the Fresnel term, but only the Brewster term, to account for total internal reflection.
Since you do all mixing in the fragment shader, you don't need blending, hence no need to sort drawing operations for the water depth.
Yes, rendering water is not trivial.
My goal is to draw white lines over an asphalt road. Since the properties of the road change, there cannot be just a texture representing both asphalt and white lines.
The current approach is to apply the asphalt texture and code some information in the other two texture coordinates. In a pixel shader, reading those coordinates, I decide whether that fragment should be white or not.
This results in high levels of aliasing. And that’s the problem I want to try to solve.
I have been changing the “whiteness” of the line applying smoothstep or linear interpolation. I have also changed the width and color according to distance from camera. This helps a little bit, but at far away distances, there are still ugly aliased lines.
How would you go on doing this? Would it be better to have a texture representing a smoothed white line and accessing the texels? Should I implement a bilinear filter accessing neighboring texels?
You should simply use 2 textures with 2 coordinates.
Small seamless asphalt texture tiled on the road polygon.
Mark texture with alpha that you will place on the middle of this polygon (with texture coordinate offset)
Or you can create extra polygons in the middle of the road for marks to avoid any aliasing.
To make it all looks real you can apply Texture Bombing with dirt and cracks.
is it possible to create a GLSL shader to get any object to be surrounded by a glowing effect?
Let's say i have a 3d cube and if it's selected the cube should be surrounded by a blue glowing effect. Any hints?
Well there are several ways of doing this. If each object is also represented in a winged edge format then it is trivial to calculate the silhouette and then extrude it to generate a glow. This however is, very much, a CPU method.
For a GPU method you could try rendering to an offscreen buffer with the stencil set to increment. If you then perform a blur on the image (though only writing to pixels where the stencil is non zero) you will get a blur around the edge of the image which can then be drawn into the main scene with alpha blending. This is more a blur than a glow but it would be relatively easy to re-jig the brightness so that it renders a glow.
There are plenty of other methods too ... here are a couple of links for you to look through:
http://http.developer.nvidia.com/GPUGems/gpugems_ch21.html
http://www.codeproject.com/KB/directx/stencilbufferglowspart1.aspx?display=Mobile
Have a hunt round on google because there is lots of information :)
Greetings all,
As seen in the image , I draw lots of contours using GL_LINE_STRIP.
But the contours look like a mess and I wondering how I can make this look good.(to see the depth..etc )
I must render contours so , i have to stick with GL_LINE_STRIP.I am wondering how I can enable lighting for this?
Thanks in advance
Original image
http://oi53.tinypic.com/287je40.jpg
Lighting contours isn't going to do much good, but you could use fog or manually set the line colors based on distance (or even altitude) to give a depth effect.
Updated:
umanga, at first I thought lighting wouldn't work because lighting is based on surface normal vectors - and you have no surfaces. However #roe pointed out that normal vectors are actually per vertex in OpenGL, and as such, any POLYLINE can have normals. So that would be an option.
It's not entirely clear what the normal should be for a 3D line, as #Julien said. The question is how to define normals for the contour lines such that the resulting lighting makes visual sense and helps clarify the depth?
If all the vertices in each contour are coplanar (e.g. in the XY plane), you could set the 3D normal to be the 2D normal, with 0 as the Z coordinate. The resulting lighting would give a visual sense of shape, though maybe not of depth.
If you know the slope of the surface (assuming there is a surface) at each point along the line, you could use the surface normal and do a better job of showing depth; this is essentially like a hill-shading applied only to the contour lines. The question then is why not display the whole surface?
End of update
+1 to Ben's suggestion of setting the line colors based on altitude (is it topographic contours?) or based on distance from viewer. You could also fill the polygon surrounded by each contour with a similar color, as in http://en.wikipedia.org/wiki/File:IsraelCVFRtopography.jpg
Another way to make the lines clearer would be to have fewer of them... can you adjust the density of the contours? E.g. one contour line per 5ft height difference instead of per 1ft, or whatever the units are. Depending on what it is you're drawing contours of.
Other techniques for elucidating depth include stereoscopy, and rotating the image in 3D while the viewer is watching.
If your looking for shading then you would normally convert the contours to a solid. The usual way to do that is to build a mesh by setting up 4 corner points at zero height at the bounds or beyond then dropping the contours into the mesh and getting the mesh to triangulate the coords in. Once done you then have a triangulated solid hull for which you can find the normals and smooth them over adjacent faces to create smooth terrain.
To triangulate the mesh one normally uses the Delaunay algorithm which is a bit of a beast but there does exist libraries for doing it. The best of which I know of is the ones based on Guibas as Stolfi papers since its pretty optimal.
To generate the normals you do a simple cross product and ensure the facing is correct and manually renormalize them before feeding into the glNormal.
The in the old days you used to make a glList out of the result but the newer way is to make a vertex array. If you want to be extra flash then you can look for coincident planar faces and optimize the mesh down for faster redraw but thats a bit of a black art - good for games, not so good for CAD.
(thx for bonus last time)