unity中光照模型和光照計算

光源類型

  • 方向光:Directional
  • 點光源:Point
  • 聚光燈:Spot

光照模型

每一種類型的光源都可能同時會有以下光照模型:
- Diffuse:漫反射
- Specular:鏡面反射

光照衰減

  • 方向光:沒有衰減
  • 點光源
    • 距離衰減:光源有光照範圍[near,far],在near距離內的光照係數爲1,在far距離外的光照係數爲0,在該兩者之間的頂點會隨距離進行衰減,光照強度與距離的平方成反比。Unity中的計算方式爲:DisAtten = 1/(1 +atten*atten * dis * dis),其中atten是衰減係數,dis是到光源的距離
  • 聚光燈
    • 距離衰減:與點光源一樣
    • 聚光衰減:除了距離衰減,聚光燈還有圓錐內的衰減。聚光燈的光照區域是個圓錐體,該圓錐體有外錐角A和內錐角B,在內錐角內的頂點無聚光衰減,在外錐角外的點無光照效果,光照係數。在內外錐角之間的頂點會進行衰減。假設頂點與光照方向的夾角爲C。則其聚光衰減係數爲:Spot = (cos(C/2) - cos(A/2)) / (cos(B/2) - cos(A/2))
    • 最終的衰減係數爲:FinalAtten = DisAtten * SpotAtten。

光照計算

最終光照結果是所有光照成分的總和 = 環境光 + 自發光+ sum(漫反射)+sum(鏡面反射)。

  • 環境光:AmbitentColor * AmbientMaterial * AmbientIntensity
  • 自發光:EmissionColor * EmissionIntensity
  • 漫反射:LightColor * DiffuseMaterial * DiffuseIntensity * dot(N,L) 。N是法線方向,L是指向光源的方向向量。以下方式計算法線N和L的點積(即夾角餘弦)
  • 鏡面反射:LightColor * SpecularMaterial * SpecularIntensity * pow(dot(R,V),shininess),其中R是反射光的方向,V是頂點到眼睛的方向。
  • 強度intensity默認都是1。SpecularMaterial默認都是1。
  • 計算函數
@ lightPostion:平行光(-direction,0)    點光源和聚光燈(position,1)
@ lightColor:燈光顏色
@ eyePos:頂點在相機空間的座標
@ eyeyNormal:頂點在相機空間的法線
@ viewDir:頂點到相機的方向
@ diffuseMaterial:漫反射材質係數
@ specularMaterial:鏡面反射材質係數,unity中不設置,默認爲1
@ shininess:鏡面反射高亮度,[0,1]
@ atten:反射增強係數
@ specColor:鏡面反射結果
@ return:漫反射結果
half computeLighting(float4 lightPostion,half3 lightColor,
                float3 eyePos,half3 eyeNormal,half3 viewDir,
                half3 diffuseMaterial,half3 specularMaterial,half shininess,
                half atten,inout half3 specColor)
{

    float3 dirToLight = lightPostion //光照方向的反向
    if(lightPostion.w == 1)
    {
        dirToLight -= eyePos
        dirToLight = normalize(dirToLight)
    }
    half NdotL = max(dot(eyeNormal,dirToLight),0)
    half3 diffse = lightColor * diffuseMaterial * atten
    if(NdotL > 0)
    {
        half3 h = normalize(dirToLight + viewDir)
        half HdotN = max(dot(eyeNormal,h),0)
        half sp = saturate(pow(HdotN,shininess * 128))
        half3 specular = atten * lightColor * specularMaterial * sp
        specColor += specular
    }

    return diffse
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章