Making far objects look fading or transparent - graphics

I have a 3D rectangle, rotated 45 degrees as in the attached screenshot. I would like the lines and the far edge (A) to look fading. Moreover, when i rotate the camera, i want the 'new' far lines and edges to look fading. So if B will be in the place if A, B and the lines to B will look fading. How can i do that?
If it makes any difference, i use OpenGL ES 2.0 on iOS.

I'd suggest enabling alpha blending and in your pixel shader you set the resulting color's alpha value based on the depth.
Something like result.a = clamp(1.0/(-gl_FragCoord.z + 1.0), 0.0, 1.0) might work.

Related

Smooth transition between two colors

I am trying to figure out how to achieve a smooth transition between two colors.
I.E. this image is taken from Wikipedia.
When I try to do the same using my code (C++), first idea that came to mind is using the HSV color space, but the annoying in-between colors show-up.
What is the good way to achieve this ?
This is going to sound weird, maybe... but vertex shaders will do this nicely. If that's a quad (two tris) then place one colour on the left 2 vertices, and the other on the right, and it should blend across nicely.
Caveat: Assumes you're using some kind of OpenGL.
The only part of your question I feel I can answer is that you must somehow be transitioning through too many values in the H part of HSV.
H is for hue (different colors, like the rainbow effect in your gradient). In this case, it looks to me like you are only merging 2 different hues.
S is for saturation (strength of color from highly saturated to
gray)
L is for lightness (more or less luminosity (from your
color to its most white)
This is caused by a lack of color in between, as black (or grey in your case) = desaturated. It is like putting two transparent fade images together, there is a see through area in the middle as 2 50% transparencies don't equal 100% solid color.
To avoid this, I'd suggest placing one color above the other and fading that to transparent. That way there is a solid color base with the transition above.
I dont know what your using to display (DirectX, Windows display or whatever ) but try just having two images, one solid color and a single color with a fade from solid to transparent infront. That might work.

Finding pixels inside an ellipse

My maths skills are terrible so I don't even know where to start with this. This is for a hobby project written in C#.
To keep things simple, let's say I need to operate on all of the pixels positioned inside an ellipse. How would I get an array of the valid pixel locations inside the ellipse that I need to work with?
For that task i would recommend taking a look at bresenhams filled circle Algorithm.
If you scale the y achsis you can use it to draw ellipses, too.
Bresenham algorithms work by using only integer arithmetic, which makes them fast(est)
This works only for axe-parallel ellipses
In an ellipse the sum of the distance between a point in the ellipse and both foci is twice the major axis so:
PF1 + PF2 = 2a
Where P is the point, F1 and F2 the foci and a the semi major axis.
If the sum is less then 2a the point will be inside the ellispe.
Wikipedia

Banding with alpha transparency in XNA WP7

Having some issues with smooth alpha gradients in texture files resulting in bad banding issues.
I have a 2D XNA WP7 game and I've come up with a fairly simple lighting system. I draw the areas that would be lit by the light in a separate RenderTarget2D, apply a sprite to dim the edges as you get further away from the light, then blend that final lighting image with the main image to make certain areas darker and lighter.
Here's what I've got so far:
As you can see, the banding is pretty bad. The alpha transparency is quite smooth in the source image, but whenever I draw the sprite, it gets these huge ugly steps between colors. Just to check I drew the spotlight mask straight onto the scene with normal alpha blending and I still got the banding.
Is there any way to preserve smooth alpha gradients when drawing sprites?
Is there any way to preserve smooth alpha gradients when drawing sprites?
No, you cannot. WP7 phones currently use 16 bit color range system. One pixes got: 5 red bits, 5 blue, 6 green (humans see a wider spectrum of green color).
Found out that with Mango, apps can now specify that they support 32bpp, and it will work on devices that support it!
For XNA, put this line at the top of OnNavigatedTo:
SharedGraphicsDeviceManager.Current.PreferredBackBufferFormat = SurfaceFormat.Color;
For Silverlight add BitsPerPixel="32" to the App element in WMAppManifest.xml.

Algorithm for Polygon Image Fill

I want an efficient algorithm to fill polygon with an Image, I want to fill an Image into Trapezoid. currently I am doing it in two steps
1) First Perform StretchBlt on Image,
2) Perform Column by Column vertical StretchBlt,
Is there any better method to implement this? Is there any Generic and Fast algorithm which can fill any polygon?
Thanks,
Sunny
I can't help you with the distortion part, but filling polygons is pretty simple, especially if they are convex.
For each Y scan line have a table indexed by Y, containing a minX and maxX.
For each edge, run a DDA line-drawing algorithm, and use it to fill in the table entries.
For each Y line, now you have a minX and maxX, so you can just fill that segment of the scan line.
The hard part is a mental trick - do not think of coordinates as specifying pixels. Think of coordinates as lying between the pixels. In other words, if you have a rectangle going from point 0,0 to point 2,2, it should light up 4 pixels, not 9. Most problems with polygon-filling revolve around this issue.
ADDED: OK, it sounds like what you're really asking is how to stretch the image to a non-rectangular shape (but trapezoidal). I would do it in terms of parameters s and t, going from 0 to 1. In other words, a location in the original rectangle is (x + w0*s, y + h0*t). Then define a function such that s and t also map to positions in the trapezoid, such as ((x+t*a) + w0*s*(t-1) + w1*s*t, y + h1*t). This defines a coordinate mapping between the two shapes. Then just scan x and y, converting to s and t, and mapping points from one to the other. You probably want to have a little smoothing filter rather than a direct copy.
ADDED to try to give a better explanation:
I'm supposing both your rectangle and trapezoid have top and bottom edges parallel with the X axis. The lower-left corner of the rectangle is <x0,y0>, and the lower-left corner of the trapezoid is <x1,y1>. I assume the rectangle's width and height are <w,h>.
For the trapezoid, I assume it has height h1, and that it's lower width is w0, while it's upper width is w1. I assume it's left edge "slants" by a distance a, so that the position of its upper-left corner is <x1+a, y1+h1>. Now suppose you iterate <x,y> over the rectangle. At each point, compute s = (x-x0)/w, and t = (y-y0)/h, which are both in the range 0 to 1. (I'll let you figure out how to do that without using floating point.) Then convert that to a coordinate in the trapezoid, as xt = ((x1 + t*a) + s*(w0*(1-t) + w1*t)), and yt = y1 + h1*t. Then <xt,yt> is the point in the trapezoid corresponding to <x,y> in the rectangle. Now I'll let you figure out how to do the copying :-) Good luck.
P.S. And please don't forget - coordinates fall between pixels, not on them.
Would it be feasible to sidestep the problem and use OpenGL to do this for you? OpenGL can render to memory contexts and if you can take advantage of any hardware acceleration by doing this that'll completely dwarf any code tweaks you can make on the CPU (although on some older cards memory context rendering may not be able to take advantage of the hardware).
If you want to do this completely in software MESA may be an option.

What is the formula for alpha blending for a number of pixels?

I have a number of RGBA pixels, each of them has an alpha component.
So I have a list of pixels: (p0 p1 p2 p3 p4 ... pn) where p_0_ is the front pixel and p_n_ is the farthest (at the back).
The last (or any) pixel is not necessary opaque, so the resulting blended pixel can be somehow transparent also.
I'm blending from the beginning of the list to the end, not vice-versa (yes, it is raytracing). So if the result at any moment becomes opaque enough I can stop with correct enough result.
I'll apply the blending algorithm in this way: ((((p0 # p1) # p2) # p3) ... )
Can anyone suggest me a correct blending formula not only for R, G and B, but for A component also?
UPD: I wonder how is it possible that for determined process of blending colors we can have many formulas? Is it some kind of aproximation? This looks crazy, as for me: formulas are not so different that we really gain efficiency or optimization. Can anyone clarify this?
Alpha-blending is one of those topics that has more depth than you might think. It depends on what the alpha value means in your system, and if you guess wrong, then you'll end up with results that look kind of okay, but that display weird artifacts.
Check out Porter and Duff's classic paper "Compositing Digital Images" for a great, readable discussion and all the formulas. You probably want the "over" operator.
It sounds like you're doing something closer to volume rendering. For a formula and references, see the Graphics FAQ, question 5.16 "How do I perform volume rendering?".
There are various possible ways of doing this, depending on how the RGBA values actually represent the properties of the materials.
Here's a possible algorithm. Start with final pixel colours lightr=lightg=lightb=0, lightleft=1;
For each r,g,b,a pixel encountered evaluate:
lightr += lightleft*r*(1-a)
lightg += lightleft*g*(1-a)
lightb += lightleft*b*(1-a)
lightleft *= 1-a;
(The RGBA values are normalised between 0 and 1, and I'm assuming that a=1 means opaque, a=0 means wholly transparent)
If the first pixel encountered is blue with opacity 50%, then 50% of the available colour is set to blue, and the rest unknown. If a red pixel with opacity 50% is next, then 25% of the remaining light is set to red, so the pixel has 50% blue, 25% red. If a green pixel with opacity 60% is next, then the pixel is 50% blue, 25% red, 15% green, with 10% of the light remaining.
The physical materials that correspond to this function are light-emitting but partially opaque materials: thus, a pixel in the middle of the stack can never darken the final colour: it can only prevent light behind it from increasing the final colour (by being black and fully opaque).

Resources