0

I am trying to implement shader for a LineRenderer (Unity component). And i need to get value from 0 to 1 for x axis in frag shader, that means position in local texture coordinates (0 for pixel on the left side of texture and 1 for right side border).

As documentation says _MainTex_TexelSize contains information about texture size and _MainTex_ST contains information about tiling. So it seems simple. I need multiply uv.x and (_MainTex_TexelSize.z * _MainTex_ST.x).

There is my shader:

Shader "LineRendering/Test"
{
    Properties
    {
        [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags
        {
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
            "PreviewType" = "Plane"
            "CanUseSpriteAtlas" = "True"
        }

        LOD 200

        Cull Off
        Lighting Off
        ZWrite Off
        Fog { Mode Off }
        Blend One OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM

            #pragma target 3.0          
            #pragma vertex vert
            #pragma fragment frag
            #pragma enable_d3d11_debug_symbols

            #include "UnityCG.cginc"
            #include "noiseSimplex.cginc"

            struct appdata_t
            {
                fixed4 vertex : POSITION;
                fixed2 uv : TEXCOORD0;
            };

            struct v2f
            {
                fixed4 vertex : SV_POSITION;
                fixed2 uv : TEXCOORD0;
                fixed2 srcPos : TEXCOORD1;
                fixed2 texelSize : TEXCOORD2;
                fixed2 tilingCapacity : TEXCOORD3;
            };

            uniform fixed4 _MainTex_TexelSize, _MainTex_ST;

            v2f vert(appdata_t IN)
            {
                v2f OUT;

                OUT.vertex = UnityObjectToClipPos(IN.vertex);
                OUT.uv = IN.uv;
                //OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
                //OUT.uv = fixed2(IN.uv.x * (_MainTex_ST.x + _MainTex_ST.z), (IN.uv.y +  * _MainTex_ST.y));
                //OUT.uv = (IN.uv * _MainTex_ST.xy + _MainTex_ST.zw);               

                OUT.texelSize = fixed2(_MainTex_TexelSize.z, _MainTex_TexelSize.w);
                OUT.tilingCapacity = fixed2(_MainTex_ST.x, _MainTex_ST.y);

                return OUT;
            }

            fixed4 frag(v2f IN) : COLOR
            {
                fixed4 output;
                output.a = 1;

                fixed relativeWidth = IN.uv.x / (IN.texelSize.x * IN.tilingCapacity.x);             

                //fixed relativeWidth = IN.uv.x / (_MainTex_TexelSize.z * _MainTex_ST.x);                   

                output.rgb = fixed3(relativeWidth, relativeWidth, relativeWidth);

                return output;
            }

            ENDCG
        }
    }
}

But this shader don't work as I expect.

How it's looks like

I am trying to debug this shader in runtime but getting weird results. Texel size and tiling capacity variable have 1 as value.

Shader debug.

So I need your help. What am I doing wrong? Is there some other way to get texture size for LineRenderer in Unity?

Programmer
  • 121,791
  • 22
  • 236
  • 328
Sergiy Klimkov
  • 530
  • 7
  • 15
  • In this case, you would want to have texturemode = stretch instead of tile. https://docs.unity3d.com/ScriptReference/LineTextureMode.Stretch.html – Leo Bartkus Oct 19 '18 at 12:33
  • Shader posted above, and this shader: https://stackoverflow.com/questions/52852185/how-can-i-convert-uv-coordinates-to-world-space is a part of one biggest shader. So stretch mode is not the solution, cause this is break noise mapping. – Sergiy Klimkov Oct 19 '18 at 12:39
  • Also, if you get stuck because you need both stretch and tile, you can use the color channel to carry data into the shader by applying a color gradient and then using it for uv coordinates. – Leo Bartkus Oct 19 '18 at 12:40
  • If you really want 0 to 1 along the X axis, (not the length of the line) you will need to pass in the world space bounds of the line into the shader and then use subtraction and division to map world coordinates to the 0..1 range. – Leo Bartkus Oct 19 '18 at 12:43
  • Baking is undesirable, I can use assign distance from point0 and poin1 throw materialPropertyBlock instead. But it is undesirable too. I Didn't fully understand what you mean when you say "to pass in the world space bounds of the line into the shader". Can you explane? I think i need just information about tiling. But {TextureName}_ST does not returning tiling info correctly. – Sergiy Klimkov Oct 19 '18 at 13:17

0 Answers0