三种光照模型的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能提升多少拼接效率呢?为此写个简 ...
随机推荐
- iOS网络编程--ASIHTTPRequest框架安装和配置-图文解说
ASIHTTPRequest框架是优秀的第三方Objective-C的HTTP框架,支持Mac OS X和iOS下的HTTP开发.技术支持网站是http://allseeing-i.com/ASIHT ...
- [置顶]
kubernetes创建资源yaml文件例子--pod
kubernetes创建pod的yaml文件,参数说明 apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 ...
- python 文件操作的注意事项
我们经常用python读取文件信息,这里有些注意事项 with open('test.txt', 'r') as f: print 'f.read', f.read() with open('test ...
- Java学习之自动装箱和自动拆箱源码分析
自动装箱(boxing)和自动拆箱(unboxing) 首先了解下Java的四类八种基本数据类型 基本类型 占用空间(Byte) 表示范围 包装器类型 boolean 1/8 true|false ...
- Elasticsearch 索引实例
1.简述 ElasticSearch包含了一系列的感念,比如索引(indexing).搜索(search)以及聚合(aggregations),现在我们主要介绍indexing. 在Elasticse ...
- 用new和delete运算符进行动态分配和撤销存储空间
測试描写叙述:暂时开辟一个存储空间以存放一个结构体数据 #include <iostream> #include <string> using namespace std; s ...
- 编译安装Nginx和php搭建KodExplorer网盘
编译安装Nginx和php搭建KodExplorer网盘 环境说明: 系统版本 CentOS 6.9 x86_64 软件版本 nginx-1.12.2 php ...
- Windows远程CentOS桌面
Windows远程CentOS桌面 1.VNC 服务器配置 1) 安装vncserver yum install -y vnc-server 2) 修改配置 vi /etc/sysconfig/vnc ...
- agruments应用——求出函数参数的总合&&css函数——设置/读取对象的属性&&当前输入框高亮显
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Linux——Django 开发环境部署(一)
Django 开发环境部署(一) 之所以 写这篇文章的原因在于django环境的确轻松搭建,之前Ubuntu上安装了,的确很轻松,但是后期我才知道随便做个环境出来很容易到了后面很麻烦,污 染了系统里的 ...