#### 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

in Examples Posts: 192

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

``````--# 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

``````

• Mod
Posts: 9,733

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

• 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
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
--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

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;
}
]],
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: 2,500

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

• 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.

• Posts: 192

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.

• 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