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

Combining textures / Vertex painting

Discussion in 'Shaders' started by Stankiem, Sep 14, 2015.

  1. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    We have need of an 8-color vertex painting shader. We've spent weeks trying to adapt some various shaders and this is what we've come up with, we are not good with shaders and looking for some help!

    The system works by basically using the first 4 bits of a base 255 color code for one texture and the last 4 bits for the other color. In the shader it comes through as a 0-1 RBGA number of course.

    The shader works fine for any of the color2 textures, but breaks down when trying to use color3 r g or b. All of our combining / splitting math i'm 100% sure is correct, because I swapped color 2 and color 3 in the code below and it failed with color3 still. so the rest of the shader is broken somehow. This part:

    Code (CSharp):
    1. half4 t0 = tex2D (_BaseTexture, IN.uv_BaseTexture);
    2.          
    3.             half4 t1 = tex2D (_Texture1, IN.uv_Texture1);
    4.             half4 t2 = tex2D (_Texture2, IN.uv_Texture2);
    5.             half4 t3 = tex2D (_Texture3, IN.uv_Texture3);
    6.             half4 t4 = tex2D (_Texture4, IN.uv_Texture4);
    7.             half4 t5 = tex2D (_Texture5, IN.uv_Texture5);
    8.             half4 t6 = tex2D (_Texture6, IN.uv_Texture6);
    9.             half4 t7 = tex2D (_Texture7, IN.uv_Texture7);
    10.             //half4 t8 = tex2D (_Texture8, IN.uv_Texture8);
    11.          
    12.             half4 cum = ((t1 * color3.r) + (t4 * color2.r) + (t2 * color3.g)  + (t5 * color2.g) + (t3 * color3.b)  + (t6 * color2.b)  + (t7 * color3.a) ) ;
    13.               //changed from fixed to half floating point variable.
    14.             half fac = color3.r + color2.r + color3.g + color2.g + color3.b + color3.a  + color2.b ;
    15.          
    16.             if(fac != 0)
    17.             {
    18.                 cum /= fac;
    19.              
    20.             }
    21.          
    22.             cum = lerp(t0,cum,fac);
    23.          
    24.             o.Albedo = cum.rgb;
    25.             o.Specular = cum.a;
    Can someone please have a look at this for a few moments and let me know what I'm doing wrong? Below is also a picture of what it looks like



    Code (CSharp):
    1. void surf (Input IN, inout SurfaceOutput o) {
    2.             float4 color = IN.color;
    3.             float4 color1 = color;
    4.             float4 color2;
    5.             float4 color3;
    6.             color3.r = (0.0627450980392157 * int( color1.r * 16));
    7.             color3.g = (0.0627450980392157 * int( color1.g * 16));
    8.             color3.b = (0.0627450980392157 * int( color1.b * 16));
    9.             color3.a = color1.a ;
    10.             color2.r = (0.0627450980392157 * ((color1.r * 255) - (int( color1.r * 16) * 16)  ));
    11.             color2.g = (0.0627450980392157 * ((color1.g * 255) - (int( color1.g * 16) * 16))  );
    12.             color2.b = (0.0627450980392157 * ((color1.b * 255) - (int( color1.b * 16) * 16) ) );
    13.             //color2.a = (0.0627450980392157 * ((color1.a * 255) - (int( color1.a * 16) * 16)  ));
    14.                  
    15.             half4 t0 = tex2D (_BaseTexture, IN.uv_BaseTexture);
    16.      
    17.             half4 t1 = tex2D (_Texture1, IN.uv_Texture1);
    18.             half4 t2 = tex2D (_Texture2, IN.uv_Texture2);
    19.             half4 t3 = tex2D (_Texture3, IN.uv_Texture3);
    20.             half4 t4 = tex2D (_Texture4, IN.uv_Texture4);
    21.             half4 t5 = tex2D (_Texture5, IN.uv_Texture5);
    22.             half4 t6 = tex2D (_Texture6, IN.uv_Texture6);
    23.             half4 t7 = tex2D (_Texture7, IN.uv_Texture7);
    24.             half4 t8 = tex2D (_Texture8, IN.uv_Texture8);
    25.      
    26.             half4 cum = ((t1 * color3.r) + (t4 * color2.r) + (t2 * color3.g)  + (t5 * color2.g) + (t3 * color3.b)  + (t6 * color2.b)  + (t7 * color3.a) ) ;
    27.             fixed fac = color3.r + color2.r + color3.g + color2.g + color3.b + color3.a  + color2.b ;
    28.      
    29.             if(fac != 0)
    30.             {
    31.                 cum /= fac;
    32.             }
    33.      
    34.             cum = lerp(t0,cum,fac);
    35.             o.Albedo = cum.rgb;
    36.             o.Specular = cum.a;
    37.      
    38.         }
     
    Last edited: Sep 15, 2015
  2. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    Would really really appreciate some help with this! =) I know so little about shaders and I'm thinking it's just something simple I'm missing I hope.
     
  3. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    I edited the original post with some more information. I am now 100% sure the math to split and combine is correct as I swapped color2.x = and color3.x = and it was still color3 having issues. So something below the color value assignments is the issue.

    Also, I swapped t1 for t4, t5 for t2 etc.. and the opposite colors still had issues. So it appears the issue is with t1 stuff, not color3 possibly?
    half4 cum = ((t1 color3.r) + (t4 color2.r) + (t2 color3.g) + (t5 color2.g) + (t3 color3.b) + (t6 color2.b) + (t7 * color3.a) ) ;
     
    Last edited: Sep 15, 2015
  4. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    It appears to be using the default texture defined in properties? But that doesn't appear to be the only issue based on my pics given. Really hoping someone can lend a hand with this. Will even pay someone for their time if that's what it takes.
     
  5. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    Anyone?? =(
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    I'm pretty sure you need to decode the colors in the vertex shader. The interpolated value you get in the fragment shader (which surf is part of) won't be properly encoded.

    Also @Stankiem you're only posting part of your shader. Some of the issues you're describing could be caused by errors in other parts of you shader. Post the entire shader if you still need help.
     
    Last edited: Sep 29, 2015
  7. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    Here is the entire shader. Any help would be amazing! Thanks

    Code (CSharp):
    1. Shader "Factions Terrain" {
    2.     Properties {
    3.         _BaseTexture ("Dirt", 2D) = "red" {}
    4.         _Texture1 ("Texture 1 (Unused)", 2D) = "red" {}
    5.         _Texture2 ("Texture 2 (Unused)", 2D) = "red" {}
    6.         _Texture3 ("Texture 3 (Unused)", 2D) = "red" {}
    7.         _Texture4 ("Texture 4", 2D) = "white" {}
    8.         _Texture5 ("Texture 5", 2D) = "white" {}
    9.         _Texture6 ("Sand", 2D) = "white" {}
    10.         _Texture7 ("Grass", 2D) = "blue" {}
    11.     }
    12.     SubShader {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.      
    16.         CGPROGRAM
    17.         #pragma surface surf Lambert nolightmap
    18.         #pragma enable_d3d11_debug_symbols
    19.         #pragma target 3.0
    20.  
    21.         sampler2D _BaseTexture;
    22.         sampler2D _Texture1;
    23.         sampler2D _Texture2;
    24.         sampler2D _Texture3;
    25.         sampler2D _Texture4;
    26.         sampler2D _Texture5;
    27.         sampler2D _Texture6;
    28.         sampler2D _Texture7;
    29.      
    30.         struct Input {
    31.             float2 uv_BaseTexture;
    32.             float2 uv_Texture1;
    33.             float2 uv_Texture2;
    34.             float2 uv_Texture3;
    35.             float2 uv_Texture4;
    36.             float2 uv_Texture5;
    37.             float2 uv_Texture6;
    38.             float2 uv_Texture7;
    39.             float4 color : COLOR;
    40.         };
    41.  
    42.         void surf (Input IN, inout SurfaceOutput o) {
    43.             float4 color = IN.color;
    44.             float4 color1 = color;
    45.             float4 color2;
    46.             float4 color3;
    47.             color3.r = (0.0627450980392157 * int( color1.r * 16));
    48.             color3.g = (0.0627450980392157 * int( color1.g * 16));
    49.             color3.b = (0.0627450980392157 * int( color1.b * 16));
    50.             color2.a = color1.a ;
    51.             color2.r = (0.0627450980392157 * ((color1.r * 255) - (int( color1.r * 16) * 16)  ));
    52.             color2.g = (0.0627450980392157 * ((color1.g * 255) - (int( color1.g * 16) * 16))  );
    53.             color2.b = (0.0627450980392157 * ((color1.b * 255) - (int( color1.b * 16) * 16) ) );
    54.                      
    55.             half4 t0 = tex2D (_BaseTexture, IN.uv_BaseTexture);
    56.             half4 t1 = tex2D (_Texture1, IN.uv_Texture1);
    57.             half4 t2 = tex2D (_Texture2, IN.uv_Texture2);
    58.             half4 t3 = tex2D (_Texture3, IN.uv_Texture3);
    59.             half4 t4 = tex2D (_Texture4, IN.uv_Texture4);
    60.             half4 t5 = tex2D (_Texture5, IN.uv_Texture5);
    61.             half4 t6 = tex2D (_Texture6, IN.uv_Texture6);
    62.             half4 t7 = tex2D (_Texture7, IN.uv_Texture7);
    63.          
    64.             half4 cum = ((t1 * color3.r) + (t4 * color2.r) + (t2 * color3.g)  + (t5 * color2.g) + (t3 * color3.b)  + (t6 * color2.b)  + (t7 * color2.a) ) ;
    65.             half fac = color3.r + color2.r + color3.g + color2.g + color3.b + color2.a  + color2.b ;
    66.          
    67.             if(fac != 0)
    68.             {
    69.                 cum /= fac;
    70.             }
    71.          
    72.             cum = lerp(t0,cum,fac);
    73.          
    74.             o.Albedo = cum.rgb;
    75.             o.Specular = cum.a;
    76.          
    77.         }
    78.         ENDCG
    79.     }
    80.     FallBack "Diffuse"
    81. }
    82.  
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Code (CSharp):
    1. Shader "Factions Terrain" {
    2.     Properties {
    3.         _BaseTexture ("Dirt", 2D) = "red" {}
    4.         _Texture1 ("Texture 1 (Unused)", 2D) = "red" {}
    5.         _Texture2 ("Texture 2 (Unused)", 2D) = "red" {}
    6.         _Texture3 ("Texture 3 (Unused)", 2D) = "red" {}
    7.         _Texture4 ("Texture 4", 2D) = "white" {}
    8.         _Texture5 ("Texture 5", 2D) = "white" {}
    9.         _Texture6 ("Sand", 2D) = "white" {}
    10.         _Texture7 ("Grass", 2D) = "blue" {}
    11.     }
    12.     SubShader {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.    
    16.         CGPROGRAM
    17.         #pragma surface surf Lambert vertex:vert nolightmap
    18.         #pragma enable_d3d11_debug_symbols
    19.         #pragma target 3.0
    20.         sampler2D _BaseTexture;
    21.         sampler2D _Texture1;
    22.         sampler2D _Texture2;
    23.         sampler2D _Texture3;
    24.         sampler2D _Texture4;
    25.         sampler2D _Texture5;
    26.         sampler2D _Texture6;
    27.         sampler2D _Texture7;
    28.    
    29.         struct Input {
    30.             float2 uv_BaseTexture;
    31.             float2 uv_Texture1;
    32.             float2 uv_Texture2;
    33.             float2 uv_Texture3;
    34.             float2 uv_Texture4;
    35.             float2 uv_Texture5;
    36.             float2 uv_Texture6;
    37.             float2 uv_Texture7;
    38.             fixed4 color1 : COLOR0;
    39.             fixed4 color2 : COLOR1;
    40.         };
    41.  
    42.         void vert (inout appdata_full v, out Input o)
    43.         {
    44.             UNITY_INITIALIZE_OUTPUT(Input,o);
    45.             o.color1 = fixed4(0.0627450980392157 * int4(v.color * 16));
    46.             o.color2 = fixed4(0.0627450980392157 * ((v.color * 255) - (int4(v.color * 16) * 16)));
    47.         }
    48.         void surf (Input IN, inout SurfaceOutput o) {                    
    49.             fixed4 t0 = tex2D (_BaseTexture, IN.uv_BaseTexture);
    50.             fixed4 t1 = tex2D (_Texture1, IN.uv_Texture1);
    51.             fixed4 t2 = tex2D (_Texture2, IN.uv_Texture2);
    52.             fixed4 t3 = tex2D (_Texture3, IN.uv_Texture3);
    53.             fixed4 t4 = tex2D (_Texture4, IN.uv_Texture4);
    54.             fixed4 t5 = tex2D (_Texture5, IN.uv_Texture5);
    55.             fixed4 t6 = tex2D (_Texture6, IN.uv_Texture6);
    56.             fixed4 t7 = tex2D (_Texture7, IN.uv_Texture7);
    57.        
    58.             fixed4 cum = (
    59.                         (t1 * IN.color1.r)
    60.                         + (t4 * IN.color2.r)
    61.                         + (t2 * IN.color1.g)
    62.                         + (t5 * IN.color2.g)
    63.                         + (t3 * IN.color1.b)
    64.                         + (t6 * IN.color2.b)
    65.                         + (t7 * IN.color2.a)
    66.                         );
    67.            
    68.             fixed fac = IN.color1.r + IN.color2.r + IN.color1.g + IN.color2.g + IN.color1.b + IN.color2.a + IN.color2.b;
    69.        
    70.             if(fac != 0)
    71.             {
    72.                 cum /= fac;
    73.             }
    74.        
    75.             cum = lerp(t0,cum,fac);
    76.        
    77.             o.Albedo = cum.rgb;
    78.             o.Specular = cum.a;
    79.        
    80.         }
    81.         ENDCG
    82.     }
    83.     FallBack "Diffuse"
    84. }
    85.  
    Try that. Haven't tested it apart from it doesn't throw any warnings.
     
  9. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    Unfortunately it only draws t0 and t7. All other textures don't show at all.
    I do see something odd though. t7 is supposed to use 8 bits of alpha instead of 4 like the rest of the textures. I see you changed the parsing (math) lines, but didn't do anything different with t7 as I did, but your t7 works which I find very strange.. I don't have the knowledge of what to make of it, but hoping that it might give you a clue to what's going on.

    Thanks a ton! Please PM me your paypal address after we get this sorted =)
     
  10. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Is there any particular reason you cannot use the additional UV channels for painting? I have a 12 texture vertex blend, triplanar mapped, but even without triplanar you could map 10 textures. Do all the UV channels actually come through? There's only 4 available on the meshes.

    You also might consider non-integer based conversions, and just use the encoding built into Unity's shader libraries.
     
  11. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    Plutoman, thank you for your response, however I do not know what UV channels are or what they are used for, nor how they would help me. I did about 10 minutes of searching on UV channels and really all I could find is lightmapping stuff, and it really made no sense to me. Also, what are you talking about when you refer to Unity's shader libraries? Like I said, I am a complete noob with shaders, just pieced this attempt together with bits of others and some reading.

    Basically this is what I'm trying to do:
    -We are using models as our terrain since it is a very dynamic world. It is an MMO, so as the player moves through the world, the server periodically sends updated texturing information to the client(s).
    -We must parse the texturing string into usable texturing info.
    -Grass grows, trees replace grass with forest floor stuff, players build farms and roads etc.. etc.. so this stuff is always changing, hence the need for it to be dynamic.

    I'm open to different ways of doing it, but this is the best solution we have found thus far.
     
  12. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    I'd need a bit more info first, but I think I have the gist of it. This is a long read, so I apologize! This is my warm-up before I settle into some math calculations I have to set up, I needed something to get my brain going.

    So to be clear - this is a modeled terrain, not a Unity terrain? Did you model it yourself, or use say, a voxel program? How experienced with code are you? Basically speaking - a vertex on a mesh (that's the individual point, the triangles are 3 vertexes where it draws between them) has data associated with it.

    One such piece of data is vertex colors. These are either 4 8-bit floats or 4 32-bit floats, depending on the precision used. For each vertex, there's also a normal stored. That's 3 floats. In addition to that, there's tangents. That's 4 floats, but it's auto-normalized with surface shaders, so I would not touch it.

    Additionally, there's the UV channels. These are 4 sets of 2 floats. You're actually using them for textures already - the two floats are basically a 2d mapping to texture coordinates, usually. However, you do not need to use them for that - they can be used for anything. You use them currently individually for each texture, but you can use the same texture coordinates for different textures - instead of having a different set for each. Example at the very bottom.

    http://docs.unity3d.com/ScriptReference/Mesh.html

    Check out this page, and you'll see all the parameters. They can be assigned through scripts, or set through a modeling program. I don't know exactly how you are painting textures, but painting UV's can be done exactly the same way - it's just accessing a different data set. Basically, instead of using vertex colors in a fancy way, you can avoid all the special forms of encoding and just use additional data on the mesh.

    Now, for the Unity libraries..
    https://unity3d.com/get-unity/download/archive

    There's the built in shaders. However, it's also stored inside your Unity installation in "Unity\Editor\Data\CGIncludes". Don't touch those, though, if you want to edit them, edit the built in ones, and just reference them instead.

    Here's a snippet from one my terrain shaders;
    Code (csharp):
    1.  
    2. Pass {
    3.             Name "DEFERRED"
    4.             Tags {
    5.                 "LightMode"="Deferred"
    6.             }
    7.  
    8.             CGPROGRAM
    9.             #pragma hull hull
    10.             #pragma domain domain
    11.             #pragma vertex tessvert
    12.             #pragma fragment frag
    13.             #define UNITY_PASS_DEFERRED
    14.             #pragma multi_compile __ TEX0
    15.             #pragma multi_compile __ TEX1
    16.             #pragma multi_compile __ TEX2
    17.             #pragma multi_compile __ TEX3
    18.             #pragma multi_compile __ TEX4
    19.             #pragma multi_compile __ TEX5
    20.             #pragma multi_compile __ TEX6
    21.             #pragma multi_compile __ TEX7
    22.             #pragma multi_compile __ TEX8
    23.             #pragma multi_compile __ TEX9
    24.             #pragma multi_compile __ TEX10
    25.             #pragma multi_compile __ TEX11
    26.             #include "UnityCG.cginc"
    27.             #include "Tessellation.cginc"
    28.             #include "UnityPBSLighting.cginc"
    29.             #include "UnityStandardBRDF.cginc"
    30.             #pragma fragmentoption ARB_precision_hint_fastest
    31.             #pragma multi_compile_shadowcaster
    32.             #pragma exclude_renderers xbox360 ps3
    33.             #pragma target 5.0
    34.          
    35.             #include "DeferredMain.cginc"
    36.             ENDCG
    37.         }
    The key part her is how the #include works. You can see how they go there. Basically, when you #include a cginc file, it inserts the code from that file into that spot. So for the UnityCG.cginc, what it's inserting into the compiled shader is a bunch of constants, settings, and a bunch of functions. It doesn't have any of the code that is 'ran', but it is similar to including a file in C where it will include the functions from that file. If you go through the UnityCG.cginc file, you'll see functions for "EncodeFloatRG", "EncodeFloatRGBA", etc, along with decodes.

    The bulk of my code for the main pass, then, actually lies in the DeferredMain.cginc.

    I won't put all of it here, as I have some nested includes, too... but in my vertex input, I do this;

    Code (csharp):
    1.  
    2. struct VertexInput {
    3.     float4 vertex : POSITION;
    4.     float3 normal : NORMAL;
    5.     float2 texcoord0 : TEXCOORD0;
    6.     float2 texcoord1 : TEXCOORD1;
    7.     float2 texcoord2 : TEXCOORD2;
    8.     float2 texcoord3 : TEXCOORD3;
    9.     float4 vertexColor : COLOR;
    10. };
    When you use a surface shader, the appdata_full will automatically include the UV channels for the other sets of texture coordinates. And like I mentioned, they don't have to be texture coordinates - the shader interprets them however it would like.

    Here's where I get the diffuse color;

    Code (csharp):
    1.  
    2. Texture2D<float4> _Diffuse0; uniform float4 _Diffuse0_ST; SamplerState sampler_Diffuse0;
    3. Texture2D<float4> _Diffuse1; uniform float4 _Diffuse1_ST;
    4. Texture2D<float4> _Diffuse2; uniform float4 _Diffuse2_ST;
    5. Texture2D<float4> _Diffuse3; uniform float4 _Diffuse3_ST;
    6. Texture2D<float4> _Diffuse4; uniform float4 _Diffuse4_ST;
    7. Texture2D<float4> _Diffuse5; uniform float4 _Diffuse5_ST;
    8. Texture2D<float4> _Diffuse6; uniform float4 _Diffuse6_ST;
    9. Texture2D<float4> _Diffuse7; uniform float4 _Diffuse7_ST;
    10. Texture2D<float4> _Diffuse8; uniform float4 _Diffuse8_ST;
    11. Texture2D<float4> _Diffuse9; uniform float4 _Diffuse9_ST;
    12. Texture2D<float4> _Diffuse10; uniform float4 _Diffuse10_ST;
    13. Texture2D<float4> _Diffuse11; uniform float4 _Diffuse11_ST;
    14.  
    15. float3 GetTextureDiffuse( float2 UV, float4 vertexColor, float4 uv0 , float4 uv1 )
    16. {
    17.     float4 tex = float4(0,0,0,0);
    18.     #ifdef TEX0
    19.     if (vertexColor.r > .01)
    20.     {
    21.         tex += _Diffuse0.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse0)) * vertexColor.r;
    22.     }
    23.     #endif
    24.     #ifdef TEX1
    25.     if (vertexColor.g > .01)
    26.     {
    27.         tex += _Diffuse1.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse1)) * vertexColor.g;
    28.     }
    29.     #endif
    30.     #ifdef TEX2
    31.     if (vertexColor.b > .01)
    32.     {
    33.         tex += _Diffuse2.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse2)) * vertexColor.b;
    34.     }
    35.     #endif
    36.     #ifdef TEX3
    37.     if (vertexColor.a > .01)
    38.     {
    39.         tex += _Diffuse3.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse3)) * vertexColor.a;
    40.     }
    41.     #endif
    42.  
    43.     #ifdef TEX4    
    44.     if (uv0.r > .01)
    45.     {
    46.         tex += _Diffuse4.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse4)) * uv0.r;
    47.     }
    48.     #endif
    49.     #ifdef TEX5
    50.     if (uv0.g > .01)
    51.     {
    52.         tex += _Diffuse5.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse5)) * uv0.g;
    53.     }
    54.     #endif
    55.     #ifdef TEX6
    56.     if (uv0.b > .01)
    57.     {
    58.         tex += _Diffuse6.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse6)) * uv0.b;
    59.     }
    60.     #endif
    61.     #ifdef TEX7
    62.     if (uv0.a > .01)
    63.     {
    64.         tex += _Diffuse7.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse7)) * uv0.a;
    65.     }
    66.     #endif
    67.  
    68.     #ifdef TEX8    
    69.     if (uv1.r > .01)
    70.     {
    71.         tex += _Diffuse8.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse8)) * uv1.r;
    72.     }
    73.     #endif
    74.     #ifdef TEX9
    75.     if (uv1.g > .01)
    76.     {
    77.         tex += _Diffuse9.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse9)) * uv1.g;
    78.     }
    79.     #endif
    80.     #ifdef TEX10
    81.     if (uv1.b > .01)
    82.     {
    83.         tex += _Diffuse10.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse10)) * uv1.b;
    84.     }
    85.     #endif
    86.     #ifdef TEX11
    87.     if (uv1.a > .01)
    88.     {
    89.         tex += _Diffuse11.Sample(sampler_Diffuse0, TRANSFORM_TEX(UV, _Diffuse11)) * uv1.a;
    90.     }
    91.     #endif
    92.     return tex.rgb;
    93. }
    Now, not all of that would make sense at first. I combine the UV0, 1, 2, and 3 into two float4's when I pass the data from the vertex to the fragment (in a surface shader, that's a vertex to a surface). So it's the same info though. I also use multi_compile to optimize the textures, so it only ever uses a shader variant that loads as many textures as it has. That is controlled by scripts, though, separately, the shader cannot do anything to control that on it's own easily.

    The other is that I'm using direct HLSL, and you can replace all the ".Sample....." with tex2D just fine. It's a different syntax which is windows only.

    Anyways, to close up; read through this stuff here;
    http://docs.unity3d.com/Manual/ShadersOverview.html
    http://docs.unity3d.com/Manual/SL-Reference.html

    That should give you a good overview. I've dumped a lot of info on you, but I hope it helps. The main thing is that you can take the UV channels on the meshes and assign them to mean something.

    Quick (won't compile, though) example!

    Code (csharp):
    1.  
    2. Shader "Example/Custom Vertex Data"
    3. {
    4.     Properties
    5.     {
    6.      _MainTex ("Texture", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Tags { "RenderType" = "Opaque" }
    12.      
    13.         CGPROGRAM
    14.         #pragma surface surf Lambert vertex:vert
    15.      
    16.         struct Input {
    17.             float2 uv_MainTex;
    18.             float4 color1;
    19.             float4 color2;
    20.             float4 color3;
    21.         };
    22.      
    23.         void vert (inout appdata_full v, out Input o)
    24.         {
    25.             UNITY_INITIALIZE_OUTPUT(Input,o);
    26.             o.color1 = float4(v.texcoord0, v.texcoord1);
    27.             o.color2 = float4(v.texcoord2, v.texcoord3);
    28.             o.color3 = v.color;
    29.         }
    30.      
    31.         sampler2D _MainTex;
    32.      
    33.         void surf (Input IN, inout SurfaceOutput o)
    34.         {
    35.             float4 tex = float4(0,0,0,0);
    36.             tex += tex2D (_MainTex, IN.uv_MainTex) * IN.color1.x;
    37.             tex += tex2D (_SecondTex, IN.uv_MainTex) * IN.color1.y;
    38.             // blah blah
    39.         }
    40.         ENDCG
    41.     }
    42.     Fallback "Diffuse"
    43. }
     
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    @Plutoman Any reason you don't use the full float4 UVs? If you're just encoding data there's no reason to not use TEXCOORD3 and TEXCOORD4 as their full float4. It's also totally unnecessary to use a vert function for it.

    Code (CSharp):
    1.         struct Input {
    2.             float2 uv_MainTex;
    3.             float4 color1 : TEXCOORD3;
    4.             float4 color2 : TEXCOORD4;
    5.             float4 color3 : COLOR0;
    6.         };
    Would suffice ... though setting the vertex color to color3 I disagree with ...

    @Stankiem This doesn't necessarily help you directly. I guess it's more a question of how you're painting the values to begin with.
     
    Plutoman likes this.
  14. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    @bgolus
    I actually did not know they could be used as a float4. You learn something new every day!

    And sure, that's just how it ended up getting typed out.. was just a quick toss into notepad++ from one of the surface shader examples.

    Just threw a lot of info out there since he did not seem to be aware of these concepts. And I don't write any surface shaders, really, everything I do is vert/frag, so I am used to having a vert function. Just habit, I guess.
     
  15. Stankiem

    Stankiem

    Joined:
    Dec 4, 2013
    Posts:
    115
    I won't quote your thread to save space, I'll just type answers as I read your questions here.

    -It was created in worldbuilder. I am intermediate coder, and I know the basics of the 3d modelling so yes your bit on vertex info I knew. Everything below is pretty much new to me.
    -We are painting the vert colors (RGBA) manually via code at runtime.

    Thanks so much for the amazing writeup! We will be sorting through all the data and trying to write this up over the next couple weeks. Will be sure to report our results back here!
     
  16. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    @Stankiem - So you're getting 7 float values and were packing them into the vert colors. Yeah, going forward pack them into the UVs. You'll need to use Mesh.SetUV (2 and 3) and not Mesh.uv3 / Mesh.uv4 as the later expect a Vector2 where as SetUV can take a Vector2, Vector3, or Vector4.
     
  17. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    That's quite useful to know. I will definitely keep that in mind, as I had spent some time trying to encode for more data for myself.. Glad to know! That must be fairly recent, then, too, because SetUV did not exist until.. 5.2 I believe? Think I remember seeing that in the patch notes.

    So basically in terms of mesh data, you get access to 16 32-bit floats worth of data, automatically, assuming you need the tangents, normals, and diffuse. 14 if you need texture coordinates, but if you use a triplanar mapping, you get access to 20 floats. Quite a bit of data, actually.

    Look forward to see how it goes, and I hope it goes well!