Terrain Shader Problems

hello,

i currently have this shader as my terrain shader, it has 4 textures however i want it to have 9 to make up the material. how would i go about doing this?.

here is the shader:

Shader "Custom/4-Part Texture" {
    Properties {
        _MainTex0 ("Base (RGB)", 2D) = "white" {}
        //Added three more textures slots, one for each image
        _MainTex1 ("Base (RGB)", 2D) = "white" {}
        _MainTex2 ("Base (RGB)", 2D) = "white" {}
        _MainTex3 ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex0;
        //Added three more 2D samplers, one for each additional texture
        sampler2D _MainTex1;
        sampler2D _MainTex2;
        sampler2D _MainTex3;

        struct Input {
            float2 uv_MainTex0;
        };

        //this variable stores the current texture coordinates multiplied by 2
        float2 dbl_uv_MainTex0;

        void surf (Input IN, inout SurfaceOutput o) {

            //multiply the current vertex texture coordinate by two
            dbl_uv_MainTex0 = IN.uv_MainTex0*2;

            //add an offset to the texture coordinates for each of the input textures
            half4 c0 = tex2D (_MainTex0, dbl_uv_MainTex0 - float2(0.0, 1.0));
            half4 c1 = tex2D (_MainTex1, dbl_uv_MainTex0 - float2(1.0, 1.0));
            half4 c2 = tex2D (_MainTex2, dbl_uv_MainTex0);
            half4 c3 = tex2D (_MainTex3, dbl_uv_MainTex0 - float2(1.0, 0.0));

            //this if statement assures that the input textures won't overlap
            if(IN.uv_MainTex0.x >= 0.5)
            {
                if(IN.uv_MainTex0.y <= 0.5)
                {
                    c0.rgb = c1.rgb = c2.rgb = 0;
                }
                else
                {
                    c0.rgb = c2.rgb = c3.rgb = 0;
                }
            }
            else
            {
                if(IN.uv_MainTex0.y <= 0.5)
                {
                    c0.rgb = c1.rgb = c3.rgb = 0;
                }
                else
                {
                    c1.rgb = c2.rgb = c3.rgb = 0;
                }
            }

            //sum the colors and the alpha, passing them to the Output Surface 'o'
            o.Albedo = c0.rgb + c1.rgb + c2.rgb + c3.rgb;
            o.Alpha = c0.a + c1.a + c2.a + c3.a ;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

You need to specify an “AddPassShader” dependency to use with each subsequent batch of 4 textures. Custom Unity Terrain Material / Shaders | Alastair Aitchison

that isn’t the problem, the 4 textures create 1 large texture through the material. and what i want is the material to support 9 textures so it can cover my terrain

here is what the shader does:

it takes the split terrain image and combines it using the shader, what i want it to do is use 9 textures, but still have the same outcome

so instead of fitting 4 textures it fits this format:

BUMP!

Boy, I don’t like the way this shader is written. But I don’t have a better one handy for you.

It also won’t let me easily copy your code, so I’ll just refer to line numbers. Lines 40 thru 62 are the heart of the code. It taking uv_MainTex0 (not to be confused with _MainTex0, I’m wondering if someone hasn’t hacked on this code a bit already) as an input. uv_MainTex0 is a float2 or x,y value pair.

I’m guessing this is a pixel shader here and not a vertex shader. I’m used to working in HLSL and have worked very little with Unity’s shaders (I think Unity uses Cg if I recall correctly but its noticeably different). So I’m guessing that uv_MainTex0 is a value fed in for every single pixel separately allowing you to control the color of each pixel.

It looks to me like both the X and Y values in it are doubled on line 32. I’m not sure what that’s about. I would need to see the input being fed in to know what the original values are but they appear to be a percentage between 0.0 and 1.0. Presumably then it would double as high as 2.0. (That’s a pretty big presumption. I’m not sure its true. But I can’t tell without seeing the code that calls it.)

Lines 35 thru 38 offset uv_MainTex0 by various amounts that are either 0 or 1. After doubling, that would give values of either 2.0, 1.0, or 0.0 for a full value of 1 that was doubled and then had either 1 or 0 subtracted from it. It appears to be offsetting the UV coorindates/mapping by displacing it between 1 and 2 units in both directions. I don’t “get” what this is trying to achieve. It looks almost as if this was intended to use 1 texture and someone hacked on it without understanding what its doing. Either that, or I just don’t get it. I wonder if this displacement is even called for.

Its using uv_MainTex0 as UV coordinates on those lines and pulling color from the four textures to be stored in the c0 thru c3 values. I guess a half4 is 4 floating point numbers of half precision. Basically, its rgba, red, green, blue, alpha values for color that’s being pulled from each of the 4 textures, but why offset the position within the texture image and why double that in the first place. It would seem to me that you would want to assign which texture is being used based on input rather than on position. I would have used a control texture to control which of the other 3 textures to use (or more than 3 if you like).

I don’t know. But what I do know is that lines 40 through 62 control which texture gets used. The doubled value is only used for the positional offset. So, the X and Y values of uv_MainTex0 are probably still a percentage between 0.0 and 1.0 at this point. Four on or off values gives you 4 combinations for 4 textures.

If X >= 50% and Y <= 50% then set all of the colors of every texture except c3 to black (remember we’re only drawing one pixel here as it will be called again for the next pixel).

If X>=50% and Y >50% then set all colors of every texture to black except c1.

If X < 50% and Y <=50% then set all colors of every texture to black except c2.

And the final option is to set all textures to black except c0.

Then when it adds together all of their colors it will only have the color of the one texture not set to black. It adds all the alpha (transparency) values too, but that looks like it does nothing to me. The alphas haven’t been changed in code and are probably all set to completely opaque. Adding them together would burn out the color (color is alpha in this case) and set it to 100% because you can’t go past 100%. So it changes the transparency from what it was to what it already was? Seems like a worthless line of code that’s merely slowing down your shader but I could be wrong without testing it. Its more evidence that someone’s been hacking.

So, I think if you were to duplicate another set of lines of code everywhere there’s a _MainTexn to values between 4 and 7 you would have 8 textures as inputs. Then if you modify that if then logic to be 25% instead of 50% you could use input values of either 0.0, 0.25, 0.5, 0.75, or 1.0 for both X and Y. Wait… that’s 16 unique combinations, right? Well, you could either not use half of those combinations or make 16 textures. At some point Cg is not going to like how many textures you’re sending it. I’m not sure what that point is. In fact, it’s probably not a limit of Cg but probably a limit of the graphics card itself and the Shader Model. But I don’t know if you could getaway with 16 textures or not.

I suppose that if you have control of the input you could use values of 33% for 0.0, 0.3, 0.6, and 0.9 (which is basically 100% even though it represents 0.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999… you get the point.

Anyway, that should yield 9 combinations of X and Y values. You could use the same technique of setting color to zero for all textures except that one texture and then adding their colors together. Since they’ll all be black except the one selected the sum of the colors is whatever color is in the selected texture.

Personally, if I had of written this shader, I would have used a percentage of each color instead of only the selected color. But apparently this works.

I don’t know about the offset in lines 34 thru 38. I question whether offsetting is even necessary. You need one line for every texture to grab the color of that texture’s pixel. But why offset it and if you’re going to modify this, what should your values be for the new textures? Who knows without knowing why this is even in the code.

I would try making all 9 the same as c2 on line 37. If that doesn’t work then you’ll have to figure out why the offset is there. The more I look at this code the more I think someone probably wrote some code that made some sense a long time ago and then people hacked on it and passed it along to one another until we have this. I wonder if its not time for a complete re-write.

Here is the shader in pastebin: http://pastebin.com/SiU7esRC

if you had time could you add me on skype so you can help me with this? :slight_smile:
my skype name is thommoboy1