Unity - UV Offset per particle - Is it possible?

Hello,

Does anyone know how to change UV Offset per particle in a single emitter?

I have a scenario in which a simple shader is multiplying and panning some textures in order to generate smoke. The problem is that the emitter is spawning particles with the same instance of the material and the whole effect looks and scrolls with the same exact offset. I would love to vary this on per particle basis. I would love the solution to involve shader work but I don’t think that you can access in any way material instances.

Anyone had the same problem and maybe has a simple solution?

1 Like

Use the particle Color, it will come through to the shader as vert colour stream.

so give each particle a random red colour, offset uvs by the red vert stream and you’ll get random particle uv offset.

3 Likes

Or if you want to do it in C# you can make a component that defines a random value per particle, or uses world position (another good driver).

If you’re in Unity 5.5, you also have access to vertex streams per particle, which allow you to pass quite a bit more information into the particle shaders.

looking forward to Unity 5.5. Looks like a few things are getting updated :smiley:

@Alcolepone - this one is a really neat trick! I’m always sending information to particles that I’ve completely missed that you can do this the other way around - that’s really enlightening! Thank you! Works like a charm! :heart_eyes:

@Keith I was trying to do this using C# but I’m not much of a coder and couldn’t get past this:

using UnityEngine;
using System.Collections;

public class Particle_Texture_Random_Offset : MonoBehaviour 
{
	public int materialIndex = 0;
	public string textureName = "_MainTex";

	Vector2 uvRandom = Vector2.zero;

	void Start() 
	{
		uvRandom = new Vector2( Random.value, Random.value );

		if( GetComponent<Renderer>().enabled )
		{
			GetComponent<Renderer>().materials[ materialIndex ].SetTextureOffset( textureName, uvRandom );
		}
	}
}

But this only works for separate Emitters - could you provide a valid solution that changes material per Particle not per Emitters? This could be usefull if I’ll ever need color information from vertex.

Anyway - thank you very much :slight_smile:

Use the particle Color, it will come through to the shader as vert colour stream.

HAHA! The old unreal trick!

1 Like

In Unity 5.5, you will very soon be able to pass a custom vertex stream to the shader called “Random”. It’s a float4, where the XYZ contains random values (0-1 range) that remain constant for the lifetime of the particle they are assigned to, and W is a random number that changes as the particle ages, and could be used for a flickering effect.

It sounds like this would be perfect for applying random UV offsets to your particles.

Hopefully the random stream will be available in 5.5.0b9, or maybe b10…!

1 Like

Hey Richard - this is awesome, but poses the problem that we’ll have to take the full float4 - I’m currently using all of my vertex streams (lifespan, custom1, and custom2), and it would be a dream for me to set custom1.w or something to be a random value per particle (currently using a component to set this).

I have no clear concept of how a better, user-defined channel packing method for vertex streams should work, but they are a big limitation right now - even lifespan forces me to take a float2, when all I’m hoping to use is .x.

Also - it’s great to see you on here!

1 Like

Thanks, I’ve been reading a few posts for a while and thought I ought to sign up :wink:

The limitations on how to set up the vertex streams is indeed a problem. In the short term I hope we can expose all 8 texcoords, so users not developing for GLES2 can send in more data. But that doesn’t solve the wastage of sending data you don’t care about. The UI would be tricky, but my biggest question is how to fill the vertex data in from the CPU efficiently. A totally custom packing solution would be hard to prepare quickly when we build the vertex buffer.

But… it’s all progress :slight_smile:

1 Like

About your code from quickly looking at it, I see you are missing the actual particle system.

You need to:
ParticleSystem = getComponent…

Then manipulate each particle by calling:
p.getComponent…

Sorry I didn’t try a full script and send the answer. Im looking at it from my phone in bed (1:30am)

Cheers

that was going to be my suggestion at first, but then I realized that unfortuntely world position would not work because it would update at every farme causing your UVs to go nuts. You would have to buffer the position and use that instead (possible?).

one idea off the top of my head - if in code you have access to the particle ID you could possibly multiply a random value by that for each instance.

Sorry, trying to be helpful without having used Unity is several years. :slight_smile:

Until 5.5 release, i’m still using the old Particle color to control values in the shader. But have noticed recently that the rgb values dont produce nice smooth results, but rather harsh steps. RichardK has something changed with the way the particles colors are defined? have they changed precision?

We added a fixed step blend mode to the Gradient editor in 5.5, could that be enabled by mistake? It’s a drop down on the Gradient Editor, make sure it says Blend.

Nothing else has changed that should affect this, that I can think of.

If that doesn’t help, I’d recommend submitting a bug so we can figure it out.

I’m currently using 5.4, and don’t see that option, so i guess its not that?

Ok, not that then. If you can report a bug with a minimal repro project we will get to the bottom of it :slight_smile: