Flat Shaded 3D models

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

Previous topic - Next topic

Scavenger

I've been working on elements for my game, and looking through demoscene stuff to get inspiration for some of the SFX I want to use to tell the story with. One of these things is flat shaded 3D models, which I have an affinity for - they look incredibly oldschool, and I do make 3D models as well as pixel art. I know flat shaded 3D prims are possible in AGS, the AGS3D module/plugin is testament to that. Unfortunately, that module/plugin only does 16/32bit, and my game is in 8-bit. Being 8-bit, it also brings up the problem that any shading can't rely on just RGB values. I've been thinking about this, and I think if I hardcode what tri is coloured what palette slot, I may be able to produce 3D images within the bounds of my game's limitations, like so:


The black outline is so that the image can be seen even when the model is turned at an angle, since in this shading model, we wouldn't have the luxury of actual shading or lighting. But because of the lack of actual shading, I can also get away with using less polys for everything. I'd guess the flow would be like this:
1) Load OBJ model
2) Have an array the size of the number of tris in the model, with assigned colours to them
3) Draw the model using the assigned colours onto a full screen drawing surface.
4) Duplicate the drawing surface, have a completely black sprite, and cut out the model's dimensions with CopyTransparencyMask.
5) Draw the sillhouette 4 times, at offsets (0,-1),(0,1),(1,0),(-1,0) onto a new drawing surface
6) Draw the final sprite onto the drawing surface at offset (0,0).

But I'm not actually too up on the programming side of this (I'm an artist :<), and I can't find any old versions of the AGS3D module (the one that uses DrawTriangle) to test it out.

So, how easy would this be to do, and more importantly, would it be fast enough to run real time? I don't need any fancy texture mapping, or lighting, or even high polys, I just need to be able to rotate, scale, and position a model in 3D space. Where would I begin to do something like this?

abstauber

Quoteand I can't find any old versions of the AGS3D module (the one that uses DrawTriangle) to test it out.
This one?
http://www.kweepa.com/step/ags/tech/Ags3d113.zip

Scavenger

#2
Ah, excellent! I'll try that one out!

Edit: Hmm, I don't think the non-plugin version can load obj files, it only makes primitives. I'll still see what I can glean from it, see if I can't make it run in 8bit.

Khris

#3
I had to try this and got this far (coded from scratch):



I didn't know about CopyTransparencyMask and it's working great!
Haven't tried it in 8bit yet though.

No clipping or z-sorting yet, but I implemented backface culling and that works perfectly for convex objects.

Scavenger

Aaah, that's really awesome, Khris! That's exactly what I was talking about! I am always consistently amazed at the talent in these forums, ahaha.

How many polys do you think could be rendered like that without slowdown? Is it feasible for AGS to handle without choking on itself? I tested out just raw DrawTriangle commands once, and on my old laptop, I managed to get up to 2000/frame without it dropping below 60fps. But I'm guessing with the extra math involved for 3D, the reality would be a lot less. I'm pretty excited - I've made 3D models as a basis for my 2D work, but I've never used them realtime in a game before!

(And I guess 8bit would be trivial to do, so long as you have a palette and the ability to set colours to each tri.)

Khris

I did try to optimize this from the start, for instance the position of vertices that are used by multiple triangles is only calculated once.
Right now, without any sorting, displaying 40 rotating cubes doesn't reduce the frame rate, but if I increase it to a mere 50, the FPS drop to 35; 60 cubes, 31.

With 40 cubes, I'm rotating 320 vertices and drawing ~240 tris, plus there's dynamic lighting and the backface culling, which means three dot products, vector length and ArcCos calculations times 480 tris.

60:

Calin Leafshade

The calculation and the looping in the script is likely to be the bottleneck here. As a lua script you could probably get 10 times the performance.

Khris

Yep, which would bring this guy right back to 40 FPS :)



Added z-sorting, importing obj files and fixed the lighting calculation (I had to rewrite it entirely, I'm surprised the first version gave decent results, given how completely off it was).

Scavenger

I cannot believe this! I am absolutely astounded! Quite honestly I thought it would be an impossible task or a pipe dream, but there you go, doing it in mere days. Thank you so much!

In terms of colouring it in 8bit, I could whip up a simple CLUT generator that mixes together two or three shades of each colour in a range (in my game it would be 0-63), so you can approximate lighter and darker colours - it's not that difficult, I already have a more sophisticated version for translucency, making blends between black, a target colour, and white should be pretty trivial. How many shades are required for a suitable 3D effect? I'll whip something up.

Though, if you want to go real basic for lo colour 3D, you'd just need some way of painting the tris manually - I think that's how it worked in Alone In The Dark? (like this). No lighting, just coloured polygons. I remember Carnby's suit in particular having shading "drawn" onto it. Not the most fancy thing around, but suitable for what I want to use it for, at least, and it'll look like it has a texture on even though it's literally just coloured triangles!

selmiak

my head exploded just a bit right now!
AGS can party like its 95 now :D
Khris, this is great! Can you also put a pixel/bitmap texture on these lowpoly models?

Khris

#10
Thanks guys, but it's actually not that complicated, believe it or not :)

Getting this to work in 8bit should be pretty simple; I'll try it later. I think four or five shades should be enough to give decent results.
Shading without a lightsource is possible, sure, but it will look a lot less impressive ;)

As for texturing this, no way. Even texturing a single cube will bring the frame rate down to single digits, unfortunately. At least with pure AGSScript; one could of course use a plugin to do this, but what's the point? It's probably more reasonable to use another engine altogether in that case. Or use blocky raytracing instead.

Here's a four color version:

This does not matter at all for speed though, as you can see ;D

Scavenger

That's looking great, Khris! I can't wait to be making models to put in an AGS game. It'll be the most advanced game of 1992.

Regarding texturing, there's no way you could make perspective correct textures, but flat on textures might be possible, if only technically:


By drawing the triangle on another surface, using that as a template to cut out a base texture, and blitting that on the model's drawing, you could get the kind of "endless field" effect that was used in Escape from Monkey Island, and a lot of cheaper animations. If you have sprites with the different levels of brightness, you could even retain the 3D effect whilst having the texture.

The problem here would be that you'd require 10-20 extra commands per poly, and the effect wouldn't be that great.

Khris

#12
Flat textures could be shaded in a 16 or 32 bit game by drawing a semi-transparent black rectangle on top.

I did a quick speed test regarding perspective texturing:


The numbers speak for themselves, I guess :(
When I drew every other pixel, I got up to 26 FPS.

Scavenger

So do you think this solution is workable in AGS? Does it go any faster if you manually set each tri's colour as a static thing instead of calculating it? I know I'd probably be able to create prettier looking models that way - I don't really have much use for lighting, it just gets in the way of faking texture, and though lighting a model is neat, it's practicality is pretty limited for what I'd use it for - the majority of my game has a very basic flat colour/cel shaded style. Even if I could get 256 tris with just flat colours without slowdown, that would be enough for me, I can work around pretty much any limit.

(Also, would it ease up on the processing if it was rendered at half-speed? It could still be pretty smooth, but due to it's simplicity it wouldn't need to be super smooth, and you could split up the processing between two frames instead of doing it all on one)

Thankyou again for your help!

Monsieur OUXX

Sorry for necro-posting, but I would really, really like the source to this (flat-shaded 3D and texturing) to be made available. I genuinely think that it could benefit the AGS community, and it would be the base for some AGS tool that I'd like to develop. Khris, what says you?
 

Khris

I'll necro-post again because I was asked for the source and saw you asking for it, too.
Here it is: https://drive.google.com/open?id=1CpA2newcPHNFaTtFmOCgXak2hX1b1pcs

Crimson Wizard

#16
Quote from: Khris on Thu 31/05/2018 17:24:42
I'll necro-post again because I was asked for the source and saw you asking for it, too.
Here it is: https://drive.google.com/open?id=1CpA2newcPHNFaTtFmOCgXak2hX1b1pcs

Maybe unrelated to the original question, but I got curious about this yesterday, don't remember why, so decided to finally learn how to work with transformation matrixes, and this was the result:
Spoiler


[close]

Had this silly dream of making a game in filled triangles since playing old DOS simulators :).

I don't post any code yet, since its a terrible mix of several C++ snippets found in the web. But I finally know how to compose rotation matrix (better late than never lol).
https://www.dropbox.com/s/xrrejaawe0l3oku/Test3DPolygons.zip?dl=0
Controls: Q/W, A/S, Z/X - move camera in 3 axes, E/R, D/F, C/V - rotate around 3 axes.
It's bugged (no visibility check, perspective is weird, and rotating camera opposite way around makes triangles appear all over the screen).

I was thinking maybe using your code as a reference and mix in lighting too :).

Khris

#17
Quote from: Crimson Wizard on Thu 31/05/2018 20:44:28It's bugged (no visibility check, perspective is weird, and rotating camera opposite way around makes triangles appear all over the screen).
You can solve the 1st and 3rd issue with frustum culling, btw. Welcome to hell ;)

Snarky

I'm pretty sure Frustum Culling is one of the wizards at Unseen University. :P

Scavenger


Tested out one of my own models, it's exciting to see! Looks like you can safely render around 200 polys without getting much slowdown (this model's about 500). And there are some geometry errors I'm getting which I'll have to iron out myself. But so far: Promising!

SMF spam blocked by CleanTalk