#114348 - keldon - Sun Jan 07, 2007 12:45 am
Tagline: by rendering semi transparent polygon scene with z-buffering I mean a typical scene with many polygons where polygons (or even the textures) have variable transparency!
This is my understanding of how it is (or can be) achieved.
---
First draw the solid polygons and keep the z buffer. Any pixel drawn from a semi transparent polygon behind an already drawn pixel is ignored!
What I will describe first is how you render each pixel. You do it in this order:
- retrieve semi transparent texel
- sort texels by z,
- draw texels in order using semi transparency
Now at this stage it seems stupid to think of sorting your texels for every pixel, and you are too right. Unless you are drawing a mass intersection of semi transparent polygons you are rarely ever going to see more than two polygons cross each other in any one pixel, and you will not see many crosses per line! So your sort code can be very simple. [By the way] it is best to have an already sorted list and only fix the order when there is a problem.
Drawing each pixel
(*EDIT*)code has been altered
Now this might seem very costly; but consider pixel.add only returns false if the texel is found to be behind something drawn already (excluding the existing background). And since there is only one pixel object instantiated, you can have make use of one with multiple levels of undo! Also note that there are rarely a large number of pixels where intersections between polygons occur so it is best to write the method in a way
Drawing each line
Before reaching the stage where we are able to draw pixels we need the texels from each semi transparent polygon. Well each polygon has the following information stored that would be required:
- x/y s,u and 1/z deltas for polygon's texture map to update for next pixel
- s,u and 1/z for each polygon's texture map at current pixel
- (*EDIT*)minx and maxx for each row
Each semi transparent polygon records maxx andminx, s,u and 1/z for the beginning of each line. This can be maintained without memory allocation 'woes' through obvious costless memory management schemes.
Adding and removing semi transparent polygons to and from the pipeline
For adding and removing polygons you need only do the following:
- for each row store a boolean map of which polygons begin/end on this line
- do the same [independantly] for each column
This might seem cumbersome at first, but you can make use of storing the two boolean map inside an integer(or array of integers) and simply performing a bitwise AND. A non zero value tells you that an element needs to be examined. This will happen no more than two times for each polygon being drawn.
---
I am sure there are plenty of different ways that you can draw many semi transparent textured polygons in software, but I wonder if this method is any good and where it stands in comparison to the rest; and most importantly whether there has been a flaw in my thinking. I have been wondering how to do it efficiently for a while now, and for some reason this idea came to mind now!
EDIT: Changed title and added tagline
Last edited by keldon on Sun Jan 07, 2007 5:09 pm; edited 1 time in total
This is my understanding of how it is (or can be) achieved.
---
First draw the solid polygons and keep the z buffer. Any pixel drawn from a semi transparent polygon behind an already drawn pixel is ignored!
What I will describe first is how you render each pixel. You do it in this order:
- retrieve semi transparent texel
- sort texels by z,
- draw texels in order using semi transparency
Now at this stage it seems stupid to think of sorting your texels for every pixel, and you are too right. Unless you are drawing a mass intersection of semi transparent polygons you are rarely ever going to see more than two polygons cross each other in any one pixel, and you will not see many crosses per line! So your sort code can be very simple. [By the way] it is best to have an already sorted list and only fix the order when there is a problem.
Drawing each pixel
Code: |
pixel.setColour ( getPixel(x,y));
for (Cell <Texel> tCell = drawingPolys.head.next; tCell != null; tCell = tCell.next ){ Texel texel = tCell.element; boolean hasCollided; if (hasCollided = pixel.add(texel.colour, texel.alpha, texel.z)){ // swap two texels Cell <Texel>prevTexel = tCell.prev; tCell.element = prevTexel.element; prevTexel.element = texel; // will revert back to previous pixel state and previous cell pixel.undo(); tCell = tCell.prev; }; } setPixel(x,y,pixel.colour,pixel.z); |
(*EDIT*)code has been altered
Now this might seem very costly; but consider pixel.add only returns false if the texel is found to be behind something drawn already (excluding the existing background). And since there is only one pixel object instantiated, you can have make use of one with multiple levels of undo! Also note that there are rarely a large number of pixels where intersections between polygons occur so it is best to write the method in a way
Drawing each line
Before reaching the stage where we are able to draw pixels we need the texels from each semi transparent polygon. Well each polygon has the following information stored that would be required:
- x/y s,u and 1/z deltas for polygon's texture map to update for next pixel
- s,u and 1/z for each polygon's texture map at current pixel
- (*EDIT*)minx and maxx for each row
Each semi transparent polygon records maxx andminx, s,u and 1/z for the beginning of each line. This can be maintained without memory allocation 'woes' through obvious costless memory management schemes.
Adding and removing semi transparent polygons to and from the pipeline
For adding and removing polygons you need only do the following:
- for each row store a boolean map of which polygons begin/end on this line
- do the same [independantly] for each column
This might seem cumbersome at first, but you can make use of storing the two boolean map inside an integer(or array of integers) and simply performing a bitwise AND. A non zero value tells you that an element needs to be examined. This will happen no more than two times for each polygon being drawn.
---
I am sure there are plenty of different ways that you can draw many semi transparent textured polygons in software, but I wonder if this method is any good and where it stands in comparison to the rest; and most importantly whether there has been a flaw in my thinking. I have been wondering how to do it efficiently for a while now, and for some reason this idea came to mind now!
EDIT: Changed title and added tagline
Last edited by keldon on Sun Jan 07, 2007 5:09 pm; edited 1 time in total