00:00
00:00
Newgrounds Background Image Theme

LightyJaeger just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

AS:3Dimensions-Intermediate

5,095 Views | 18 Replies
New Topic Respond to this Topic

AS:3Dimensions-Intermediate 2005-08-11 17:23:44


AS Mains Power Supply

AS:3Dimensions-Basic

-_--_--_--_--_--_--_--_--_--_--_--_--_--_-
-_--_--_--_--_--_--_--_-
-¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯-
-¯--¯--¯--¯--¯--¯--¯--¯-

AS:3Dimensions - Intermediate

---------

in this thread im going to discuss using fills in your 3d engine with basic flat-lighting and back-face culling (along with some advancements for a better rendering)

Sample file
note that fills are set to 85 transparency so you can see the back-face culling at work

//

in my basic thread, i discussed the floating balls sample, each ball was simply a coordinate being rotated and projected onto the screen.
fills (polygons) are simply a group of coordinates joined together filled with a colour

//

there are two ways you could go about setting up your 3d models:

the first is to create a list of polygons with the coordinates for each vertices listed for each coordinate:

the second is to create 2 lists:
the first being a list of the coordinate of each vertex
the second being a list of polygons - but instead of listing the coordiantes of each vertex, you give a reference to a vertex in the first list

the advantages of the second is it requires less computation on rotations and projection
but the disadvantages are when you need to clip polygons to the viewing frustum (dont worry about what i just said for this thread :p)

//

i like to use the second way but ill give an example for both using a pyramid model:

the first way:

var polygons:Array = [
[[-100,0,100],[100,0,100],[100,0,-100],[-1
00,0,-100]],
[[-100,0,100],[0,200,0],[100,0,100]],
[[100,0,100],[0,200,0],[100,0-100]],
[100,0,-100],[0,200,0],[-100,0,-100]],
[[-100,0,-100],[0,200,0],[-100,0,100]]
]

the second way:
var vertex:Array = [[-100,0,100],[100,0,100],[100,0,-100],[-1
00,0,-100],[0,200,0]];
var polygon:Array = [[4,0,1,2,3],[3,0,4,1],[3,1,4,2],[3,2,4,3]
,[3,3,4,0]];

(note that the first number in the polygon array is the number of vertices, its not neccesary but it keeps things a bit neater in code)

again its what youd rather use, i think that the second way is far neater

//

at the end of each polygon index you can then add other info for the polygon like the colour of its fill etc. for example [4,0,2,5,1,0x00ff00]
//

since from my other thread you will already know how to rotate coordinates and to project them, the next thing is how do you do z-sorting on polygons?

in a proper 3d engine for proper games, each pixel of each polygon is tested called a z-buffer, since this isnt possible (and would be far far far too slow) you can only z-sort the polygons
the most effective way is by finding the average distance to the camera for each vertex and sort the polygons by this

you then draw the polygons from the back to the front overlapping polygons behind with the ones infront:

you need to use the array function sortOn for this:

you need to go through each polygon and find the average distance to the camera (using pythagoreus theorem extended to 3dimensions - hyp^2 = x^2+y^2+z^2)

you then store it in an array with a refernence to the polygon: ie <arrayname>.push({dis:<the average distance>, poly:<the index in the polygon array for that polygon>});

with that array you call <arrayname>.sortOn("dis",18); (18 means it is in descending order so the first item in the array will be the back polygon)

//

Response to AS:3Dimensions-Intermediate 2005-08-11 17:25:55


the next step is back-face culling and lighting: these are more complicated and require vector math

(vector terms used are: the dot-product, the cross-product, unit-vector)

if you dont know what a vector is :
a vector is a mathematical object which has both magnitude and direction:
if you are traveling 10mph east, you could describe it as a vector as <10,0>
if you are travelling 5mph south-west, you could describe it as a vector of <-3.53,-3.53>

back-face culling is a method that removes polygons that the camera cannot see because they are facing away from the camera (back-facing)
to find out if a polygon is facing away from the camera you have to find the normal to the plane that the polygon is on, but you dont need to worry about planes (not the flying type),

the normal of a polygon is a vector that is perpendicular to it (at 90 degrees)

to find the normal you first have to find 2 vectors that lie on the polygon which is found by the first 3 vertices in the polygon:

if you take each coordinate to be a vector from the origin then these 2 vectors on the polygon can be found by

vector1 = vertex2-vertex1;
vector2 = vertex3-vertex2;

vector subtraction follows:

v3.x = v1.x-v2.x;
v3.y = v1.y-v2.y;
v3.z = v1.z-v2.z;

the normal to the polygon is then the unit vector of the cross-product of these two vectors

normal = (vector1 x vector2)divided by the normal

vector cross-product follows:

v3.x = (v1.y*v2.z) - (v1.z*v2.y);
v3.y = (v1.z*v2.x) - (v1.x*v2.z);
v3.z = (v1.x*v2.y) - (v1.y*v2.x);

a unit-vector is a vector whos normal(length) = 1;
to find the unit-vector of a vector:

length = sqrt(v.x*v.x+v.y*v.y+v.z*v.z); << Pythagoreus theorem
v2.x = v.x/length;
v2.y = v.y/length;
v2.x = v.z/length;

this unit-vector is the normal to the polygon, it can now be used to determine whether the polygon is facing towards, or away from the camera

to do this you need to find the angle between the camera vector and the polygon normal (since we aernt using dynamic cameras, we can use <0,0,-1>)

to find the angle we use the dot-product which follows:

v1 dot v2 = (v1.x*v2.x) + (v1.y*v2.y) + (v1.z*v2.z);

the dot product of two vectors returns the COSINE of the angle between them, we do not however have to find the actual angle: since the normal is a unit-vector, the

cosine of the angle will always be between -1 and 1

all we need to do to see if its facing away from the camera is to see if the the dot-product is more than or equal to 0 (0 being perpendicular to the camera)

however this is not the only thing we can use this for: the angle can also be used to shade the fills so that ones facing further away from the camera are coloured darker than the others where you can simple scale each colour value by the number:

ie if the colour for the fill is 0xff0000 (red) and the cosine of the angle between is 0.5 then you would colour the polygon 0x800000 (0x80 being half of 0xff)

you can use this handy function for doing so:

function shadecol(col:Number,bri:Number):Number
{
var red:Colour = col>>16;
var grnblu:Number = col - (red<<16);
var grn:Number = grnblu >> 8;
var blu:Number = (grnblu - (grn<<8))>>4;
//
red *= bri;
grn *= bri;
blu *= bri;
return red<<16|grn<<8|blu<<4;
}
b

where bri would be the cosine of the angle

the last thing to mention is a the method of obtaining a more accurate back-face culling when using perspective

to do this when finding the normal to the polygon for back-face culling, you have to put each
coordinates x and y into perspective and keep the z component as it is (only temporarily ofcourse) otherwise it can lead toback-face culling where polygons that shouldnt be removed are removed, and ones that should be removed aernt (due to the way perspective modifies the coordinates)

note that using this method will take up more CPU if you also wish to have accurate flat-shading as youd have to find the normal in perspective, and not in perspective

this way you take perspective into account when culling the polygons

i know ive gave out alot of stuff here and alot is quite complicated to grasp: but look over it a few times and you should get the idea behind it all:
finnaly to give a bit of help: here is a little similar to psuedo-code example

-------------------------------------
render function:

create a new array names zsort;

for each polygon:
>>find the normal to the polygon (non-perspective or perspective (perspective giving a more accurate culling of polygons) )
>>if the dot-product of the normal with <0,0,-1> is >= 0 then continue to the next polygon
>>else
>>>>find the colour for the polygon using the return of the dot-product (non-perspective)
>>>>find the average of the distances to each vertex from the camera (you can use <0,0,-5000>)
>>>>add a new item to the zsort array as an object with one var. named dis with the average distance and another named poly with the index in the polygon array of

the current polygon
-------------
zsort.sortOn("dis",18);
-------------
for each iteam in zsort:
>>retrieve the polygon
>>project each vertex onto the screen and colour the polygon
-------------------------------------

(A VERY IMPORTANT THING TO REMEMBER WHICH CAN BE QUITE CONFUSING AT FIRST)
if you use back-face culling (its not neccesary) then you must make sure that the first 3 vertices are in a clock-wise order

if you dont understand it this pic will help: (note the way the vertices are ordered in a clock-wise direction so that the normal faces outwards from the object)

Response to AS:3Dimensions-Intermediate 2005-08-11 17:29:46


wow it looks really great
but do you think you can be able to make even a real 3d shooter in flash?
handle that in youre expert threath :P

Response to AS:3Dimensions-Intermediate 2005-08-11 17:34:36


i dont tihnk ill do an expert thread - far too complicated considering my class for dealing with it is +1000 lines and deals with spherical collisions and clipping polygons to the viewing frustum with a static world with a moving rotating camera with triggers and well... far too complicated

anyone that wants to see what can be achieved with 3d in flash can have a look at these tho:
http://delta.ecwhost.com/sample.html << simple 3d
http://delta.ecwhost.com/sample2.html << more advanced using triggers to remove and add sections of the world when neccesary
http://delta.ecwhost.com/sample3.html << same as 2 but a wireframe with back-face culling set to false
http://delta.ecwhost.com/testCols.html << testing spherical collisions (runs alot slower because of the spheres)

Response to AS:3Dimensions-Intermediate 2005-08-11 17:40:04


At 8/11/05 05:34 PM, dELta_Luca wrote: anyone that wants to see what can be achieved with 3d in flash can have a look at these tho:

...speechless. How long has it taken you to get to grips with all this 3d stuff?

Response to AS:3Dimensions-Intermediate 2005-08-11 17:55:11


i first delved into 3d last year around this time when i made a movie similar to the one in my basic thread:

i then stopped looking into 3d until march when i first got to grips with fills (tho knowwhere near aswell as now)

the 4 samples i shown in my last post were made with my 3d class, i believe i first started on the class in mid april and finished it to what it is at the moment in late may:

since then i havnt really done anything more for 3d in flash but once ive got my project out of the way (with the extra power-boost of flash player 8) im going to (hopefully) do a rewrite of the class increasing its performance and start on the other collisions against boxes and planes etc and hopefully get a game out of it

Response to AS:3Dimensions-Intermediate 2005-08-11 18:25:12


At 8/11/05 05:55 PM, dELta_Luca wrote: and hopefully get a game out of it

I too have gotten into 3D engines and such and would love to help you with a game...if you are willing to accept my help that is...

Basic 3D box experiment/thing...

...obviously a very small sample right there...


BBS Signature

Response to AS:3Dimensions-Intermediate 2005-08-11 18:37:02


I refuse to belive you are only fourteen years old :O


BBS Signature

Response to AS:3Dimensions-Intermediate 2005-08-11 18:43:13


Damn, and most ppl think animating is hard! Jesus that's gotta take thousands of lines!!!!!!! Now you are my idol!!! Screw Krinkels!!!! lol...

Response to AS:3Dimensions-Intermediate 2005-08-11 18:55:16


At 8/11/05 06:37 PM, Afro_Ninja wrote: I refuse to belive you are only fourteen years old :O

too bad, i could photocopy my passport info if you really dont believe it?

Response to AS:3Dimensions-Intermediate 2005-08-11 19:06:47


its hard to believe

Response to AS:3Dimensions-Intermediate 2005-08-11 19:33:22


want proof? heres some proof

http://img239.images..16/proofofage4fi.jpg

Response to AS:3Dimensions-Intermediate 2005-08-11 19:37:38


Well I'll be damned :p


BBS Signature

Response to AS:3Dimensions-Intermediate 2005-08-11 19:39:41


At 8/11/05 07:37 PM, Afro_Ninja wrote: Well I'll be damned :p

Smart kid ;D


- - Flash - Music - Images - -

BBS Signature

Response to AS:3Dimensions-Intermediate 2005-08-11 19:58:42


Related reading: 3D trig on kirupa.com


- - Flash - Music - Images - -

BBS Signature

Response to AS:3Dimensions-Intermediate 2005-10-06 17:28:57


At 8/11/05 07:06 PM, <deleted> wrote: its hard to believe

Never before have I seen A deleted person's account post!!!!

Response to AS:3Dimensions-Intermediate 2005-10-06 17:49:24


i, too, am 14.

thanks for making me feel stupid -_-


snyggys

Response to AS:3Dimensions-Intermediate 2005-10-22 03:05:17


At 10/21/05 10:19 PM, MusicianEXE wrote:
"you then store it in an array with a refernence to the polygon: ie <arrayname>.push({dis:<the average distance>, poly:<the index in the polygon array for that polygon>});
with that array you call <arrayname>.sortOn("dis",18); (18 means it is in descending order so the first item in the array will be the back polygon)"
you never exlaned where the values of dis and poly are stored, therefore I cannot have the faces layered by the value of poly because I don't know how to access it.

well each polygon's data is stored in an array (whether you used method one or method two)
so you can target each polygon by storing a number referring to its position in the array:

you create an array and for each polygon you store an object with 2 variables:
dis -> the average of the distances to its vertices ( i explained this (or im pretty sure i did))
poly -> the polygons position in the polygon array (i just explained this in this post)

you then use sortOn (18) to sort the array by the variable dis:

obviously each time you render you need to do this again

Response to AS:3Dimensions-Intermediate 2006-02-26 11:01:14


you realise of course that you are now a god