三种光照模型的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能提升多少拼接效率呢?为此写个简 ...
随机推荐
- CM3大礼包
- ubuntu配置无密码登录
1 本地生成ssh公钥和私钥, 2将公钥拷贝到ubuntu上的.ssh/authorized_keys 中
- rabbitmq集群节点操作
节点恢复过程中把数据删掉很重要,恢复一单结点,再清数据 节点增加: 1. rabbitmq-server -detached --- .erlang.cooike的权限,400 属主rabbitm ...
- 搭建Git本地服务器(转)
http://www.cnblogs.com/trying/archive/2012/06/28/2863758.html 当前任务,学习中... 公司小范围用法: 服务器上做的: 在服务器上建立一 ...
- log4j教程 12、日志记录到数据库
log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 buff ...
- crontab配置
1.命令功能 通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本.时间间隔的单位可以是分钟.小时.日.月.周及以上的任意组合.这个命令非常适合周期性的 ...
- div 事件透传
有些时候,我们会想要把一个 div 层覆盖在另一个 div 层上,要让下层的 div 响应鼠标事件而上层的不响应仅仅只做内容展示. 这种时候,我们就可以用到一个 CSS 属性:pointer-even ...
- .net 真实代理和透明代理的交互
.本地代理调用 using System; using System.Runtime.Remoting ; using System.Runtime.Remoting.Services ; using ...
- JavaScript AJAX原生写法
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- 【Excle数据透视表】如何将行字段中的某个项目拖动到第一行显示
如下图:需要把上海放到第一显示 步骤 方法一: 单击"地区"下的"上海"→鼠标移动到单元格边框处→鼠标变成四向箭头→向上拖拽 方法二: 单击单元格A5→编辑区域 ...