Texture Size Node broken?

Hello.
Can someone clarify, how does the Texture Size Node currently work? For sure it does not work as described in documentation.
For me it seems, that it just returns 1 for all outputs no matter what I do.
I’ve encountered this in Unity 2023.2 (URP 16.0.4) and tested it in latest Unity 6 (URP 17.0.3) versions.

Here are some examples where I would like to offset the texture by some amount of pixels indicated by OffsetValue variable.

For me the only way to achieve correct results is by manually calculating the correct texel/pixel size in UV units (by dividing by 128 which is the size of my texture in pixels)

But then I tried to connect directly to texture size and this it works exactly the same as above

And finally it’s essentially the same as this:

So is this node currently broken or am I doing something wrong?

1 Like

If your texture is 128x128, the Width and Height output ports of the Texture Size node should both give you a value of 128. And Texel Width and Texel Height should give you the reciprocal of 128 (0.0078125). It is possible that something is broken, but this node has worked ok for me

Just to verify - do you have a texture in the exposed _MainTex material slot? In order for the node to work correctly as you currently have it set up, you would need to make a new material that references this shader and then apply your 128x128 texture to the exposed _MainTex slot in that material.

And (just as a test) does it work as you expect if instead of connecting the exposed _MainTex parameter to the Texture Size node, if you select the texture asset directly on the Texture Size node iteself?

Thank you for the reply!
It seems that I indeed did not have a texture applied to the _MainTex material/shader slot in the inspector. Despite having the texture asset assigned to object’s sprite renderer (this is a 2D project and I use sprites).
After assigning the texture asset to material slot as well, now it works. Thank you!

I thought it would pull the texture automatically from Sprite Renderer because of “_MainTex” reference. I guess, it doesn’t.
What if I use the same material for a different sprite with different texture sizes? Wouldn’t there be any issues if sprite renderer has one texture asset assigned, but its material - some other?

You can use the same shader, but you’d need to create a separate material (both materials would reference the same shader) in order to assign a different texture to it. So the data flow is like this:

Texture->Material->Shader

What texture is used is controlled by the setting on the material. So it’s not possible to use the same material with the different texture.

Ok, thank you for the insights!

Is this the preferred workflow? To simply use different materials for different objects? I recall reading somewhere, that this is computationally expensive and should be avoided if possible.
If I have multiple 2D characters each with their own texture (sprite atlas), then I should simply use a separate material for each?

I did some more testing and it partly works with the same material as well as long as the texture size is the same.
It appears, that Sample Texture 2D Node does take the texture pixel color data from Sprite Renderer (via _MainTex reference, I assume), it ignores the texture assigned to material in the inspector. But the Texture Size node does not take the data from Sprite Renderer and uses the size from the texture assigned to material in the inspector.
So if texture sizes are the same, sprite renderer image can be changed and the shader will use that.

So my final question is - is it possible to make the Texture Size Node get the size from Sprite Renderer (instead of texture in material slot) just like the Sample Texture 2D node is able to get the pixel color data from the Sprite Renderer?

2 Likes

Unfortunately I’m not very familiar with the Sprite Renderer. I wasn’t aware that the Texture Size node and the Sample Texture 2D node behave differently as you’re describing. That’s odd. You’re welcome to report on bug on it. In the mean time is sounds like you have a decent work-around.

I am having the same issue with per sprite render textures size returning 1. What is interesting is if I edit the shader sometimes it will work properly, until I reload the scene. When I first created my shader it worked completely fine, but when I opened my project the next day it was broken

This is a flaw that is really frustrating.

I have a shader ready that makes a one-pixel outline around the sprites. And instead of hanging one material on all the SpriteRenderer-s, I’ll have to create a material for each manually.

I guess I could write a component that would create this material when the scene starts, but damn, there are a lot of game-objects, and I’m afraid it might affect performance.

P.S.
Alright, that’s interesting… sort of.

I was about to report a bug and started a new empty project. I’ve moved my shader and some test-sprites to a new project, created a material, and… everything worked as it should have.

Then I started digging further and discovered that the default project does not have a Render Pipeline Asset in the graphics settings. My main project had a URP asset set.

The fun thing is that the built-in renderer replaces the “_MainTex” field in the editor with the texture from the SpriteRenderer immediately, without conflicts with other game-objects that use the same material.

So, if this is not critical for you, then one of the solutions is to reset the render in the settings: Edit → Project Settings… → Graphics → Default Render Pipeline (set this field to None).

P.P.S.
Be prepared to fix all your materials and shaders in the project. I also had to recheck all the scenes.