- Home /
Is it possible to access the dimensions of a texture in a shader?
I'm trying to make a screen space shader that renders a texture which keeps always its natural size, regardless of the screen resolution or aspect ratio. That would mean the bigger the resolution the more times the texture would repeat. I would also like it to work for whatever texture, maybe even one provided by the user, so hard coding the actual picture dimensions wouldn't work, although that's what I'm doing right now.
Is there any way to access them? The code so far is like this:
float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
screenUV *= float2(_ScreenParams.x/[[Texture.Width]],_ScreenParams.y/[[Texture.Height]]);
Answer by Owen-Reynolds · Apr 01, 2014 at 04:45 PM
No, the shader doesn't know or care about the actual pixel size of a texture.
But, Unity code can look up the texture size, and that's all you need. I'm assuming you have a plane covering the background, holding the texture. You can do you're second line in Unity code, one time, to change the background material's tiling:
Texture2D T1;
Transform backPlane;
...
float xTile = Screen.width / T1.width, yTile = Screen.height / T1.height;
Vector2 backTiling = new Vector2( xTile, yTile );
backPlane.renderer.material.mainTextureOffset = backTiling;
For a test, type into a material's tiling yourself, with some precomputed numbers.
Thanks a lot. I think changing the offset and tiling wouldn't work in my case, but your answer set me on the right path.
I added a new property to the shader:
_TexSize ("Texture Size", Float) = 512
Which I can dynamically set through an external script:
renderer.material.SetFloat("_TexSize", T1.width);
Again, thanks.
Answer by AllanSamurai · Dec 11, 2015 at 12:36 PM
yes(tested)
http://docs.unity3d.com/Manual/SL-PropertiesInPrograms.html
look at Special Texture properties:
Texture size
{TextureName}_TexelSize - a float4 property contains texture size information:
x contains 1.0/width
y contains 1.0/height
z contains width
w contains height
so
For example, if a shader contains texture named _MainTex, the size information will be in a _MainTex_TexelSize vector.
_MainTex_TexelSize.z //contains width
_MainTex_TexelSize.w //contains height
The green thing doesn't mean best answer -- it's just the one the original question asker Accepted. It's understood that people will upvote whichever one they like and looking at the green one is just for fun (here, you can see it relates to specific details of the Q.)
Answers should be sorted by votes, but what can you do.
Alas this doesn't seem to be offered for 3D textures.
Can you give a better example of how this works?
Using any members of "$$anonymous$$ainTex_TexelSize" in the surface shader throws errors. Do you need to add the $$anonymous$$ainTex as a texture sampler first? I'm using the Sprites/Diffuse shader, with "[PerRendererData] _$$anonymous$$ainTex("Sprite Texture", 2D) = "white" {}".
you'll need declared this part "float4 _MainTex_TexelSize;" before use inside surf function:
//declaration
float4 _MainTex_TexelSize;
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
o.Albedo = c.rgb * c.a;
// now we can use it. Its just example to test if works
o.Alpha = c.a * _MainTex_TexelSize.x;
}
This is what I was looking for, but just after decalring the variable all other components in the shader graph are throwing errors (lol)
Your answer
Follow this Question
Related Questions
Transparency and texture atlases, shader calls affecting performance? 2 Answers
Changing Eye Colour (Colour only non-white parts of a texture?) 2 Answers
Change particle tint color via script 1 Answer
Object space normal map warning the texture is not a normal map 1 Answer
My mesh didn’t appear in Unity 0 Answers