在上一篇,学会了怎么使用ShaderLab 语法:Properties,这一次,我们将会使用属性值点亮材质球。
1:Delete>sampler2D _MainTex;
2:1行位置Add>
float4 _EmissiveColor; float4 _AmbientColor; float _MySliderValue;
以上3个变量都要和Properties中申明的书写一致,保证值得正确引用匹配,此处一定要用复制。
接下来,在surf中使用这些变量传递过来的值。
3:surf方法稍作修改
void surf (Input IN, inout SurfaceOutput o) { float4 c; c=pow((_EmissiveColor+_AmbientColor),_MySliderValue); o.Albedo = c.rgb; o.Alpha = c.a; }
接下来,就可以在gui上直接调整参数。
此处用到的pow(arg1,arg2)是自带的函数,相当于数学中的求幂power。
完成的shader代码应该如下:
//code start----------------------------------------------------------------------------------
Shader "91YGame/BasicMyDiffuse" { Properties { _EmissiveColor("Emissive Color",Color) = (1,1,1,1) _AmbientColor("Ambient Color",Color)=(1,1,1,1) _MySliderValue("Slider Value",Range(0,10))=1.3 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert float4 _EmissiveColor; float4 _AmbientColor; float _MySliderValue; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float4 c; c=pow((_EmissiveColor+_AmbientColor),_MySliderValue); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
//code end----------------------------------------------------------------------------------
通过以上的学习,我们可以更深刻的理解到,在Properties中申明一个属性后,就为着色器提供了一种从gui获得属性值的方法。
这些值会传递给SubShader 中的同名变量中,所以我们也就可以在surf中直接使用设置的值,通过上面的步骤,我们完成了最基础的漫反射组件。
SurfaceOutput 是表面着色器(Surface Shader)的标准输出结构是这样的:
struct SurfaceOutput { half3 Albedo; //反射率 half3 Normal; //法线 half3 Emission; //自发光,用于增强物体自身的亮度,使之看起来好像可以自己发光 half Specular; //镜面 half Gloss; //光泽 half Alpha; //透明 };
后面,我们将会经常使用这个结构体。
既然的有输出,也就有入。常见的输入结构使用值如下:
输入结构 Input
通常具有着色器所需的所有纹理坐标。纹理坐标必须被命名为纹理名称前加“uv
”(或以“uv2
”开头以使用第二纹理坐标集)。
其他能放入 Input 结构中的值:
float3 viewDir
- 将包含视线方向,用于计算视差 (Parallax) 效果、边缘光照等。float4 (COLOR)
语义的 float4
- 将包含插值逐顶点颜色。float4 screenPos
- 将包含反射效果的屏幕空间位置。例如,在 Dark Unity 中由 WetStreet 着色器 (WetStreet Shader) 使用。float3 worldPos
- 将包含世界坐标空间位置。float3 worldRefl
- 将包含世界坐标反射向量,条件是表面着色器不写入 o.Normal。具体示例可见反射 - 漫反射着色器 (Reflect-Diffuse Shader)。float3 worldNormal
- 将包含世界坐标法线向量,条件是表面着色器不写入 o.Normal。float3 worldRefl; INTERNAL_DATA
- 将包含世界坐标反射向量,条件是表面着色器写入 o.Normal。要基于逐像素法线贴图获得反射向量,请使用 WorldReflectionVector (IN, o.Normal)
。具体示例可见反射 - 凹凸着色器 (Reflect-Bumped Shader)。float3 worldNormal; INTERNAL_DATA
- 将包含世界坐标法线向量,条件是表面着色器写入 o.Normal。要基于逐像素法线贴图获得法线向量,请使用 WorldNormalVector (IN, o.Normal)
//更多内容 ,参见蛮牛api:
http://www.unitymanual.com/m/Components/SL-SurfaceShaders.html