How do you make a moon in a 3D game?

Hello, everyone!
I’m currently working on a Minecraft look-alike FPS and I would like to add a moon to the sky (just a flat mesh with a moon texture). However, I’m not sure what the proper way of doing this is. I feel that to draw a really large mesh that’s really far away sounds a bit ridiculous, but I can’t think of anything else. I’m thinking I should draw a small mesh that circles around and follows the player at a short distance but the problem with that is that meshes behind the moon will appear… well, behind the moon. How can I tell openGL to draw the moon behind everything else? Is this possible? Is there a better way to make a moon? Thanks in advance, guys! :smile:

First, it doesn’t need to be a 3D moon, you can just use a 2D picture. You will need to rotate it to face the camera, if your camera is moving about, but that’s not hard.

Then all you need to do is set the z value of the moon to be far away so it is drawn behind everything else.

If the moon is static (doesn’t rise and set within a day/ night cycle), then you could use a skybox which has a moon painted on it.

I made the moon and it looks great! I would like to post a video but I don’t know how… :frowning:

  • codea has a build-in gameplay video recorder
  • you can publish the recorded video to youtube and then post the link here (which should get parsed to a inline-video automatically by the forum software)

Thanks, @se24vad! But I won’t post a video because I don’t have a youtube channel.

You can give me the moon code, and I’ll post a video

The code is too long to post in the forums. It passes the character limit. :frowning:

The share it via GitHub

I don’t have a github account or a pastebin account.

@Kolosso you don’t need a github account, you can make a gist without one.

Okay, how do I use github?

After I’ve pasted the code into a gist, do I press “create public gist”?

Yup

Here’s the code:
https://gist.github.com/Kolosso7/19a23d2236456bb53d9f881a773becdf

By the way, sorry @se24vad, @TokOut, @MattthewLXXIII and @yojimbo2000 for wasting your time sometimes I ask too many questions when I could have looked up my questions… :frowning:

@Kolosso Here some code I modified to make a 3D sphere look kind of like a moon.

displayMode(FULLSCREEN)

function setup()
    ang=0
    createMoon()
end

function createMoon()
    tab={}
    r=30    --moon radius
    M,N=40,60
    for n=0,N do
        tab[n]={}
        for m=0,M do
            x=r * math.sin(math.pi * m/M) * math.cos(2*math.pi * n/N)
            y=r * math.sin(math.pi * m/M) * math.sin(2*math.pi * n/N)
            z=r * math.cos(math.pi * m/M)
            tab[n][m]=vec3(x,y,z)
        end
    end
    sph={}
    for n=0,N-1 do
        for m=0,M-1 do
            table.insert(sph,tab[n][m]) table.insert(sph,tab[n][m+1])
            table.insert(sph,tab[n+1][m+1]) table.insert(sph,tab[n][m])
            table.insert(sph,tab[n+1][m]) table.insert(sph,tab[n+1][m+1])
        end
    end
    cols={}
    for z=1,#sph,6 do
        v=math.random()/8+.7
        col=vec4(v,v,v,1)
        for c=1,6 do
            table.insert(cols,col)
        end
    end
    moon=mesh()
    moon.vertices=sph
    moon.colors=cols      
end

function draw()  
    background(40, 40, 50)
    perspective(15)
    camera(2000,0,0,0,0,0,0,1,0)
    rotate(90,1,0,0)
    rotate(-30,0,1,0)
    ang=(ang+.2)%360
    rotate(ang,0,0,1)
    moon:draw()
end

@dave1707 Wow! That looks awesome!! :smiley:

Sun :slight_smile:

displayMode(FULLSCREEN)

function setup()
    ang=0
    createMoon()
    timeChangePixels = 0
end

function createMoon()
    tab={}
    r=130    --moon radius
    M,N=40,60
    for n=0,N do
        tab[n]={}
        for m=0,M do
            x=r * math.sin(math.pi * m/M) * math.cos(2*math.pi * n/N)
            y=r * math.sin(math.pi * m/M) * math.sin(2*math.pi * n/N)
            z=r * math.cos(math.pi * m/M)
            tab[n][m]=vec3(x,y,z)
        end
    end
    sph={}
    for n=0,N-1 do
        for m=0,M-1 do
            table.insert(sph,tab[n][m]) table.insert(sph,tab[n][m+1])
            table.insert(sph,tab[n+1][m+1]) table.insert(sph,tab[n][m])
            table.insert(sph,tab[n+1][m]) table.insert(sph,tab[n+1][m+1])
        end
    end
    cols={}
    for z=1,#sph,6 do
        v=math.random()/8+.7
        col=vec4((225+v)/2,(v+1)/2,v/3,1)
        for c=1,6 do
            table.insert(cols,col)
        end
    end
    moon=mesh()
    moon.vertices=sph
    moon.colors=cols
end

function draw()  
    background(40, 40, 50)
    perspective(15)
    camera(2000,0,0,0,0,0,0,1,0)
    rotate(90,1,0,0)
    rotate(-30,0,1,0)
    ang=(ang+.2)%360
    rotate(ang,0,0,1)
    moon:draw()
    
    -- Tests
    timeChangePixels = timeChangePixels + 1
    
    if timeChangePixels >= 200 then
        cols={}
        for z=1,#sph,6 do
            v=math.random()/8+.7
            col=vec4((225+v)/2,(v+1)/2,v/3,1)
            for c=1,6 do
                table.insert(cols,col)
            end
        end
        moon.colors = cols
        
        timeChangePixels = 0
    end
end


When the sun is hidden by the moon…

function setup()
    displayMode(FULLSCREEN)
    darkish = 0
    moon = {}
    moon.pos = vec2(WIDTH * (3/4), HEIGHT * (3/4))
    moon.state = 1
    sunShine = false
    sunShineTable = {}
    for r = 1, 270 do
        table.insert(sunShineTable, 0)
    end
    
    -- You can edit this values
    speedAction = 1
end

function draw()
    background((255-darkish)/2, 255)
    strokeWidth(0)
    fill(255, 200, 0, 255)
    ellipse(WIDTH/2, HEIGHT/2, 350, 350)
    stroke(255, 255, 255, 255)
    if sunShine then
        translate(WIDTH/2, HEIGHT/2)
        for r = 1, #sunShineTable do
            rotate(360/#sunShineTable)
            strokeWidth(5 + math.random(-2, 1))
            line(-200 + sunShineTable[r], 0, 200 - sunShineTable[r], 0)
            sunShineTable[r] = sunShineTable[r] + math.random(-1, 1)
        end
        translate(-WIDTH/2, -HEIGHT/2)
    elseif moon.pos.x <= WIDTH/2 then
        for r = 1, #sunShineTable do
            translate(WIDTH/2, HEIGHT/2)
            rotate(360/#sunShineTable)
            if sunShineTable[r] <= 100 then
                strokeWidth(5)
                line(-200 + sunShineTable[r], 0, 200 - sunShineTable[r], 0)
            end
            translate(-WIDTH/2, -HEIGHT/2)
            sunShineTable[r] = sunShineTable[r] + 2 * speedAction
        end
    end
    strokeWidth(0)
    fill((255-darkish)/2, 255)
    ellipse(moon.pos.x, moon.pos.y, 350, 350)
    
    -- In total shine
    if moon.pos.x > WIDTH/2-5 and moon.pos.x < WIDTH/2+5 then
        sunShine = true
    else
        sunShine = false
    end
    
    -- Lightning Check
    if moon.pos.x <= WIDTH/2 then
        moon.state = 2
    end
    if moon.pos.x <= WIDTH/4 then
        moon.state = 0
    end
    if moon.state == 1 then
        darkish = darkish + .05 * speedAction
    elseif moon.state == 2 then
        darkish = darkish - .05 * speedAction
    end
    moon.pos.x = moon.pos.x - .05 * speedAction
    moon.pos.y = moon.pos.y - .0385 * speedAction
end