Using blending to create multiple areas of transparency surrounded by black - java

I've been playing around in openGL a little bit and I was wondering how I can take an image (say for example a black background) and then render a smaller white gradient over the top but have it make the white gradient transparent (instead of white) and remove from the black background. Leaving a black background with a transparent gradient in the center. I'm using LWJGL if that helps.
Is there any way of doing this with blending?
Edit: Okay, is there any way of instead of subtracting two images, I draw black around an image? So I have my white gradient, change it to be transparent and then draw black all around that?

Fixed function is usually implemented using shaders in modern GL drivers (there are old ATI's presentations with SM2.0+ shaders for all of the fixed functionality).
The close-to-trivial blending fragment shader like this
in vec2 TexCoord;
uniform sampler2D Texture0;
uniform sampler2D Texture1;
out vec4 out_FragColor;
void main()
{
vec4 Color = texture(Texture0, TexCoord);
/// The mask contains (R,G,B,A) - image + transparency
/// for both the mask and the source
vec4 Mask = texture(Texture1, TexCoord);
/// Mask is also significant as a color source, not only the alpha
out_FragColor = Color * ( 1.0 - Mask.a ) + Mask * Mask.a;
/// Thanks to Tim's comment, the last line can be done simpler:
/* out_FragColor = mix(Color, Mask, Mask.a); */
}
should mix the image the way you want to.
This is not overkill for modern hardware and it is 100% compatible even with the GL ES 2.0 hardware.
EDIT:
The image from one of my projects (simple mask used to create the fade-away reflection).
We use this mask
and get the final result in this image: Gallery

It may be possible to achieve what you want in the specific case, but in general once you 'draw a black background', there's no way to make it transparent afterward. You can't remove or erase pixels that have already been drawn.
If you can draw the gradient before the black background, then you can deposit the alpha into the framebuffer, and then sample the destination alpha when you draw the black background afterward. You'll need to have a real alpha texture though, as you can't really convert a white gradient to an alpha gradient at draw time.
Here's my suggested pseudocode:
draw whatever you want in the background
create texture with alpha gradient
lock color channels with glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE);
draw alpha gradient over background
unmask color channels with glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
draw 'black texture' with following blend options: glBlend(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA)
That should leave you with a black texture with a blended gradient to whatever was underneath it.

Related

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.

Combining a FBO texture with a main image after post processing to achieve a glow effect

I'm trying to create a glow effect. I'm using OpenGL ES 3.0. I can create an outline of my object (a cube) using the stencil buffer, so I have no trouble with that. I can also render this outline to texture using a FBO, and achieve a blur effect using a box blur or Gaussian blur. However, the part that I'm have trouble with is in combining the resultant blurred glow outline (i.e the post-processed image) back with my original object, so that it lines the edges of the cube. I can blit the blurred texture onto the screen--but that copies the low-resolution blur over my high-resolution cube--meaning that I can no longer see my cube, just the blurred outline texture.
Question: How do I combine both into one image on the screen?
I want to make a composite image that consists of both images.
It's probably something simple, but I can't think of a way to do it. Pseudo code would be helpful.
Thanks
I think you want additive blending of those two images, correct?. Two approaches come to mind. Note that when using additive blend, you automatically get brighter colors as the values are summed.
1) If you have both the original cube and the blurred cube in textures, render a single screen-size quad with a fragment shader like this:
#version 300 es
precision mediump float;
uniform sampler2D originalTexture;
uniform sampler2D blurTexture;
in vec2 texCoord;
void main()
{
vec4 originalColor = texture(originalTexture, texCoord);
vec4 blurColor = texture(blurTexture, texCoord);
gl_FragColor = originalColor+blurColor;
}
The advantage with this approach is you can easily add multipliers to the colors to fine-tune the effect, e.g. tone down the glow if it's too much.
Alternatively, you can render your cube normally from geometry. In that case, just add the texture lookup from the blur texture to your fragment shader, and add the color values.
2) You could leverage the fixed-function blending. First render the original cube as you would normally, then set the blend mode:
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
Now, when you bind the blur texture and render to the same render target, those should overlap and give you your effect. This gives an equivalent result to the above shader. You can try using glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE) too to reduce the result brightness. This approach should be faster than the shader approach.
I'm unsure if blending works with glBlitFramebuffer, but it's worth a shot I guess. Hope some of this works!

OpenGL muliply/add texture with glColor

I'm making a game in Java using the LWJGL and Slick.
From what I understand glColor multiplies the RGB values, but what if I wanted to add color to a texture that's had RBG removed? (desaturated)
The purpose of this is to create a grey texture and then use OpenGL to add color to it in code.
Adding is most likely not what you wan't. Adding is more of a brightening effect.
It sounds like the feature that you wan't is multiplying (glColor). If you have a grayscale texture, mulyiplying it with a color like red will create an image where the white parts of the texture are pure red, and the dark sections are darker shades of red.
Read:
http://en.wikipedia.org/wiki/Blend_modes

Rendering lighting

I have a small block engine similar to a very early version of Minecraft using LWJGL. I now want to actually implement lighting. I understand how it works I'm just confused as to how I'm supposed to render lighting. Am I supposed to change the "brightness" of the texture to simulate bright terrain? I'm asking how to actually change the light value of a quad, maybe there are some tutorials out there? I want it to be block by block, no smooth lighting. I have figured out that blocks need to have a light value, and for every block next to it, you decrease that light value by a little bit until its "black".
(At least) two options, assuming a fixed-function renderer:
Use a single texture (your basic texture atlas, with the default GL_MODULATE texenv.) and set a per-vertex gray-scale color to darken the texture in proportion to the light level. With GL_MODULATE the texture RGB channels are multiplied by the vertex color RGB channels. So a vertex color of RGB(255,255,255) would be fully lit, RGB(0,0,0) would be pure black, and RGB(128,128,128) would be somewhere in the middle.
Use two textures (appearance atlas and lightmap atlas) and multitexture. The light level is set for a given face by supplying texture coordinates that select the appropriate lightmap square. If you animate the lightmap you can get a day/night cycle "for free" without having to iterate over the entire volume fixing up vertex colors like in #1.

Categories

Resources