Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.6k stars 245 forks source link

Should support for voxel texture weights be replaced with a voxel material ID? #688

Open NoTalkOnlyProx opened 3 weeks ago

NoTalkOnlyProx commented 3 weeks ago

Over on #685 it came up that @MGilleronFJ and @Zylann (are you the same person? I'm not sure, but both accounts replied to me) is considering removing texture weight painting, and replacing with an alternative.

Since #685 was covering too many issues at once, I have split it into multiple issues and closed it. So perhaps it would be a good idea to separate that discussion out to its own issue as well.

Here are the relevant exchanges from that original issue:

@MGilleronFJ:

I didn't really know how to introduce texturing to the graph generator, and I tested that only once or twice a long time ago, then never actually used it. I used OutputSingleTexture more.

My feeling right now is that individual weights are hard to use properly, complicated internally, don't scale well, and are expensive. I'm considering to remove them rather than trying to solve all the issues that may come from it. Especially since I'm also thinking of changing the texturing format into something less featured but simpler and lighter.

@notalkonlyprox

Ah, please don't remove it! For what it's worth, IMO, this is a core feature of a good terrain engine. I was really very glad to see that you had gone to the effort of adding it! A simpler mode does make sense if users don't need that level of detail. Maybe an alternative texturing mode entirely? But I understand if your concern is keeping the code-base maintainable. Still, I would be very sad to see this feature go.

@Zylann

As much as you would like it, I don't really want to maintain it. I have found it too complicated to manage. This is not as simple as what you'd see on a heightmap terrain system (the graph makes it look that way, but has a lot of work to do with the result in order to cram it into voxels; which is further "crunched" down by meshing). Voxels are volumetric, and per-voxel texturing often ends up used very differently, due to resource constraints and differences that make it not suitable for a bunch of cases. The format I chose originally is also quite heavy. If you make use of a lot of weights, it more than doubles the size of voxel chunks. I don't have the motivation to keep the weight nodes in the long term (you're also the only one to attempt using that in a very long time). I'm considering to switch to a system where each voxel has only one material ID (up to 256 values (which could mean textures), highly compressible), and that's it. It's very simple, and seen most people rather use that. That's also what No Man's Sky uses. At least, this is what I'm inclined to work on eventually. Keep in mind this is not the only way to have texture variation in the terrain. This is just one source of data for doing so. I would only use it if some parts of terrain need to have gameplay-related volumetric information about what voxels themselves are made of (a very common example are ore patches and dirt/rock changes; not grass, not snow). It can be combined with procedural techniques in shaders.

My response will be in comments

NoTalkOnlyProx commented 3 weeks ago

As much as you would like it, I don't really want to maintain it. I have found it too complicated to manage.

Bummer. Obviously, this is your project to manage. So whether or not maintaining it is worthwhile is ultimately your call. I am in no position to demand otherwise. But if there is a way for you to simply not remove it without it being too much of a development burden, I would be very grateful. I do understand that this is unlikely to be the case, however.

This is not as simple as what you'd see on a heightmap terrain system

Believe me, believe me, I understand fairly well the complexities, I read through a lot of that source code you contributed xD. And, while this code-base is large enough that I have only very basic understanding of your approach, I actually quite like the approach you chose!

I'm considering to switch to a system where each voxel has only one material ID (up to 256 values ). That's also what No Man's Sky uses.

I can understand the allure of that system, and you are probably right that if it were a choice between the two systems, that system would be the better choice for the vast majority of users. One area I am not super familiar with is your voxel storage systems, so I don't know whether it would be easily possible to offer both the 8-bit approach and the 16-bit splat approach, and then leave the latter up to weirdos like me to maintain. The wishful side of me hopes that you could somehow do that without much burden. But I understand if the reality is that you can't.

Keep in mind this is not the only way to have texture variation in the terrain.

Certainly! The key thing this lets me do, that other approaches do not, is feature-aware texturing. Suppose I create generators (or perhaps modifiers, or perhaps just scripted voxel data editors) that result in special features in the terrain. The current system allows me to paint those features in with custom textures, and still get (fairly) smooth long-scale gradients. Obviously the 8-bit nature of the weights will cause the transition to be kinda steppy, but it's better than nothing.

With shader-level techniques, I can add very smoothly transitioning details, but not that are feature-aware. With the 8-bit integer idea, I can do feature-specific painting, but not smoothly. I do think there is a justifiable use-case for the middle-ground that is your current solution, for what it is worth

But again, I respect that I am just an interloper here, and you are the one dedicating significant amounts of your time to maintaining this project. I am happy to offer some of my time to fix the specific issues I encounter with this system that, admittedly, seemingly only I and a very small contingent of others have interest in. But that help by its nature will be only of limited usefulness if the feature itself is impeding you in other areas, I understand completely. So if this is your final decision, I will respect that, and I guess try to find a way to work within the limitations.

But I would like to discuss it just a bit before totally giving up :P

Zylann commented 3 weeks ago

If you would like this format to stay and work on it, I would not be opposed to keeping it around, if it is made modular. That's going to be my ideal plan at least, when I add the next format. Right now this is not really the case, because it happens to be the "only" one format there is, and it has required "intrusive" custom code in various places to be supported, so it doesn't sound trivial at the moment.

Note about the issue title: it's a bit misleading, I don't intend to remove texture painting. Instead I'd like to simplify the voxel format down to 1 material per voxel, and wanted to drop support of output weight nodes in the graph system. So yeah, weights in voxel data would pretty much be removed. Shader-wise, things dont actually change much, blending may still occur, only across one voxel, for the per-voxel part.

NoTalkOnlyProx commented 3 weeks ago

Fantastic, yeah. I am happy to stick around and help maintain it if you make it modular. If you are wanting me to make it modular, I honestly don't think I would have the time to get as deeply familiar as is required with the entire engine to be able to do that cleanly. But maybe that will change

So, when you get to the point of either removing it or modularizing it, and if modularizing it is not something you are willing to dedicate dev time to (understandable), then ping me, and let's consider it from there?

Zylann commented 3 weeks ago

I think the main problem to make it modular is the way I had to intertwine it into the Transvoxel mesher.

I recently experimented with a different implementation of dual marching cubes, to which I attempted to add the 1-material-per-voxel format, in a modular way: I made it so material data is produced in a second meshing pass, instead of the main pass. This might have some performance cost, and also it wasn't great (but that's more an issue with DMC). But the advantage of two passes is that if a different material format is needed, a different second pass function can be written, without touching the first pass. But none of this is ready, it's still in an experimental branch.

Meanwhile the Transvoxel implementation isn't like that at all currently, because of performance reasons: it seems that if I move it out, performance might degrade due to the implications.