Unity Shaders学习笔记之为创建自定义慢反射光照模型

Posted 程序员小毛驴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shaders学习笔记之为创建自定义慢反射光照模型相关的知识,希望对你有一定的参考价值。

一、简介

  Lambert的光照模型是一个很经典的漫反射模型,光强与入射光的方向和反射点处表面法向夹角的余弦成正比。简单解释就是一个点的反射光强是和该点的法线向量和入射光向量和强度和夹角有关系的,其结果就是这两个向量的点积。光照模型的计算是在surf方法的表面着色之后,根据输入的光照条件,对原来的颜色在这种光照下的表现进行计算,最后输出新的颜色值给渲染单元完成在屏幕的绘制自定义光照模型,需要先定义一个计算光照的函数,名称格式为Lighting<Your Chosen Name>,然后在声明处使用声明:#pragma surface s1 CustomDiffuse。

二、如何操作

修改上一节的代码【Unity Shaders】学习笔记之为表面着色器添加属性(四) 1.将#pragma标记修改为如下代码: #pragma surface surf BasicDiffuse

2.在SubShader中加入如下代码:
inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten)

	float difLight = max(0, dot (s.Normal, lightDir));
	float4 col;
	col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
	col.a = s.Alpha;
	return col;


 3.返回到unity窗口,着色器会自动编译。如果没问题,你可以看到材质已经发生了些的变化。
修改前:

修改后:

三、实现原理

 #pragma surface指令告诉着色器将使用哪个光照模型来计算。在我们创建的第一个着色器代码里,默认使用Lighting.cginc文件里包含的Lambert光照模型,所以可以使用这种光照模型来计算。

half4 LightingName(SurfaceOutput s, fixed3 lightDir, fixed atten)

该函数用于不需要视角方向的前向着色

half4 LightingName(SurfaceOutput s, fixed3 lightDir, half3 viewDir,fixed atten)

该函数用户需要视角方向的前向着色

half4 LightingName(SurfaceOutput s, half4 light)

该函数用于需要使用延迟着色的项目

点积函数是cg语言的另一个内置数学函数,我们可以用它来比较两个向量在空间里的方向。点积函数会检查两个向量是互相平行还是互相垂直。任意两个向量都可以通过点积函数获得-1~1的夹角范围,-1表示平行向量并背离你的方向,1表示平行向量,不过是朝着你的方向,0表示和你垂直的方向向量。

为了完成漫反射计算,我们需要将Unity和SurfaceOutput结构体提供我们的数据做乘法运算。为此我们需要乘上s.Albedo和_LightColor0.rgb然后再将结果与difLight * atten相乘,最后返回这个值做颜色值。

四、实现原理

 通过cg标准库中的max函数,我们可以限制点积函数的计算结果。max函数采用两个参数max(arg1,arg2),我们在着色器里使用max函数来确保漫反射的计算结果永远介于0和点积最大值之间。这样你就永远不会得到小于0的值,更不会是-1,否则可能会在你的着色器生成极度黑色区域,并且在之后的运算中容易出现问题。

  在cg标准库函数里还有一个类似的saturate函数,可以帮助我们将浮点值限制在0~1。saturate(和max)两者唯一的区别是saturate可以直接将浮点值转换称饱和度。max函数包含两个参数并返回二者之间的最大值


本章参考《Unity Shaders and Effects Cookbook》一书,感谢原书作者提供的学习资料

以上是关于Unity Shaders学习笔记之为创建自定义慢反射光照模型的主要内容,如果未能解决你的问题,请参考以下文章

Unity Shaders学习笔记——渲染管线

Unity Shaders学习笔记——SurfaceShader认识结构

Unity Shaders学习笔记——SurfaceShaderBasicDiffuse和HalfLambert

Unity Shaders学习笔记——SurfaceShader混合纹理

Unity Shaders学习笔记——SurfaceShader法线贴图

Unity Shaders学习笔记——SurfaceShader用纹理改善漫反射