高光反射计算公式(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入门(四):高光的更多相关文章

  1. Unity Shader入门精要学习笔记 - 第7章 基础纹理

    转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图“黏”在模型表面,逐纹素地控制模型的颜色. 在美术 ...

  2. Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

    转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...

  3. Unity Shader入门精要读书笔记(一)序章

    本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...

  4. Unity Shader入门精要学习笔记 - 第17章 Unity的表面着色器探秘

    转自 冯乐乐的<Unity Shader 入门精要> 2010年的Unity 3 中,Surface Shader 出现了. 表面着色器的一个例子. 我们先做如下准备工作. 1)新建一个场 ...

  5. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

  6. Unity Shader入门精要学习笔记 - 第10章 高级纹理

    转载自 冯乐乐的 <Unity Shader入门精要> 立方体纹理 在图形学中,立方体纹理是环境映射的一种实现方法.环境映射可以模拟物体周围的环境,而使用了环境映射的物体可以看起来像镀了层 ...

  7. Unity Shader入门精要学习笔记 - 第9章 更复杂的光照

    转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...

  8. Unity Shader入门精要学习笔记 - 第8章 透明效果

    转载自 冯乐乐的 <Unity Shader入门精要> 透明是游戏中经常要使用的一种效果.在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道.当开启透明混合后,当一个物体被渲染 ...

  9. Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

    摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐 ...

  10. Unity Shader入门

    Unity Shader入门 http://www.cnblogs.com/lixiang-share/p/5025662.html http://www.manew.com/blog-30559-1 ...

随机推荐

  1. HIVE出现Read past end of RLE integer from compressed stream Stream for column 1 kind LENGTH position: 359 length: 359 range: 0错误

    错误日志 Diagnostic Messages for this Task: Error: java.io.IOException: java.io.IOException: java.io.EOF ...

  2. FreeSWITCH视频直播

    大家都知道,如今,视频直播比较火啊. 今天,在FreeSWITCH精英群里分享了FreeSWITCH做视频直播相关的技术. 首先,要做直播就得有好机器.笔者买了一台阿里云的主机,买的是按量付费的,4核 ...

  3. leetcode No.500 键盘行 keyboard-row (Python3实现)

    题目描述 给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词.键盘如下图所示. 示例: 输入: ["Hello", "Alaska", " ...

  4. 从原理到应用,Elasticsearch详解

    简介 Elasticsearch(简称ES)是一个分布式.可扩展.实时的搜索与数据分析引擎.ES不仅仅只是全文搜索,还支持结构化搜索.数据分析.复杂的语言处理.地理位置和对象间关联关系等. ES的底层 ...

  5. [Linux.centOS].安装Redis 腾讯云

    环境 { "服务器运营商":"腾讯云", "操作系统":"CentOS 7.5 64位", "CPU" ...

  6. Python - Django - form 组件动态从数据库取 choices 数据

    app01/models.py: from django.db import models class UserInfo(models.Model): username = models.CharFi ...

  7. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之Windows服务安装

    背景说明 EasyDSS流媒体解决方案是由安徽旭帆信息科技有限公司自主研发的一套集流媒体点播.转码.管理.直播.录像.检索.时移回看于一体的一套完整的商用流媒体解决方案.EasyDSS软件以压缩包的形 ...

  8. General VDPConfig对讲配置工具

    General VDPConfig大华楼宇对讲配置工具是ConfigTool的一个对讲模块,主要服务对象为可视对讲的门口机和室内机,大华可视对讲在独户应用中,利用了自身在视频监控领域的优势,充分整合了 ...

  9. SPI ServiceLoader源码分析

    public class ddd { public static void main(String[] args) { ServiceLoader1<Hello> sl = Service ...

  10. 【转帖】极简Docker和Kubernetes发展史

    极简Docker和Kubernetes发展史 https://www.cnblogs.com/chenqionghe/p/11454248.html 2013年 Docker项目开源 2013年,以A ...