高光反射计算公式(phong模型)Cspecular=(Clight*Mspecular)max(0,v*r)mgloss

mgloss为材质的官泽度,也成反射度,控制高光区域亮点有多大

Mspecular是材质的高光反射颜色,控制材质对于高光反射的轻度和颜色

Clight为光源的颜色和强度

v是观察方向的单位向量

r是反射方向 r=2(法线单位向量n*光源方向向量)法线单位向量-光源方向向量

高光反射计算公式(Blinn模型)Cspecular=(Clight*Mspecular)max(0,n*h)mgloss

n为法线向量的单位向量

h是对观察方向和光源方向取平均后归一化得到的:h(注:单位向量)=(v(注:单位向量)+光源方向)/|(v(注:单位向量)+光源方向)|

下面分别是逐顶点和逐像素两种写法

phong模型 逐顶点:

Shader "study/Chapter6/halfLambertShader" {
Properties{
_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
_Specular("Specular",Color)=(1,1,1,1)//控制材质高光反射颜色
_Gloss("Gloss",Range(8.0,256)) = 20 //用于控制高光区域的大小
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM #pragma vertex vert
#pragma fragment frag #include "Lighting.cginc" fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss; struct a2v{
float4 vertex:POSITION;
fixed4 normal:NORMAL;
};
struct v2f{
float4 pos:SV_POSITION;
fixed3 color:COLOR;
};
v2f vert(a2v v){ v2f o;
o.pos=UnityObjectToClipPos(v.vertex); fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
//内置函数写法,下面给出内置函数
//fixed3 worldNormal=normalize(UnityObjectToWorldNormal(v.normal););
fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject)); fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir)); //反射方向get the reflect direction in world space
fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal)); //get the view direction in world space
//世界空间下观察方向
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(unity_ObjectToWorld,v.vertex).xyz); //Computer specular term
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss); o.color=diffuse+ambient+specular; return o; }
fixed4 frag(v2f i):SV_Target{
return fixed4(i.color,1.0);
} ENDCG
}
}
FallBack "Specular"
}

  phong模型 逐像素:

Shader "study/Chapter6/SpecularPixelLevelShader"
{
Properties{
_Diffuse("Diffuse",Color)=(1,1,1,1)
_Specular("Specular",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8.0,256))=20
} SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "Lighting.cginc" fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss; struct a2v{
fixed4 vertex:POSITION;
fixed3 normal:NORMAL;
};
struct v2f{
fixed4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
}; v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//使用内置函数写法
//o.worldNormal = UnityObjectToWorldNormal(v.normal);
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(_WorldSpaceCameraPos.xyz);
//漫反射部分
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
//世界空间下反射光矢量
fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));
//视野方向
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
//高光
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss);
//最终观察到的光照
return fixed4(ambient+diffuse+specular,1.0);
}
ENDCG
}
}
FallBack "Specular"
}

  Blinn模型逐像素

Shader "study/Chapter6/BlinnPhongShader"
{
Properties{
_Diffuse("Diffuse",Color)=(1,1,1,1)
_Specular("Specular",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8.0,256))=20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss; struct a2v{ float4 vertex:POSITION;
float3 normal:NORMAL;
};
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{ float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
//内置函数写法
//float3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldNormal, worldLightDir));
//内置函数写法
//fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldNormal));
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
fixed3 halfDir=normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);
return fixed4(ambient+diffuse+specular,1.0);
}
ENDCG
}
}
FallBack "Specular"
}

  

unity的内置函数

仅用于前向渲染的只有在渲染模式为前向渲染时(“LightMode”=“ForwordBase”或者"LightMode"="ForwordAdd")

这三个函数里的内置变量——WorldSpaceLightPos0等才能被正确赋值。

注:这一篇以及之前漫反射都是单一平行光源下计算的,查看效果时,去掉天空盒,设置方法为window->Lighting->skybox

unity shader入门(四):高光的更多相关文章

  1. Unity Shader入门精要学习笔记 - 第7章 基础纹理

    转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图“黏”在模型表面,逐纹素地控制模型的颜色. 在美术 ...

  2. Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

    转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...

  3. Unity Shader入门精要读书笔记(一)序章

    本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...

  4. Unity Shader入门精要学习笔记 - 第17章 Unity的表面着色器探秘

    转自 冯乐乐的<Unity Shader 入门精要> 2010年的Unity 3 中,Surface Shader 出现了. 表面着色器的一个例子. 我们先做如下准备工作. 1)新建一个场 ...

  5. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

  6. Unity Shader入门精要学习笔记 - 第10章 高级纹理

    转载自 冯乐乐的 <Unity Shader入门精要> 立方体纹理 在图形学中,立方体纹理是环境映射的一种实现方法.环境映射可以模拟物体周围的环境,而使用了环境映射的物体可以看起来像镀了层 ...

  7. Unity Shader入门精要学习笔记 - 第9章 更复杂的光照

    转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...

  8. Unity Shader入门精要学习笔记 - 第8章 透明效果

    转载自 冯乐乐的 <Unity Shader入门精要> 透明是游戏中经常要使用的一种效果.在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道.当开启透明混合后,当一个物体被渲染 ...

  9. Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

    摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐 ...

  10. Unity Shader入门

    Unity Shader入门 http://www.cnblogs.com/lixiang-share/p/5025662.html http://www.manew.com/blog-30559-1 ...

随机推荐

  1. 【Python】解析Python中类的使用

    目录结构: contents structure [-] 类的基本使用 专有方法 继承 单重继承 多重继承 砖石继承 1.类的基本使用 下面是类使用的一个简单案例, class person: &qu ...

  2. Xamarin.FormsShell基础教程(8)Shell的模版构成

    Xamarin.FormsShell基础教程(8)Shell的模版构成 Shell模版创建的页面包含内容页.标签栏.侧滑菜单.搜索框四部分.下面依次介绍这几个部分. 内容页:内容页就是为用户呈现内容的 ...

  3. 运维笔记--Docker文件占用磁盘空间异常处理

    场景描述: 1. 服务器运行一段时间后,发现系统盘磁盘空间在不断增加,一开始的时候,不会影响系统,随着时间的推移,磁盘空间在不断增加,直到有一天你会发现系统盘剩余空间即将使用完,值得庆幸的是,如果您使 ...

  4. [转]manjaro安装vmware虚拟机

    全球领先的信息与通信解决方案供应商华为,近日面向全球ICT从业者,以及有兴趣掌握ICT相关知识的人士,免费推出其图形化网络仿真工具平台—eNSP.该平台通过对真实的网络设备的仿真模拟,帮助广大ICT从 ...

  5. spring boot 打包引入第三方jar

    本文作者:@Ryan Miao 本文链接:https://www.cnblogs.com/woshimrf/p/springboot-package-3rdparty-lib.html 版权声明: 本 ...

  6. 快速读取TXT几百万行数据, 然后插入到数据,SqlBulkCopy功能的确是有效率

    public static void Main(string[] args) { string strPath = "F:\\Download\\600.txt"; int lin ...

  7. Centos7环境下部署搭建discuz论坛

    1.首先搭建lnmp环境 2.从官网复制git地址(https://gitee.com/ComsenzDiscuz/DiscuzX),在服务器上安装git命令 yum install git -y  ...

  8. Java分布式:分布式锁之数据库实现

    Java分布式:分布式锁之数据库实现 分布式锁系列教程重点分享锁实现原理 锁实现原理 创建一张名为methodLock的数据库表,为方法名字段(method_name)添加唯一性约束. CREATE ...

  9. ANR无法生成traces.txt文件

    在有些设备上ANR无法生成traces.txt文件,kill -3又不能准确把握时机或者没权限,可能是软件访问这个路径失败,可以在/data/anr/下面建立一个空的traces.txt,注意保证an ...

  10. 【Spring Boot学习之十一】整合mongoDB

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 参考: SpringBoot+Mongodb的使用