Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Physically based lighting shader

Discussion in 'Shaders' started by Pixelstudio_nl, Aug 7, 2013.

  1. Pixelstudio_nl

    Pixelstudio_nl

    Joined:
    Jun 22, 2009
    Posts:
    179
    Hi people,

    Im trying to create a shader based on the log post below :

    http://www.altdevblogaday.com/2011/08/23/shader-code-for-physically-based-lighting/

    So i thought, ill create a custom lighting function in a shader (code is below), hope that is the right approach :)
    But i must be doing something wrong cause i get no specular what so ever.....
    The output is a dull color...

    Any idea's ?

    Code (csharp):
    1.  
    2.  Shader "Example/PBL" {
    3.     Properties {
    4.       _MainTex ("Texture", 2D) = "white" {}
    5.       _Diffuse ("diffuse Color", Color) = (1.0, 1.0, 1.0, 1.0)
    6.       _specular_power ("Specular", Float) = 20.0
    7.       _specular_color ("Specular Color", Color) = (1.0, 1.0, 1.0, 1.0)
    8.     }
    9.     SubShader {
    10.       Tags { "RenderType" = "Opaque" }
    11.       CGPROGRAM
    12.       #pragma surface surf PBL
    13.  
    14.       float _specular_power;
    15.       float _specular_color;
    16.       float4 _Diffuse;
    17.  
    18.       const float PI = 3.14159265358;
    19.       const float PI_OVER_FOUR = 0.785398163395;
    20.       const float PI_OVER_TWO = 1.570796;
    21.  
    22.       half4 LightingPBL (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
    23.          
    24.           float3 h = normalize(lightDir + viewDir);                    
    25.           float h_dot_l = dot(h, lightDir);
    26.           float n_dot_l = max(0, dot(s.Normal, lightDir ));
    27.           float n_dot_h = max(0, dot(s.Normal, h));
    28.           float n_dot_v = max(0, dot(s.Normal, viewDir));
    29.          
    30.           half3 diffuse = n_dot_l;
    31.  
    32.           // visibility
    33.           float alpha = 1.0f / ( sqrt( PI_OVER_FOUR * _specular_power + PI_OVER_TWO ) );
    34.           float visibility_term = ( n_dot_l * ( 1.0 - alpha ) + alpha ) * ( n_dot_v * ( 1.0 - alpha ) + alpha );
    35.           visibility_term = 1.0f/ visibility_term;
    36.  
    37.           // Specular (blinn phong)
    38.           float normalisation_term = ( _specular_power + 2.0f ) / 8.0f;
    39.           float blinn_phong = pow( n_dot_h, _specular_power );
    40.           float specular_term = normalisation_term * blinn_phong * _specular_power;
    41.  
    42.           // Fresnel
    43.           float base = 1.0f - h_dot_l;    
    44.           float exponential = pow( base, 5.0f );
    45.           float fresnel_term = _specular_color + ( 1.0f - _specular_color ) * exponential;
    46.        
    47.           half4 c;
    48.          
    49.           c.rgb = (s.Albedo  + (specular_term * n_dot_l * fresnel_term * visibility_term * _specular_color)) * (atten *2);
    50.           c.a = s.Alpha;
    51.          
    52.           return c;
    53.  
    54.       }
    55.  
    56.       struct Input {
    57.           float2 uv_MainTex;
    58.       };
    59.       sampler2D _MainTex;
    60.  
    61.       void surf (Input IN, inout SurfaceOutput o) {
    62.           o.Albedo = _Diffuse ;
    63.       }
    64.       ENDCG
    65.     }
    66.    
    67.   }
    68.  
     
  2. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    Code (csharp):
    1.  
    2. float4 _specular_color;
    3.  
    and
    Code (csharp):
    1.  
    2. c.rgb = (s.Albedo * n_dot_l + (specular_term * n_dot_l * fresnel_term * visibility_term * _specular_color.rgb)) * (atten *2);
    3.  
    and

    Code (csharp):
    1.  
    2. visibility_term = n_dot_l * n_dot_v;
    3. visibility_term = 1.0f/ visibility_term;
    4.  
    and
    Code (csharp):
    1.  
    2. float specular_term = normalisation_term * blinn_phong;
    3.  
     
    Last edited: Aug 8, 2013
  3. Pixelstudio_nl

    Pixelstudio_nl

    Joined:
    Jun 22, 2009
    Posts:
    179
    Hi there!

    Thanks for that "float4 _specular_color;" was a real DUH :)
    Still something is not working (left is the shader im working on)
    $brdf.png
     
  4. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    $111111.JPG
    Code (csharp):
    1.  
    2.      Shader "Example/PBL" {
    3.         Properties {
    4.           _MainTex ("Texture", 2D) = "white" {}
    5.           _Diffuse ("diffuse Color", Color) = (1.0, 1.0, 1.0, 1.0)
    6.           _specular_power ("Specular", Float) = 20.0
    7.           _specular_color ("Specular Color", Color) = (1.0, 1.0, 1.0, 1.0)
    8.         }
    9.         SubShader {
    10.           Tags { "RenderType" = "Opaque" }
    11.           CGPROGRAM
    12.           #include "Lighting.cginc"
    13.           #pragma surface surf PBL
    14.      
    15.           float _specular_power;
    16.           float4 _specular_color;
    17.           float4 _Diffuse;
    18.      
    19.           const float PI = 3.14159265358;
    20.           const float PI_OVER_FOUR = 0.785398163395;
    21.           const float PI_OVER_TWO = 1.570796;
    22.      
    23.           half4 LightingPBL (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
    24.              
    25.               float3 h = normalize(lightDir + viewDir);                    
    26.               float h_dot_l = max(0,dot(h, lightDir));
    27.               float n_dot_l = max(0, dot(s.Normal, lightDir ));
    28.               float n_dot_h = max(0, dot(s.Normal, h));
    29.               float n_dot_v = max(0, dot(s.Normal, viewDir));
    30.              
    31.               half3 diffuse = n_dot_l;
    32.      
    33.               // visibility
    34.               //float alpha = 1.0f / ( sqrt( PI_OVER_FOUR * _specular_power + PI_OVER_TWO ) );
    35.               //float visibility_term = ( n_dot_l * ( 1.0 - alpha ) + alpha ) * ( n_dot_v * ( 1.0 - alpha ) + alpha );
    36.               float visibility_term = n_dot_l * n_dot_v;
    37.               visibility_term = 1.0f/ visibility_term;
    38.  
    39.               // Specular (blinn phong)
    40.               float normalisation_term = ( _specular_power + 2.0f ) / 8;
    41.               float blinn_phong = pow( n_dot_h, _specular_power);
    42.               float specular_term = normalisation_term * blinn_phong;
    43.  
    44.               // Fresnel
    45.               float base = 1.0f - h_dot_l;    
    46.               float exponential = pow( base, 5.0f );
    47.               float fresnel_term = _specular_color + ( 1.0f - _specular_color ) * exponential;
    48.            
    49.               half4 c;
    50.               c.rgb = (s.Albedo * n_dot_l * _LightColor0.rgb + (specular_term * n_dot_l * fresnel_term * visibility_term * _specular_color.rgb * _LightColor0.rgb)) * (atten *2);
    51.               c.a = s.Alpha;
    52.               return c;
    53.           }
    54.      
    55.           struct Input {
    56.               float2 uv_MainTex;
    57.           };
    58.           sampler2D _MainTex;
    59.      
    60.           void surf (Input IN, inout SurfaceOutput o) {
    61.               o.Albedo = _Diffuse ;
    62.           }
    63.           ENDCG
    64.         }
    65.        Fallback "Diffuse"
    66.       }
    67.  
     
  5. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    The speculars have artifacts... Try normalizing your normals.
     
  6. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Here is my code, I have the same problem I don't know what you mean exactly.

    Code (csharp):
    1. Shader "Advanced/Physically-Based/BlinnPhong"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex("Base (RGB)", 2D) = "white" {}
    7.         _SpecColor ("Specular Color", Color) = (1,1,1,1)
    8.         _SpecPower ("Specular Intensity", Float) = 20
    9.         //Fresnel ("Fresnal", Range(0.01, 5.0)) = 1.5
    10.        
    11.     }
    12.         SubShader
    13.         {
    14.        
    15.        
    16.             Pass
    17.             {
    18.                
    19.             Tags {"RenderType" = "Opaque"}
    20.            
    21.                 CGPROGRAM
    22.                 //pragmas go here!
    23.                 #pragma vertex vert
    24.                 #pragma fragment frag
    25.                 #pragma target 3.0
    26.            
    27.            
    28.                 //User defined variables
    29.                 uniform float4 _Color;
    30.                 //uniform float _ColorInt;
    31.                 //uniform float _Fresnel;
    32.                 uniform float4 _SpecColor;
    33.                 uniform sampler2D _MainTex;
    34.                 uniform float4 _MainTex_ST;
    35.                 uniform float _SpecPower;
    36.                 //uniform float _RimPower;
    37.                 //uniform float4 _RimColor;
    38.                
    39.                 //Constant variables
    40.                 uniform float PI = 3.14159265358;
    41.                 uniform float PI_OVER_TWO = 1.570796;
    42.                 uniform float PI_OVER_FOUR = 0.785398163395;
    43.                
    44.                
    45.                 //Unity defined variables
    46.                 uniform float4 _LightColor0;
    47.                
    48.                 //These are Pre-Defined variables in Unity3D 4.x and up!
    49.                 //float4x4 _Object2World;
    50.                 //float4x4 _World2Object;
    51.                 //float4 _WorldSpaceLightPos0;
    52.            
    53.                 //base Input structs - these are how functions communicate
    54.                 //Input struct - Putting info that will be fed to the greddy shaders!
    55.                 struct vertexInput
    56.                 {
    57.                     float4 vertex : POSITION; //Accessing the position of the objects vertices
    58.                     float3 normal : NORMAL;
    59.                     float4 texcoord : TEXCOORD0;
    60.                 };
    61.                 //Output struct - What we output from the vertex function into our shaders below
    62.                 struct vertexOutput
    63.                 {
    64.                     float4 pos : SV_POSITION;
    65.                     float4 posWorld : TEXCOORD0;
    66.                     float3 normalDir : TEXCOORD2;
    67.                     float4 tex : TEXCOORD0;
    68.                 };
    69.                 //Vertex shader
    70.                 vertexOutput vert(vertexInput r0)
    71.                 {
    72.                     vertexOutput c0;
    73.                    
    74.                     c0.posWorld = mul(_Object2World, r0.vertex);
    75.                     c0.normalDir = normalize(mul(float4(r0.normal, 0.0), _World2Object).xyz);
    76.                    
    77.                     c0.pos = mul(UNITY_MATRIX_MVP, r0.vertex);
    78.                     return c0;
    79.        
    80.                 }
    81.                 //Pixel shader
    82.                 float4 frag(vertexOutput s0) : COLOR
    83.                 {
    84.                    
    85.                     //Textures
    86.                     float4 DiffuseTex = tex2D(_MainTex, s0.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
    87.                    
    88.                     //Vectors
    89.                     float3 normalDirection = s0.normalDir;
    90.                     float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - s0.posWorld.xyz);
    91.                     float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    92.                     float3 halfDirection = normalize(lightDirection + viewDirection);
    93.                     float atten = 1.0;
    94.                    
    95.                     //N*L
    96.                     float3 NdotL = saturate( dot(normalDirection, lightDirection ) );
    97.                     //N*H
    98.                     float3 NdotH = saturate( dot(normalDirection, halfDirection ) );
    99.                     //N*V
    100.                     float3 NdotV = saturate( dot(normalDirection, viewDirection) );
    101.                     //H*L
    102.                     float3 HdotL = max(0, dot(halfDirection, lightDirection ) );
    103.                    
    104.                     //Diffuse Lighting
    105.                     float3 diffuse = NdotL * _LightColor0;
    106.                    
    107.                     //Specular Term
    108.                     float normalisationTerm = ( _SpecPower + 2.0f ) / 8.0f;
    109.                     float blinnPhong = pow( NdotH, _SpecPower );
    110.                     float specularTerm = normalisationTerm * blinnPhong;
    111.                    
    112.                     //Cosine Term
    113.                     float cosineTerm = NdotL;
    114.                    
    115.                     //Fresnal Term
    116.                     float base = 1.0f - HdotL;
    117.                     float exponential = pow( base, 5.0f );
    118.                     float fresnelTerm = _SpecColor + ( 1.0f - _SpecColor ) * exponential;
    119.                    
    120.                     //Visibility Term
    121.                     //float alpha = 1.0f / (sqrt (PI_OVER_FOUR * _SpecPower + PI_OVER_TWO) );
    122.                     float visibilityTerm = NdotL * NdotV;
    123.                     visibilityTerm = 1.0f / visibilityTerm;
    124.                    
    125.                     //Specular Lighting
    126.                     float3 specular = specularTerm * cosineTerm * fresnelTerm * visibilityTerm * _LightColor0.xyz;
    127.                    
    128.                     //Final lighting
    129.                     float3 lightFinal = diffuse + specular + UNITY_LIGHTMODEL_AMBIENT.xyz;
    130.                    
    131.                     return float4 (DiffuseTex * lightFinal, 1.0);
    132.  
    133.            
    134.                 }
    135.                
    136.                 ENDCG
    137.             }          
    138.                 //Fallback ""
    139.         }
    140.        
    141.         Fallback "VertexLit"
    142. }
    What makes physically-based rendering so good? This doesn't look all that great in my opinion, it looks nothing like other things I have seen..
    What can I add to my shader to make it look better, how can I add the cook torrance specular like Unity from Mastering DX11 Slides from GDC, How can I add ambient diffuse where its illuminated from a cubemap?
     
  7. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Exactly that... change float3 normalDirection = s0.normalDir; to float3 normalDirection = normalize(s0.normalDir);

    When you interpolate between two normalized vectors, the resulting vector needs to be normalized again ;)
     
  8. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Ahhh thanks! and about the last part do you know anything about that? I know your more experienced than I am from a lot of your previous posts on the forums.

     
  9. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    I wouldn't call it physically based... even the classic old Lambert model is physically based. It's just a more elaborate model, that can accurately represent a wider range of materials. Blinn-Phong looks fine for plastic materials, Cook-Torrance for both plastic and metals and Oren-Nayar for rough materials. The difference cannot be really seen on a simple sphere, but starts to look really convincing on some more complex models.

    To answer your other two questions: You have to implement it by yourself!

    EDIT: By the way.. I stumbled upon a nice BRDF model that's quite similar to Blinn-Phong, but looks nicer and runs faster, because it doesn't use a pow instruction. So it's mobile-friendly! It goes like this (adapted to the code above):

    Code (csharp):
    1. float normalisationTerm = (_SpecPower + 1 ) / 3;
    2. float trowbridgeReitz = 1 / (1 + (1 - NdotH * NdotH) * _SpecPower);
    3. float specularTerm = normalisationTerm * trowbridgeReitz * trowbridgeReitz; // It's squared!
    Just a note: I couldn't find the proper normalisation term, but this worked fine for my use case... You might want to adjust it a bit so that it scales similarly to BlinnPhong.
     
    Last edited: Aug 14, 2013
  10. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Thanks alot for your help, I've added ambient light from a filtered cubemap, cook torrance specular and other things that I added just because :) results look nice with all maps in place but many things to fix/add:

    Code (csharp):
    1. Shader "Advanced/Physically-Based/Cook-Torrance"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (0.5,0.5,0.5,1)
    6.         _SpecColor ("Specular Color", Color) = (1,1,1,1)
    7.         _MainTex("Base (RGB)", 2D) = "white" {}
    8.         _AOTex("Ambient Occlusion", 2D) = "white" {}
    9.         _NormalMap("Normal Map", 2D) = "bump" {}
    10.         _RoughnessTex("Roughness", 2D) = "white" {}
    11.         _SpecMap("Specular Map", 2D) = "white" {}
    12.         _AmbientDiffuse("Filtered CubeMap", Cube) = "" {}
    13.         _Cube("CubeMap (HDR)", Cube) = "" {}
    14.         _SpecPower ("Specular Intensity", Range(-0.09, 50.0)) = 1.5
    15.         _Bumpiness ("Normalmap Bumpiness", Range(-2.0, 2.0)) = 1.5
    16.         _Roughness ("Roughness", Range(0, 10.0)) = 1.5
    17.        
    18.     }
    19.         SubShader
    20.         {
    21.        
    22.        
    23.             Pass
    24.             {
    25.                
    26.             Tags {"RenderType" = "Opaque"}
    27.            
    28.                 CGPROGRAM
    29.                 //****Pragmas go here!****\\
    30.                 #pragma vertex vert
    31.                 #pragma fragment frag
    32.                 #pragma target 3.0
    33.            
    34.            
    35.                 //****User defined variables****\\
    36.                
    37.                 //Samplers
    38.                 uniform sampler2D _MainTex;
    39.                 uniform sampler2D _AOTex;
    40.                 uniform sampler2D _NormalMap;
    41.                 uniform sampler2D _RoughnessTex;
    42.                 uniform sampler2D _SpecMap;
    43.                 uniform samplerCUBE _AmbientDiffuse;
    44.                
    45.                 //Float4's
    46.                 uniform float4 _Color;
    47.                 uniform float4 _SpecColor;
    48.                 uniform float4 _MainTex_ST;
    49.                 uniform float4 _AOTex_ST;
    50.                 //Floats
    51.                 uniform float _SpecPower;
    52.                 uniform float _Bumpiness;
    53.                 uniform float _Roughness;
    54.  
    55.                
    56.                 //****Constant variables****\\
    57.                 uniform float PI = 3.14159265358;
    58.                 uniform float PI_OVER_TWO = 1.570796;
    59.                 uniform float PI_OVER_FOUR = 0.785398163395;
    60.                
    61.                
    62.                 //****Unity defined variables****\\
    63.                 uniform float4 _LightColor0;
    64.                
    65.                 //****These are Pre-Defined variables in Unity3D 4.x and up!****\\
    66.                 //float4x4 _Object2World;
    67.                 //float4x4 _World2Object;
    68.                 //float4 _WorldSpaceLightPos0;
    69.            
    70.                 //****Base Input structs****\\
    71.                
    72.                 //Input struct
    73.                 struct vertexInput
    74.                 {
    75.                     float4 vertex : POSITION; //Accessing the position of the objects vertices
    76.                     float3 normal : NORMAL;
    77.                     float4 texcoord : TEXCOORD0;
    78.                     float4 tangent : TANGENT;
    79.                 };
    80.                 //Output struct
    81.                 struct vertexOutput
    82.                 {
    83.                     float4 pos : SV_POSITION;
    84.                     float4 tex : TEXCOORD0;
    85.                     float4 posWorld : TEXCOORD1;
    86.                     float3 normalDir : TEXCOORD2;
    87.                     float3 tangentDir : TEXCOORD3;
    88.                     float3 binormalDir : TEXCOORD4;
    89.                    
    90.                 };
    91.                 //Vertex shader
    92.                 vertexOutput vert(vertexInput r0)
    93.                 {
    94.                     vertexOutput c0;
    95.                    
    96.                     c0.normalDir = normalize(mul(float4(r0.normal, 0.0), _World2Object).xyz);
    97.                     c0.tangentDir = normalize(mul(_Object2World, r0.tangent).xyz );
    98.                     c0.binormalDir = normalize(cross(c0.normalDir, c0.tangentDir) * r0.tangent.w );
    99.                    
    100.                    
    101.                     c0.posWorld = mul(_Object2World, r0.vertex);
    102.                     c0.tex = r0.texcoord;
    103.                    
    104.                     c0.pos = mul(UNITY_MATRIX_MVP, r0.vertex);
    105.                     return c0;
    106.        
    107.                 }
    108.                 //Pixel shader
    109.                 float4 frag(vertexOutput s0) : COLOR
    110.                 {
    111.                    
    112.                     //****Textures****\\
    113.                    
    114.                     //Diffuse
    115.                     float4 DiffuseTex = tex2D(_MainTex, s0.tex.xy);
    116.                    
    117.                     //Ambient Occlusion
    118.                     float4 AmbientTex = tex2D(_AOTex, s0.tex.xy);
    119.                    
    120.                     //Normal Map
    121.                     float4 NormalMap = tex2D(_NormalMap, s0.tex.xy);
    122.                    
    123.                     //Roughness
    124.                     float2 RoughTex = tex2D(_RoughnessTex, s0.tex.xy).rg;
    125.                    
    126.                     //Specular
    127.                     float4 SpecularMap = tex2D(_SpecMap, s0.tex.xy);
    128.                    
    129.                     //****Modifications****\\
    130.                     DiffuseTex *= _Color;
    131.                     DiffuseTex *= AmbientTex;
    132.                     RoughTex.r *= 3.0f;
    133.                    
    134.                     //Unpack Normals
    135.                     float3 localCoords = float3(2.0 * NormalMap.ag - float2(1.0, 1.0), 0.0 );
    136.                     localCoords.z = _Bumpiness;
    137.                    
    138.                     //Normal Transpose
    139.                     float3x3 local2World = float3x3(s0.tangentDir, s0.binormalDir, s0.normalDir);
    140.                    
    141.                    
    142.                     //****Vectors****\\
    143.                     float3 normalDirection = normalize(mul(localCoords, local2World ) );
    144.                     float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - s0.posWorld.xyz);
    145.                     float3 reflectionDirection = reflect(viewDirection, normalize(normalDirection) );
    146.                     float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    147.                     float3 halfDirection = normalize(lightDirection + viewDirection);
    148.                     float atten = 1.0;
    149.                    
    150.                    
    151.                     //N*L
    152.                     float3 NdotL = saturate( dot(normalDirection, lightDirection ) );
    153.                     //N*H
    154.                     float3 NdotH = saturate( dot(normalDirection, halfDirection ) );
    155.                     //N*V
    156.                     float3 NdotV = saturate( dot(normalDirection, viewDirection) );
    157.                     //H*L
    158.                     float3 HdotL = saturate( dot(halfDirection, lightDirection ) );
    159.                     //H*V
    160.                     float3 HdotV = saturate( dot(halfDirection, viewDirection ) );
    161.                    
    162.                     //****Terms****\\
    163.                    
    164.                     //Diffuse Lighting
    165.                     float3 diffuse = NdotL * _LightColor0;
    166.                    
    167.                     //Ambient Term
    168.                     float3 ambientTerm = texCUBE(_AmbientDiffuse, reflectionDirection);
    169.                    
    170.                     //Geometric Term
    171.                     float G1 = ( 2.0f * NdotH * NdotV ) / HdotV;
    172.                     float G2 = ( 2.0f * NdotH * NdotL ) / HdotV;
    173.                     float geometricTerm = min( 1.0f, max( 0.0f, min( G1, G2 ) ) );
    174.                    
    175.                     //Roughness Term
    176.                     float R2 = RoughTex.r * RoughTex.r;
    177.                     float NdotH2 = NdotH * NdotH;
    178.                     float A = 1.0f / ( 4.0f * R2 * NdotH2 * NdotH2 );
    179.                     float B = exp( -( 1.0f - NdotH2 ) / ( R2 * NdotH2 ) );
    180.                     float roughnessTerm = A * B *_Roughness;
    181.                    
    182.                     //Specular Term
    183.                     float normalisationTerm = (_SpecPower + 1 ) / 3.141592;
    184.                     float trowbridgeReitz = 1 / (1 + (1 - NdotH * NdotH) * _SpecPower);
    185.                     float specularTerm = normalisationTerm * trowbridgeReitz * trowbridgeReitz;
    186.                    
    187.                     //Cosine Term
    188.                     float cosineTerm = NdotL;
    189.                    
    190.                     //Fresnal Term
    191.                     float fresnelTerm = RoughTex.g + ( 1.0f - RoughTex.g ) * pow( 1.0f - NdotV, 5.0f );
    192.                    
    193.                     //Visibility Term
    194.                     float visibilityTerm = NdotL * NdotV;
    195.                    
    196.                     //Specular Lighting
    197.                     float3 specular = (SpecularMap * specularTerm) * (geometricTerm * roughnessTerm * fresnelTerm * _LightColor0.xyz) / (visibilityTerm);
    198.                    
    199.                     //Final lighting
    200.                     float3 lightFinal = diffuse + specular + ambientTerm + UNITY_LIGHTMODEL_AMBIENT.xyz;
    201.                    
    202.                     return float4 (DiffuseTex * lightFinal, 1.0);
    203.  
    204.            
    205.                 }
    206.                
    207.                 ENDCG
    208.             }          
    209.                
    210.         }
    211.         //****Fallbacks****\\
    212.         Fallback "VertexLit"
    213. }
     
  11. Pixelstudio_nl

    Pixelstudio_nl

    Joined:
    Jun 22, 2009
    Posts:
    179
    Cool!! nice work!
     
  12. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
  13. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Awesome! Make sure to post some screenshots, or even a demo, when it's all done and set. :)