0

Okay, so me and a friend are attempting to create a 3D engine of sorts and we've recently made our way past all the preliminary bugs. At last, we managed to get a block of dirt rendered (I'd post an image but I don't yet have enough reputation). Now, however, we are running into some more problems and this time we have no idea what's wrong.

See, when you move to the either side of the block, holes begin randomly developing in the faces. Example, example. I suppose I ought to explain how our rendering works - we're using Pygame (without any real 3D library, that's kinda the point), and couldn't figure out how we should transform images when moving about in 3D space. So, we decided to split all the pixels into separate Tile classes and render them as polygons with color - much easier, just have to calculate the vertices instead of mapping an image. The way we make sure holes like these don't happen is by sorting them all according to distance from the camera, and rendering in that order.

At some point we'll implement optimizations like backface culling, but until then we have this big problem: our distance function doesn't seem to be working properly!


Here's what we have to calculate distance:

def pointdist(self, point):
        return (self.x - point[0]) * (self.x - point[0]) + (self.y - point[1]) * (self.y - point[1]) + (self.z - point[2]) * (self.z - point[2])

We have a list master_buffer that holds all the tiles, and puts the ones to be rendered in draw_buffer - right now, that's all of them, because we don't have any filtering or optimizations implemented yet.

for tile in self.master_buffer:
    self.draw_buffer.append(tile)

self.draw_buffer.sort(key=(lambda tile: c.pointdist(tile.center)))

After that, we just go through draw_buffer, calculate, and render. That's all the filtering we're doing, so we can't fathom why it'd form such holes.

If you need additional examples or parts of the code, feel free to ask. Advice on our method in general is also welcome.

RESPONSES:

  • In response to calculating the sum twice, I'm doing this for performance - I've read that multiplication is significantly faster than exponents in python when the exponent is small, so that is what I am doing.
  • In response to my question not being clear enough, I am trying to figure out why there are holes in my cube. That is made quite clear, in my opinion.
  • In response to not having square roots, that's because I don't need the distance, I need to compare distances. If a > b, then sqrt(a) > sqrt(b) always, so leaving out sqrt will improve performance.
  • c, my camera, is not inside the cube when this is happening. The drawing code performs the calculations, and immediately renders - nothing can happen in between.

EDITS:

  • I think it may be helpful for everyone to know that the only angle at which there are no problems is when viewing top and front faces - any other faces viewed, and things will start falling apart.
  • Also, if it helps, the axes are: +x to the right, +y going backwards, and +z downward.

  • Seeing as no one has been able to find a problem, we will attempt to take the approach of calculating distance for each face rather than individual tiles. It will mean we are locked into using cubes, but that's the best route for now.

  • you don't need to calculate every difference twice... you can just do `(self.x - point[0]) ** 2` – Jason Stein Jul 05 '17 at 19:38
  • Welcome to Stack Overflow. Please read [ask] in order to understand the kind of questions that we find acceptable. Your question contains too much disparate information, which makes the concrete question hard to capture. If you just want to address the point distance function, please make a [MCVE] of that, including a set of sample inputs and what you'd expect as output. Other than that, questions asking for advice or recommendations are _off-topic_, and will likely be closed if they are not improved. – E_net4 Jul 05 '17 at 19:38
  • This is just a guess, but if your distance function is correct, then the problem is probably with `c` not being what you expect it to be. Two possibilities that I can think of right now are your `c` is updated after that computation but before the rendering, or your `c` is inside the cube. – Miguel Jul 05 '17 at 19:54

0 Answers0