固定功能shader,表面shader,顶点片段shader 的输入输出元素集总结

元素集是我自己造的词,因为发现像固定管线的Material,surface和顶点shader里面的函数输入和输出的结构体很难记,所以写这篇总结下

固定功能着色器

关于固定功能着色器的输入,个人认为难记的在这里,当然在之前的博客也提到过

Material     
            {    
                Diffuse [_Color]  <span style="white-space:pre">      </span>//漫反射颜色块  
                Ambient [_Color]  <span style="white-space:pre">      </span>//环境光颜色块,通常和漫反射颜色是同一个  
                Shininess [_Shininess]  <span style="white-space:pre">    </span>//光泽度,用来指定光斑(镜面高光照亮的部分)的大小,其值约大,光斑越小,反之则越大,要在SeparateSpecular On时才会有效  
                Specular [_SpecColor]  <span style="white-space:pre">     </span>//镜面高光的颜色,一般只影响光斑部分颜色  
                Emission [_Emission]  <span style="white-space:pre">      </span>//光泽颜色,会影响整个贴图,影响甚至比_Color要大  
            }  


固定功能着色器的输出,是由SetTexture决定,可参考 http://blog.csdn.net/u013833399/article/details/47424379

表面着色器

这个输入结构体可以自己定义,不过还是用它的语义词,这些语义词都是规定了的

</pre><pre name="code" class="csharp">
<pre name="code" class="csharp"><pre name="code" class="csharp">struct Input     
        {    
        float2 uv_MainTex;//主纹理的uv值
        float2 uv_BumpMap;//凹凸纹理的uv值
        float2 uv_Detail;//细节纹理的uv值
        float3 viewDir;//当前坐标的视角方向,可以用作computing Parallax effects(计算视差效果,这个我不懂)和边缘光照
	float4 color:Color;//每个顶点的颜色,带语义词Color
	float4 screenPos;//屏幕空间中的位置,为了做反射或者屏幕空间效果。对这个,我不是很确定,估计是二维的,就是在屏幕上的xy,错了再修改
	float4 worldPos;//世界空间的坐标,就是指那个顶点的世界空间坐标,就是原object控件乘以UNITY_MATRIX_M的变换矩阵,
	float3 worldRefl;//世界空间中的反射向量,如果表面着色器不写入o.normal,就包含这个参数。官网是请参考Reflect-Diffuse 的例子。其实这个是,当我的surf函数不写入o.normal的时候使用的,可以用来做cubemap 的反射,就是反射周围的环境,例如这个函数o.Emission = texCUBE (_Cube, IN.worldRefl).rgb;
	float3 worldRefl; INTERNAL_DATA//这个是当我要写入o.normal 的时候会包含世界空间的反射向量。想一想就是,原先不写入o.normal的时候,法线其实是可以自己计算出来的,但是效果不好,所以worldRefl可以马上得到。但是如果写入了o.normal,就是外来的法线贴图的话(一般都是,因为发现贴图可以产生很强的凹凸感觉,效果很棒),worldRefl1就需要重新计算,所以需要加个INTERNAL_DATA,至于具体意思我就不清楚了。在surf函数里面得到有外来法线输入的世界空间的反射向量,用WorldReflectionVector (IN, o.Normal)计算得到。
	float3 worldNormal; INTERNAL_DATA//这个与上面类似,写入o.normal时包含世界空间的法线向量。根据官网的说法,就是,得到基于每个顶点的法线贴图的法线向量,其实就是外来的normlmap取出法线向量来。要取出得用这个函数, WorldNormalVector (IN, o.Normal),要先写入o.normal才能取。
};


 前面这些带uv 的都是要有外面的输入的定义,如Sample2D _MainTex; 

输出

struct SurfaceOutput
{
    fixed3 Albedo;  // 反射率,就是颜色值,一般可以添加纹理颜色,细节纹理,渐变色等等
    fixed3 Normal;  // 法线,可以用法线贴图来添加
    fixed3 Emission;//自发光颜色,这个很强悍可以大范围的改变颜色,用法官网有反射cube(texCUBE (_Cube, IN.worldRefl).rgb;)和边缘高光(o.Emission = _RimColor.rgb * pow (rim, _RimPower);)两种
    half Specular;  // 镜面反射度,这个网上的资料都比较简短。自己去了解了下,其实这个是规定整个镜面反射的范围,越小,则产生镜面反射度点越多。它的范围是0.01-1或者前面更小一点,但是不要到0,到0会导致一些区域变黑,查了光照模型函数也不知道为什么
    fixed Gloss;    // 光泽度,我理解为反射的力度,1为最强,0为最弱。可以模拟金属生锈的过程。这个是区域一起变化的效果,就是说反射的中间区域和外面区域并无区别
    fixed Alpha;    // 透明度
};
对于Specular和Gloss的理解,cginc的函数是这段代码
float spec = pow (nh, s.Specular*128.0) * s.Gloss;
fixed4 c;
c.rgb = s.Albedo * light.color * diff + light.color * _SpecColor.rgb * spec;


新版untiy5还有另外的两种形式

struct SurfaceOutputStandard
{
    fixed3 Albedo;      
    fixed3 Normal;      
    half3 Emission;
    half Metallic;      // 1.
    half Smoothness;    // 2.
    half Occlusion;     // 3
    fixed Alpha;       
};
1.Metallic参数
金属度。范围0-1,越大则表相处越强的金属度,可以反射外面的颜色,反之,则体现出自己的颜色。

2.Smoothness

光滑度。范围0-1,越大则越光滑,反射光就越集中,产生光斑。反之则越粗糙,颜色趋于相同,光斑消失。

3.Occlusion

封闭图灰度值。封闭图就是一张灰度图。用来表示接受来自ambient和reflect的间接光照权重,值越大(约白)接受越多,所以有些衣服里面的就变暗咯。


对于Metallic和Smoothness,我自己实验了下。确实可以反射环境的颜色。但是,只有天空盒和光源可以反射,如果旁边有物体,我实验是没有显示出来。

贴图为证。


灯光设为粉色。metallic和smooth都设为1,就是说,最大化显示环境颜色。不过只是反射了天空盒的样子。我怀疑是它是用cubemap弄的。


关于occlusion,有输入输入的话,就像下图模型的脖子那里,可以显示较暗的颜色


还有一种输出,StandardSpecular

struct SurfaceOutputStandardSpecular
{
    fixed3 Albedo;      
    fixed3 Specular;    //镜面反射的颜色
    fixed3 Normal;      
    half3 Emission;
    half Smoothness;    
    half Occlusion;     
    fixed Alpha;        
};


顶点片段着色器

输入
可以选择默认形式,也可以自己写
struct appdata_base {
	float4 vertex : POSITION;//空间顶点坐标
	float3 normal : NORMAL;//空间法线坐标
	float4 texcoord : TEXCOORD0;//第一张纹理贴图的uv值,下面的<span style="font-family: Arial, Helvetica, sans-serif;">TEXCOORD1...类推</span>
};

struct appdata_tan {
	float4 vertex : POSITION;
	float4 tangent : TANGENT;//切线值,表示贴图uv在模型上du的体现,就是横向方向上的体现
	float3 normal : NORMAL;
	float4 texcoord : TEXCOORD0;
};

struct appdata_full {
	float4 vertex : POSITION;
	float4 tangent : TANGENT;
	float3 normal : NORMAL;
	float4 texcoord : TEXCOORD0;
	float4 texcoord1 : TEXCOORD1;
	float4 texcoord2 : TEXCOORD2;
	float4 texcoord3 : TEXCOORD3;
#if defined(SHADER_API_XBOX360)
	half4 texcoord4 : TEXCOORD4;
	half4 texcoord5 : TEXCOORD5;
#endif
	fixed4 color : COLOR;//这个官网的例子不清楚,我试验默认都是1.
};


输出
fixed4向量
顶点片段着色器的输出比较简单,就只要输出一个fixed4的向量就可以了。不过中间纷繁复杂的计算过程就要自己设计咯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值