Unity Shader 学习笔记(7) 高光反射

来源:互联网 发布:无主之地2mac 编辑:程序博客网 时间:2024/05/02 04:24

Unity Shader 学习笔记(7) 高光反射

参考书籍:《Unity Shader 入门精要》
3D数学 学习笔记(8) 光照

Phong模型的逐顶点、逐像素,和Blinn模型对比:


Phong模型


逐顶点光照(Gouraud shading,高洛德着色)

Properties {    _Diffuse ("Diffuse",Color) = (1,1,1,1)    _Specular ("Specular",Color) = (1,1,1,1)    // 反射颜色    _Gloss ("Gloss",Range(8.0,256)) = 20        // 高光区域大小}

Pass中关键代码:

struct a2v {    float4 vertex : POSITION;    float3 normal : NORMAL;};struct v2f {    float4 pos : SV_POSITION;    fixed3 color : COLOR0;};v2f vert (a2v v){    v2f o;    o.pos = UnityObjectToClipPos(v.vertex);    // 下面这块是逐顶点漫反射,详见上一篇。    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;    fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);    fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));    // 计算获得出射方向r。reflect:发射方向,CG提供的函数。worldLightDir是光照方向,与L方向相反。    fixed reflectDic = normalize(reflect(-worldLightDir,worldNormal));    // 视觉方向v。即相机到物体的向量归一化。    // 等价UnityWorldSpaceViewDir(mul(unity_ObjectToWorld,v.vertex))    fixed viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld,v.vertex).xyz);    // 高光反射系数,Phong模型公式,假设只有一个平行光源_LightColor0。    fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDic,viewDir)),_Gloss);    o.color = ambient + diffuse + specular;    return o;}fixed4 frag(v2f i) : SV_Target {    return fixed4(i.color,1.0);}

逐像素光照(Phong shanding,Phong着色)

没有太大区别,只是把计算过程丢到了片元着色器。

struct v2f {    float4 pos : SV_POSITION;    float3 worldNormal : TEXCOORD0;    float3 worldPos : TEXCOORD1;};v2f vert (a2v v){    v2f o;    o.pos = UnityObjectToClipPos(v.vertex);    o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject);        o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;    return o;}fixed4 frag(v2f i) : SV_Target {    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;    fixed3 worldNormal = normalize(i.worldNormal);    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);    fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));    fixed reflectDic = normalize(reflect(-worldLightDir,worldNormal));    fixed viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);    fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDic,viewDir)),_Gloss);    return fixed4(ambient + diffuse + specular,1.0);}

Blinn光照模型

计算快于Phong模型。两种都是经验模型。一些情况下Blinn模型更符合实验结果。

直接修改上面Phong的逐片元代码即可。

// 视觉方向v//fixed viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));// 单位向量hfixed3 halfDir = normalize(worldLightDir + viewDir);// 套公式fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(worldNormal,halfDir)),_Gloss);

阅读全文
0 0
原创粉丝点击