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实现的更多相关文章

  1. 【Unity Shader】(三) ------ 光照模型原理及漫反射和高光反射的实现

    [Unity Shader](三) ---------------- 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 ...

  2. unity3d shader之Roberts,Sobel,Canny 三种边缘检测方法

    方法其实都差不多,就是用两个过滤器,分别处理两个分量 Sobel算子 先说Sobel算子 GX为水平过滤器,GY为垂直过滤器,垂直过滤器就是水平过滤器旋转90度.过滤器为3x3的矩阵,将与图像作平面卷 ...

  3. 【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&混合操作编译

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨)  ...

  4. 2、shader基本语法、变量类型、shader的三种形式、subshader、fallback、Pass LOD、tags

    新建一个shader,名为MyShader1内容如下: 1._MainTex 为变量名 2.“Base (RGB)”表示在unity编辑面板中显示的名字,可以定义为中文 3.2D 表示变量的类型 4. ...

  5. 编写Unity3D着色器的三种方式

    不管你会不会写Unity3D的shader,估计你会知道,Unity3D编写shader有三种方式,这篇东西主要就是说一下这三种东西有什么区别,和大概是怎样用的. 先来列一下这三种方式: fixed ...

  6. Unity三种截屏方法(非自带API)

    者利用了三种表现形式: 1,选择截图路径的方法 2,直接截取截屏的方法 3,截取鼠标圈选区域. 上代码,: 第一种是调用.net的类库,需要引用System.Windows.Forms.dll,在As ...

  7. 盛大游戏技术总监徐峥:Unity引擎使用的三种方式

    在5月13日Unite 2017 案例分享专场上,盛大游戏技术总监徐峥分享了使用Unity引擎的三种方式,以下为详细内容: 大家好,我先简单介绍一下我自己,我是盛大游戏的技术总监徐峥.我今天想分享的主 ...

  8. 简谈百度坐标反转至WGS84的三种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 基于百度地图进行数据展示是目前项目中常见场景,但是因为百度地图 ...

  9. 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率

    之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...

随机推荐

  1. ASIHTTPREQUEST framework compile error when method is called / link error

    never mind!!! duplicate: Error with iOS 5.1 when i use ASIHTTPRequest and SBJSON "I would take ...

  2. hibernate,mybatis,beetlsql 全面比較

    这是我的一个综合评分.总共分为12个单项.每一个单项最高5分.最低0分. 注意.评价仅仅包括这些软件提供的标准功能,不包括第三方提供的功能,如代码生成等. 开发效率 hibernate  能获取数据库 ...

  3. 如何给JQ的ajax方法中的success()传入参数?

    当时在使用JQuery提供的Ajax技术的时候,我有个需求,就是要给它请求成功后调用的success()方法传入参数: 所以,我就直接这样子写了: <script> function ge ...

  4. appium python学习记录

    这是网上找到的测试用例 from appium import webdriver desired_caps = {} desired_caps['platformName'] = 'Android' ...

  5. Litepal 数据库操作框架的使用 (火)

    LitePal是GitHub上一款开源的Android数据库框架. 它採用了对象关系映射(ORM)的模式,将平时开发时最经常使用的一些数据库功能进行了封装.使得开发人员不用编写一行SQL语句就能够完毕 ...

  6. linux /etc/hosts 配置问题

    在java code中获取本机IP的程序如下: import java.net.InetAddress; public class Test { public static void main(Str ...

  7. iOS_block代码块

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  8. vue笔记三(组件)

    十.组件 1.组件中的data为函数 2.props: 父组件向子组件传递数据 子组件:Child.vue <template> <span>{{ myMsg }}</s ...

  9. Laravel之Eloquent ORM关联

    一.一对一 1.主对从(hasOne) 从User模型中取出用户的手机 User模型中: /** * 获取关联到用户的手机 */ public function phone() { return $t ...

  10. python——Container之字典(dict)详解

    字典(dictionary)是除列表以外python之中最灵活的内置数据结构类型.列表是有序的对象结合,字典是无序的对象集合.两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取. ...