Hi, i've maneged to get a 3 texture shader to work by fethcing the vertex colors from a model and that works. Now i want to add more textures to it like 6 , but you can only assign RGB to vertex colors so those are 3 textures max , now i wast hinking on using an external RGBA texture which will define the channels and textures for 3 more textures on the terrain but my problem is how to color that image i tried using a white background or black background or transparent but nothing works correctly. This is the shader : Code (CSharp): Shader "Exile/Terrain/6lyr_terrain" { Properties { _Color ("Color", Color) = (0,0,0,1) _Layer1 ("Layer1 tex", 2D) = "white" {} _Layer2 ("Layer2 tex", 2D) = "white" {} _Layer3 ("Layer3 tex", 2D) = "white" {} _Layer4 ("Layer4 tex", 2D) = "white" {} _Layer5 ("Layer5 tex", 2D) = "white" {} _Layer6 ("Layer6 tex", 2D) = "white" {} _AddColorMap ("Layer 3 to 6 colormap", 2D) = "white" {} } SubShader { Pass { Cull Back Fog { Mode Off } CGPROGRAM // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members normal) #pragma exclude_renderers d3d11 xbox360 #include "UnityCG.cginc" #pragma vertex vert #pragma fragment frag sampler2D _Layer1; sampler2D _Layer2; sampler2D _Layer3; sampler2D _Layer4; sampler2D _AddColorMap; float4 _Color; float4 _Layer1_ST; float4 _Layer2_ST; float4 _Layer3_ST; float4 _Layer4_ST; float4 _AddColorMap_ST; struct appdata { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float4 color : COLOR; float2 uv_Layer1 : TEXCOORD0; float2 uv_Layer2 : TEXCOORD1; float2 uv_Layer3 : TEXCOORD2; float2 uv_Layer4 : TEXCOORD5; float2 uv_ADC : TEXCOORD3; float3 normal; float3 lightDir : TEXCOORD4; }; v2f vert (appdata_full v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.color = v.color; o.uv_Layer1 = TRANSFORM_TEX(v.texcoord, _Layer1); o.uv_Layer2 = TRANSFORM_TEX(v.texcoord, _Layer2); o.uv_Layer3 = TRANSFORM_TEX(v.texcoord, _Layer3); o.uv_Layer4 = TRANSFORM_TEX(v.texcoord, _Layer4); o.uv_ADC = TRANSFORM_TEX(v.texcoord, _AddColorMap); o.normal = normalize(mul(_Object2World,float4(v.normal,0))); o.lightDir = normalize(WorldSpaceLightDir(v.vertex)); return o; } float4 frag (v2f i) : COLOR { float4 l1 = tex2D (_Layer1, i.uv_Layer1); float4 l2 = tex2D (_Layer2, i.uv_Layer2); float4 l3 = tex2D (_Layer3, i.uv_Layer3); float4 l4 = tex2D (_Layer3, i.uv_Layer4); float4 adc = tex2D (_AddColorMap, i.uv_ADC); float4 color = float4(1, 1, 1, 1); float3 lambert = saturate (dot(i.lightDir,i.normal)); color.rgb = (((l1 * i.color.r) + (l2 * i.color.g) + (l3 * i.color.b)) * lambert) * _Color; color.rgb *=(l4 * adc.b); return color; } ENDCG } } } Some input on how to properly achieve this problem is nice ! Imagery on the problem: The external colormap : The problem
If you plan draw it in some 2d application it's may become kinda ass pain. When you draw value in some layer you should subtract that value from other layers(perhaps you draw pixel in 1st texture red layer then you need subtract that value from 1.g, 1.b, 1a, 2.r, 2.g, 2.b) and in finally you need normalize all layers to 1 value (divide each layer value by their summ). In the shader only you need to do add each texture multiplied by their channel mask together. I think terrain engine works at same way. ------------------------ I think little, is not necessary normalize result after 1st step, instead 2 hand drawn mask texture may be prepared to mix with this operation, but it's will be very tricky to draw good looking mask by hands.
OK, so what do you mean exactly with the and in finally you need normalize all layers to 1 value (divide each layer value by their summ) ?. Because shaders is really not my strongpoint
I have this atm , but then those divide by the sum is not really clear to me float3 m1red = l1 * i.color.r; float3 m1green = l2 * i.color.g; float3 m1blue = l3 * i.color.b; float3 m2red = l4 * adc.r; float3 m2green = l5 * adc.g; float3 m2blue = l6 * adc.b; float3 col1r = (m1green + m1blue + m2red + m2green + m2blue) - m1red; float3 col1g = (m1red + m1blue + m2red + m2green + m2blue) - m1green; float3 col1b = (m1red + m1green + m2red + m2green + m2blue) - m1blue; float3 col2r = (m1red + m1green + m1blue + m2green + m2blue) - m2red; float3 col2g = (m1red + m1green + m1blue + m2red + m2blue) - m2green; float3 col2b = (m1red + m1green + m1blue + m2red + m2green) - m2blue; color.rgb = ((col1r + col1g + col1b + col2r + col2g + col2b) * lambert) * _Color;
Here is a multitexture shader. i would be grateful if you would change the crossfade values to be 6-12-16 textures. It's not very well written, it's an example of what kindof works, to write it again properly, i'd suggest shelving the crossfade values as they are done and write a new version from scratch. it's pretty good anyways: Code (csharp): Shader "Custom/MultiTexture" { Properties { _TexTop ("Top", 2D) = "white" {} _TexMid ("Mid", 2D) = "white" {} _TexBot ("Bot", 2D) = "white" {} _TopLimit("TopLimit", Range(-1, 1)) = 0.7 _BotLimit("BotLimit", Range(-1, 1)) = 0.27 _MidLimit("MidLimit", Range(-1, 1)) = 0.43 _TotalMetres("TotalMetres", float) = 100 _MidZone("_MidZone", Range(-100, 100)) = 20 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 //Cull Off CGPROGRAM #pragma surface surf Lambert #pragma exclude_renderers ps3 flash sampler2D _TexTop; sampler2D _TexMid; sampler2D _TexBot; float _TopLimit; float _MidLimit; float _BotLimit; float _TotalMetres,_MidZone; struct Input { float2 uv_TexTop; float3 worldNormal; float incline; float3 worldPos; }; void vert (inout appdata_full v, out Input o) { UNITY_INITIALIZE_OUTPUT(Input,o); o.incline = abs(v.normal.y); } void surf (Input IN, inout SurfaceOutput o) { float Alti = (IN.worldPos.y+_MidZone)/_TotalMetres; float4 resultCol = // Above topLimit, 100% topTexture Alti >= _TopLimit ? tex2D(_TexTop, IN.uv_TexTop) // Below botLimit, 100% botTexture : (Alti <= -_BotLimit ? tex2D(_TexBot, IN.uv_TexTop) // Between sideLimit and -MidLimit, 100% MidTexture : (Alti <= _MidLimit && Alti >= -_MidLimit ? tex2D(_TexMid, IN.uv_TexTop) // Above 0 outside thresholds, blend between side and top : (Alti > 0 ? lerp(tex2D(_TexTop, IN.uv_TexTop), tex2D(_TexMid, IN.uv_TexTop), 1 - ((Alti - _MidLimit) / (_TopLimit - _MidLimit))) // Below 0, outside thresholds, blend between side and bot : lerp(tex2D(_TexBot, IN.uv_TexTop), tex2D(_TexMid, IN.uv_TexTop), 1 - ((abs(Alti) - _MidLimit) / (abs(_BotLimit) - _MidLimit)))))); o.Albedo = resultCol.rgb; o.Alpha = resultCol.a; } ENDCG } FallBack "Diffuse" }
First of all thanks for the reply but i should have mentioned that i fixed my problem and fully wrote a correctly working shader with 5 textures blending at the same time (had to disable one channel on the second mask to allow for the previous textures to only be drawn by that single mask so it wouldn't draw under the two other textures of the second mask texture