当前位置:   article > 正文

unity3D Shader<三>漫反射_surface surf lambert 公式

surface surf lambert 公式

一、漫反射的说明

         对于粗糙物体表面的某一点,其亮度应该和入射光线与该点的垂直程度有关,也就是入射光线与此点的夹角相关。如果我们用L表示单位长度的入射光线,用C表示到达此点的光线强度和颜色,用N表示此点的发线,那么物体表面此点的亮度Lum就可以用下面的公式来表示:

         Lum = C * max(0,cos<L,N>)

         <L,N>表示的是方向矢量L和N之间的夹角,其cos就是这两个方向的点乘积,在unity通过Cg的标准函数库dot(L,N)来完成。这个值对于背向光线的点来说为负,其实就是对其照明为0,因此使用标准函数库中的max(0,value)来对结果进行一些控制。计算到此为此我们叫按照这种方式对物体进行照明计算的模型叫做Lambert。

对应的代码段为#pragma surface surf Lambert。

(注意,这个Lambert可以命名为其他的名字,相应的写光照模型函数时,其命名也要改变比如Unity内置三个Lighting Model函数,

如果用#pragma surface surf Lambert命名光照模型函数的话

这三个的函数名为

              half4 LightingLambert(SurfaceOutput s, half3 lightDir, half atten){} 

      这个函数被用于forward rendering(正向渲染),但是不需要考虑view direction(观察角度)时。

    • [plain]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
      1. half4 LightingLambert (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten){}  

      这个函数被用于forward rendering(正向渲染),并且需要考虑view direction(观察角度)时。
    • [plain]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
      1. half4 LightingLambert_PrePass (SurfaceOutput s, half4 light){}  

      这个函数被用于需要使用defferred rendering(延迟渲染)时。

如果用#pragma surface surf BasicDiffuse命名,则后面书写这些函数时,就如下面所示

half4 LightingBasicDiffuse

half4 LightingBasicDiffuse_PrePass


二、具体漫反射代码

  1. Shader "Custom/MyLightTest" {
  2. Properties {
  3. _EmissiveColor("自发光的颜色:",Color) = (1,1,1,1)
  4. _AmbientColor("环境光的颜色:",Color) = (1,1,1,1)
  5. _Change("改变的值:",Range(0,10)) = 2.5
  6. }
  7. SubShader {
  8. Tags { "RenderType"="Opaque" }
  9. LOD 200
  10. CGPROGRAM
  11. #pragma surface surf BasicDiffuse
  12. //对上面一行的解释
  13. //surface - 声明的是一个表面着色器
  14. //surf - 着色器代码的方法的名字
  15. //Lambert - 使用的光照模型。
  16. //规则#pragma surface surfaceFunction lightModel [optionalparams]
  17. //surface - 声明的是一个表面着色器
  18. //surfaceFunction - 着色器代码的方法的名字
  19. //lightModel - 使用的光照模型。
  20. //#pragma surface surf BasicDiffuse 自定义了光照模型为BasicDiffuse,
  21. //下面的函数为实现这个自定义的光照模型,函数命名规则为Lightin加上自定义的自定义的光照模型名称
  22. inline float4 LightingBasicDiffuse (SurfaceOutput s,fixed3 lightDir,fixed atten)
  23. {
  24. //漫反射光的公式:I = Aintensity*Acolor + Dintensity*Dcolor *N.L
  25. //前面的Aintensity*Acolor是环境光的公式(得到场景中光源的颜色)
  26. float difLight = max(0,dot(s.Normal,lightDir));//这里相当于漫反射公式的N.L
  27. float4 col;
  28. //_LightColor0.rgb(Unity提供)光源颜色
  29. //s.Albedo为当前材质反射率(从surf函数计算后输出)
  30. //atten表明了光线的衰减率根据DX中的衰减定义,这是固定衰减
  31. //这里用的乘法公司 物体自身的镜面放射*场景中光源的颜色*漫反射强度*衰减率*自行修改的值
  32. col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
  33. col.a = s.Alpha;
  34. return col;
  35. }
  36. sampler2D _MainTex;
  37. float4 _EmissiveColor;
  38. float4 _AmbientColor;
  39. float _Change;
  40. struct Input {
  41. float2 uv_MainTex;
  42. };
  43. void surf (Input IN, inout SurfaceOutput o) {
  44. float4 c = pow((_EmissiveColor + _AmbientColor),_Change);
  45. o.Albedo = c.rgb;
  46. o.Alpha = c.a;
  47. }
  48. ENDCG
  49. }
  50. FallBack "Diffuse"
  51. }



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/107859
推荐阅读
相关标签
  

闽ICP备14008679号