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

#include custom ".cginc" files.

Discussion in 'Shaders' started by zezba9000, Jun 27, 2011.

  1. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    985
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I keep mine in the same directory as my shaders that reference it - seems to work perfectly fine. Haven't tried it in other directories though :/
     
    FlightyFelon likes this.
  3. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    985
    Ok its not working no matter what I try. Are you on WIndows or Mac?

    Im including a blank "ShaderBase.cginc" file. Does there have to be something in it? I didn't think there did...

    All shaders are in the root "Assets" folder.
    Ive tried: "#include "ShaderBase.cginc""
    And:: "#include "Assets/ShaderBase.cginc""
    Neither work.

    Here is my test shader, very basic-----------------------

    Shader "Test/Diffuse"
    {
    Properties
    {
    _Diffuse ("Diffuse", 2D) = "white" {}
    }

    SubShader
    {
    Tags { "RenderType" = "Opaque" }
    CGPROGRAM
    //#include "UnityCG.cginc" <<< THIS WORKS >>>
    //#include "ShaderBase.cginc" <<< THIS DOES NOT WORK >>>
    #pragma surface surf SimpleLambert

    half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half distance)
    {
    half NdotL = dot (s.Normal, lightDir);
    return half4(s.Albedo, s.Alpha) * _LightColor0 * NdotL * distance;
    }

    struct Input
    {
    float2 uv_MainTex;
    };
    sampler2D _Diffuse;

    void surf (Input IN, inout SurfaceOutput o)
    {
    o.Albedo = tex2D (_Diffuse, IN.uv_MainTex).rgb;
    }
    ENDCG
    }
    Fallback "Diffuse"
    }
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I'm on Windows.

    Ehr, if you're including a blank one... there'd be no way to know if it works or not.

    Try writing a function in it and then call it in your shader.
     
  5. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    985
    Hmmm well i'm totally confused as to why its not working if something so simple is working for you.
    Would you mind posting a simple Shader and Shader #include file source that works on your end?? Maybe then I can see what i'm doing wrong...

    I tried putting this method in my "ShaderBase.cginc".. still does not work::
    ----------
    inline float3 WorldSpaceViewDir( in float4 v )
    {
    return v.xyz;
    }
    ----------
     
  6. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    985
    Does anybody have a simple working example of some source I could look at to try and figure out what is going on with my shades??

    Ive written HLSL for years now... I don't understand how I could have so much troubled with such a simple issue.
     
  7. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I've got this in my include, which is called "ExplorationLighting.cginc" ;
    Code (csharp):
    1.  
    2. struct SurfaceOutputCharacter {
    3.     fixed3 Albedo;
    4.     fixed3 Normal;
    5.     fixed4 AnisoDir;
    6.     fixed3 Emission;
    7.     fixed3 Specular;
    8.     fixed Alpha;
    9. };
    10.  
    11. sampler2D _AnisoRamp, _RampTex;
    12. float _Cutoff;
    13. inline fixed4 LightingExplorationCharacter (SurfaceOutputCharacter s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    14. {
    15.     fixed3 h = normalize(lightDir + viewDir);
    16.     fixed NdotL = saturate(dot(s.Normal, lightDir));
    17.     float nh = saturate(dot(s.Normal, h));
    18.    
    19.     fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h);
    20.     float2 anisoUV = float2(HdotA, 0.5);
    21.     anisoUV -= 0.2;
    22.     fixed3 aniso = pow(tex2D(_AnisoRamp, anisoUV), s.Specular.g * 64) * s.Specular.r;
    23.    
    24.     float spec = pow(nh, s.Specular.g * 128) * s.Specular.r;
    25.     spec = saturate(lerp(spec, aniso, s.AnisoDir.a));
    26.  
    27.     float3 ramp = tex2D(_RampTex, float2((NdotL * 0.5 + 0.5) * atten)).rgb * s.Specular.b;
    28.  
    29.     fixed4 c;
    30.     c.rgb = pow((((pow(s.Albedo + ramp, 2.2) * _LightColor0.rgb * NdotL) * (_LightColor0.rgb * (1 - spec))) + (_LightColor0.rgb * spec)) * (atten * 2), 0.45);
    31.     c.a = 1;
    32.     clip(s.Alpha - _Cutoff);
    33.    
    34.     return c;
    35. }
    36.  
    37. float _Cutoff;
    38. inline fixed4 LightingExplorationStandard (SurfaceOutput s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    39. {
    40.     fixed3 h = normalize(lightDir + viewDir);
    41.    
    42.     fixed NdotL = saturate(dot(s.Normal, lightDir));
    43.    
    44.     float nh = saturate(dot(s.Normal, h));
    45.     float spec = pow(nh, s.Gloss * 128) * s.Specular;
    46.  
    47.     fixed4 c;
    48.     c.rgb = pow(((pow(s.Albedo, 2.2) * _LightColor0.rgb * NdotL) * ((1 - spec) * _LightColor0.rgb) + (_LightColor0.rgb * spec)) * (atten * 2), 0.45);
    49.     c.a = s.Alpha;
    50.     clip(s.Alpha - _Cutoff);
    51.    
    52.     return c;
    53. }
    54.  
    55. struct SurfaceOutputAniso {
    56.     fixed3 Albedo;
    57.     fixed3 Normal;
    58.     fixed4 AnisoDir;
    59.     fixed3 Emission;
    60.     half Specular;
    61.     fixed Gloss;
    62.     fixed Alpha;
    63. };
    64.  
    65. sampler2D _AnisoRamp;
    66. float _AnisoOffset;
    67. inline fixed4 LightingExplorationAniso (SurfaceOutputAniso s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    68. {
    69.     fixed3 h = normalize(lightDir + viewDir);
    70.     float nh = saturate(dot(s.Normal, h));
    71.  
    72.     fixed NdotL = saturate(dot(s.Normal, lightDir));
    73.     fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h);
    74.  
    75.     float2 anisoUV = float2(HdotA, 0.5);
    76.     anisoUV.x += _AnisoOffset;
    77.     fixed3 aniso = pow(tex2D(_AnisoRamp, anisoUV), s.Gloss * 128) * s.Specular;
    78.  
    79.     fixed3 spec = fixed3(pow(nh, s.Gloss * 128) * s.Specular);
    80.     spec = lerp(spec, aniso, s.AnisoDir.a);
    81.  
    82.     fixed4 c;
    83.     c.rgb = pow(((pow(s.Albedo, 2.2) * _LightColor0.rgb * NdotL) * ((1 - spec) * _LightColor0.rgb) + (_LightColor0.rgb * spec)) * (atten * 2), 0.45);
    84.     c.a = 1;
    85.     clip(s.Alpha - _Cutoff);
    86.     return c;
    87. }
    88.  
    89. struct SurfaceOutputEyes {
    90.     fixed3 Albedo;
    91.     fixed3 Normal;
    92.     fixed3 Normal2;
    93.     fixed3 Emission;
    94.     half Specular;
    95.     fixed Gloss;
    96.     fixed Alpha;
    97. };
    98.  
    99. inline fixed4 LightingExplorationEyes (SurfaceOutputEyes s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    100. {
    101.     fixed3 h = normalize(lightDir + viewDir);
    102.    
    103.     fixed NdotL = saturate(dot(s.Normal, lightDir));
    104.    
    105.     float nh = saturate(dot(s.Normal2, h));
    106.     float spec = pow (nh, s.Gloss * 128) * s.Specular;
    107.    
    108.     fixed4 c;
    109.     c.rgb = pow(((pow(s.Albedo, 2.2) * _LightColor0.rgb * NdotL) * ((1 - spec) * _LightColor0.rgb) + (_LightColor0.rgb * spec)) * (atten * 2), 0.45);
    110.     c.a = 1;
    111.     return c;
    112. }
    113.  
    114. inline fixed4 LightingExplorationRiver (SurfaceOutput s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    115. {  
    116.     fixed3 h = normalize(lightDir + viewDir);
    117.     float nh = saturate(dot (s.Normal, h));
    118.     float spec = pow(nh, 128);
    119.    
    120.     fixed4 c;
    121.     c.rgb = _LightColor0.rgb * spec * (atten * 2);
    122.     c.a = 1;
    123.     return c;
    124. }
    125.  
    And this in my shader;
    Code (csharp):
    1.  
    2. /*
    3. Ramp at light terminator.
    4.  
    5. Masked anisotropic highlight.
    6.  
    7. Alphatested.
    8. */
    9.  
    10. Shader "Exploration/Character" {
    11.     Properties {
    12.         _Color ("Main Color", Color) = (1,1,1,1)
    13.         _MainTex ("Diffuse (RGB)", 2D) = "white" {}
    14.         _SpecularTex ("Specular (R) Gloss (G) Null (B)", 2D) = "gray" {}
    15.         _BumpMap ("Normal (Normal)", 2D) = "bump" {}
    16.         _RampTex ("SSS Ramp (RGB)", 2D) = "black" {}
    17.         _AnisoDirection ("Anisotropic Direction (RGB)", 2D) = "black" {}
    18.         _AnisoRamp ("Anisotropic Ramp (RGB)", 2D) = "black" {}
    19.         _Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5
    20.     }
    21.  
    22.     SubShader{
    23.         Tags {"RenderType" = "Opaque"}
    24.         CGPROGRAM
    25.             #include "ExplorationLighting.cginc"
    26.             #pragma surface surf ExplorationCharacter fullforwardshadows
    27.             #pragma target 3.0
    28.            
    29.             struct Input
    30.             {
    31.                 float2 uv_MainTex;
    32.             };
    33.            
    34.             sampler2D _MainTex, _SpecularTex, _NormalTex, _AnisoDirection;
    35.                
    36.             void surf (Input IN, inout SurfaceOutputCharacter o)
    37.             {
    38.                 fixed4 albedo = tex2D(_MainTex, IN.uv_MainTex);
    39.                 o.Albedo = albedo.rgb;
    40.                 o.Alpha = albedo.a;
    41.                 o.AnisoDir = tex2D(_AnisoDirection, IN.uv_MainTex);
    42.                 o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
    43.                 o.Specular = tex2D(_SpecularTex, IN.uv_MainTex).rgb;
    44.             }
    45.         ENDCG
    46.     }
    47.     FallBack "Transparent/Cutout/VertexLit"
    48. }
    49.  
    Both files reside in the same directory. Works perfectly.
     
    mannyhams likes this.
  8. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    985
    Tnx so much, that helped me rule out that I wasn't going crazy...Well I did kinda go crazy trying to figure this out LOL.

    Ok all my code was fine all along.
    Because im using VisualStudio I had created my "ShaderBase.cginc" file I used for testing as a ".cs" file then changed its extension to ".cginc"... Somehow this added 4 extra byes onto the file that you can't get rid of. If you create the file as ".txt" to begin with, you don't have this issue.

    Why creating ".cs" file vs a ".txt" file in visual studios are any different in size is very odd.
    The error in Unity3d was "Bad characters in the source file at line 0".

    NOTE for others:: DO NOT, create your ".cginc" file as ".cs" files and change the ext, because it WILL NOT work.

    Tnx again ;)
     
    mannyhams likes this.
  9. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Haha, weird. Must be something to do with the encoding. Glad you got it sorted.
     
  10. Beugnen

    Beugnen

    Joined:
    Oct 4, 2012
    Posts:
    6
    Thanks I can confirm a similar problem.

    It failed for me when I created a File.New.File.Text Document in Visual Studio renaming the file extension to .cginc. Seems Visual Studio mucks it up regardless of how the file is created.

    I created and pasted in the initial code externally via Windows Notepad and all is well.

    I notice the file created is UTF-8 without BOM compared to UTF-8 that Visual Studio seems to be defaulting to in my environment.

    $Untitled.png
     
    Last edited: Jan 18, 2014
    PrimalCoder and tokar_dev like this.
  11. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I've always created them via right clicking in the directory and clicking new text document, then renaming the extension :p
     
  12. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    190
    Man am I glad I found this thread - saved me hours of frustration.

    I can confirm that creating a .cginc file by renaming a .cs file created in VS will result in an invalid file. Beugnen nailed it by pointing out the difference in the UTF-8 formats: If the file has the BOM set, then it will be invalid for .cginc files.

    Oddly enough, this seems to only apply to .cginc files - if you create an actual .shader inside Unity the BOM bytes will be set at the beginning of the file, which won't cause any problems. If you then change the extension to .cginc, it won't work. Creating it as a text file in Windows explorer (like Farfarer mentioned) will result in a valid file (without the BOM) - other than that, I think you could simply strip the BOM using a hex editor.
     
  13. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Another possible approach is to select one of the .cginc files Unity provides, duplicate it, modify it and drag it in the project.

    If you need to include a .cginc file called myFile.cginc that is in folder1 in a shader file that lies in folder 2

    folder1
    |
    --folder2

    Add the following line in the file in folder 2

    #include "../myFile.cginc"

    If the myFile.cginc is two folders up in the hierarchy, then you can do

    #include "../../myFile.cginc"
     
  14. Andrey-Postelzhuk

    Andrey-Postelzhuk

    Joined:
    Nov 26, 2013
    Posts:
    75
    Thanks! It solved my problem too.
     
  15. SimplyLinn

    SimplyLinn

    Joined:
    Jun 10, 2014
    Posts:
    9
    This is a bit of a gravedigging, but I'd just like to explain why I think it doesn't work with BOM set

    Basically, BOM is adding bytes to the beginning of the file, like a header, that tells any editor that "This is a UTF-8 file"

    My guess is that the #include does a binary copy of the source, before giving it to the compiler, and also include the extra BOM-bytes. However, when you do #include they get included somewhere where they're NOT supposed to be, and thus results in invalid characters in the final text-file.
     
  16. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    972
    I would be grateful for explaining this:
    Suppose I have one shader file and two files:
    - myFile1.cginc
    - myFile2.cginc
    both localized in the "included" subfolder.
    I include the first file in my shader with line:
    #include "included/myFile1.cginc"
    How to include myFile2.cginc inside myFile1.cginc?
    with
    #include "included/myFile2.cginc" (relative to shader file)
    or
    #include "myFile2.cginc" (relative to myFile1.cginc) ???
     
  17. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    #include "myFile2.cginc";
    You add a "../" as"prefix" for each folder hierarchy level that is above the current file folder level.
     
  18. Stevepunk

    Stevepunk

    Joined:
    Oct 20, 2013
    Posts:
    205
    I tried this and I'm getting the error: "Can't find include file."