How to effectively blur a single object in a scene with GLSL? - java

I'm trying to blur an object in my scene with a GLSL shader.
What I do is when I'm drawing my scene, I may reach an object that needs to be blurred. When I do, I do so in two passes (from what I understand this is more optimized than doing so in a single pass).
So I draw the object to an off-screen FBO (transparent BG) with a horizontal blur. I then draw this FBO to the screen's default FBO with the vertical blur.
This is the result (method #1 in this image):
The white "glow" is problematic. However, if I draw the object to an off-screen FBO that does not have a transparent BG, I get the correct blur result from method #2 in the above image. However, I now obviously have a white BG behind the object - also not good.
What I'm asking is how exactly are you supposed to blur with the two-pass approach if you can't use a transparent-BG FBO? Or is there some trick I can do to fix this? Maybe mess with the blending src/dst functions?

Related

Libgdx Spritebatch bug

however, i have a weird issue, when drawing, it seems the outside 1px of an image is stretched to fit a rectangle, but the inside is only stetched to an extend, i was drawing to 48x48 tiles, but drew a 500x500 tile to show the issue. [ 500x500 draws fine ]
the worst part seems to be, it chooses when to stretch and not to stretch. and also what to strech. im sorry this is hard to explain but i have attached a image that i hope does a better job.
it could just be misunderstanding how to use a draw with spritebatch
edit: Tile is 48x48 not 64x64, ive just been working all day.
This is because you are not rendering "pixel perfect" which means your image does not line up with the pixel grid of your monitor. A quick fix might be to set a linear filter for your textures, since by default it uses nearest and thus a pixel on the screen will inherit the closest color it can get. A linear filter will interpolate colors and make that line "look" thinner.
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
If you are using texturepacker you can do this in one go by altering it's settings.
texturePackerSetting.filterMin = Texture.TextureFilter.Linear;
texturePackerSetting.filterMag = Texture.TextureFilter.Linear;
Or you could edit the atlas file itself by by changing the filter parameter to:
filter: Linear,Linear
This obviously costs more power since it needs to do more calculations for each pixel you drawn to the screen but I would not worry about this until your drawing is starting to get a bottleneck.
Another solutions is to draw pixel perfect which means you need to set your viewport to the size of the device gdx.graphics.getWidth, gdx.graphics.getHeight, in other words a ScreenViewport and draw your textures at exact sizes you want them. Of course this means a screen with more pixels sees more of your game world then a screen with less pixels and the more pixels a device has the smaller your textures will look. Another drawback of this is that you have to forget about any zooming or draw sprites for each level of zoom so they line up with the pixel grid of the device again.

Slick2d / LWJGL Adjusting alpha channel in OpenGL layer ( Java )

I apologize for some of my ignorance as I am fairly new to Slick2D and LWJGL. Essentially what I'm trying to do is make a scene look like night time by covering it with a GL_QUADS rectangle that is tinted blue and is translucent.
That part is easy enough. What I want to do from there is draw triangles into this layer that vary the alpha channel so. The reason I want to do this is so I can simulate a light source by decreasing the opacity of the blue tinted rectangle as it gets closer to the light source.
I drew an example of what the expected result should be with the green being the background, the blue being the nighttime effect created by a blue tinted rectangle, and the increasingly dim light source in the center.
I need to find a way to do this with triangles because I created a raycasting algorithm that generates the result as a series of gradient triangles.
I apologize if this is explained poorly. I will answer any questions you might have.
Here is the chunk of code used to create the blue tinted rectangle:
glColor4f (0.0f,0.0f,1.0f,0.4f);
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(screenWidth,0);
glVertex2f(screenWidth,screenHeight);
glVertex2f(0,screenHeight);
glEnd();
I would like to write a modified version of the following code to adjusted the alpha channel of that rectangle.
glBegin(GL_TRIANGLES);
setAlphaOfPriorLayer(0.0f);
glVertex2f(x1,y1);
setAlphaOfPriorLayer(0.4f);
glVertex2f(x2,y2);
setAlphaOfPriorLayer(0.4f);
glVertex2f(x3,y3);
glEnd();
Again, I'm using triangles to approximate a circle and allow for proper raycasting.
To achieve this, the use of a Frame Buffer Object is super useful. A FBO allows you to essentially render to a texture which can then be displayed on the screen. In my particular case, I rendered the elements to a FBO then used a shader while drawing it to the screen to get the desired opacities.

With Java's graphics shape drawing operations, is there an easy way to give the shapes transparency gradients and blurry edges?

What I would like is to give circles a fill color with a gradient that starts from the middle and then as it moves out to the edges becomes progressively more transparent, giving a blur effect. What is the simplest way of doing this?
Try setting an appropiately defined java.awt.RadialGradientPaint (using Colors with alpha), then render your circles using that. You may need to translate the graphics coordinate system to get the gradient centered in the circle. (http://docs.oracle.com/javase/7/docs/api/java/awt/RadialGradientPaint.html)
Or just make an image in a graphics program and simply draw the image.

Why do I need to disable GL_TEXTURE_2D after drawing string in order for shapes to render?

I'm using the Slick2D library in order to render text to the screen but in order to render gl shapes like Rect, I need to first disable GL_TEXTURE_2D. I'm just curious as to why that is needed. Why does GL_TEXTURE_2D disable the rendering of shapes?
The way OpenGL works is basically one large, global state machine. When you bind a texture, every triangle you draw afterwards will use that texture.
The issue here is that the text drawing doesn't unbind it's texture afterwards, so the shapes you draw afterwards will be using that texture instead of no texture. The reason why you think it's "disabling" rendering is because the texture is made up of characters with everything else being transparent. What you're seeing is OpenGL drawing your shape with opacity at 0.
What happens when you disable GL_TEXTURE_2D is that the texture gets unbound and you draw regularly without a texture.
Because the string's texture is applied. As you probably don't set any texture coords it probably uses a section of the texture that is transparent and hence you see nothing.

Why does my off screen rendering Canvas3D not work?

I've been trying to make off screen rendering to work, using Java3D 1.5.2. In my source code I've been trying to attach an extended Canvas3D that will do off-screen rendering to SimpleUniverse, but doing so will break the render:
62. // FOR SOME REASON THIS BREAKS RENDERING
63. universe.getViewer().getView().addCanvas3D(canvas);
The full source code is a bit too large to paste on StackOverflow so I made it available via Pastie over here.
Line 63 has been commented out and has the ordinary Canvas3D do on-screen rendering. It will render a cube and display this in a JFrame. However if you remove the comment the off-screen render will cause the on-screen one from not rendering. Also the off-screen rendering will return a "big black nothing" BufferedImage.
I'd like to know how to make the off screen rendering work, i.e. render the scene of a rotated cube to a buffered image. I've been looking at the Java3D provided example code for off-screen rendering and they do it as this as well (with the exception that they use the Raster object to render the off screen buffer back to an on-screen window).
It might be the physical dimension of the Screen3D that is wrong. The value is supposed to be size of the physical screen in meters. You can test with:
screen3D.setPhysicalScreenWidth(0.0254/90.0 * destWidth);
screen3D.setPhysicalScreenHeight(0.0254/90.0 * destHeight);
The values are from the top of the Screen3D javadoc. The problematic line worked together with the above code, at least for me :)
Setting the wrong physical dimension may also change the aspect ratio of the rendered image.

Categories

Resources