三种光照模型的shader实现
1.Lambert模型,公式为I=Kd*Il(N*L);

Shader "Custom/Lambert_A" {
Properties {
_Diffuse("Diffuse",Color)=(,,,)
}
SubShader {
Pass{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include"Lighting.cginc"
fixed4 _Diffuse;//为了使用Properties中声明的属性
struct a2v//顶点着色器的输入结构体
{
float4 vertex:POSITION;//位置
float3 normal:NORMAL;//法向量
};
struct v2f//顶点着色器的输出结构体
{
float4 pos:SV_POSITION;//一般用SV_POSITION作为输出
fixed3 color:COLOR;
};
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//获取环境光
fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));//得到顶点单位法向量
fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//获取顶点指向灯光的单位向量
fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLight));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
o.color=ambient+diffuse;//与环境光叠加
return o;
}
fixed4 frag(v2f i):SV_Target
{
return fixed4(i.color,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐像素代码(效果较好)
Shader "Custom/Lambert_B" {
Properties {
_Diffuse("Diffuse",Color)=(,,,)
}
SubShader {
Pass{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include"Lighting.cginc"
fixed4 _Diffuse;//为了使用Properties中声明的属性
struct a2v//顶点着色器的输入结构体
{
float4 vertex:POSITION;//位置
float3 normal:NORMAL;//法向量
};
struct v2f//顶点着色器的输出结构体
{
float4 pos:SV_POSITION;//输出位置
fixed3 worldNormal:TEXCOORD0;
};
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);//得到顶点单位法向量
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));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
fixed3 color=ambient+diffuse;//与环境光叠加
return fixed4(color,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐顶点
Shader "Custom/Lambert_B" {
Properties {
_Diffuse("Diffuse",Color)=(,,,)
}
SubShader {
Pass{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include"Lighting.cginc"
fixed4 _Diffuse;//为了使用Properties中声明的属性
struct a2v//顶点着色器的输入结构体
{
float4 vertex:POSITION;//位置
float3 normal:NORMAL;//法向量
};
struct v2f//顶点着色器的输出结构体
{
float4 pos:SV_POSITION;//输出位置
fixed3 worldNormal:TEXCOORD0;
};
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);//得到顶点单位法向量
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));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
fixed3 color=ambient+diffuse;//与环境光叠加
return fixed4(color,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐像素(效果较佳)
2.Phong模型,公式为I=KsIl(V*R)^ns

Shader "Custom/Phong_A" {
Properties {
_Diffuse("Diffuse",Color)=(,,,)
_Specular("Specular",COlor)=(,,,)
_Gloss("Gloss",Range(8.0,))=
}
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;
fixed3 color:COLOR;
};
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,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));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));//得到反射光的单位向量
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(unity_ObjectToWorld,v.vertex).xyz);//视角方向=世界空间的摄像机位置-世界空间的顶点位置
fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss);//光源颜色*材质高光颜色*(视角方向和反射光方向的点积(V*R))
o.color=ambient+diffuse+specular;//环境光+漫反射+高光
return o;
}
fixed4 frag(v2f i):SV_Target
{
return fixed4(i.color,1.0);
}
ENDCG
}
}
FallBack "Specular"
}
逐顶点
Shader "Custom/Phong_B" {
Properties {
_Diffuse("Diffuse",Color)=(,,,)
_Specular("Specular",COlor)=(,,,)
_Gloss("Gloss",Range(8.0,))=
}
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;
fixed3 worldNormal:TexCOORD0;
float3 worldPos:TEXCOORD1;
};
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,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));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
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);//光源颜色*材质高光颜色*(视角方向和反射光方向的点积(V*R))
return fixed4(ambient+diffuse+specular,1.0);//环境光+漫反射+高光
}
ENDCG
}
}
FallBack "Specular"
}
逐像素(效果较好)
3.Blinn Phong模型,公式为I=KsIl(N*H),其中H=(L+V)/|L+V|;

Shader "Custom/Blinn_Phong" {
Properties {
_Diffuse("Diffuse",Color)=(,,,)
_Specular("Specular",COlor)=(,,,)
_Gloss("Gloss",Range(8.0,))=
}
SubShader {
Tags { "LightMode"="ForwardBase" }
Pass{
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;
fixed3 worldNormal:TexCOORD0;
float3 worldPos:TEXCOORD1;
};
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,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));
//fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
fixed3 halfDir=normalize(worldLightDir+viewDir);
fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(worldNormal,halfDir)),_Gloss);
return fixed4(ambient+diffuse+specular,1.0);
}
ENDCG
}
}
FallBack "Specular"
}
Blinn_Phong
三种光照模型的shader实现的更多相关文章
- 【Unity Shader】(三) ------ 光照模型原理及漫反射和高光反射的实现
[Unity Shader](三) ---------------- 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 ...
- unity3d shader之Roberts,Sobel,Canny 三种边缘检测方法
方法其实都差不多,就是用两个过滤器,分别处理两个分量 Sobel算子 先说Sobel算子 GX为水平过滤器,GY为垂直过滤器,垂直过滤器就是水平过滤器旋转90度.过滤器为3x3的矩阵,将与图像作平面卷 ...
- 【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&混合操作编译
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨) ...
- 2、shader基本语法、变量类型、shader的三种形式、subshader、fallback、Pass LOD、tags
新建一个shader,名为MyShader1内容如下: 1._MainTex 为变量名 2.“Base (RGB)”表示在unity编辑面板中显示的名字,可以定义为中文 3.2D 表示变量的类型 4. ...
- 编写Unity3D着色器的三种方式
不管你会不会写Unity3D的shader,估计你会知道,Unity3D编写shader有三种方式,这篇东西主要就是说一下这三种东西有什么区别,和大概是怎样用的. 先来列一下这三种方式: fixed ...
- Unity三种截屏方法(非自带API)
者利用了三种表现形式: 1,选择截图路径的方法 2,直接截取截屏的方法 3,截取鼠标圈选区域. 上代码,: 第一种是调用.net的类库,需要引用System.Windows.Forms.dll,在As ...
- 盛大游戏技术总监徐峥:Unity引擎使用的三种方式
在5月13日Unite 2017 案例分享专场上,盛大游戏技术总监徐峥分享了使用Unity引擎的三种方式,以下为详细内容: 大家好,我先简单介绍一下我自己,我是盛大游戏的技术总监徐峥.我今天想分享的主 ...
- 简谈百度坐标反转至WGS84的三种思路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 基于百度地图进行数据展示是目前项目中常见场景,但是因为百度地图 ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
随机推荐
- 分布式数据库以及OS
http://blog.csdn.net/longronglin/article/category/230501
- vs2010 sharepoint项目部署与查看
1.选中sharepoint项目,视图→属性窗口,填写站点url ,我这里原来写81,但是81已经放了另外一个项目,所以要把它改为刚刚新增的82端口 不知道影不影响,反正我重新打开了一遍. 2.重新生 ...
- win10 安装java
https://jingyan.baidu.com/article/fea4511a12b158f7bb9125b9.html 一 下载java SE 官网 二设置环境变量 JAVA_HOME PAT ...
- iOS:自定义模态动画 --UIPresentationController
UIPresentationController :展示控制器,是iOS8的一个新特性,用来展示模态窗口的.它是所有模态控制器的管理者. 即: 1> 管理所有Modal出来的控制器 2> ...
- ASP.NET MVC学习---(一)ORM框架,EF实体数据模型简介
现如今 对象关系映射(ORM)框架 被大量的使用于企业级应用的开发 为什么要使用ORM? ADO.NET操作数据库不好吗? 我们可以仔细想想 当我们使用ADO.NET操作数据库的时候 我们需要先获取连 ...
- Java三大器之过滤器(Filter)的工作原理和代码演示
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet, 静 ...
- 解决dubbo问题:forbid consumer(1)
原因: 1.dubbo服务没有起动起来 2.dubbo链接的地址出现异常 3.dubbo服务端更新了服务接口,没有发布 如果已上都没有问题,那么还有一个原因就是 “ 别人的代码有问题 阻碍了 你的程序 ...
- Nodejs 模拟telnet
代码下载:https://files.cnblogs.com/files/xiandedanteng/nodejsTelnet.rar 效果: server.js代码: var net=require ...
- windows pip源
首先在window的文件夹窗口输入 : %APPDATA% 然后在底下新建pip文件夹,然后到pip文件夹里面去新建个pip.ini,然后再里面输入内容 [global] timeout = 6000 ...
- Python——os.path.dirname(__file__) 与 os.path.join(str,str)
Python os.path.dirname(__file__) Python os.path.join(str,str) (1).当"print os.path.dirname(__f ...