Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Randomized textures (sprite strip) #2746

Open
KenneyNL opened this issue May 31, 2015 · 69 comments
Open

Randomized textures (sprite strip) #2746

KenneyNL opened this issue May 31, 2015 · 69 comments
Labels
@ Client / Audiovisuals Feature request Issues that request the addition or enhancement of a feature

Comments

@KenneyNL
Copy link

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.

@KenneyNL KenneyNL changed the title Randomized textures Randomized textures (sprite strip) May 31, 2015
@est31 est31 added the Feature request Issues that request the addition or enhancement of a feature label May 31, 2015
@celeron55
Copy link
Member

OK

@C1ffisme
Copy link

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

@TeTpaAka
Copy link
Contributor

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

@KenneyNL
Copy link
Author

#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.

@C1ffisme
Copy link

C1ffisme commented Jun 1, 2015

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.

@ExcaliburZero
Copy link
Contributor

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.

@Wuzzy2
Copy link
Contributor

Wuzzy2 commented Jun 2, 2015

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?

@KenneyNL
Copy link
Author

KenneyNL commented Jun 2, 2015

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.

@4aiman
Copy link
Contributor

4aiman commented Jun 4, 2015

  1. Wasn't the increase of additional info to store amongst the reasons to decline coloured light sources? (I'm only asking)

@PilzAdam
Copy link
Contributor

PilzAdam commented Jun 4, 2015

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

@C1ffisme
Copy link

C1ffisme commented Jun 4, 2015

@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.

@4aiman
Copy link
Contributor

4aiman commented Jun 5, 2015

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

@cheapie
Copy link
Contributor

cheapie commented Jun 5, 2015

@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.

@ExcaliburZero
Copy link
Contributor

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.

@4aiman
Copy link
Contributor

4aiman commented Jun 5, 2015

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?

@ExcaliburZero
Copy link
Contributor

@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.

@4aiman
Copy link
Contributor

4aiman commented Jun 5, 2015

@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.

@sofar
Copy link
Contributor

sofar commented Apr 10, 2016

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)

@rdnuk
Copy link

rdnuk commented Apr 28, 2016

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. ?

@sofar
Copy link
Contributor

sofar commented Apr 28, 2016

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

@rdnuk
Copy link

rdnuk commented Apr 28, 2016

@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: #3446 & #3923

@sofar
Copy link
Contributor

sofar commented Apr 28, 2016

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.

@rubenwardy
Copy link
Contributor

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

@sofar
Copy link
Contributor

sofar commented Apr 28, 2016

@rubenwardy that's what that is.

@paramat
Copy link
Contributor

paramat commented Apr 29, 2016

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.

@numberZero
Copy link
Contributor

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 =)

@paramat
Copy link
Contributor

paramat commented Sep 13, 2017

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.

@numberZero
Copy link
Contributor

numberZero commented Sep 13, 2017

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 (Real global 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).

@rdnuk
Copy link

rdnuk commented Dec 8, 2017

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

@NathanSalapat
Copy link
Contributor

@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.

@rubenwardy
Copy link
Contributor

rubenwardy commented Dec 8, 2017

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.

@tacotexmex
Copy link
Contributor

tacotexmex commented Apr 12, 2018

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)

@numberZero
Copy link
Contributor

numberZero commented Apr 12, 2018

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

@rubenwardy
Copy link
Contributor

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

@paramat paramat added the Non-trivial A large amount of work is required to address this (sometimes to the point of being infeasible) label Apr 12, 2018
@numberZero
Copy link
Contributor

@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)

@tacotexmex
Copy link
Contributor

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

@ghost
Copy link

ghost commented Apr 14, 2018

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

dirt
grass_sand
sand_only

See this version of the implementation

@tacotexmex
Copy link
Contributor

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).

@ghost
Copy link

ghost commented Apr 15, 2018

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 😄

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.

@tacotexmex
Copy link
Contributor

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.

@numberZero
Copy link
Contributor

How should it interoperate with texture combining?

@tacotexmex
Copy link
Contributor

tacotexmex commented Feb 2, 2019

Not sure, ideas? 🤔

@rdnuk
Copy link

rdnuk commented Feb 2, 2019

@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

@tacotexmex
Copy link
Contributor

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

@rdnuk
Copy link

rdnuk commented Feb 2, 2019

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

@tacotexmex
Copy link
Contributor

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

@NovaAndrom3da
Copy link
Contributor

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.

In regard to numbers 3 & 4... Maybe allow the client to randomize it? If there are a lot of randomized nodes in the world (say, implementing a randomized grass texture), it could increase the size of data storage & transfer. I could be wrong, but I can't think of a use case where randomized textures being consistent between players & clients would be useful.

@Desour
Copy link
Member

Desour commented Oct 21, 2022

(For choosing a random texture one can make a hash of the node pos, tile index and map seed. It won't change after digging and placing the node again, but that's fine imo.)


Related:
Instead of choosing a random texture from a set, one can use stochastic texture sampling.
See also: #12746 (comment)
Unity3D uses it for example: https://github.com/UnityLabs/procedural-stochastic-texturing#read-more

@HybridDog
Copy link
Contributor

Here are some screenshots from a modified stochastic texture sampling demo with Minetest textures.

grass, snow, stone and coal block
2022-11-19-141000_1920x1054_scrot
2022-11-19-141307_652x524_scrot
2022-11-19-141437_1920x1054_scrot
2022-11-19-141719_1920x1054_scrot

Limitation: It works badly with textures which have connected structures, e.g. bricks and cobblestone:
2022-11-19-141825_564x376_scrot
2022-11-19-141140_849x898_scrot

@sfan5 sfan5 removed the Non-trivial A large amount of work is required to address this (sometimes to the point of being infeasible) label Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@ Client / Audiovisuals Feature request Issues that request the addition or enhancement of a feature
Projects
None yet
Development

No branches or pull requests