unity shader入门(四):高光
高光反射计算公式(phong模型)Cspecular=(Clight*Mspecular)max(0,v*r)mgloss
mgloss为材质的官泽度,也成反射度,控制高光区域亮点有多大
Mspecular是材质的高光反射颜色,控制材质对于高光反射的轻度和颜色
Clight为光源的颜色和强度
v是观察方向的单位向量
r是反射方向 r=2(法线单位向量n*光源方向向量)法线单位向量-光源方向向量
高光反射计算公式(Blinn模型)Cspecular=(Clight*Mspecular)max(0,n*h)mgloss
n为法线向量的单位向量
h是对观察方向和光源方向取平均后归一化得到的:h(注:单位向量)=(v(注:单位向量)+光源方向)/|(v(注:单位向量)+光源方向)|
下面分别是逐顶点和逐像素两种写法
phong模型 逐顶点:
Shader "study/Chapter6/halfLambertShader" {
Properties{
_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
_Specular("Specular",Color)=(1,1,1,1)//控制材质高光反射颜色
_Gloss("Gloss",Range(8.0,256)) = 20 //用于控制高光区域的大小
}
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;
fixed4 normal:NORMAL;
};
struct v2f{
float4 pos:SV_POSITION;
fixed3 color:COLOR;
};
v2f vert(a2v v){ v2f o;
o.pos=UnityObjectToClipPos(v.vertex); fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
//内置函数写法,下面给出内置函数
//fixed3 worldNormal=normalize(UnityObjectToWorldNormal(v.normal););
fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject)); fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir)); //反射方向get the reflect direction in world space
fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal)); //get the view direction in world space
//世界空间下观察方向
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(unity_ObjectToWorld,v.vertex).xyz); //Computer specular term
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss); o.color=diffuse+ambient+specular; return o; }
fixed4 frag(v2f i):SV_Target{
return fixed4(i.color,1.0);
} ENDCG
}
}
FallBack "Specular"
}
phong模型 逐像素:
Shader "study/Chapter6/SpecularPixelLevelShader"
{
Properties{
_Diffuse("Diffuse",Color)=(1,1,1,1)
_Specular("Specular",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8.0,256))=20
} SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "Lighting.cginc" fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss; struct a2v{
fixed4 vertex:POSITION;
fixed3 normal:NORMAL;
};
struct v2f{
fixed4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
}; v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//使用内置函数写法
//o.worldNormal = UnityObjectToWorldNormal(v.normal);
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(_WorldSpaceCameraPos.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 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss);
//最终观察到的光照
return fixed4(ambient+diffuse+specular,1.0);
}
ENDCG
}
}
FallBack "Specular"
}
Blinn模型逐像素
Shader "study/Chapter6/BlinnPhongShader"
{
Properties{
_Diffuse("Diffuse",Color)=(1,1,1,1)
_Specular("Specular",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8.0,256))=20
}
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;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
}; v2f vert(a2v v){
v2f o;
o.pos=UnityObjectToClipPos(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{ float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
//内置函数写法
//float3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldNormal, worldLightDir));
//内置函数写法
//fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldNormal));
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
fixed3 halfDir=normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);
return fixed4(ambient+diffuse+specular,1.0);
}
ENDCG
}
}
FallBack "Specular"
}
unity的内置函数
仅用于前向渲染的只有在渲染模式为前向渲染时(“LightMode”=“ForwordBase”或者"LightMode"="ForwordAdd")
这三个函数里的内置变量——WorldSpaceLightPos0等才能被正确赋值。
注:这一篇以及之前漫反射都是单一平行光源下计算的,查看效果时,去掉天空盒,设置方法为window->Lighting->skybox
unity shader入门(四):高光的更多相关文章
- Unity Shader入门精要学习笔记 - 第7章 基础纹理
转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图“黏”在模型表面,逐纹素地控制模型的颜色. 在美术 ...
- Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照
转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...
- Unity Shader入门精要读书笔记(一)序章
本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...
- Unity Shader入门精要学习笔记 - 第17章 Unity的表面着色器探秘
转自 冯乐乐的<Unity Shader 入门精要> 2010年的Unity 3 中,Surface Shader 出现了. 表面着色器的一个例子. 我们先做如下准备工作. 1)新建一个场 ...
- Unity Shader入门精要学习笔记 - 第14章非真实感渲染
转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...
- Unity Shader入门精要学习笔记 - 第10章 高级纹理
转载自 冯乐乐的 <Unity Shader入门精要> 立方体纹理 在图形学中,立方体纹理是环境映射的一种实现方法.环境映射可以模拟物体周围的环境,而使用了环境映射的物体可以看起来像镀了层 ...
- Unity Shader入门精要学习笔记 - 第9章 更复杂的光照
转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...
- Unity Shader入门精要学习笔记 - 第8章 透明效果
转载自 冯乐乐的 <Unity Shader入门精要> 透明是游戏中经常要使用的一种效果.在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道.当开启透明混合后,当一个物体被渲染 ...
- Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础
摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐 ...
- Unity Shader入门
Unity Shader入门 http://www.cnblogs.com/lixiang-share/p/5025662.html http://www.manew.com/blog-30559-1 ...
随机推荐
- ubuntu解决网络连接的优先级
ubuntu下无线连接网络,有线连接板卡,解决网络连接的优先级 1. 查看网关 ip route show dev wlp2s0 proto kernel scope link src dev wl ...
- Egret自定义计时器(TimerManager和Laya.timer)
一 自定义计时器 因为游戏中经常用到计时器,比如每1秒发射一枚子弹啊,每2秒怪物AI自动转向啊 每次去new Timer 然后addEventListener(egret.TimerEvent... ...
- 爬虫相关-scrapy框架介绍
性能相关-进程.线程.协程 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. 串行执行 import requests def fetc ...
- Python正则简单实例分析
Python正则简单实例分析 本文实例讲述了Python正则简单用法.分享给大家供大家参考,具体如下: 悄悄打入公司内部UED的一个Python爱好者小众群,前两天一位牛人发了条消息: 小的测试题: ...
- Content-Type四种常见取值
一.application/x-www-form-urlencoded 最常见 POST 提交数据的方式.浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 applica ...
- C/C++配置
VScode 插件推荐与C/C++配置 https://www.cnblogs.com/harrypotterjackson/p/11432252.html 阅读目录 C++类 美化 git tab ...
- STL之iterator源码解析
摘要 迭代器是一种行为类似指针的对象,本文介绍iterator与traits的关系,以及对traits内容的补充.包含stl_iterator.h的部分内容,并用c++11对其进行略微改写. iter ...
- python综合作业要求
要求: 1.课程成绩数据(学号尾数为0,1同学完成) 至少要完成内容:分析每年不同班级平均成绩情况.不同年份总体平均成绩情况.不同性别学生成绩情况,并用一定图表展示. 2.集美大学各省录取分数数据(学 ...
- 【C++/C】指针基本用法简介-A Summary of basic usage of Pointers.
基于谭浩强老师<C++程序设计(第三版)>做简要Summary.(2019-07-24) 一.数组与指针 1. 指针数组 一个数组,其元素均为指针类型数据,该数组称为指针数组.(type_ ...
- Python知识点总结篇(二)
列表 列表:一个值,包含多个字构成的序列,用[ ]括起来,[]是一个空列表,不包含任何值,类似于空字符串,负数下标表示从后边开始,-1表示列表最后一个下标,它是一种可变的数据类型,值可以添加.删除或改 ...