Filled backgrounds when drawing transparent primitives in 3D

This may be just a question, not a bug, but I could only choose one category, so forgive me if this is something intended that I’m just not getting. I’ve been playing around with the 3D capabilities in Codea, and I’ve noticed that sometimes, when I draw primitives like text and ellipses, their entire bounds are filled in, not just the part that’s supposed to be opaque. It’s as though I were drawing them directly above a rect() of the same dimensions filled in with the background color.

I’m drawing a bunch of rotating “stars”, and they cover each other up.
Screenshot: http://i.imgur.com/SKZE8l.jpg

Is this a bug, a quirk, or a feature I’m just unaware of?

Source, if it helps:


-- 3D Test

-- Use this function to perform your initial setup
local starcount = 1000
local starrange = 1000
function setup()
    -- generate star locations
    stars = {}
    for i = 1, starcount do
        stars[#stars + 1] = {
            x = math.random(starrange);
            y = math.random(starrange);
            z = math.random(starrange);
            rotation = 0; -- initial rotation, changes every frame
            drotation = math.random(-180, 180); -- rotation speed in degs/scnd
        }
    end
    camx = starrange / 2
    camy = starrange / 2
    camz = starrange / 2
    angle = 0
    parameter("camx", -starrange / 2, starrange * 1.5)
    parameter("camy", -starrange / 2, starrange * 1.5)
    parameter("camz", -starrange / 2, starrange * 1.5)
    parameter("angle", 0, 360)
end

-- This function gets called once every frame
function draw()
    ellipseMode(CORNER)
    fill(255, 255, 255)
    stroke(255, 248, 0, 255)
    -- This sets a dark background color 
    background(0, 0, 0, 255)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    -- setup 3D matrix
    pushMatrix()
        -- setup perspective
        perspective()
            camera(
                -- eye location
                camx, camy, camz,
                -- look vector
                camx + math.sin(math.rad(angle)),
                camy,
                camz + math.cos(math.rad(angle))
            )
            -- draw stars
            for i, v in ipairs(stars) do
                -- rotate star
                v.rotation = v.rotation + v.drotation * DeltaTime
                -- transform to star-local coordinate system
                pushMatrix()
                    translate(v.x, v.y, v.z)
                    rotate(v.rotation, 0, 1, 0)
                    -- draw primitive to represent star
                    ellipse(-20, -20, 40, 40)
                popMatrix()
            end
        -- undo perspective
        ortho()
    popMatrix()
end

Try To make your background transparent with this (alpha=0 instead of 255):

    -- This sets a dark background color 
    background(0, 0, 0, 0)

Maybe it will help

Transparent background didn’t help, unfortunately.

It’s as though I were drawing them directly above a rect() of the same dimensions filled in with the background color.

Almost. You are drawing them directly above a rect filled with a transparent colour and this brings you into conflict with OpenGL’s approach to z-buffering in that it doesn’t take into account the alpha when deciding if a pixel is above another one.

.@SelectricSimian unfortunately this is simply down to the way OpenGL handles blended fragments — in that it doesn’t. It treats them as opaque for the purposes of depth testing.

The way to resolve this (somewhat) is to sort and render your transparent polygons from back to front.

.@Simeon Thanks, I’ll do that. Could this also be solved by using a polygon() function (which as far as I can tell isn’t exposed to Codea) to approximate an ellipse, or is that what Codea already does behind the scenes?

Yes, that would solve your ordering issue.

Actually you can do that with the mesh() class, which allows arbitrary triangle meshes. I have a Star example that you can use for this purpose:

http://twolivesleft.com/Codea/Talk/discussion/734/star-mesh/p1