Search Unity

Combining textures in a custom shader

Discussion in 'Shaders' started by zRedCode, Jan 21, 2015.

  1. zRedCode

    zRedCode

    Joined:
    Nov 11, 2013
    Posts:
    131
    So, im working on the my first surface shader.
    Im making a shader that thakes 6 textures (3 albedos and 3 normals), and combines the textures using 2 values.
    Is used to make rust and scratches on weapons.
    So i readed the documentation and started writing this (using only albedos for now):
    Code (CSharp):
    1. Shader "WeaponRustandScratchBlend" {
    2.     Properties {
    3.         _RustAmount ("Rust Amount", range (0.0, 1.0)) = 0
    4.         _ScratchesAmount ("Scratches Amount", range (0.0, 1.0)) = 0
    5.         _MainTex ("Weapon (RGBA)", 2D) = "white" {}
    6.         _RustTex ("Rust (RGBA)", 2D) = "blue" {}
    7.         _ScratchesTex ("Scratches (RGBA)", 2D) = "green" {}
    8.     }
    9.    
    10.     SubShader {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.        
    14.         CGPROGRAM
    15.         #pragma surface surf Lambert
    16.  
    17.         sampler2D _MainTex;
    18.         sampler2D _RustTex;
    19.         sampler2D _ScratchesTex;
    20.  
    21.         struct Input {
    22.             float2 uv_MainTex;
    23.             float2 uv_RustTex;
    24.             float2 uv_ScratchesTex;
    25.         };
    26.  
    27.         void surf (Input IN, inout SurfaceOutput o) {
    28.             half4 main = tex2D (_MainTex, IN.uv_MainTex);
    29.             half4 rust = tex2D (_RustTex, IN.uv_RustTex);
    30.             half4 scratches = tex2D (_ScratchesTex, IN.uv_ScratchesTex);
    31.             //SetTexture [main] {combine main lerp (_RustAmount) rust}; here comes the problems, this line causes errors on unity.
    32.             o.Albedo = main.rgb;
    33.             o.Alpha = main.a;
    34.         }
    35.         ENDCG
    36.     }
    37.     FallBack "Diffuse"
    38. }
    39.  
    I think SetTexture is deprecated (the documentaiton says is legacy), so how i can blend two textures and output the result in the albedo?
    Thanks in advance
     
  2. zRedCode

    zRedCode

    Joined:
    Nov 11, 2013
    Posts:
    131
    Little update, i got it working (a sort of)
    Code (CSharp):
    1. Shader "Fatal Error/Weapon Procedural" {
    2.     Properties {
    3.         _RustAmount ("Rust Amount", range (0.0, 1.0)) = 0
    4.         _ScratchesAmount ("Scratches Amount", range (0.0, 1.0)) = 0
    5.         _MainTex ("Weapon (RGBA)", 2D) = "" {}
    6.         _MainNrm ("Weapon Normals", 2D) = "" {}
    7.         _RustTex ("Rust (RGBA)", 2D) = "" {}
    8.         _RustNrm ("Rust Normals", 2D) = "" {}
    9.         _ScratchesTex ("Scratches (RGBA)", 2D) = "" {}
    10.         _ScratchesNrm ("Scratches Normals", 2D) = "" {}
    11.    
    12.     }
    13.    
    14.     SubShader {
    15.         Tags { "RenderType"="Opaque" }
    16.         LOD 350
    17.        
    18.         CGPROGRAM
    19.         #pragma target 3.0
    20.         #pragma surface surf Lambert
    21.         ENDCG
    22.         CGINCLUDE
    23.         #define _GLOSSYENV 1
    24.         #define UNITY_PBS_LIGHTING_INCLUDED
    25.         #define UNITY_SETUP_BRDF_INPUT MetallicSetup
    26.  
    27.         sampler2D _MainTex; //Texture dell'arma
    28.         sampler2D _MainNrm; //Normali dell'arma
    29.         sampler2D _RustTex; //Texture ruggine dell'arma
    30.         sampler2D _RustNrm; //Normali dell'arma
    31.         sampler2D _ScratchesTex; //Texture graffi dell'arma
    32.         sampler2D _ScratchesNrm; //Normali graffi dell'arma
    33.         float _RustAmount; //Ammontare della ruggine
    34.         float _ScratchesAmount; //Ammontare dei graffi
    35.  
    36.         struct Input {
    37.             float2 uv_MainTex;
    38.             float2 uv_MainNrm;
    39.             float2 uv_RustTex;
    40.             float2 uv_RustNrm;
    41.             float2 uv_ScratchesTex;
    42.             float2 uv_ScratchesNrm;
    43.         };
    44.  
    45.         void surf (Input IN, inout SurfaceOutput Out) {
    46.             half4 Main = tex2D (_MainTex, IN.uv_MainTex);
    47.             half4 MainNrm = tex2D (_MainNrm, IN.uv_MainNrm);
    48.             half4 Rust = tex2D (_RustTex, IN.uv_RustTex);
    49.             half4 RustNrm = tex2D (_RustNrm, IN.uv_RustNrm);
    50.             half4 Scratches = tex2D (_ScratchesTex, IN.uv_ScratchesTex);
    51.             half4 ScratchesNrm = tex2D (_ScratchesNrm, IN.uv_ScratchesNrm);
    52.             Out.Albedo = (Rust.rgb * _RustAmount) + (Scratches.rgb * _ScratchesAmount) + Main.rgb;
    53.             Out.Normal = UnpackNormal ((tex2D (_RustNrm, IN.uv_RustNrm) * _RustAmount) + (tex2D (_ScratchesNrm, IN.uv_ScratchesNrm) * _ScratchesAmount) + tex2D (_MainNrm, IN.uv_MainNrm));
    54.             Out.Alpha = Main.a;
    55.         }
    56.         ENDCG
    57.     }
    58.     FallBack "Diffuse"
    59. }
    60.  
     
  3. gambiting

    gambiting

    Joined:
    Jul 23, 2014
    Posts:
    7
    Yeah you can just mix half4 values that you got from the textures using lerp:

    Code (CSharp):
    1. Out.Albedo = lerp(  tex2D( _MainTex, IN.uv_MainTex), tex2D( _RustTex, IN.uv_MainTex), 0.5f);
    That will mix your _MainTex and_RustTex in 50/50 proportion. Change the 0.5f to achieve a different split between them. Hope that helps.
     
  4. zRedCode

    zRedCode

    Joined:
    Nov 11, 2013
    Posts:
    131
    Thanks, saved my day, so if i understand, the syntax is:
    Code (CSharp):
    1. lerp (firstHalf4,  secondHalf4, interpolationValue)
    But this takes care of alpha of each texture?
    EDIT: Solved by myself how to make it take care of the alpha.
     
    Last edited: Jan 21, 2015
  5. Marek_Bakalarczuk

    Marek_Bakalarczuk

    Joined:
    Dec 28, 2012
    Posts:
    114
    Hi, can you post some more info? I'm struggling with car livery dirt with alpha, and can't make it to work