zoukankan      html  css  js  c++  java
  • 一些光照模型

    1.  Lambert

    Diffuse Light

    与视角无关

    float NdotL = max(0.0, dot(s.Normal, lightDir));
    float4 finalColor;
    finalColor.rgb = s.Albedo * _LightColor0 * NdotL;
    finalColor.a = s.Alpha;
    return finalColor;


     折叠源码
    fixed diff = max(0, dot(s.Normal, lightDir));
     
    fixed4 c;
    c.rgb = s.Albedo * _LightColor0 * diff * atten;
    c.a = s.Alpha;
    return c;



    2. Half-Lambert

    半条命起源

    可以看清物体暗的部分的形状,因此物体显得更加扁平

    float NdotL = max(0.0, dot(s.Normal, lightDir));
    float HalfLambertDiffuse = pow(NdotL * 0.5 + 0.5, 2.0);
    float4 finalColor;
    finalColor.rgb = s.Albedo * _LightColor0 * HalfLambertDiffuse * atten;
    finalColor.a = s.Alpha;
    return finalColor;



    3. Phong

    表现高光效果

    diffuse light and specular light

    float NdotL = max(0, dot(s.Normal, lightDir));
     
    float3 lightReflectDirection = reflect(-lightDir, s.Normal);
    float RdotV = max(0, dot(lightReflectDirection, viewDir));
    float spec = pow(RdotV, _SpecPower/4) * _SpecularColor;
     
    float4 color;
    color.rgb = (s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec) * atten;
    color.a = s.Alpha;
    return color;



    4. Blinn-Phong

    建立在Phong的基础上。Phong计算light reflection vector ,而Blinn计算Half Direction替之,即灯光方向和视角方向的半角向量。
    好处是高光更加柔和。

    float NdotL = max(0, dot(s.Normal, lightDir));
     
    float3 halfVector = normalize(lightDir + viewDir);
    float NdotH = max(0, dot(s.Normal, halfVector));
    float spec = pow(NdotH, _SpecPower) * _SpecularColor;
     
    float4 color;
    color.rgb = (s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec) * atten;
    color.a = s.Alpha;
    return color;


    5. PBR

    完全基于物理的



    6. Banded-lighting

    将连续的灯光变为离散的一段一段的

    float NdotL = max(0.0, dot(s.Normal, lightDir));
     
    float lightBandsMultiplier = _LightSteps / 256;
    float lightBandsAdditive = _LightSteps / 2;
    fixed bandedNdotL = (floor((NdotL * 256 + lightBandsAdditive) / _LightSteps))
        * lightBandsMultiplier;
     
    float3 lightingModel = bandedNdotL * s.Albedo;
    float3 attenColor = atten * _LightColor0.rgb;
    float4 finalDiffuse = float4(lightingModel * attenColor, 1);
    return finalDiffuse;

    7. Minnaert

    特别适合天鹅绒或月亮,这类多孔可渗透性或纤维状的表面,这类表面会导致大量光反向散射

    float3 viewDirection = viewDir;
    float NdotL = max(0, dot(s.Normal, lightDir));
    float NdotV = max(0, dot(s.Normal, viewDirection));
     
    float3 minnaert = saturate(NdotL * pow(NdotL*NdotV, _Roughness));
     
    float3 lightingModel = minnaert * s.Albedo;
    float3 attenColor = atten * _LightColor0.rgb;
    float4 finalDiffuse = float4(lightingModel * attenColor, 1);
    return finalDiffuse;


    8. Oren–Nayar

    Lambert 光照模型,是一个让光线向各个角度都均匀辐射的模型。这个均匀实在太不可思议了,真实物体表面理应不是这样的。

    在灯光方向不变的情况下,观察物体的角度不同,物体表面光强、颜色也会发生变化(一般粗糙物体正光光强比背光光强要强)。就是光线向各个角度并非均匀辐射。

    Oren-Nayar model 这个主要来自于Michael Oren和Shree K. Nayar在SIGGRAPH94上发表的论文Generalization of Lambert’s Reflectance Model。里面通过统计的等手段总结出比较接近真实粗糙表面的数学公式

    http://www1.cs.columbia.edu/CAVE/publications/pdfs/Oren_SIGGRAPH94.pdf

    float roughness = _Roughness;
    float roughnessSqr = roughness * roughness;
    float3 o_n_fraction = roughnessSqr / (roughnessSqr + float3(0.33, 0.13, 0.09));
    float3 oren_nayar = float3(1, 0, 0) + float3(-0.5, 0.17, 0.45) * o_n_fraction;
    float3 viewDirection = viewDir;
    float cos_ndotl = saturate(dot(s.Normal, lightDir));
    float cos_ndotv = saturate(dot(s.Normal, viewDirection));
    float oren_nayar_s = saturate(dot(lightDir, viewDirection)) - cos_ndotl * cos_ndotv;
    oren_nayar_s /= lerp(max(cos_ndotl, cos_ndotv), 1, step(oren_nayar_s, 0));
     
     
    //lighting and final diffuse
    float attenuation = atten;
    float3 lightingModel = s.Albedo * cos_ndotl * (oren_nayar.x + s.Albedo * oren_nayar.y + oren_nayar.z * oren_nayar_s);
    float3 attenColor = attenuation * _LightColor0.rgb;
    float4 finalDiffuse = float4(lightingModel * attenColor, 1);
    return finalDiffuse;


  • 相关阅读:
    代码示例_触摸屏驱动
    代码示例_中断下半部
    代码示例_mmap的实现
    代码示例_阻塞IO
    代码示例_LCD控制
    代码示例_平台总线
    驱动_I2c驱动框架
    驱动_Input输入子系统
    Windows切换桌面或窗口快捷键
    几何分布
  • 原文地址:https://www.cnblogs.com/CloudLiu/p/10855354.html
Copyright © 2011-2022 走看看