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. 解析HTML文件 - 运用SgmlReader类来解析HTML文件

    运用.NET Framework类来解析HTML文件.读取数据并不是最容易的.虽然你可以用.NET Framework中的许多类(如StreamReader)来逐行解析文件,但XmlReader提供的 ...

  2. JAVA常见算法题(十五)

    package com.xiaowu.demo; /** * * 输入三个整数x,y,z,请把这三个数由小到大输出. * * @author WQ * */ public class Demo15 { ...

  3. centos7 安装LNMP(php7)之php7.0 yum安装

    http://www.jianshu.com/p/35f21210668a 安装过程参考上面的网址

  4. api.js

    ylbtech-JavaScript-util: api.js API 代理接口 1.A,JS-效果图返回顶部   1.B,JS-Source Code(源代码)返回顶部 1.B.1, m.yinta ...

  5. 关于RBAC(Role-Base Access Control)的理解

    基于角色的访问控制(Role-Base Access Control) 有两种正在实践中使用的RBAC访问控制方式:隐式(模糊)的方式和显示(明确)的方式. 今天依旧有大量的软件应用是使用隐式的访问控 ...

  6. 为什么输入shutdown -h -t会报错:command not fount

    如果是直接用普通用户($)的身份进行输入[user@localhost ~]$ shutdown -h -t 是不能执行,因为普通用户没有关闭机器的权限. 然而直接使用[user@localhost ...

  7. tensorflow seq2seq.py接口实例

    以简单英文问答问题为例测试tensorflow1.4 tf.contrib.legacy_seq2seq中seq2seq文件的几个seq2seq接口 github:https://github.com ...

  8. bash: /bin/bash^M: bad interpreter: No such file or directory

    在windows下编写shell脚本在linux下运行会出报错: [hadoop@master data]$ ./load_ods_table.sh -bash: ./load_ods_table.s ...

  9. JAVA Eclipse如何开发Android的多页面程序

    Fragment可以认为是Activity的一个界面的组成部分,Fragment必须依存于Activity.   在layout文件夹中新建一个xml文件,布局方式采用RelativeLayout,注 ...

  10. Android学习(十五) 系统服务

    一.常用系统服务 后台Service在系统启动时被SystemService开启 1.MountService:监听是否有SD卡安装和移除. 2.ClipboardService:提供剪切板功能. 3 ...