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

(Single) Unreal Engine Spherical Area Light

Discussion in 'Made With Unity' started by JecoGames, May 5, 2014.

  1. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Hello my name is Cian Mc Sweeney and recently I have been experimenting with physically based shading and area lights. I found this code here: https://www.shadertoy.com/view/ldfGWs I managed to port this to unity but with only a single light. I am working on making this support multiple lights and might add other PBS stuff like reflections etc but for now I'm leaving it up to ye. Well anyways here's the code:

    C# script attached to light:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. [ExecuteInEditMode]
    4. public class AreaLight : MonoBehaviour {
    5.     public Color LightColor;
    6.     public float LightRadius;
    7.     // Use this for initialization
    8.     void Start () {
    9.  
    10.     }
    11.  
    12.     // Update is called once per frame
    13.     void Update () {
    14.         Vector4 areaPos = new Vector4(transform.position.x,transform.position.y,transform.position.z,1);
    15.         Shader.SetGlobalVector ("_LightPos",areaPos);
    16.         Shader.SetGlobalColor("_LightColor",LightColor);
    17.         Shader.SetGlobalFloat("_LightRadius",LightRadius);
    18.  
    19.     }
    20. }
    21.  
    Shader:

    Code (csharp):
    1.  
    2. Shader "Custom/AreaLights" {
    3.  
    4.     Properties {
    5.  
    6.         _MainTex ("Base (RGB)", 2D) = "white" {
    7.         _Roughness("Roughness",float)=.5
    8.          _FO("FO",float)=5
    9.     }
    10.  
    11.     SubShader {
    12.      Pass{
    13.      Tags { "LightMode"="ForwardBase" }
    14.  
    15.      
    16.  
    17.         CGPROGRAM
    18.         #pragma vertex vert
    19.  
    20.         #pragma fragment frag
    21.  
    22.         #pragma target 3.0
    23.  
    24.         float3 _LightColor;
    25.  
    26.         float3 _LightPos;
    27.  
    28.         float _LightRadius;
    29.  
    30.         float _Roughness;
    31.  
    32.         float _FO;
    33.  
    34.      
    35.  
    36.         float specTrowbridgeReitz(float HoN,float a,float aP){
    37.  
    38.         float a2 = a*a;
    39.  
    40.         float ap2 = aP*aP;
    41.  
    42.         return ( a2 * ap2 ) / pow( HoN * HoN * ( a2 - 1.0 ) + 1.0, 2.0 );
    43.  
    44.         }
    45.  
    46.      
    47.  
    48.         float visSchlickSmithMod( float NoL, float NoV, float r )
    49.  
    50.        {
    51.  
    52.        float k = pow( r * 0.5 + 0.5, 2.0 ) * 0.5;
    53.  
    54.        float l = NoL * ( 1.0 - k ) + k;
    55.  
    56.        float v = NoV * ( 1.0 - k ) + k;
    57.  
    58.        return 1.0 / ( 4.0 * l * v );
    59.  
    60.        }
    61.  
    62.      
    63.  
    64.        float fresSchlickSmith( float HoV, float f0 )
    65.  
    66. {
    67.  
    68.     return f0 + ( 1.0 - f0 ) * pow( 1.0 - HoV, 5.0 );
    69.  
    70. }
    71.  
    72.      
    73.  
    74.        float sphereLight(float3 pos,float3 N,float3 V,float3 r,float f0,float roughness,float NoV,out float NoL){
    75.  
    76.        float3 L = _LightPos - pos;
    77.  
    78.        float3 centerToRay = dot(L,r)*r-L;
    79.  
    80.        float3 closestPoint = L + centerToRay * clamp( _LightRadius / length( centerToRay ), 0.0, 1.0 );
    81.  
    82.        float3 l = normalize(closestPoint);
    83.  
    84.        float3 h = normalize(V+l);
    85.  
    86.        NoL = clamp(dot(N,l),0.0,1.0);
    87.  
    88.        float HoN = clamp(dot(h,N),0.0,1.0);
    89.  
    90.        float HoV = dot(h,V);
    91.  
    92.      
    93.  
    94.        float distL = length(L);
    95.  
    96.        float alpha = roughness * roughness;
    97.  
    98.        float alphaPrime = clamp(_LightRadius/(distL*2.0)+alpha,0.0,1.0);
    99.  
    100.      
    101.  
    102.        float specD = specTrowbridgeReitz( HoN, alpha, alphaPrime );
    103.  
    104.        float specF = fresSchlickSmith( HoV, f0 );
    105.  
    106.        float specV = visSchlickSmithMod( NoL, NoV, roughness );
    107.  
    108.      
    109.  
    110.        return specD * specF * specV*NoL;
    111.  
    112.        }
    113.  
    114.      
    115.  
    116.        float3 areaLights(float3 pos,float3 nor,float3 V){
    117.  
    118.        float roughness = _Roughness;
    119.  
    120.        float f0 = _FO;
    121.  
    122.      
    123.  
    124.      
    125.  
    126.      
    127.  
    128.        float NoV = clamp(dot(nor,V),0.0,1.0);
    129.  
    130.        float3 r =reflect(-V,nor);
    131.  
    132.      
    133.  
    134.        float NdotLSphere;
    135.  
    136.        float specSph = sphereLight(pos,nor,V,r,f0,roughness,NoV,NdotLSphere);
    137.  
    138.        float3 color = 0.3183*(NdotLSphere*_LightColor)+(specSph*_LightColor)+UNITY_LIGHTMODEL_AMBIENT;
    139.      
    140.  
    141.        return pow(color,float3(1.0/2.2));
    142.  
    143.      
    144.  
    145.        }
    146.  
    147.      
    148.  
    149.         struct vertexInput{
    150.  
    151.         float4 vertex:Position;
    152.  
    153.         float3 normal:NORMAL;
    154.  
    155.         };
    156.  
    157.      
    158.  
    159.         struct vertexOutput{
    160.  
    161.         float4 pos:SV_POSITION;
    162.  
    163.         float4 posInW:TEXCOORD0;
    164.  
    165.         float3 N : TEXCOORD1;
    166.  
    167.         };
    168.  
    169.      
    170.  
    171.         vertexOutput vert(vertexInput i){
    172.  
    173.         vertexOutput o;
    174.  
    175.         o.pos = mul(UNITY_MATRIX_MVP,i.vertex);
    176.  
    177.         o.N = normalize(float3(mul(float4(i.normal,0.0),_World2Object)));
    178.  
    179.         o.posInW = mul(_Object2World,i.vertex);
    180.  
    181.         return o;
    182.  
    183.         }
    184.  
    185.      
    186.  
    187.         float4 frag(vertexOutput i):COLOR{
    188.  
    189.         float3 N = normalize(i.N);
    190.  
    191.      
    192.  
    193.         float3 viewDir = normalize(_WorldSpaceCameraPos-float3(i.posInW));
    194.  
    195.      
    196.  
    197.         float3 color = areaLights(i.posInW,N,viewDir);
    198.  
    199.         return float4(color,0.0);
    200.  
    201.      
    202.  
    203.         }
    204.  
    205.         ENDCG
    206.  
    207.     }
    208.  
    209.     }
    210.  
    211.     FallBack "Diffuse"
    212.  
    213. }
    214.  
    215.  
    $Screenshot.png

    If you have any questions feel free to ask :)
     
    Last edited: Aug 21, 2014
  2. carking1996

    carking1996

    Joined:
    Jun 15, 2010
    Posts:
    2,605
    Screenshots? :)
     
  3. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Sorry its not much to look at, have not had time to make it look pretty $Screenshot.png
     
  4. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Also no attenuation yet(Im working on it ;))
     
  5. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    It doesn't work, i copied it but there are a few errors, i fix them but nothing is rendered
     
  6. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Have you put the c# script on a sphere and the shader on the objects you want the light to affect? If so and its still not working,what version of unity are you using and what OS are you running? Also what are the errors your getting,I don't get any.
     
    Last edited: Sep 21, 2014
  7. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    i think the problem is that i use unity 4, i see now the #target 3.0
     
  8. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    i get error in this line:
    return pow(color,float3(1.0/2.2));
     
  9. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    Never mind, solved it, there were a few cast that are not valid anymore in 4.0 (i think).

    I tried all day to do it, and i tought mine was wrong...but now that i have yours, i removed from it all the diffusion, intensity etc, and it is exactly like mine^^
    Thanks man, great job, and you made me realize that i didn't waste my afternoon^^
     
    Last edited: Sep 23, 2014
  10. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Could you send me your version as after downloading unity 4.6(shader was made in 4.3) my one doesn't work,thanks;)
     
  11. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    I'm using yours now (cause i don't want to implement diffuse effects et cetera), i just changed a few lines....for example, if you do:

    float3(some_float4_data)

    now change it into

    some_float4_data.xyz
     
  12. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Thanks,unity's shaders can be so annoying;) BTW before this happened I was working on attenuation and multiple lights,it was while fiddling with multiple lights that I broke the project;) I more or less know what to do now,should have it working by the end of this week.
     
  13. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    ok thanks^^ though it is still not correct, or at least not the way i'd like it...i'd like something like a pure mirror reflection, our version has a few problem, for example if you lower the view direction, the reflection shrink, but the width should remain the same (i hope i explained well)
     
  14. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    For a complete mirror that's easy,just take out the diffuse bits from the shader and only include the specular,also put the roughness really low(not 0 as that causes issues, but something like 0.01,I'll probably add texture maps to the shader eventually to enable you to choose this depending on texture color.
     
  15. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    the point i'm trying to make, is that if you completely remove everything but the specular, which i did, the reflection as i want it, is not perfect...the angle of "distortion" of the reflaction is not right when the sphere is at the border of the screen, and if the angle between normal and view direction is high, the reflected image shrink ina odd way
    http://cdn.homedit.com/wp-content/uploads/2011/06/floating-sphere-light-slide-1.jpg
    look at this image. I would like a reflection like that (but i chose a S***ty image to make my point, cause with that orientation, our shader it's ok)
     
  16. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Try playing with the FO value in the material,other than that it could be in the code itself,I don't claim to understand the algorithm,I simply ported it from here
    do you need something like this? F0 = 1 roughness = .002
     

    Attached Files:

    • test.png
      test.png
      File size:
      131 KB
      Views:
      1,327
  17. Ceffa93

    Ceffa93

    Joined:
    Dec 2, 2013
    Posts:
    46
    i played with it, but it's not entirely correct^^ if you remove all the irrelevant stuff like diffusion, the remaining reflection is not matematically correct, it has a few flow...when you add diffusion, intensity and other stuff, the effect is pretty good, but there is still something wrong at the base....i understand why it behave like that, but i don't know how to fix it^^
     
  18. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Well this is an approximation and not physically accurate,as explained in unreal engines paper on it,so its understandable why it doesn't look completely "right".
     
  19. viru7

    viru7

    Joined:
    Sep 8, 2016
    Posts:
    1
    Hi, I am working with Unity 5 and facing some errors with script above. Would you mind sharing the updated Shader script if you have one. Thanks
     
  20. JecoGames

    JecoGames

    Joined:
    Jan 10, 2013
    Posts:
    135
    Sorry for late reply, haven't worked on this in 2 years so I don't currently have an up to date script and won't for awhile as I am currently in my final year in school and super busy "studying". I should be able to work on this again after June anyways.