Home Technical Talk

Shader Halp... please!!!!

ngon master
Offline / Send Message
almighty_gir ngon master
Hey guys, i'm at it again!!!

Working on a pbr shader based on the GGX formula that are floating around. Been looking at both UE4 and The Order 1866 tech papers. Everything seems to be going smoothly apart from one thing:

the specular hot-spot only appears where the camera is, ie: it follows the camera around, when i would have thought it should be located in-line with the light source, right?.

here's a screenshot to help describe what i mean:
i2sbKnG.png

i've marked where the specular highlight should be in relation to the light source. so far only the "fresnel" function seems to respect where the light source is, the visibility and specular functions follow the camera (from what i can gather anyway).

any help?
//physical based lighting shader test
//Written by Lee Devonald - Character Artist, 2014. 
// Http://crazyferretstudios.com.
//references and source math found here: http://blog.selfshadow.com/publications/s2013-shading-course/
Shader "Custom/PBR_Debug" {

//Shader properties (that are visible to the user).
Properties 
	{
	    _Colour ("Colour Test", Color) = (0,0,0,0)
	    _Metalness ("Metalness Test", Range (0.0,1.0)) = 0
	    _BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
	    _Cube ("Cube", CUBE) = "white" {}
	    _GlossTest ("Gloss Test", Range (0.0,1.0)) = 0.0
   }
       
       
        
        
SubShader 
	{
        Tags { "Queue"="Transparent" }
        LOD 200
       
        CGPROGRAM
        #pragma surface surf CustomPBR
        #include "UnityCG.cginc"
        #pragma glsl
        #pragma target 3.0
        #pragma exclude_renderers d3d11_9x
        
        #define OneOnLN2_x6 8.656170
		#define Pi 3.14159265358979323846
       
        half4 _Colour;
        half _Metalness;
        sampler2D _BumpMap;
        samplerCUBE _Cube;
        half _GlossTest;
                
                                
        struct SurfaceOutputCustom
			{
				
			    fixed3 Albedo;
			
			    fixed3 Normal;
			
			    fixed3 Emission;
			
			    fixed4 Specular;
			
			    fixed Gloss;
			
			    fixed Alpha;				 
			
			    fixed3 Mask1;
			    
			    fixed3 Mask2;
				
			};               

			float calcVisibility(float NoL, float NoV, float alpha2)
			{
				float invGeo1 = NoL + sqrt(alpha2 + (1 - alpha2) * NoL * NoL);
				float invGeo2 = NoV + sqrt(alpha2 + (1 - alpha2) * NoV * NoV);
				return 1.0f / (invGeo1 * invGeo2);
			}
						
			float calcSpecular(float alpha2, float NoH)
			{
				float denominator = (NoH * NoH) * (alpha2 - 1) + 1;
				denominator = Pi * denominator * denominator;
				return alpha2 / denominator;
			}
			
	        fixed4 LightingCustomPBR(SurfaceOutputCustom s, float3 lightDir, float3 viewDir, half atten)
	        {
	   			//normalizing vectors
	   			float3 N = normalize(s.Normal);
	   			float3 L = normalize(lightDir);
	   			float3 V = normalize(viewDir);
	   			float3 Spec = (s.Specular.rgb);           			
	   			
	   			//bunch of vectors
	   			float NoL = max(0,(dot(N,L)));
                float NoV = max(0,dot(N,V));
                float3 H = normalize(N + V);		                
                float LoH = saturate(dot(L,H));
                float VoH = saturate(dot(V,H));
                float NoH = max(0,dot(N,H));
                
	   			
	   			fixed alpha = _GlossTest;
	   			alpha *= alpha;
	   			float alpha2 = alpha * alpha;
	   			fixed3 Fresnel = Spec + ( 1.0 - Spec) * pow(1.0f - saturate(LoH), 5);
	                
                float3 SpecCol = saturate(calcSpecular(alpha2, NoH) / calcVisibility(NoL, NoV, alpha2) * Fresnel);
                 
	   			half3 Albedo = (s.Albedo.rgb);
                
                fixed4 c;
				c.rgb = (Albedo * (1 - SpecCol) + SpecCol) * _LightColor0.rgb * NoL * (atten * 2);
                return c;
	        }   
                       
       
        struct Input { 
       
        float2 uv_MainTex;
        float3 viewDir;
        float3 worldRefl; INTERNAL_DATA       
               
        };             
        void surf (Input IN, inout SurfaceOutputCustom o) 
		{
        	half4 Diff = _Colour * (1 - _Metalness);
        	half4 Spec = 0.04f * (1 - _Metalness) + _Metalness * _Colour;
        	                                                         
            o.Albedo = Diff.rgb;                   
            o.Specular = Spec;
            o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_MainTex));
            
            float3 V = normalize(IN.viewDir);
            half rim = 1.0 - saturate(dot(normalize(V), o.Normal));
            float3 worldN = WorldReflectionVector(IN, o.Normal);
            fixed Roughness = _GlossTest;
            
            half4 cubeLightColour = texCUBElod (_Cube, float4(worldN, Roughness * 10)); 
            o.Emission = (Spec * cubeLightColour).rgb;
        }
        ENDCG
	}
	FallBack "diffuse"
}

Replies

Sign In or Register to comment.