Add per-part 'Random Offset' property to Materials to break up repetition on duplicated part sets

Currently, one material displays in the exact same pattern on every single part. This leads to the following issue where clear duplicative tiling shows up on builds that are comprised of numerous similarly-shaped blocks of the same material.

It would be nice to have the ability to check a ‘random offset’ property onto a material to avoid this issue.

Note: this post is not specifically suggesting WorldAligned materials as seen in Unreal Engine, but a simple material coordinate offset per-part to avoid multi-part texture repetition.


(Compiled later response into original post)

11 Likes

Is that what material pattern organic does? Or do you mean something that works for bricks?

3 Likes

The Organic setting under Tiling>Pattern does add an extra layer of randomness to a material, but this property is meant to help break up tiling on a single part rather than between multiple parts. In addition, it’s not meant to be used on materials that have repeating patterns (see below, blobs of bricks blend into each other unnaturally)

Plus, the material still displays in the exact same manner across parts even with Organic enabled (always starting at the top left corner without offset), so in this example you can see each part has the exact same pattern with the same patches of brick appearing in the same location so it looks very repetitive.

6 Likes

Sure but won’t this cause many issues? How would you go by implementing this? In my view, when it is time to repeat the texture, it would still cause some unnatural looking formation. The repeated tiling on similar parts issue would still persist as well.

I would suggest maybe giving a brief idea on how you think this could be implemented. Just so that the engineers find this post interesting and this actually gets implemented.

2 Likes

Okay, well, let me give an example for you to better understand what I am trying to convey. Below is a material I designed in Substance Designer. It’s meant to look like somebody has coloured in the part with watercolour paint. It looks good when it’s on one single stretching part.

My game features destructibility, so in areas of the level design there will be walls made up of numerous similar parts to be broken up. This leads to the issue at hand, they can look pretty bad and repetitive as the texture begins in the exact same location on the brick each time, in the example above you can see a dark patch at the bottom right of each brick. This is the same area of the texture that I highlighted in red on the large brick.

While adding a ‘Random Offset’ wouldn’t make the material between bricks seamless (my aim here isn’t to make the bricks seamless, just not to have the texture be so repetitive), it would avoid an unintended pattern from cropping up on these sections of the level.

My proposed idea is to add a ‘Random Offset’ property under the Material Manager so you can set certain materials to have a random starting point on your material textures per-part.


2 Likes

Ah, so having textures that can be seamless with more than one adjacent parts.

You should have such info mentioned on the original topic by default rather than providing them when someone asks. It would get your post to get more attention.

1 Like

My apologies, I thought I could get away with quite a simple explanation ^^’ - and not quite a ‘seamless’ suggestion as stated above, that would be a “World-Space” material like you can set up in Unreal Engine, but afaik those are a lot more costly to performance than a standard material.

1 Like

If you go with simply a random offset I fear you’ll replace your issue with another one where objects with certain materials (bricks, wooden planks, etc.) cannot be stacked anymore without any obvious seams.

image

You already mentioned it while I was writing this reply, but maybe the better option would be to support an option for triplanar projection to be applied in world space rather than object space. It’s how smooth terrain works I believe. You might still run into problems where materials won’t map nicely when objects are rotated in certain ways though.

Honestly, maybe the best solution is to just union your walls together and solve collision with invisible parts (disgusting, I know), since it will solve the repeated tiling issue on the material.

5 Likes

It would be great for this feature to have an offset increment option as well, maybe even with a separate increment and max offset value.

For example, if the increment is 1 and the max offset is 50 it will offset the texture of different parts by a random whole number between 0 and 50.

If the increment is 0.5 and the max offset is 50, it will choose a number(which when doubled is a whole number) between 0 and 50.

When the increment is 0 it behaves as you described in the post, the random offset could be any real number within the range of 0 and 50.

I personally understood it but the more clarity a post has the better

2 Likes

Good point. This could potentially be fixed with another property then, such as ‘Random Offset Snapping’ (Vector 2) - so when you have ‘Random Offset’ checked, it would stick to certain units on your texture to improve stacking on geometric materials.

Whatever the best units to snap the texture offset to is up for debate. I imagine it could work as a ratio of the entire texture. For this example I am naming the offset snap property as ‘Random Ratio Snap’, so the randomly chosen texture offset snaps to an imaginary column/row.

image

For example if your brick texture has 7 stacks of bricks up-down and 4 bricks left-right, you’d use a ratio of (4, 7) and it would snap the top-left of your randomly offsetted material to these relative positions of your texture.
image

1 Like

Ooo, I like this implementation! But as textures are technically square, would a separate horizontal and vertical offset be necessary? Perhaps some elaboration into the use-case would help me see if it has an application

1 Like

You could perhaps get away with a single Ratio Snap variable, but a Vector2 to refine snapping on both axes would cover up issues in instances of certain tiling patterns that have differing X & Y shape stacking amounts, in the case that Zomebody gave for a brick texture.

Bricks tend to be wider and squatter, more fit vertically than horizontally. Another example would be wooden planks.

For this example, I’ll be using bricks that have uneven ratios between their axes.

A texture of 4x8 bricks wouldn’t really encounter any stacking issues due to one number easily factoring into the other, but for 3x8 bricks, having unified snapping offset would result in some inconsistency. As you can see on the right two examples, the selected offset begins partway into a brick’s tiling.

Being able to set the snapping per-axes would improve accuracy in select scenarios to help environment artists closer achieve what they had in mind :grinning:

From reading this, what you want to achieve is a better blending to make the tiling more seamless for textures that don’t seamlessly tile?

1 Like

No no, my point in this feature request focuses on making duplicated parts next to each other have different offsets on the same material to avoid repetition from occuring :slight_smile:

Current material behaviour:

Desired behaviour:

2 Likes

Ah I see what you mean now yeah. This is something that can be solved in other engines like Unreal Engine quite easily!

In Unreal Engine you can for example make a texture be on a object in 2 ways. Lets say we have a wall right? Like in your example.

Method 1: Texture the object via its UV map.

This is the most basic way, but it results in the problem you described above. Heres a example from Unreal Engine 5.


Method 2: WorldAlignedTexture node.

Now this can be easily fixed in a way, UE has a material node called “WorldAlignedTexture” where textures are tiled in world space instead of UV’s. Here’s a example of it.


Now obviously, both come with their ups and downsides, but i think this is basically what you are looking for no? These are just 3 cubes together basically.

image

2 Likes

Yes I am aware of these! I studied Unreal Engine as part of my 3 year University course ^^ This isn’t the exact feature I was asking for in my original post, however it would also make for a great solution in itself.

I was told somewhere in the course that, using too many WorldAligned materials could have performance impacts compared to just using regular coordinates, which is why I am asking for a simple random coordinate offset instead. How entirely true this is, I’m not sure.

1 Like

Oh, thanks for correcting me. And can I ask how they are more costly to performance? I am interested in this.

1 Like

It’s the kind of thing that would cause noticeable performance hits when used on thousands upon thousands of instances with WorldAligned materials. So in most instances it would be fine, but if used in huge maps with detail, such as showcases, it could be of concern. I’m sure the talented Roblox engineering team could come up with a more performant solution though.

Lincoln Hughes UE4 Master Materials — Experience points.
How expensive is World Aligned Textures? Is it Okay to used it in my case? - Rendering - Epic Developer Community Forums

The way it works (in Unreal Engine) is that it works out the position, rotation and scale of the part in 3D space and ‘projects’ the material onto it, so if you had multiple meshes intersecting with each other to try and build rough but contiguous terrain, the material would blend them together seamlessly.

Regular material


WorldAligned material.

1 Like

Interesting! Does the performance impact purely come from using multiple materials? What if I use 1 master material with texture parameters? Basically doing material instancing? So we have 1 material and let’s say 10 different instances which just change the parameters like: tiling, textures used etc

1 Like

Another thing I could think of is using the CSG api to Union these during runtime? If they are like procedurally generated? Unions do “fix” this issue somewhat, but I’m not sure if that suits your use case here

1 Like