Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Quick 3d and noise() example for people beginning in 3d

I tried to document this as well as I could, just a little starter 3d project. It simply provides a block class and a quick snippet of code that generates noise onto which the blocks are mapped. It creates a nice, hilly effect :D


--# block block = class() function block:init(x,y,z,dim,tex,p) -- you can accept and set parameters here --use parameters to define all vertices needed to make a cube self.verts={ vec3(x+dim/2,y-dim/2,z+dim/2), vec3(x-dim/2,y-dim/2,z+dim/2), vec3(x+dim/2,y-dim/2,z-dim/2), vec3(x-dim/2,y-dim/2,z-dim/2), vec3(x+dim/2,y+dim/2,z+dim/2), vec3(x-dim/2,y+dim/2,z+dim/2), vec3(x+dim/2,y+dim/2,z-dim/2), vec3(x-dim/2,y+dim/2,z-dim/2) } --use parameter p to determine how much of image to crop out self.tex={ vec2(0+p/2,0+p/2), vec2(0+p/2,1-p/2), vec2(1-p/2,0+p/2), vec2(1-p/2,1-p/2) } --set up our actual mesh self.m=mesh() --put the verts in order into our mesh self.m.vertices={ self.verts[1],self.verts[5],self.verts[3], self.verts[3],self.verts[7],self.verts[5], self.verts[1],self.verts[5],self.verts[2], self.verts[2],self.verts[6],self.verts[5], self.verts[2],self.verts[6],self.verts[4], self.verts[4],self.verts[8],self.verts[6], self.verts[4],self.verts[8],self.verts[3], self.verts[7],self.verts[8],self.verts[3], self.verts[5],self.verts[6],self.verts[8], self.verts[5],self.verts[7],self.verts[8], self.verts[1],self.verts[2],self.verts[4], self.verts[1],self.verts[3],self.verts[4] } --put the texCoords into our mesh self.m.texCoords={ self.tex[3],self.tex[4],self.tex[1], self.tex[1],self.tex[2],self.tex[4], self.tex[3],self.tex[4],self.tex[1], self.tex[1],self.tex[2],self.tex[4], self.tex[3],self.tex[4],self.tex[1], self.tex[1],self.tex[2],self.tex[4], self.tex[1],self.tex[2],self.tex[3], self.tex[4],self.tex[2],self.tex[3], self.tex[4],self.tex[2],self.tex[1], self.tex[4],self.tex[3],self.tex[1], self.tex[4],self.tex[2],self.tex[1], self.tex[4],self.tex[3],self.tex[1] } --set the user-defined texture self.m.texture=tex --make sure there is no tint self.m:setColors(255,255,255) end function block:draw() -- Codea does not automatically call this method --draw the mesh self.m:draw() end function block:touched(touch) -- Codea does not automatically call this method end --# Main function setup() --set up our height map m={} --set up our control variable control=math.random(1,100) --generate heightmap for y=1,20 do m[y]={} for x=1,20 do m[y][x]=block(x*20,noise(x/10,y/10,control)*100,y*20,20,"Cargo Bot:Game Area",0.1) end end --initialize the y position pos=0 end function draw() background(40,40,40) --set perspective and field of view perspective(45,WIDTH/HEIGHT) --set the camera position, look values, and orientation camera(0,pos,0, 200,0,200, 0,1,0) --iterate through table and draw each element for i,v in pairs(m) do for a,b in pairs(v) do b:draw() end end --move upwards pos = pos + 1 end

Comments

  • dave1707dave1707 Mod
    Posts: 7,602

    @TheSolderKing Nice example. I changed pos=pos+1 to .1 to slow down the scrolling. Made it more interesting.

  • IgnatzIgnatz Mod
    edited March 2015 Posts: 5,396

    @TheSolderKing - nice

    Unless you are building Minecraft, you may prefer a smoother landscape, like this, which also has fewer vertices because it doesn't use blocks. (The shader tiles the texture nicely). It would look nice with a good texture and some lighting.

    Your next challenge is to put stuff on it and walk over it!

    function setup()
        displayMode(FULLSCREEN)
        --set up our height map
        m={}
        --set up our control variable
        control=math.random(1,100)
        --generate heightmap
        local n,s=100,20
        for y=1,n+1 do
            m[y]={}
            for x=1,n+1 do
                m[y][x]=noise(x/10,y/10,control)
            end
        end
        tex=readImage("SpaceCute:Background") --:copy(4,4,62,62)
        local w,h=s*3/tex.width,s*3/tex.height
        mm=mesh()
        v,t={},{}
        for x=1,n do
            for y=1,n do
                v[#v+1]=vec3(x*s,m[x][y]*100,y*s)    t[#t+1]=vec2(w*(x-1),h*(y-1))
                v[#v+1]=vec3((x+1)*s,m[x+1][y]*100,y*s)    t[#t+1]=vec2(w*(x),h*(y-1))
                v[#v+1]=vec3((x+1)*s,m[x+1][y+1]*100,(y+1)*s)  t[#t+1]=vec2(w*(x),h*(y))
                v[#v+1]=vec3((x+1)*s,m[x+1][y+1]*100,(y+1)*s)  t[#t+1]=vec2(w*(x),h*(y))
                v[#v+1]=vec3(x*s,m[x][y+1]*100,(y+1)*s)    t[#t+1]=vec2(w*(x-1),h*(y))
                v[#v+1]=vec3(x*s,m[x][y]*100,y*s)    t[#t+1]=vec2(w*(x-1),h*(y-1))
            end
        end
        mm.vertices=v
        mm.texCoords=t
        mm.texture=tex
        mm.shader=shader(TileShader.vertexShader,TileShader.fragmentShader)
        --initialize the y position
        posx,posy=0,40
    end
    
    function draw()
        background(40,40,40)
        --set perspective and field of view
        perspective(45,WIDTH/HEIGHT)
        --set the camera position, look values, and orientation
        camera(posx,posy,0, 200,posy/2,200, 0,1,0)
        mm:draw()
        --move upwards
        posx = posx + 0.1
        posy=posy+0.25
    end
    
    TileShader = {
    vertexShader = [[
    uniform mat4 modelViewProjection;
    attribute vec4 position;
    attribute vec4 color;
    attribute vec2 texCoord;
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    void main()
    {
        vColor=color;
        vTexCoord = texCoord;
        gl_Position = modelViewProjection * position;
    }
    ]],
    fragmentShader = [[
    precision highp float;
    uniform lowp sampler2D texture;
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    void main()
    {
        lowp vec4 col = texture2D( texture, vec2(mod(vTexCoord.x,1.0), mod(vTexCoord.y,1.0)));
        gl_FragColor = col;
    }
    ]]}
    
  • Posts: 1,226

    Hi @TheSolderKing and @Ignatz,

    Thanks for this input - I'm working on something similar and these examples will help speed up my own development.

    Couple of issues this raised - firstly @TheSolderKing - when copying and pasting your code using Aircode I obtained an error with respect to the perspective. I had pasted your code as is into one Tab. By moving the block class below the setup() and draw() functions the error was resolve - I presume you have written your code for cutting and pasting using the new app button which will generate separate tabs - think that's the cause one to watch out for.

    Secondly using Aircode - I very often edit the comment fields at the top of the Main tab. This causes me problems with the cursor - it very often won't allow me to select or sometimes even click into the top couple of lines - I can usually get this to work but it can take some fiddling with. Whilst editing your code I found that the cursor even ended up in the active Tab title for the Main tab - what I mean is I selected the word Main above the editing block of code ???

    Something wrong here with Aircode - anyone else experience this ?

    Thanks for you postings.

    Bri_G

    :D

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Bri_G - I have a lot of cool stuff on 3D in my ebook and blog, which you're welcome to use.

  • Thanks @dave1707! I tried changing it to pos=pos+0.1, and it makes it a lot cooler to look at.

    Thanks @Ignatz! That code is really cool! Can you give me a quick rundown of how it works? I tried to do something like that, but I never could figure out how to turn the vertices into triangles.

    @Bri_G I haven't had this problem with aircode, at least not yet because I do not use aircode very often.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @TheSolderKing

    ** Creating the vertices **

    I used the same table of heights as you, but added an extra row and column (think of the mesh as being a wireframe. If you want 20 squares, you need 21 rows and 21 columns).

    Then I just loop through from 1 to numRows-1, creating two triangles for the current tile. So the tile whose bottom left corner is at (3,4) is a square with corners (3,4), (4,4), 4,5), (3,5). I can create two triangles with the vertices (3,4), (4,4), (4,5) and (4,5), (3,5), (3,4).

    ** Tiling the texture **

    This explains how to tile a texture repeatedly across a large surface (flat or bumpy). The trick is a shader with just one simple change to the normal code, and special texture coordinates.

    https://coolcodea.wordpress.com/2013/05/25/64-3d-tiling-images-across-an-object/

    Then, later when I understood what the shader was doing, I wrote this

    https://coolcodea.wordpress.com/2013/06/06/78-shaders-tiling-images/

    Make sure you understand this one, it is really, really valuable for tiling large or weirdly shaped surfaces.

    If you want to put stuff on a bumpy surface, or walk on it, I have code for that. It's all in my blog.

Sign In or Register to comment.