Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Idea for shader. Using Uv2

Discussion in 'Shaders' started by mckoupel, May 28, 2015.

  1. mckoupel

    mckoupel

    Joined:
    May 25, 2015
    Posts:
    11
    Hello, I've troubles with my surface shader. There are uv1 for each vertex, and uv2 which I'm calculating inside the shader, using special values wrote before in tangent (or color). Unfortunatly, if I pass this values in surface shader they are changing (interpolation?). Therefore I'm calculating uv2 in vert shader. Next, trying pass uv2 and uv1 (for mixing both) in surface shader, but uv2 empty or call error (depends of my method). I know that texcoord1 using for lightmaps, but can't disable it. Also lightmaps would be usefull, because I'm trying to painting generated terrain with different heights...Any ideas to do it?

    simplified code:

    Code (CSharp):
    1. Shader "Custom/Painter"
    2. {
    3.     Properties
    4.     {
    5.         _Atlas ("Atlas (RGB)", 2D) = "white" {}
    6.         _AtlasMask ("Atlas Mask (RGB)", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.  
    13.         CGPROGRAM
    14.         #pragma target 3.0
    15.         #pragma surface surf Lambert vertex:vert
    16.  
    17.         #include "UnityCG.cginc"
    18.  
    19.         sampler2D _Atlas;
    20.         sampler2D _AtlasMask;
    21.    
    22.         struct Input
    23.         {
    24.             float2 uv_Atlas;
    25.             float2 uv2_Atlas;
    26.  
    27.             float3 worldPos;
    28.  
    29.            //my values passing from c#
    30.             float4 tangent;
    31.             float4 color: COLOR;
    32.         };
    33.  
    34.         float2 getNewUV(float n)
    35.         {
    36.             //some operations
    37.         }
    38.      
    39.         void vert (inout appdata_full v, out Input o)
    40.         {
    41.             UNITY_INITIALIZE_OUTPUT(Input, o);
    42.  
    43.             //calculate new uv
    44.             float myValue= floor(v.color.x * 100);
    45.             float2 newUV = getNewUV(myValue);
    46.  
    47.             //save new uv
    48.             v.texcoord1.xy = newUV ;
    49.         }
    50.  
    51.         void surf (Input IN, inout SurfaceOutput o)
    52.         {        
    53.              // if write float myValue= floor(v.color.x * 100) there - myValue will be interpolated
    54.  
    55.             float3 color1 = tex2D(_Atlas, IN.uv_Atlas).rgb;
    56.             float3 color2 = tex2D(_Atlas, IN.uv2_Atlas).rgb;
    57.  
    58.            //need mix color1 and color2
    59.              
    60.             o.Albedo = color1 * color2; //not working (Error: Redefinition _Atlas_ST)
    61.  
    62.           //if rename in initialization uv2_Atlas to uv_AtlasMask - color2 empty
    63.  
    64.  
    65.         }
    66.         ENDCG
    67. }
    68. }
    69.  
    Maybe I need use second pass and assign uv1 in first, uv2 in second pass? But how can I mix it? I don't know how take current vertex albedo in surfase shader.
     
    Last edited: May 29, 2015
  2. Sessional

    Sessional

    Joined:
    Apr 21, 2013
    Posts:
    45
    I'm going to take a shot in the dark:

    v.texcoord1.xy = newUV ;

    I take it this line is where you think you are making uv2? You are saving the data back into the vertex structure, not into the out Input o structure that you have. That Input structure is the structure that gets passed to the surf function.

    Try doing something like o.uv2_Atlas = newUv; instead.
     
  3. mckoupel

    mckoupel

    Joined:
    May 25, 2015
    Posts:
    11
    o.uv2_Atlas = newUV don't have any effect. I even tried in vertex shader: o.uv_Atlas.xy = 0 and use color1 in surface for testing. But in surface shader result had no changing - I saw initial uv.(( It's main reason why I'm using texcoord1. For example if i don't use color1 in surface, then my texcoord1 vertex changing are working (o.Albedo = color2). But o.Albedo = color1 * color2 no... It's magic)))

    P.S. Maybe out Input o need some command for saving?
     
    Last edited: May 29, 2015
  4. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    I think you might be confused on how these shaders work.

    So, anything involved in a vertex will always be interpolated. You can't avoid that.

    That's because a pixel is calculated (in the fragment shader, which in this case, is basically the surf() portion) based on values of all the vertexes around it. You see, a vertex (the vert function) is not calculating for a triangle. It is calculating at each corner of the triangle. Then, the rest of the shader gets some value that lies in between, with some geometrical math.

    The vert never explicitly passes data to the rest of the shader, the vert creates data for the vertex, and then the surf() is used for each pixel with the data from the nearest verts, interpolated.

    You can't have a value calculated and passed to the surf without it being interpolated - because you are using points in the middle of a triangle. How does that point know 'which' one to choose from?

    I may be missing your intent, but the line in the comments as to what you are trying to do lead me on this line of thoughts. If I'm saying things you already know, I apologize.
     
  5. mckoupel

    mckoupel

    Joined:
    May 25, 2015
    Posts:
    11
    Thank you for reminding. I truly see all of your said in the results of shader work:



    On the first image showed how must look uv1 and uv2 (red) together. And uv2 quad on the second. There is a frame around the edges because of uv jump (it's exactly middle of triangles as you said). I hoped dispose of this by mixing uv's with diiferent opacity on the edges (maybe by mask). Anyway, I need to do experiments. But have no idea how to pass uv2 and uv1 to surf() at the same time...

    Actually, It's the shader for mixing hexes textures outside hexes.
    I have programmatically generated meshes which composed in landscape




    And I want to get result as a Honey Hex project:



    Someone says that I need to create texture with mixing hex and use projector. But I want really big maps (250 x 250 and more) and afraid that texture size would be too large. And mixing textures along seams also would be not much varied. So, trying to create my shader and assign different masks (little bigger then hexes) with personal priority for each hex.


    Probably it's not best decision, but how else I can get good-looking and varied result?
     
  6. mckoupel

    mckoupel

    Joined:
    May 25, 2015
    Posts:
    11
    Maybe I need use grabpass?