Minetest: Randomized textures (sprite strip)

Created on 31 May 2015  Â·  66Comments  Â·  Source: minetest/minetest

In a same way that nodes are currently animated (sprite strip) it could also function to give nodes a random appearance. Upon placing the node, a random frame of the stripe strip will be selected. The random seed could be done using a noise.

This would eliminate the duplication of nodes to achieve random node textures.

@ Client / Audiovisuals Feature request Non-trivial

Most helpful comment

Since I disliked the previous example I felt obliged to come up with a better one. Here's Pixel Perfection with 3–10 alternating textures per node. My favorite is the stonebrick wall.

screenshot_20180414_132339
screenshot_20180414_132342

All 66 comments

OK

I made an issue like this at some point, I guess it got lost.

2433 is related. I think this was the one @C1ffisme meant.

2433 would still clutter the texture folder though with multiple alternatives of the same texture, I think having them all in 1 texture file is a bit more handy.

I dunno, it may help some people with texture packs, depending on what they are trying to do.

We could add both as an alternative for people.

This feature sounds like it could be useful.

I agree with KenneyNL that it would probably be better to use sprite strips rather than individual files, as it would be more like the current system for animated nodes.

Some questions arise:

How and when should the sprite be selected?
And how and where will the selected sprite be stored?

Should the sprite be allowed to change on a game restart?
Should it be equally for all clients or does every client determine the sprite by itself?

Some things I can answer from a game designer perspective;

  1. Upon placing/constructing the node.
  2. Using some sort of noise algorithm? No idea on that.
  3. Nope, random textures should stay the same.
  4. It should be equal for everyone.
  1. Wasn't the increase of additional info to store amongst the reasons to decline coloured light sources? (I'm only asking)

@4aiman there is no need to store this extra information; it can be pseudo-randomly generated each time the mapblock mesh is updated.

@PilzAdam Now there's a good idea, give the man a medal!

Okay, so it's kindof hard to do that over the internet.

In fact, we could just use the seed provided by the world already, seeing as it's used for the rest of mapgen. That might work.

@PilzAdam so the textures will "dance" on every update?
I thought the original idea was to preserve the selected texture over time.

@4aiman I think the idea was to have the seed be based off of the mapblock position, so that the "random" numbers will be the same every time for any given mapblock.

I think as C1ffisme and cheapie mentioned, if the random texture would be based on either just the node position or both the node position and the map seed (for a little bit more randomness), then the texture chosen should appear to be "random" while still remaining consistent.

Oh... now I get it :)
So, I won't be able to really choose the texture (i.e. every time I place a node in a certain position it will use the same texture)?
I'd rather want to be able to control the pattern by choosing a texture somehow.

I acknowledge that the initial problem raised in current issue will be solved and fully covered by PilzAdam's solution, but still..

Also, there's a separate issue about the connected textures.
It would be nice to integrate those into this solution while also creating a way to select the chosen texture (i.e. override the pseudo-randomly chosen one).
Step-by-step.

How hard would it be to add a way to use metadata to store the number of the texture?
A certain pre-defined field name can be used.
Will that kill performance?

@4aiman I agree that it would probably be good to have a way to set the texture of the node, as that would open up a lot of other possibilities such as connected nodes, nodes that change their appearance (like furnaces, battery boxes), etc. In the case of a random texture a random number could just be selected on create to determine the random texture.

However, I'm not sure how well that would end up working in terms of storing the metadata.

@ExcaliburZero I'm not insisting on anything.
I'm just trying to find a way to suppress the growth of the size of a mapblock. :)
All because of the fact that initial coloured light was declined due to doubling (or so I was told) the size of a mapblock.

This can be implemented using a simple random number generator that is seeded for each surface with e.g. (x + z <<8 + y <<16 + face). For an example how to make randomness consistent across mesh/map updates look at my random_xz patch or the "plant fun" patch which has this element in it. (PR 3923)

Would storing a single number make such a big diffrence to map block size? i have very little understanding of that at the moment. but it does seem like an extremly small amount of data..

this feature would also mean less nodes being created due to the many nodes that create 2 of each for purposes of having diffrent looks etc..

Grass textured nodes would especially benefit from this, being able to loose that repetative look. thats almost imposible to get rid off without leaving it looking plain.

If it really bugs people, maybe providing 2 versions of this would be better:
1) that does the random picking of a sprite without actualy storing it.(in other words it would be diffrent everytime the node is loaded.)
2) non-random that defaults to the first sprite but is changeable in the node defintion same way in the same way we fould change infotext.

so in essence you would use method 1 for things like grass and other large surfaces and you would use method 2 for things like furnaces..

getting the best of both worlds. ?

Having a method like random_xz had would require no map storage.

@sofar thats a good point. but where would it store it. In a file of its own?
And im presuming if it doesnt store it at all.. that would mean its no longer random just diffrent for each pos?

Either way it sounds like a good solution. Im just curios :)

Edit: Ive just awnsered my own question by looking at the pr: https://github.com/minetest/minetest/pull/3446 & https://github.com/minetest/minetest/pull/3923

it can't be truly random, as the mesh for each block gets regenerated regularly and you don't want the texture of your grass to change just because someone placed a dirt block somewhere.

A fixed seed works well. This is all client-side as well.

Can't you just use a RNG with a seed of (x_100+y_10+z+mapgenseed) % m

@rubenwardy that's what that is.

Clever idea but i feel it is over-complex to move towards needing multiple textures per node face. I know it would be 'optional' but i don't think over-complex non-essential ideas should be encouraged or accepted in Minetest even as options.
With our dev shortage we need to keep things simple and resist overly fancy stuff. Our worlds look fine with repeating nodes and we manage fine without them. For those used to this feature in Minecraft, too bad, don't let that make you see Minetest as worse, don't compare the two, they have an army of paid devs.
This affects meshgen which is our bottleneck, so needs a lot of justification.

@paramat I'm not sure you see the real advantage of this. This would mean you could have randomized bookshelves, or other decor, without needing to register several nodes.

I think that Minetest, the engine, should support people who want features like this.

I wouldn't do a sprite strip. We already have this exact mechanism for sounds: e.g. if you request "sound_place" you can get any of "sound_place.ogg" "sound_place.1.ogg" "sound_place.2.ogg" "sound_place.3.ogg". This sounds much more generic and could be used for any texture, including normal maps and overlays.

How about a method to override textures through node metadata? That would
come in handy for my rgblightstone mod that currently registers 4096 nodes.
I'd be able to replace that with just one, and also add more colors at the
same time.
On Apr 29, 2016 11:54 AM, "Auke Kok" [email protected] wrote:

I wouldn't do a sprite strip. We already have this exact mechanism for
sounds: e.g. if you request "sound_place" you can get any of
"sound_place.ogg" "sound_place.1.ogg" "sound_place.2.ogg"
"sound_place.3.ogg". This sounds much more generic and could be used for
any texture, including normal maps and overlays.

—
You are receiving this because you commented.
Reply to this email directly or view it on GitHub
https://github.com/minetest/minetest/issues/2746#issuecomment-215806848

@cheapie That would be nice. But while were at it, we should really make all parts of a node be override-able by metadata.

@cheapie that's nice but it would mean that mods have to touch _every_ node and attach metadata, which is expensive and adds storage space.

I see that as a solution for another problem, and so it shouldn't be used to solve a different problem.

Nodes would probably still have textures in the definition, and the texture
override metadata would only have to be present if the texture is, well,
overridden.
On Apr 29, 2016 2:47 PM, "Auke Kok" [email protected] wrote:

@cheapie https://github.com/cheapie that's nice but it would mean that
mods have to touch _every_ node and attach metadata, which is expensive
and adds storage space.

I see that as a solution for another problem, and so it shouldn't be used
to solve a different problem.

—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/minetest/minetest/issues/2746#issuecomment-215859881

@cheapie
Despite I was the one who wanted to override textures using metadata, I think that's not such a great idea as of now.

Getting metadata before drawing a node would mean reading data from a server.
I don't know whether locally saved map or a server one will be accessed, though.

I'm not sure you see the real advantage of this. This would mean you could have randomized bookshelves, or other decor, without needing to register several nodes.

Yeah i do see use for the idea, but it can be done in mods with extra nodes, basic Minetest just doesn't need this enough to justify making critical code more complex. Randomisation is a more specialist thing so a mod thing, it should not burden the basic game.
There are endless amounts of fancy ideas that could be added to Minetest, very often these are suggested forgetting the core priciples of Minetest: simple and lightweight.

@paramat

but it can be done in mods with extra nodes

C1ff said:
without needing to register several nodes.

Adding four extra nodes that do the same thing, have the same hardness, etc, but are different only in texture just means that four more nodes are being loaded at loading time.

forgetting the _core priciples_ of Minetest: simple and lightweight.

We have core principles? Because last I checked, we can't even sort out our development direction.

(Yes, I see that we added a CONTRIBUTING.md. That has to do with code styling, not development goals.)

I'm pretty sure that you are the only one who has said anything about Minetest being 'Simple and Lightweight'.

How many mapgens do we have again?

Yeah i do see use for the idea, but it can be done in mods with extra nodes, basic Minetest just doesn't need this enough to justify making critical code more complex. Randomisation is a more specialist thing so a mod thing, it should not burden the basic game.

It can be done client-side, without any server peformance impact, and almost no client side rendering impact.

Why do we want people to make hundreds of new nodetypes again?

Personally I think this is a great idea

I agree, @paramat I love the work you have done. the mapgen V7 is awsome..... but based on your anology rivers and mountains would be classed as too complex... so they shouldnt be threre?

This has nothing todo with wether minecraft uses it or not, this is based on what minetest devs/users want and overall it looks like it is wanted my the majority of those that have commented both in this issue and others like it.

This idea will improve both the overall visual looks of the game and the quality of mods that use multiple nodes to create the same effect.

Screenshot from Eloraam's Minecraft clone (RedPower 3):

https://twitter.com/therealeloraam

tiling

will be awesome in the Minetest

It should probably be done in a way that allows texture packs to supply more or less textures.

I don't thnk it improves appearence by much, if at all, the screenshots above show a badly designed texture in the first example so those are misleading.
Minetest worlds look fine as they are with repeating textures, i obsessively watch Minecraft videos and have never thought their use of randomised textures improves the appearence. After all a voxel world is all about identical cubes.
I still don't think it's worth the extra complexity in our critical bottleneck of meshgen, and moves towards an expectation of multiple textures per node makes modding and texturing more difficult.

I guess with a nice balanced texture you don't need to randomise anything. On those screenshots above we have both bad texture and North Korea like design :)

I think it's a great idea, but it does depend on the implementation being simple and general enough. I could live without it just as easily.

Duplicate of #2433

Re-opening as this has more discussion than #2433 and discusses that method too.
Closing #2433 as the duplicate even though that came first.

This conflicts with merging nodes in stripes. But as that merging doesn’t seem to affect performance (maybe it does on older GFX, but on my GeForce 8400 GS only output size matters), that’s not a problem, it just should be optional. Moreover, node colorization conflicts with that already, and this looks like an alternative for that, although actual use cases may be different. But still, param2 seems to be the place for the frame index, as it is for color now =)

Consider sofar's idea:

I wouldn't do a sprite strip. We already have this exact mechanism for sounds: e.g. if you request "sound_place" you can get any of "sound_place.ogg" "sound_place.1.ogg" "sound_place.2.ogg" "sound_place.3.ogg". This sounds much more generic and could be used for any texture, including normal maps and overlays.

So, we have several options:

  1. param2-based texture choosing. Fully controllable, suitable for various usage patterns. Requires param2 to be set in the map (thus increasing compressed size), so not very good for large solid chunks.
  2. Random texture choosing. Suitable for large areas to reduce visual repetitiveness.
  3. Large textures (#6105). Designed for large areas for the same reason.

I’d prefer (1) and (3) (for different use cases), but have nothing against (2) as yet another option. We have random Y-offset for plantlike, after all.

P.S. @paramat What sofar suggests is just an implementation detail. It looks acceptable both for (1) and (2). Just note that such texture usage is not GPU-friendly per se, so needs some tricks to work well. (Really, the whole MT needs these tricks, like using texture atlases).

Whilst we are on this subject... is there a reason why we use different texture files for each face instead of 1 texture that wraps the node? i would think the latter would be more efficient

@Ryan-Nolan If we used one file with each face a texture would have to be six times larger if every face was the same, as it would have to include the same texture six times. Now it's possible that somehow it could be coded to read differently depending on the texture size, but then if you wanted to have two faces different you'd still have to use a texture with all six faces on it. Like @tobyplowy said not very efficient for artists and it would lead to bloat.

It also wouldn't help with performance at all. The Engine doesn't render all sides of a cube. A related optimisation which would be worth doing is texture atlasing - this existed in previous versions (until 0.4.2 or so) but was buggy due to a bad implementation. I believe this could have a good performance improvement by not switching texture context when rendering.

sofar is on point with this comment: We already have it for sounds, why not textures too? There's plenty of texture packs with multiple alternates that can support it immediately.

Currently I have to register 5-10 node definitions for each unique node in order to support it. And that's only when placing the node (on_place), not in mapgen at all.

A quite horrible example shouldn't have to botch the whole issue. (Though #2433 is a better fit for this specific solution)

Because we are still limited to IrrLicht, which lacks texture arrays, for example. Animation is done by choosing a texture (by name!) before even starting rendering (the texture strip itself is only used to cut these parts from it). But the same hack with normal nodes will mean using several times more textures, that's not very good as texture changing is slow, and that will slow meshgen (which is our bottleneck) down considerably too. OTOH, using strip as is would mean bugs at edges.

Seriously, I may eventually fork IrrLicht and add support for some cool features I and we need... sfan5 confirms that’s a good idea)

UPD: fixed the name, that was sfan5 and not nerzhul. http://irc.minetest.net/minetest-dev/2017-12-28#i_5182234

Buildaworld have a fork of irrlicht with some more graphics features, may be worth looking at that

@rubenwardy Their fork looks great! It seems to have everything we need!

Of course it needs some adoption, e.g. they dropped Win32 support recently, we can’t do that. But it looks very-very promising)

Since I disliked the previous example I felt obliged to come up with a better one. Here's Pixel Perfection with 3–10 alternating textures per node. My favorite is the stonebrick wall.

screenshot_20180414_132339
screenshot_20180414_132342

I implemented that in Lua without any need for texture or engine changes. It works, but it’s hacky, though :smile:

dirt
grass_sand
sand_only

See this version of the implementation

That solution is fine if you just want random rotation of nodes, but it doesn’t work reliably for alternating textures (no other interacting mod will recognize default:stone_2 etc).

That solution is fine if you just want random rotation of nodes,

The solution is horribly hacky and after releasing it a better solution without flooding the world with metadata came in my mind :smile:

but it doesn’t work reliably for alternating textures […]

Yes, rotating nodeboxes would break how they are intended to look, but that wasn’t my goal. If ever properly implemented this implementation should handle it correctly and not simply override/force anything.

With my hacky code it’s possible to define the facedirs for the nodes so all facedirs where the node looks bad in can be omitted while defining the allowed rotation facedirs. I do this for grass for example.

So who's disapproving of sofar's idea of implementation? No-one? Ok, let's move forward.

Multiple alternate textures per node, randomized each placement

Now, even though #2433 is closed in favor of this long-winded and sprawly discussion, it quite sums it up. There would be no new Lua API addition because just like how sound alternates work, the engine would at each rendering of a node look for textures called
default_stone.2.png, default_stone.3.png, default_stone.4.png and so on.

How should it interoperate with texture combining?

Not sure, ideas? 🤔

@numberZero I think initially it should probably ignore any texture combining arguments to keep it simple. At the moment i cant imagine an example where this would be useful with texture combining. imo

The one I think of is alternates of the dirt texture because that texture is usually overlayed with a grass texture for sides.

@tacotexmex That's a good point, i didn't think of that

I wouldn't mind at all if simply the first texture in the series was always used in texture combinations.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

C1ffisme picture C1ffisme  Â·  184Comments

numberZero picture numberZero  Â·  130Comments

tenplus1 picture tenplus1  Â·  188Comments

ExeterDad picture ExeterDad  Â·  53Comments

rubenwardy picture rubenwardy  Â·  175Comments