entuland / wesh

Minetest in-game woolen mesh creator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use Minetestmapper colors.txt

benrob0329 opened this issue · comments

It would be nice if it would use the minetestmapper colors.txt rather than a custom (and more limited) format. Would make larger pallets possible. https://wiki.minetest.net/Minetestmapper

Yes, in theory it would be a great idea cause it would indeed allow for larger palettes, in practice we have some technical considerations to make first.

Colors are applied to each face just like other nodes work - that is, not simply an RGB value as pixels in an image work, but using part of a texture file. This means that any RGB value we want to use must exist as at least a single pixel in the chosen texture file, and 256 ^ 3 = 16777216 colors, and its square root is 4096 - in turn, this means that we would either need to use a 4096x4096 texture covering all those colors, or to create a customized palette texture file for each mesh that this mods captures.

Using a huge texture file is of course out of question (most of it would go unused anyway, and I'm not even sure the game / engine supports them); on the other hand, creating a customized palette texture file would be feasible, but it would mean including the code that generates such a PNG file inside this mod's code.

I happen to have found one such encoder here: https://github.com/ggcrunchy/image_ops/blob/master/png_encode.lua

In order for this to work we need the following:

  • create/import a nodes-colors mapping file that uses the suggested RGB format;
  • test and include a PNG encoder (eventually the one mentioned above)
  • write code that prepares the list of needed colors, packs them into a texture, UV maps each color to each face (such mapping will end up in the .obj file) and writes all of it to the actual PNG file;
  • write code that moves such custom textures from the world folder to the mod folder (we can't write in the mod folder at runtime, and we can't load meshes or textures from the world folder) in order to be able to actually use the new meshes in the game after reloading the world
  • all of the above should be implemented with full backwards compatibility, allowing players to continue using the current mapping system;

If I find some time I'll try to investigate the thing further and I may give it a go - at the same time, I'll be more than happy to evaluate any pull request covering this new feature.

(ideally, the best option there would be to work out the needed RGB value for each face of the mini-voxels by averaging the colors used by the texture of each face of the original nodes - that would make the whole node-colors mapping useless, but that would also be an insane amount of work, probably not even reliably doable due to the "non-cubicness" of many nodes)

Minetest does have texture modifiers for colorization and combining, so you could theoretically colorize a single pixel texture and place it inside a larger texture on the fly based on the pallette in obj.dat.

You could have a texture that is 256 pixels large, and have that be the cap as most areas will never have that many nodes crammed into one spot. When the mesh is generated, create a pallette of nodes (a list/table/array) in the order that things are UV mapped in the texture. Then have the texture modifier be generated based on that list and the colors in colors.txt and set it on nodedef.

Having a way to regenerate meshes based on the stored builds would make converting much, much easier.

EDIT: Now that I think about it, having a larger pallet would be nice, but it's also nice with the current pallet that texture packs can override the colors. The added complexity might not be worth it in this case.

Not sure I completely follow... the way I understand the colorize command in the texture's string is that you have some sort of grayscale texture (or alphascale texture, not sure about that) and you provide a single color for the whole texture, turning all shades of gray into, say, shades of red.

Can you give me any further insight, better with some sample code / sample mesh with a colorized texture, so that I can understand exactly how this thing works?

Yes, the colorize modifier only works on entire textures, however we also have the [combine modifier.

 [combine:WxH:x1,y1=filename1:x2,y2=filename2:...
Copies image from file filename1 to x1, y1 of the base image (blitted), filename2 to x2, y2, etc. The base image is created with dimensions W x H if it doesn't exist.

https://dev.minetest.net/texture

So you could take a 1x1px texture and colorize it, then place it into a larger texture.

Theoretical example:

[combine:256x1:x1,y1=(pixel.png^[colorize:red:255):x2,y1=(pixel.png^[colorize:blue:255)

Oh I see... Well, I think that would impose some additional work every time the world starts in order to generate the images, and in the perspective of having multiple meshes with a separate texture, that may become taxing if there are a lot of different ones to be loaded.

At that point, generating the PNGs at capture time would be a better option I guess, so that at least the textures are ready to use and just need to get loaded.

Thanks for the ideas, I'll look into implementing this if I find time.

The textures are rendered by the client at the time that they are needed,and the cached until a new texture is defined. Of course, the server would need to generate the texture string upon definition (unless that was cached when they were captured).

In my experience, texture modifiers are pretty darned fast, I had a texture being updated at about 20 frames per second based on an alpha mask on an entity one time, and it handled it with flying colors.

Uhm.. interesting. I was also thinking that it would be funny to have all the colors stashed in the declaration file as a string instead of creating a PNG file, but that would definitely save me from the need to integrate a PNG encoder into the mod... definitely worth giving it a shot.

Just to be sure, since you surely know more than me, about the part you cited:

[combine:WxH:x1,y1=filename1:x2,y2=filename2:
Copies image from file filename1 to x1, y1 of the base image (blitted), filename2 to x2, y2, etc. The base image is created with dimensions W x H if it doesn't exist.

Am I understanding that correctly that the resulting file will get saved and used (and cached, as I gather from your last message), without me specifying or even knowing what the resulting filename will be? I guess also that changing the definition string will result in the computed texture to be updated... I really need to find the proper time to fiddle with all of this.

Yes.

Aaaargh... no dice... we cannot use grouping with parentheses within the [combine section, and if I put multiple [colorize sections without grouping it seems that they affect all that has been combined so far, so I cannot colorize single pixels... seems like I need to actually use a PNG encoder to achieve such arbitrary palettes.

Scratch the above, Krock taught me on IRC that we can use escape sequences to use grouping there:

"[combine:2x2:0,0=(px.png\\^[colorize\\:#F00):1,1=(px.png\\^[colorize\\:#0F0)"

This is one of the references I've got there on IRC: minetest/minetest#6821

Not sure I'll be able to actually test the performance of such a technique vs using a PNG encoder, I'll probably just try to implement it with the texture modifiers and call it a day - or probably a week, or a month :P

uhm... in the end it wasn't all that big of a deal, and my few tests seem to say it's working decently.

@benrob0329 would you mind pulling the latest commit and see if it works fine for you? Any change you may want to make to colors.txt should go to custom.colors.txt that will be created in the main folder after you run it at least once.

This is dope man, the only thing might be that the forum post and README need to be updated.

screenshot_20190107_171635

EDIT: Perhaps you could colorize a B & W wool texture using the RGB values rather than having multiple pallets.

Neat, nice to see that it's working fine for you.

Yep, I'll have a further look at the code to ensure nothing broke as for importing from the old code, I want full backwards compatibility.

As for the old mechanism, it works fine and it's most likely not worth touching it - if it ain't broken... :P

Thanks for the test, I'll update the repo and publish a new release ASAP.

Version 1.1 released with the implementation of this feature and an updated README file
https://github.com/entuland/wesh/releases/tag/1.1