Flat Shaded 3D models

Started by Scavenger, Fri 14/03/2014 14:58:23

Previous topic - Next topic

eri0o

Oh... 3D characters in 2D background like Alone in the Dark in a module? (nod)

Crimson Wizard

TBH, I think it would be better to move rendering code to plugin, if you find a way to transfer drawing surface or bitmap pointer between script and plugin code.

Scavenger

Quote from: Crimson Wizard on Fri 01/06/2018 10:14:58
TBH, I think it would be better to move rendering code to plugin, if you find a way to transfer drawing surface or bitmap pointer between script and plugin code.

Yeah, it's perfectly possible, you can edit a sprite like it was an array in the plugin code, which is how I do all my graphical effects. I'd do it myself if I could understand the code, which is a long way off yet. My C++ isn't good enough to handle it, unless there is a lot of overlap between the AGSScript and C.

Additionally, is it possible to reverse the projection, so that if I point at certain screen coords, I could find out which polygon is being rendered there? It doesn't have to be particularily fast, but it'd be useful in making a painting tool.

Crimson Wizard

Quote from: Scavenger on Fri 01/06/2018 11:55:06
Additionally, is it possible to reverse the projection, so that if I point at certain screen coords, I could find out which polygon is being rendered there? It doesn't have to be particularily fast, but it'd be useful in making a painting tool.

This is done with raycast, that's all I know.

Khris

Yeah, you need to turn the mouse coordinates into 3D camera screen coordinates, unproject them into the world, then intersect the line camera-mouse with all triangles. Then find the closest one of all that get hit.

Phemar

#25


I'm always late to the party...

I started working on a 3d module a few years ago, but gave up. I came back to it last week and rewrote the thing from scratch. I just managed to implement some clipping against the screen boundaries using a version of the Sutherland-Hodgman algorithm (although mine clips at the raster stage, which is not very efficient, I'll consider moving it to before the perspective divide at some point).

It has a light source (sun), the shade is just calculated by comparing the triangle's normal to a vector from the sun, and the tint is customizable.

I'm using a python script to export vertex and triangle information from Blender to AGS script, and once I figure out how to export RGB values from a triangle's material, every triangle will be able to have its own unique tint.

You can move around the scene just like you would in any fps, camera look and WASD, (strafe and forward/backward)

As you can see I have no Z sorting yet. Well, I had one that used the average of all 3 Z values from a triangle, but the sorting algorithm slowed everything to a halt. (Was a bubble sort function, which used an index array into the original array instead of destroying the original array). Since I can't Z-Sort, and I'm using the DrawTriangle function instead of drawing each individual pixel, I can't use the z-buffer method either.

How have you guys managed to solve the Z-sorting issue?

(also, you can see something's not quite right with my backface culling function! I think it's because the vector from the player to the triangle isn't normalized, but haven't tested that yet).

Doing this thing in AGS script is tough, without any support for vec3/vec4 formats, 2d arrays or structs within structs. Oh well!

Edit: Holy crap, khris, I just looked at your code and I had no idea I could write functions that returned arrays in AGS. That would have made this soooo much easier! Time to do a refactor, I guess... Sometimes I forget how powerful AGS Script can be. I guess it's because I haven't made a game since AGS 2.62 lol.

Crimson Wizard

#26
Quote from: Phemar on Sun 24/06/2018 09:20:14
Doing this thing in AGS script is tough, without any support for vec3/vec4 formats, 2d arrays or structs within structs. Oh well!

You now can declare user managed types like this:
Code: ags

// declaration in script.ash
managed struct Vector4f
{
    float x;
    float y;
    float z;
    float w;

    import static Vector4f *Newf(float x, float y, float z, float w);
    import static Vector4f *NewVec(int x, int y, int z);
    import static Vector4f *NewVecf(float x, float y, float z);
    import static Vector4f *NewPt(int x, int y, int z);
    import static Vector4f *NewPtf(float x, float y, float z);
};

// In script.asc
static Vector4f *Vector4f::Newf(float x, float y, float z, float w)
{
    Vector4f *v = new Vector4f;
    v.x = x;
    v.y = y;
    v.z = z;
    v.w = w;
    return v;
}


They are still limited in some parts, and may work slightly slower than with global variables.
But then you can do something like:

Code: ags

struct Matrix44
{
    float x[16];
    import Vector4f *Transform(Vector4f *v);
}

Phemar

Crimson, that's awesome.

And here I was doing it like this:
Code: ags
enum Coordinates {
  eX = 0,
  eY = 1,
  eZ = 2,
  eW = 3,
};

struct Vertex
{
  float world[3];
  float camera[3];
  float screen[3];
  float normalized[3];
  int raster[2];
};

struct Triangle
{
  int vertex[3];
  float vector1[3], vector2[3];
  float vectorToSource[3];
  float normal[3];
  float center[3];
};


Then declaring an array of Triangles and Vertices and accessing them like this:

Code: ags
Vertex mesh_verts[MAX_VERTICES];
Triangle mesh_tris[MAX_TRIS];

//and then to access:
mesh_verts[mesh_tris[24].vertex[0]].raster[eX] = //whatever


Your way is basically what I wanted to do when I started, but I wasn't sure how to do it in AGS.

SMF spam blocked by CleanTalk