Search Unity

How to receive shadows in custom vert/frag shader

Discussion in 'Shaders' started by IronMathbook, Apr 14, 2014.

  1. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I wrote a vert-frag shader using unitycookie's tutorials but I have problems with it. It won't receive shadows. Read that I should add AutoLight.cginc or LIGHT_ATTENUATION(i) but I've set atten to 1/distance^2 in my code. I get declaration of "x" conflicts with previous declaration at (53) at line 47 for multiple properties when I try and include AutoLight.cginc. I tried to see how shadows are cast in AutoLight but I can't figure out what part of the code or how to port it into my shader.

    Also I would like to convert this to half Lambert lighting but I don't know what I need to do to SNdotL.

    here's my shader code ( not targeted for mobile )
    Code (csharp):
    1. Shader"custom/Skin"
    2.  
    3. {
    4.  
    5.  
    6. properties
    7.  
    8. {
    9.  
    10. //_Ramp("BlendingEffects", 2D) = "white" {}
    11.  
    12. //_Range("Gloss",range(0,20))= 5
    13.  
    14. //_AmbGlo("AmbiantLighting",range(0,50))= 10
    15.  
    16. //_Occl("Oclusion",range(0,50))= 10
    17.  
    18. _MainTex("Texture", 2D) = "white" {}
    19.  
    20.  
    21.  
    22. _Smap("SpecMap", 2D) = "white" {}
    23.  
    24. _Shininess ("Specularity",range(0.005,5))= 2
    25.  
    26. _SpecColor ("specTint",color)= (1.0,1.0,1.0,1.0)
    27.  
    28. _RimColor ("Rim Color", Color) = (1.0,1.0,1.0,1.0)
    29.  
    30. _RimPower ("Rim Power", Range(0.1,10.0)) = 3.0
    31.  
    32. _Normals ("Normal", 2D)="white" {}
    33.  
    34. _NorRange ("Dephs",range(1,5))= 3
    35.  
    36.  
    37.  
    38. // above is good
    39.  
    40.  
    41.  
    42. }
    43.  
    44. SubShader
    45.  
    46. {
    47.  
    48. Pass{
    49.  
    50. Tags{"LightMode" = "ForwardBase"}
    51.  
    52.  
    53.  
    54. CGINCLUDE
    55.  
    56. // #include "AutoLight.cginc"
    57.  
    58.  
    59.  
    60. CGPROGRAM
    61.  
    62. #pragma vertex vertsA
    63.  
    64. #pragma fragment fragsA  
    65.  
    66. #pragma target 3.0
    67.  
    68. #pragma only_renderers d3d9  debug
    69.  
    70.  
    71.  
    72. // no simcs on the pragmas
    73.  
    74.  
    75.  
    76. //user variables and unity variables
    77.  
    78. uniform half4 _Color;
    79.  
    80. uniform half4 _SpecColor;
    81.  
    82. uniform half _Shininess;
    83.  
    84. uniform half4 _LightColor0;
    85.  
    86. uniform sampler2D _MainTex;
    87.  
    88. uniform half4 _MainTex_ST;
    89.  
    90. uniform sampler2D _Normals;
    91.  
    92. uniform half4 _Normals_ST;
    93.  
    94. uniform half _NorRange;
    95.  
    96. uniform sampler2D _Smap;
    97.  
    98. uniform half4 _Smap_ST;
    99.  
    100. uniform fixed4 _RimColor;
    101.  
    102. uniform half _RimPower;
    103.  
    104.  
    105.  
    106. half4x4 _Object2World;
    107.  
    108. half4x4 _World2Object;
    109.  
    110. half4 _WorldSpaceLightPos0;
    111.  
    112. half3 _WorldSpaceCameraPos;
    113.  
    114.  
    115.  
    116. //input structs
    117.  
    118.  
    119. struct VertInput1 {   // vertex imput info
    120.  
    121. half4 vertex : POSITION;
    122.  
    123. half3 normal : NORMAL;
    124.  
    125. half4 texcoord : TEXCOORD0;
    126.  
    127. half4 tangent : TANGENT;
    128.  
    129. };
    130.  
    131.  
    132.  
    133. //output structs
    134.  
    135. struct VertOutput1 { // vertex output info
    136.  
    137. half4 pos : SV_POSITION;
    138.  
    139. half4 colur: COLOR;
    140.  
    141. half4 sktex : TEXCOORD0;
    142.  
    143. half4 lightDir : TEXCOORD1;
    144.  
    145. half3 posNormal : TEXCOORD2;
    146.  
    147. half3 tans : TEXCOORD3;
    148.  
    149. half3 binoms : TEXCOORD4;
    150.  
    151. half3 cameraView :TEXCOORD5;
    152.  
    153. half4 spTex : TEXCOORD6;
    154.  
    155.  
    156.  
    157. };
    158.  
    159.  
    160.  
    161. // vertex
    162.  
    163.  
    164.  
    165. VertOutput1 vertsA(VertInput1 g)
    166.  
    167. {
    168.  
    169. VertOutput1 h;
    170.  
    171. // direction variables
    172.  
    173.  
    174.  
    175. h.posNormal =  normalize(mul(half4(g.normal,0.0),_World2Object).xyz);
    176.  
    177. h.tans = normalize( mul(_Object2World, g.tangent).xyz);
    178.  
    179. h.binoms = normalize(cross(h.posNormal,h.tans)* g.tangent.w);
    180.  
    181.  
    182.  
    183. half4 posMain = mul(_Object2World, g.vertex);
    184.  
    185. h.pos = mul(UNITY_MATRIX_MVP, g.vertex);
    186.  
    187. h.sktex = g.texcoord;
    188.  
    189.  
    190. h.cameraView = normalize (_WorldSpaceCameraPos.xyz -posMain.xyz); //tweakable
    191.  
    192.  
    193.  
    194. // light physics
    195.  
    196. half3 facetolite= _WorldSpaceLightPos0.xyz -posMain.xyz;
    197.  
    198. half distance = length(facetolite);
    199.  
    200.  
    201.  
    202. h.lightDir = half4(normalize(lerp(_WorldSpaceLightPos0.xyz,facetolite,_WorldSpaceLightPos0.w)),
    203.  
    204. lerp(1.0,(1.0/(distance*distance)),_WorldSpaceLightPos0.w));
    205.  
    206.  
    207.  
    208. return h;
    209.  
    210.  
    211.  
    212. }
    213.  
    214.  
    215.  
    216. // fragment
    217.  
    218.  
    219.  
    220. half4 fragsA(VertOutput1 i) : COLOR
    221.  
    222. {
    223.  
    224.  
    225. //maps
    226.  
    227.  
    228.  
    229. half4 sktex = tex2D(_MainTex, i.sktex.xy + (_MainTex_ST.xy * _MainTex_ST.zw));
    230.  
    231. half4 tans = tex2D(_Normals, i.sktex.xy + (_Normals_ST.xy * _Normals_ST.zw));
    232.  
    233. half4 spTex = tex2D(_Smap, i.sktex.xy + (_Smap_ST.xy *_Smap_ST.zw));
    234.  
    235.  
    236.  
    237. //normals
    238.  
    239. half3 localCoords = half3(2.0 * tans.ag - half2(1.0,1.0),_NorRange);
    240.  
    241.  
    242.  
    243. half3x3 local2WorldTranspose = float3x3( i.tans, i.binoms, i.posNormal);
    244.  
    245. half3 normalDirection =  normalize(mul(localCoords, local2WorldTranspose));
    246.  
    247.  
    248.  
    249.  
    250. //Lambert lighting calc
    251.  
    252.  
    253.  
    254. half3 SNdotL=  saturate( dot( normalDirection,i.lightDir.xyz));
    255.  
    256. half3 thelighting = i.lightDir.w * _LightColor0.xyz *2* SNdotL;
    257.  
    258.  
    259.  
    260. //Rim Lighting
    261.  
    262. fixed rim = 1 - SNdotL;
    263.  
    264. fixed3 rimLighting = SNdotL * _RimColor.xyz * _LightColor0.xyz * pow( rim, _RimPower );
    265.  
    266.  
    267.  
    268. //Specularity calc (0.7*normalDirection,0.7*mainlightDir for wetness, specularity and shine,
    269.  
    270. half3 theshine = i.lightDir.w * spTex.rgb* max( 0.0,dot(0.7*normalDirection,0.7* i.lightDir.xyz))
    271.  
    272. * pow(max(0.0, dot(reflect(-i.lightDir.xyz, normalDirection),i.cameraView )),_Shininess);
    273.  
    274. half3 matcaplight = thelighting + (UNITY_LIGHTMODEL_AMBIENT.xyz)+ rimLighting;
    275.  
    276.  
    277.  
    278.  
    279.  
    280. // messy overlay highlights
    281.  
    282. half3 anotherT = lerp((1-(1-sktex.rgb)),((1-2*sktex.rgb)*sktex.rgb*matcaplight),step(8.9*matcaplight, 1));
    283.  
    284. half3 overlayfun = lerp((1-2*(1-sktex.rgb)),(2*sktex.rgb* matcaplight),step(matcaplight, 0.2 ));
    285.  
    286.  
    287.  
    288. half3 supertest=(overlayfun)/(1-anotherT*0.3)*(theshine*0.2) + (0.2*theshine* (_SpecColor.rgb * _LightColor0.xyz ));
    289.  
    290.  
    291.  
    292.  
    293. //final lighting
    294.  
    295. return half4 (sktex.rgb*matcaplight+supertest,1.0);
    296.  
    297.  
    298.  
    299.  
    300.  
    301. }
    302.  
    303.  
    304.  
    305. ENDCG
    306.  
    307.  
    308.  
    309.  
    310.  
    311.  
    312.  
    313. }
    314.  
    315.  
     
  2. WhiskyJoe

    WhiskyJoe

    Joined:
    Aug 21, 2012
    Posts:
    143
    Just using the LIGHT_ATTENUATION() macro will not do the trick, you have to "feed" the data to it first by specifying the light coords, the LIGHT_ATTENUATION() macro is not set by code.

    first of all, specify #pragma multi_compile_fwdbase (if you want to support more lights, this will become #pragma multi_compile_fwdadd)

    In your vertex output struct, you will need to specify LIGHTING_COORDS(x, x) where x are the next available texcoord semantics (7 and 8 in your case)

    In the vertex shader at the very end (but before the return) you will need to specify TRANSFER_VERTEX_TO_FRAGMENT(output) (or h in your case).

    LIGHT_ATTENUATION is now filled with both the shadowing and attenuation values (combined) which you can use.
     
  3. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Will adding LIGHT_ATTENUATION conflict with my lightDir which defines the attenuation for this shader?
     
  4. WhiskyJoe

    WhiskyJoe

    Joined:
    Aug 21, 2012
    Posts:
    143
    Considering that LIGHT_ATTENUTATION contains the combined shadow and attenuation factor you might get conflicts. Unless you're doing something different with your attenuation than what unity does, you will not need it anymore. Only one way to find out though!

    If you really want to keep your own calculation, you will need to dig into the include files unity provides to see how you can directly sample the shadow maps. I haven't done this myself, but I did see some relevant macros passing by that makes me think it is possible.
     
  5. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    my atten is 1/distance^2. It's set like that because it reduces the flickering I get from point lights when I move away from them. I tried checking AutoLight.cginc because I think that is where the shadow calcs are but I don't understand what's in there the variables seem to be connected to some other functions.Also there seems to be calculations for cubes and pills but not for general objects.
    do you think anyone has tried this before?
     
  6. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    I don't know exactly how it works in the Forward Lighting path, but with the Deferred Lighting path, the built-in 'Internal-PrePassLighting' shader calls ComputeShadow, which gives you most of the information you need. Normally it's combined with lighting information, so if you want to use it to get the stand-alone shadow information, you still need to do some extra work.

    It's something I had to change to create dynamic shadows on lightmaps. The source code for that project is available, so it might help you figure out how to create the effect you're looking for.
     
  7. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I looked at you code and I'm not sure if it is usable in my application

    as for computeShadow I found a reference listed in complex-prepasslight-in

    But I don't know what this is. It looks like am incomplete shader or something:

    Code (csharp):
    1.  
    2. inline half unitySampleShadow ( float3 vec , float mydist )
    3. {
    4. float z = 1.0 / 128.0 ;
    5. float4 shadowVals ;
    6. shadowVals . x = SampleCubeDistance ( vec + float3 ( z , z , z ) ) ;
    7. shadowVals . y = SampleCubeDistance ( vec + float3 ( - z , - z , z ) ) ;
    8. shadowVals . z = SampleCubeDistance ( vec + float3 ( - z , z , - z ) ) ;
    9. shadowVals . w = SampleCubeDistance ( vec + float3 ( z , - z , - z ) ) ;
    10. half4 shadows = ( shadowVals < mydist . xxxx ) ? _LightShadowData . rrrr : 1.0f ;
    11. return dot ( shadows , 0.25 ) ;
    12. }
    13. half ComputeShadow ( float3 vec , float z , float2 uv )
    14. {
    15. float fade = z * _LightShadowData . z + _LightShadowData . w ;
    16. fade = saturate ( fade ) ;
    17. float mydist = length ( vec ) * _LightPositionRange . w ;
    18. mydist *= 0.97 ;
    19. return unitySampleShadow ( vec , mydist ) ;
    20. return 1.0 ;
    21. }
    22.  
    23.  
    SampleCubeDistance seems to have come from AutoLight.cginc:

    Code (csharp):
    1. inline float unityCubeShadow (float3 vec)
    2. {
    3.     float mydist = length(vec) * _LightPositionRange.w;
    4.     mydist *= 0.97; // bias
    5.  
    6.     #if defined (SHADOWS_SOFT)
    7.     float z = 1.0/128.0;
    8.     float4 shadowVals;
    9.     shadowVals.x = SampleCubeDistance (vec+float3( z, z, z));
    10.     shadowVals.y = SampleCubeDistance (vec+float3(-z,-z, z));
    11.     shadowVals.z = SampleCubeDistance (vec+float3(-z, z,-z));
    12.     shadowVals.w = SampleCubeDistance (vec+float3( z,-z,-z));
    13.     half4 shadows = (shadowVals < mydist.xxxx) ? _LightShadowData.rrrr : 1.0f;
    14.     return dot(shadows,0.25);
    15.     #else
    16.     float dist = SampleCubeDistance (vec);
    17.     return dist < mydist ? _LightShadowData.r : 1.0;
    18.     #endif
    19. }
    But I don't know what's going on here. maybe it's someone's to be a modded AutoLight.cginc file
     
  8. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I'm going to assume that both codes are from one of unities files.
     
  9. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    You're looking at the code that's used for shadows in the Deferred lighting path.

    They contain code from Internal-PrePassLighting, like I mentioned above, but they're different from to the version used in Unity 4.3.4. They're both missing some bits. In the case of ComputeShadow you can see they forgot to remove the return 1.0f, which was only relevant before the #if blocks were removed. You're better off looking at the original file from the built-in shaders zip.

    My example project was based on the same file (Albeit one from an older version of Unity), and #pragma debug versions of surface shaders.
     
    Last edited: Apr 16, 2014
  10. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    What version is the code I posted?
    Did Deferred lighting and Forward Lighting use the same shadow code in older versions of unity?
    No matter if it did or not I guess I have to figure out where Forward Lighting's shadow code is located.
     
  11. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    I don't know. I assume it's modified by someone else, because it removes a lot of shadow types. You can find a lot of old versions in the archive, if you really want to find out which one it's most similar to.
    I don't know, but I doubt it. The code for shadows in deferred lighting is different and supports way more types of shadows. Forward Rendering only supports one directional light.

    To chase down the location of shadow code for Forward lighting, you can start by looking at the shader code generated for a surface shader using #pragma debug. In Forward Rendering, only the first lighting pass can have shadows, so you're looking for
    Code (csharp):
    1. "LightMode" = "ForwardBase".
    In the generated fragment shader you'll find a reference to
    Code (csharp):
    1. LIGHT_ATTENUATION(IN)
    Several versions of which are defined in AutoLight.cginc (in the <Unity Install Path>\Data\CGIncludes folder). From what I can tell, all of those call
    Code (csharp):
    1. SHADOW_ATTENUATION(a)
    Some versions are simply defined as a float
    Code (csharp):
    1. #define SHADOW_ATTENUATION(a) 1.0
    But there are others that actually call other methods for shadow calculation.
    Code (csharp):
    1. #define SHADOW_ATTENUATION(a) unitySampleShadow(a._ShadowCoord)
    2. #define SHADOW_ATTENUATION(a) unityCubeShadow(a._ShadowCoord)
    You can ignore the second one, because the comment above says:
    Code (csharp):
    1. // ---- Point light shadows
    (Comments never lie, right?)
    And according to the documentation, those are only supported with Deferred Lighting.
    Which leaves you with three versions of unitySampleShadow. One of them is for mobile, one is only used if SPOT is defined (so I'm guessing it's only for Deferred Lighting, again), and one of them is really simple:
    Code (csharp):
    1. inline fixed unitySampleShadow (float4 shadowCoord)
    2. {
    3.     fixed shadow = tex2Dproj( _ShadowMapTexture, UNITY_PROJ_COORD(shadowCoord) ).r;
    4.     return shadow;
    5. }
    So, there you go. I got a bit carried away tracking down the code you're looking for, but I guess it might be useful for others too.
     
    Last edited: Apr 16, 2014
  12. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Oh thank you. I will go back to working on my shader.
     
  13. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Sorry for the necro post but I'm still working on this shader. I have actually gotten it to be a good looking skin shader but I was still using the forward rendering path.
    I happen to run into a shader which is a vert/frag with shadows using deferred rendering.
    Code (CSharp):
    1. Shader "Specular-Deferred"
    2. {
    3. Properties {
    4.     _MainTex ("Base (RGB)", 2D) = "white"{}
    5.     _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
    6.      _Shininess ("Shininess", Range(0.01,1)) = 0.078125
    7. }
    8. SubShader{
    9.     Pass{Tags {"LightMode" = "PrePassBase"}
    10.     CGPROGRAM
    11.     #pragma vertex vert
    12.     #pragma fragment frag      
    13.     uniform float _Shininess;
    14.  
    15.     struct vIN
    16.     {
    17.         float4 vertex : POSITION;
    18.         float3 normal : NORMAL;
    19.     };
    20.     struct vOUT
    21.     {
    22.         float4 pos : SV_POSITION;
    23.         float3 wNorm : TEXCOORD0;
    24.     };
    25.     vOUT vert(vIN v)
    26.     {
    27.         vOUT o;
    28.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    29.         o.wNorm = mul((float3x3)_Object2World, v.normal);
    30.         return o;
    31.     }
    32.  
    33.     float4 frag(vOUT i) : COLOR
    34.     {
    35.         float3 norm = (i.wNorm * 0.5) + 0.5;
    36.         return float4(norm, _Shininess);
    37.     }
    38.     ENDCG
    39.  
    40.     }
    41.  
    42.  
    43.  
    44.  
    45.  
    46.     Pass{Tags{"LightMode" = "PrePassFinal"}
    47.     ZWrite off
    48.     CGPROGRAM
    49.     #pragma vertex vert
    50.     #pragma fragment frag
    51.  
    52.     sampler2D _MainTex;
    53.     uniform float4 _SpecColor;
    54.     uniform sampler2D _LightBuffer;
    55.  
    56.     struct vIN
    57.     {
    58.         float4 vertex : POSITION;
    59.         float2 texcoord : TEXCOORD0;
    60.     };
    61.  
    62.     struct vOUT
    63.     {
    64.         float4 pos : SV_POSITION;
    65.         float2 uv : TEXCOORD0;
    66.         float4 uvProj : TEXCOORD1;
    67.     };
    68.    
    69. vOUT vert(vIN v)
    70. {
    71.     vOUT o;
    72.     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    73.    
    74.     float4 posHalf = o.pos * 0.5;
    75.     posHalf.y *= _ProjectionParams.x;
    76.    
    77.     o.uvProj.xy = posHalf.xy + float2(posHalf.w, posHalf.w);
    78.     o.uvProj.zw = o.pos.zw;
    79.     o.uv = v.texcoord;
    80.    
    81.     return o;
    82. }
    83.  
    84.  
    85.  
    86. float4 frag(vOUT i) : COLOR
    87. {
    88.     float4 light = tex2Dproj(_LightBuffer, i.uvProj);
    89.     float4 logLight = -(log2(max(light, float4(0.001,0.001,0.001,0.001))));
    90.     float4 texCol = tex2D(_MainTex, i.uv);
    91.     return float4((texCol.xyz * light.xyz) + float3(_SpecColor.xyz) * light.w, texCol.w);
    92. }
    93.  
    94. }
    95.  
    96.  
    97.  
    98.     Pass{
    99.  
    100.  
    101. Name "ShadowCaster"
    102.     Tags { "LightMode" = "ShadowCaster" }
    103.    
    104.     Fog {Mode Off}
    105.     ZWrite On ZTest LEqual Cull Off
    106.     Offset 1, 1
    107.  
    108.     CGPROGRAM
    109.     #pragma vertex vert
    110.     #pragma fragment frag
    111.     #pragma multi_compile_shadowcaster
    112.     #include "UnityCG.cginc"
    113.  
    114.     struct v2f {
    115.         V2F_SHADOW_CASTER;
    116.     };
    117.  
    118.     v2f vert( appdata_base v )
    119.     {
    120.         v2f o;
    121.         TRANSFER_SHADOW_CASTER(o)
    122.         return o;
    123.     }
    124.  
    125.     float4 frag( v2f i ) : SV_Target
    126.     {
    127.         SHADOW_CASTER_FRAGMENT(i)
    128.     }
    129.     ENDCG
    130.     }
    131. }
    132. }

    but I'm confused as how to convert my own shader because I'm using using madcaps and highlights. Also I've never heard or seen float4 logLight = -(log2(max(light, float4(0.001,0.001,0.001,0.001)))); and I have no idea what it does in his code.
    Code (CSharp):
    1.  
    2. _MainTex("Texture", 2D) = "white" {}
    3. _Smap("SpecMap", 2D) = "white" {}
    4. _Shininess ("Specularity",range(0.005,2.5))= 0.05
    5. _MatCap ("MatCap (RGB)", 2D) = "white" {}
    6. _CapPower("matPower",range(1.2,1.7))= 1.4
    7. _Normals ("Normal", 2D)="white" {}
    8. _NorRange ("Dephs",range(0.95,8))= 3
    9.  
    10. }
    11. SubShader
    12. {
    13. Pass{
    14. Tags{"LightMode" = "ForwardBase"}
    15.  
    16. CGPROGRAM
    17. #pragma vertex vertsA
    18. #pragma fragment fragsA
    19. #pragma target 3.0
    20. #pragma only_renderers d3d9  debug
    21.  
    22.  
    23. //user variables
    24. uniform half4 _Color;
    25. uniform half _Shininess;
    26. uniform half4 _LightColor0;
    27. uniform sampler2D _MainTex;
    28. uniform half4 _MainTex_ST;
    29. uniform sampler2D _Normals;
    30. uniform half4 _Normals_ST;
    31. uniform half _NorRange;
    32. uniform half _CapPower;
    33. uniform sampler2D _Smap;
    34. uniform half4 _Smap_ST;
    35. uniform sampler2D _MatCap;
    36. uniform float2 matcapUV;
    37. half4x4 _Object2World;
    38. half4x4 _World2Object;
    39. half4 _WorldSpaceLightPos0;
    40. half3 _WorldSpaceCameraPos;
    41.  
    42. //input structs
    43.  
    44.  
    45. struct VertInput1 {   // vertex imput info
    46. half4 vertex : POSITION;
    47. half3 normal : NORMAL;
    48. half4 texcoord : TEXCOORD0;
    49. half4 tangent : TANGENT;
    50. };
    51.  
    52. //output structs
    53. struct VertOutput1 { // vertex output info
    54. half4 pos : SV_POSITION;
    55. half4 colur: COLOR;
    56. half4 sktex : TEXCOORD0;
    57. half4 lightDir : TEXCOORD1;
    58. half3 posNormal : TEXCOORD2;
    59. half3 tans : TEXCOORD3;
    60. half3 binoms : TEXCOORD4;
    61. half3 cameraView :TEXCOORD5;
    62. half4 spTex : TEXCOORD6;
    63. float2 cap  : TEXCOORD7;
    64.  
    65. };
    66.  
    67. // vertex
    68.  
    69. VertOutput1 vertsA(VertInput1 g)
    70. {
    71. VertOutput1 h;
    72. //matcap
    73.   half2 capCoord;
    74. capCoord.x = dot(UNITY_MATRIX_IT_MV[0].xyz,g.normal);
    75. capCoord.y = dot(UNITY_MATRIX_IT_MV[1].xyz,g.normal);
    76. h.cap = capCoord * 0.5 + 0.5;
    77.  
    78.  
    79. // direction variables
    80. h.posNormal =  normalize(mul(half4(g.normal,0.0),_World2Object).xyz); //normalworld
    81. h.tans = normalize( mul(_Object2World, g.tangent).xyz); //tangentworld
    82. h.binoms = normalize(cross(h.posNormal,h.tans)* g.tangent.w);//binormalWorld
    83.  
    84. half4 posMain = mul(_Object2World, g.vertex);
    85. h.pos = mul(UNITY_MATRIX_MVP, g.vertex);
    86. h.sktex = g.texcoord;
    87.  
    88. h.cameraView = normalize (_WorldSpaceCameraPos.xyz -posMain.xyz); //tweakable
    89.  
    90.  
    91.  
    92. //multilight and light physics
    93. half3 facetolite= _WorldSpaceLightPos0.xyz -posMain.xyz;
    94. half distance = length(facetolite);
    95.  
    96. h.lightDir = half4(normalize(lerp(_WorldSpaceLightPos0.xyz,facetolite,_WorldSpaceLightPos0.w)),
    97. lerp(1.0,(1.0/(distance*distance)),_WorldSpaceLightPos0.w));
    98.  
    99.  
    100. return h;
    101.  
    102. }
    103.  
    104.  
    105.  
    106. // fragment
    107.  
    108. half4 fragsA(VertOutput1 i) : COLOR
    109. {
    110.  
    111.  
    112. //maps
    113.  
    114. half4 sktexf = tex2D(_MainTex, i.sktex.xy + (_MainTex_ST.xy * _MainTex_ST.zw));
    115. half4 tans = tex2D(_Normals, i.sktex.xy + (_Normals_ST.xy * _Normals_ST.zw));
    116. half4 spTex = tex2D(_Smap, i.sktex.xy + (_Smap_ST.xy *_Smap_ST.zw));
    117.  
    118. //normals
    119. half3 localCoords = half3(2.0 * tans.ag - half2(1.0,1.0),_NorRange);
    120.  
    121. half3x3 local2WorldTranspose = float3x3( i.tans, i.binoms, i.posNormal);
    122. half3 normalDirection =  normalize(mul(localCoords, local2WorldTranspose));
    123.  
    124. //matcap
    125. fixed4 mc = tex2D(_MatCap,i.cap);
    126.  
    127. //Half-Lambert lighting calc.
    128.  
    129. half3 SNdotL=  saturate( dot( normalDirection,i.lightDir.xyz));
    130. half3 thelighting = i.lightDir.w * _LightColor0.xyz *2* SNdotL;
    131.  
    132.  
    133. //Specularty calc (0.7*normalDirection,0.7*mainlightDir for wetness, specularity and shine,
    134. half3 theshine = i.lightDir.w * 0.8*spTex.rgb*(0.4*max( 0.0,dot(0.7*normalDirection,0.7* i.lightDir.xyz)))
    135. * pow(max(0.0, dot(reflect(-i.lightDir.xyz, normalDirection),i.cameraView )),_Shininess);
    136. //spec highlights messy code
    137. half3 thehigh = i.lightDir.w * max( 0.0,dot(normalDirection, i.lightDir.xyz))
    138. *pow(max(0.0, dot(reflect(-i.lightDir.xyz, normalDirection),i.cameraView )),15);
    139. half3 thebrightness = theshine+(0.06*thehigh);
    140. //combine the lights
    141. half3 lights = (mc*_CapPower)*(thelighting)+(thebrightness);//(theshine*0.6);// + (2*UNITY_LIGHTMODEL_AMBIENT.xyz);
    142.  
    143.  
    144.  
    145. //final lighting
    146.  
    147. return half4 (sktexf.rgb*lights,1.0);
    148.  
    149. }
    150.  
    151. ENDCG
    152.  
    153. }
    154.  
    I'm alittle worried that I might have too much going on in the frag but that's not my main issues.
    I am not sure what parts of my shader should go in the base pass in deferred lighting. I know the "direction variables" need to be in the first pass but what about the "matcap" and the maps; I'm not use to separating stuff like this. Lastly can I make my own lightDirection/attenuation in deferred lighting or should I just edit AutoLight.cginc.

    I'm planning on releasing the skin shader code when I'm done so I appreciate the help.
     
  14. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    As it turned out I was able to get shadows using forward rendering by using by adding
    #include "AutoLight.cginc"
    #include "UnityCG.cginc"
    SHADOW_COORDS(x) to output struct
    TRANSFER_SHADOW(o) right above return. It has to be o so name your vertex out put o

    I had to delete
    float4x4 _Object2World;
    float4x4 _World2Object;
    float4 _WorldSpaceLightPos0;
    float3 _WorldSpaceCameraPos;

    I'm getting ready to release the shader
     
    Last edited: Feb 21, 2015