Search Unity

My Per-vertex lighting looks like a Per-pixel lighting + other questions on basic lighting.

Discussion in 'Shaders' started by kev42100, Oct 2, 2015.

  1. kev42100

    kev42100

    Joined:
    Apr 17, 2010
    Posts:
    61
    Hi everybody,

    I would like to remember the basics of lighting. Since I used the surface shaders, I lost many concepts and when I try to develop the basics, I can't understand the following results I get...

    https://onedrive.live.com/redir?res...authkey=!AC4JuF-xv0IcTw8&v=3&ithint=photo,JPG

    Here is my shader to compute a directional Light per vertex:

    Code (CSharp):
    1.  
    2. Shader "Custom/VertexLightingDiffuse"
    3. {
    4.     Properties
    5.     {  
    6.         _MatColor ("Material Color", Color) = (0.5, 0.5, 0.5, 1.0)
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         Tags
    12.         {
    13.             "RenderType"="Opaque"
    14.         }
    15.        
    16.         Pass
    17.         {
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #include "UnityCG.cginc"
    22.            
    23.             // Comes from a C# script ( LightDir = -normalize(GameObject.Find("Directional Light").transform.forward) )
    24.             uniform float4 LightDir;
    25.             uniform float4 _MatColor;
    26.            
    27.             struct v2f
    28.             {
    29.                 float4 pos : SV_POSITION;
    30.                 float4 finalColor : COLOR0;
    31.             };
    32.  
    33.          
    34.             v2f vert (appdata_full v)
    35.             {
    36.                 v2f o;
    37.                
    38.                 float3 worldSpaceNormal = mul((float3x3)_Object2World, v.normal);
    39.                 float NdotL = saturate(dot(normalize(worldSpaceNormal), LightDir));
    40.                 o.finalColor = _MatColor * NdotL;
    41.                
    42.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    43.                
    44.                 return o;                                            
    45.             }
    46.          
    47.             float4 frag (v2f i) : COLOR
    48.             {
    49.                 return i.finalColor;
    50.             }
    51.                
    52.             ENDCG
    53.         }      
    54.     }
    55.    
    56.     Fallback "Diffuse"
    57. }
    58.  
    Note: I want to use my own variables to understand as much as possible. Because when I use built-in variables, I'm more confused with the results !

    I also made a short C# script, attached to the Dir Light in my scene.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [ExecuteInEditMode]
    5. [RequireComponent(typeof(Light))]
    6. public class LightData : MonoBehaviour
    7. {
    8.     private Transform lightTransform;
    9.     private new Light light;
    10.  
    11.     void Start ()
    12.     {
    13.         this.lightTransform = this.transform;
    14.         this.light = this.GetComponent<Light>();
    15.     }
    16.    
    17.  
    18.     void Update ()
    19.     {
    20.         if (this.lightTransform != null)
    21.         {
    22.             Vector4 normalizedForward = new Vector4(
    23.                                                     this.lightTransform.forward.x,
    24.                                                     this.lightTransform.forward.y,
    25.                                                     this.lightTransform.forward.z,
    26.                                                     0.0f).normalized;
    27.  
    28.             Shader.SetGlobalVector("LightDir", -normalizedForward);
    29.  
    30.             Shader.SetGlobalColor("LightColor", this.light.color);
    31.             Shader.SetGlobalFloat("LightIntensity", this.light.intensity);
    32.  
    33.             Shader.SetGlobalVector("LightPosition", new Vector4(
    34.                                                                 this.transform.position.x,
    35.                                                                 this.transform.position.y,
    36.                                                                 this.transform.position.z,
    37.                                                                 0.0f));
    38.  
    39.             //print(normalizedForward);
    40.         }
    41.     }
    42. }
    43.  

    I use the Unity Sphere and a low-poly sphere made with Maya.

    1. I expected to see on my Unity Sphere a result like this one:



    Even if I multiply my final Color with the LightColor and LightIntensity, it still looks like a per-pixel lighting.

    2. To get a correct lighting, I need to negate the vector3.forward of the directional light. Why ?

    Thanks in advance for your precious answers/tips.
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    I could be wrong, but it looks to me each vertex on any given quad that makes up your sphere is using all the same normals. Are you not sharing verts between triangles in the model?

    As for the verse light direction, you want to light up the normals that are facing the light. So when you think about it, if the light is facing the vert and the vert normal is facing the light, the two will be opposite.
     
  3. kev42100

    kev42100

    Joined:
    Apr 17, 2010
    Posts:
    61
    @Gambit MSplitz,
    Yes I understand your reasoning, but it's quite confusing to compute the directional light with its "negate real direction"...