0
Declined

Get a specific UV Coordinate Entry?

Izzy Softy 9 years ago updated by Freya Holmér (Developer) 9 years ago 11
Image 444

Instead of using local parameters I was wondering if i could instead populate one of the UV channels on the Mesh and use it to pass in unique parameters. This way Unity doesn't need to create a new Material Instance and one less draw call as well.

What about doing the same for Normal Dir. or Tangent Dir.? ;)

P.S.
MaterialPropertyBlock's help a little in reducing draw calls but only when All the local Params are changed to the Same values. :/

P.P.S.
If it cant be done directly, what about caching the UV coord. entries to a var. internally?
ex: "_MeshHash_UV3_0" for VertexID/Entry 0. "_MeshHash_UV3_1" for array entry 1. etc...
So only the variables that the User puts in the Entry Text Field (in the UV Coord. node from Image above), need to be declared?!? I dont know if arrays can be used. ;)

Thanks, love SF! ;)

Answer

-1
Answer
Declined
You can't access specific UVs, you only have access to the barycentrically interpolated UV of the triangle currently being rendered, for the specific channel you're accessing, so I'm afraid this isn't possible.
Do shaders have Lists or Dictionaries? Anything that allows for a Key/Value?

Ohhh... how do shaders tell Meshes apart from one another? Can the Shader hijack one of the Meshes UV entries to assign a Unique ID?

Does UV Entry 0 get set to the Meshes Hashed ID from a script 1st?!? :)
Instead of calling it a Hashed ID, maybe its better to call it a Meshes InstanceID (kinda like a GameObjects InstanceID) and set that for entry 0 (presumably U, V might just stay reserved for later) for shader use? ;D
Under review
I'm not really sure what you're trying to do, that isn't already possible. You can already use multiple UV coordinate nodes with all the different UV sets, with custom data inside.
I was just hoping to use one of UV Coord. entries instead of the Material Properties.



I wanted to avoid Unity creating a new Material instance (extra draws) when brightness, desaturate, etc.. are changed on the sharedMaterial. This would mean many different meshes can all use just one shared material instance. one draw call.

Just a thought.Thanks. ;)
Don't change it in the material, put that information in the UV channels of the vertices in the mesh
I have used the UV channels of the verts of a mesh.
Only problem was... I couldn't get a specific element/array entry from the UV coords. :/
Well, without setting every single UV entry to the exact same values for U and for V that is. ;)

How would I get a specific UV coord. array entry #? :{

Then you simply use the U and V components of the UV coord node.
Sooo... its not easy to Repurpose a UV Channel that's not really being used for UV mapping, and instead populate it with Material Parameters?

Ex: Instead of doing this:
void Update()
{
  float shininess = Mathf.PingPong( Time.time, 1.0F );
  rend.material.SetFloat( "_Shininess", shininess );
}
Do this...
void Update()
{
  float shininess = Mathf.PingPong( Time.time, 1.0F );
  mesh.uv4[0].x = shininess;
}
And in the Node, access just that entry every frame?



To get a specific entry in UV4 from the mesh, enable the Entry checkbox and enter the array index 0 and read the U (x) value. And each frame it returns the shininess value (lets say it always returns .4), and its not interpolated (0 to 1, or whatever).

So, other entries in the UV4 can be used as well to pass in numeric parameters. I guess I could Append 2 UV entries to make a Vector4, if i wanted a color param, but that's not what we're discussing right now. ;D
-1
Answer
Declined
You can't access specific UVs, you only have access to the barycentrically interpolated UV of the triangle currently being rendered, for the specific channel you're accessing, so I'm afraid this isn't possible.
Ok...
I had to ask. ;D

Maybe one day there could be a way we can at least cache the UV value we need based on the Vertex ID. If it means not reading in the correct value on 1st pass, at least every other will be right. :[

Well, until it changes, but polling can check if the Mesh Instance ID is new, and reCache. I'm just doing allot of guessing here. :P

It would be awesome if someday we could do this. Game changing even. Trying to think outside the box a.t.m. ;)

You can still assign the same coordinate to all verts in a specific UV channel, eg:


mesh.uv1 = new Vector2[]{
new Vector2( shininess, somethingElse );
new Vector2( shininess, somethingElse );
new Vector2( shininess, somethingElse );
...
}