Jump to content


Photo

3d sprites


  • Please log in to reply
13 replies to this topic

#1 Digisynth

Digisynth

    GMC Member

  • Validating
  • 55 posts

Posted 16 February 2012 - 04:40 PM

Hello.

I've made my own little file format, that is basically a 3d image. Normally, am image is a 2d matrix of dots that have four values. I am using a 3d matrix, so the file is much larger (though I don't really care).

There are several possible techniques to render the 3d image that work here:

1: Minecraft style: Make a block of every pixel of the 3d image

2: Drawing a radial gradient for every pixel, where the center is the color of the pixel and the outside is transparent

3: Minecraft style blocks, but instead of solid colors I use gradients to make colors fade into each other

4: Using heavy math, make use of hexagons, where the boarders match up seamlessly into the boarders of the neighboring hexagons. (when you look at a 3d cube's outlines, it looks like a hexagon)

Every technique has it's flaws:

1: Looks too oldschool

2: At a specific angle, you can look through the image

3: Bugs up when a neighboring pixel is transparent

4: Speed issue

Does anyone know of any other technique I can use, that looks good, doesn't bug and runs fast?

Thank you in advance!

#2 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1819 posts
  • Version:GM:Studio

Posted 16 February 2012 - 08:42 PM

You're working with voxels. Marching cubes will work.

In any case, you'll want to make a model of it for speed. GM8.1 is REALLY slow at rendering triangles that aren't in models, but has little or no trouble with triangles in models.

On an unrelated note, your habit of misspelling words makes your post painful to read. Most importantly, it's "borders", not "boarders".
  • 0

#3 hit172

hit172

    GMC Member

  • New Member
  • 189 posts
  • Version:GM8

Posted 16 February 2012 - 10:49 PM

What I think you are describing is a voxel system. These can be terribly slow, even when done in better optimized game engines. Marching cubes could work if your models aren't too complicated but can be a pain to implement into Gamemaker (not to mention slow). I would recommend altering your format to allow you to export the actual geometry of your "sprite" so it doesn't have to be calculated at run time. So basically use marching cubes but have the geometry of the marching cubes pre-calculated (separate program from game and doesn't have to be made in Gamemaker) and saved into a format like the GM d3d or Wavefront obj. It is a way to make models but for performance reasons you should pre-calculate the geometry.
  • 0

#4 Digisynth

Digisynth

    GMC Member

  • Validating
  • 55 posts

Posted 18 February 2012 - 01:38 PM

The difference here with my thing is the four channels per pixel. I want to render my thing in a way that looks good. Remember though that the alpha channels of the pixels aren't completely opague or transparent, but can lie in-between. What looks least pixely, doesn't take forever to render and doesn't have drawing errors?

#5 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1819 posts
  • Version:GM:Studio

Posted 18 February 2012 - 05:35 PM

The difference here with my thing is the four channels per pixel. I want to render my thing in a way that looks good. Remember though that the alpha channels of the pixels aren't completely opague or transparent, but can lie in-between. What looks least pixely, doesn't take forever to render and doesn't have drawing errors?

You ask for a LOT.

Again, for GM, I'd say marching cubes. You'll want to construct a set of isosurfaces (surfaces for which the alpha is at some threshold), sort them so the exterior surfaces are drawn last, and save them to a model.

Good luck. You'll need it.

NOTE: The best thing you can possibly do at this point is to stop trying to do this. It'll be a massive headache for you and get worse results than if you spent the time using normal methods.
  • 0

#6 Buff-Robotix

Buff-Robotix

    Who Took My Pants!?!

  • GMC Member
  • 314 posts

Posted 19 February 2012 - 01:23 AM

Oo Ooo! This sounds like fun!
I've never heard of this technique before but it sounds promising.
For the speed issue: you don't need to render the "pixels" on the inside of the object right? So you just have to draw the outside surfaces. And then once you do that safe it as a model, because you don't want to do that again.
Making this a model: Hmm well it sounds like you have a massive set of 3D points, ya? What if each of those points were a vertex connected by a line? No... that would be really criss crossy... Wait! What if only the ajacent outside surfaces were connected by a line!
I'm having a hard time visualizing this... But let's say, in 2D points...
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
Right, now this would make a square, we only have to draw the outside edges so we connect points (0,0) - (1,0) - (2,0) all those in the Y row of 0. (0,0) - (0,1) - (0,2) all those in the X 0 column. (0,2) - (1,2) - (2,2) those in the Y 2 row. and (2,0) - (2,1) - (2,2) the X 2 column.
There now we have
___
| |
| |
-----
EDIT: Hmm, doesn't look like a square anymore... well you get the picture.

Sure, I could see this being done in 3d with a little bit of critical thinking and a d3d_primitive_begin(pr_linelist), you have the makings of a model, save it and wham!
Colors, on the other hand, hmm... I suppose some d3d_vertex_color() would take care of that, but you would have to keep all your points.
Well there's my thoughts on a vertex based surface drawing method, good luck!

RobotiX

Edited by Buff-Robotix, 19 February 2012 - 01:24 AM.

  • 0

#7 Digisynth

Digisynth

    GMC Member

  • Validating
  • 55 posts

Posted 19 February 2012 - 07:21 PM

Thanks for the help everyone, I really appreciate it! :thumbsup:

@Buff-Robotix: Actually, I have to render the inside too. Else things like realistic volumetric clouds won't work.

I have another idea though, but it will be a bit hard to explain:

It will only use width+length+height polygons, therefore the speed issue is solved.
On the other hand, it will use a lot of RAM.

- Lets imagine the sprite is inside a three-dimensional Cartesian coordinate system.

- You look downward (parallel to the Z-axis) onto the X-axis and the Y-Axis.

- Imagine form this perspective, that the sprite consists of 2d layers that are piled on top of each other.

- Render every layer as image.

- Draw all images as polygons on top of each other, as they would in a volume.

- Repeat all steps along the X-axis and then the Y-axis.

Higher resolutions will have best results.
I'll make an example to show what exactly I mean, but I'll need some time though because of work.

Edited by Digisynth, 19 February 2012 - 07:33 PM.


#8 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1819 posts
  • Version:GM:Studio

Posted 19 February 2012 - 09:10 PM

Thanks for the help everyone, I really appreciate it! :thumbsup:

@Buff-Robotix: Actually, I have to render the inside too. Else things like realistic volumetric clouds won't work.

I have another idea though, but it will be a bit hard to explain:

It will only use width+length+height polygons, therefore the speed issue is solved.
On the other hand, it will use a lot of RAM.

- Lets imagine the sprite is inside a three-dimensional Cartesian coordinate system.

- You look downward (parallel to the Z-axis) onto the X-axis and the Y-Axis.

- Imagine form this perspective, that the sprite consists of 2d layers that are piled on top of each other.

- Render every layer as image.

- Draw all images as polygons on top of each other, as they would in a volume.

- Repeat all steps along the X-axis and then the Y-axis.


Been there, done that. Results can be okay, but you will either have trouble making it not look blocky or have trouble fixing z-buffer artifacts.
  • 0

#9 Buff-Robotix

Buff-Robotix

    Who Took My Pants!?!

  • GMC Member
  • 314 posts

Posted 19 February 2012 - 10:44 PM

I have another idea though

I'm interested to see what you have, maybe a sample of your file format so I can see what I can do with it.

Draw all images as polygons on top of each other, as they would in a volume.

Hmm, I don't know, that would work fine for a cube but how will you manipulate the image for the different shapes of the model? It sounds like you are talking about volumes of a cross section, which might be done better with lines, but incredibly slow for all points.
  • 0

#10 Digisynth

Digisynth

    GMC Member

  • Validating
  • 55 posts

Posted 20 February 2012 - 08:41 PM

Hmm, I don't know, that would work fine for a cube but how will you manipulate the image for the different shapes of the model?


I use the alpha channel to make invisible pixels.

#11 PivotGamer84

PivotGamer84

    GMC Member

  • New Member
  • 170 posts

Posted 05 March 2012 - 05:33 AM

The most efficient way:

Create Event:
w = sprite_get_width(argument0);
h = sprite_get_height(argument0);
sprmod = d3d_model_create();
d3d_model_primitive_begin(sprmod, pr_trianglelist);
d3d_model_vertex_texture(sprmod, 0 - w/2, 0, 1, 0, 1);
d3d_model_vertex_texture(sprmod, w - w/2, 0, 1, 1, 1);
d3d_model_vertex_texture(sprmod, 0 - w/2, h, 1, 0, 0);
d3d_model_vertex_texture(sprmod, 0 - w/2, h, 1, 0, 0);
d3d_model_vertex_texture(sprmod, w - w/2, 0, 1, 1, 1);
d3d_model_vertex_texture(sprmod, w - w/2, h, 1, 1, 0);

d3d_model_vertex_texture(sprmod, 0 - w/2, 0, 0, 0, 1);
d3d_model_vertex_texture(sprmod, 0 - w/2, h, 0, 0, 0);
d3d_model_vertex_texture(sprmod, w - w/2, 0, 0, 1, 1);
d3d_model_vertex_texture(sprmod, w - w/2, 0, 0, 1, 1);
d3d_model_vertex_texture(sprmod, 0 - w/2, h, 0, 0, 0);
d3d_model_vertex_texture(sprmod, w - w/2, h, 0, 1, 0);
for (n = 0; n < w; n += 1) {
    d3d_model_vertex_texture(sprmod, n - w/2, 0, 0, (n + 0.5) / w, 1);
    d3d_model_vertex_texture(sprmod, n - w/2, 0, 1, (n + 0.5) / w, 1);
    d3d_model_vertex_texture(sprmod, n - w/2, h, 0, (n + 0.5) / w, 0);
    d3d_model_vertex_texture(sprmod, n - w/2, h, 0, (n + 0.5) / w, 0);
    d3d_model_vertex_texture(sprmod, n - w/2, 0, 1, (n + 0.5) / w, 1);
    d3d_model_vertex_texture(sprmod, n - w/2, h, 1, (n + 0.5) / w, 0);
}
for (n = w; n > 0; n -= 1) {
    d3d_model_vertex_texture(sprmod, n - w/2, 0, 0, (n - 0.5) / w, 1);
    d3d_model_vertex_texture(sprmod, n - w/2, h, 0, (n - 0.5) / w, 0);
    d3d_model_vertex_texture(sprmod, n - w/2, 0, 1, (n - 0.5) / w, 1);
    d3d_model_vertex_texture(sprmod, n - w/2, 0, 1, (n - 0.5) / w, 1);
    d3d_model_vertex_texture(sprmod, n - w/2, h, 0, (n - 0.5) / w, 0);
    d3d_model_vertex_texture(sprmod, n - w/2, h, 1, (n - 0.5) / w, 0);
}
for (n = 0; n < h; n += 1) {
    d3d_model_vertex_texture(sprmod, 0 - w/2, n, 1, 0, 1 - (n + 0.5) / h);
    d3d_model_vertex_texture(sprmod, 0 - w/2, n, 0, 0, 1 - (n + 0.5) / h);
    d3d_model_vertex_texture(sprmod, w - w/2, n, 0, 1, 1 - (n + 0.5) / h);
    d3d_model_vertex_texture(sprmod, w - w/2, n, 0, 1, 1 - (n + 0.5) / h);
    d3d_model_vertex_texture(sprmod, w - w/2, n, 1, 1, 1 - (n + 0.5) / h);
    d3d_model_vertex_texture(sprmod, 0 - w/2, n, 1, 0, 1 - (n + 0.5) / h);
}
for (n = h; n > 0; n -= 1) {
    d3d_model_vertex_texture(sprmod, 0 - w/2, n, 0, 0, 1 - (n - 0.5) / h);
    d3d_model_vertex_texture(sprmod, 0 - w/2, n, 1, 0, 1 - (n - 0.5) / h);
    d3d_model_vertex_texture(sprmod, w - w/2, n, 0, 1, 1 - (n - 0.5) / h);
    d3d_model_vertex_texture(sprmod, w - w/2, n, 0, 1, 1 - (n - 0.5) / h);
    d3d_model_vertex_texture(sprmod, 0 - w/2, n, 1, 0, 1 - (n - 0.5) / h);
    d3d_model_vertex_texture(sprmod, w - w/2, n, 1, 1, 1 - (n - 0.5) / h);
}

d3d_model_primitive_end(sprmod);

Draw Event:
d3d_model_draw(sprmod,0,0,0,sprite_get_texture(argument0,argument1));

  • 0

#12 hit172

hit172

    GMC Member

  • New Member
  • 189 posts
  • Version:GM8

Posted 05 March 2012 - 12:08 PM

Thanks for posting useless code. Read the topic next time.
  • 0

#13 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1819 posts
  • Version:GM:Studio

Posted 05 March 2012 - 06:32 PM

Thanks for posting useless code. Read the topic next time.

Actually, that code isn't useless. I know because I suggested that method (maybe even that code. It looks similar, but I cannot find my original code to compare it with and he might have changed some things) for a Minecraft-style sprite. It doesn't handle multiple layers, but should work for a single layer of voxels. Of course, partially transparent pixels will cause trouble, which is why I made my previous posts about that.

The assumptions made for that code are: linear interpolation is turned off (Sprites look blocky), and each pixel is either completely transparent or opaque.
  • 0

#14 PivotGamer84

PivotGamer84

    GMC Member

  • New Member
  • 170 posts

Posted 06 March 2012 - 01:04 AM


Thanks for posting useless code. Read the topic next time.

Actually, that code isn't useless. I know because I suggested that method (maybe even that code. It looks similar, but I cannot find my original code to compare it with and he might have changed some things) for a Minecraft-style sprite. It doesn't handle multiple layers, but should work for a single layer of voxels. Of course, partially transparent pixels will cause trouble, which is why I made my previous posts about that.

The assumptions made for that code are: linear interpolation is turned off (Sprites look blocky), and each pixel is either completely transparent or opaque.


It's just code from a help thread I made earlier in the year, which you posted to, about Minecraft 2D Image to 3D model. When I first tested it, it didn't work. I re-thought it out, and tested it the way I posted, and it works.

Credits to you for posting it originally.

@OP
The code most definitely isn't useless. It will be able to take your image, and create a vertex map to create a model, then draw your texture over top. It can later transformed to render as weapons, tools, or other items.

Edited by PivotGamer84, 06 March 2012 - 01:06 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users