目录

前言

内容

BRDF 模型

兰伯特定律

漫发射的计算公式

高光反射的计算公式

Blinn 模型的高光反射计算公式

逐像素与逐顶点光照

Unity 的环境光和自发光

漫反射和高光反射的 Shader 实现

漫反射光照模型(逐顶点)

高光反射模型(逐顶点)


前言

光学中,我们是用辐射度来量化光。

光照按照不同的散射方向分为两种形式:漫反射(diffuse)和高光反射(specular)。

高光反射描述物体是如何反射光线的,漫反射则表示有多少光线会被折射、吸收和散射出表面。根据入射光线的数量和方向,我们可以计算出射光线的数量和方向,通常使用出射度描述它。辐射度和出射度之间是线性关系的,它们之间的比值就是材质的漫反射和高光反射属性。

接下来将会介绍Unity内的两种光照方式实现的原理以及代码实现:

内容

BRDF 模型

早期的游戏引擎一般只有一个光照模型,BRDF 模型,即标准光照模型(Bidirectional Reflectance Distribution Function),又称 Phong 模型。

它的基本方法是,把进入到摄像机内的光线分为 4 部分,每部分使用一种方法来计算它的贡献度。

  • 自发光  描述当给定一个方向时,一个表面本身会向该方向发射多少辐射量。注意,如果没有使用全局光照,这些自发光的表面并不会照亮周围的物体,只是他本体看起来更亮而已。
  • 高光反射(金属之类的)  描述当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。
  • 漫反射  该表面会向四周散射多少辐射量
  • 环境光  描述其他所有的间接光照(就是其他物体的发射的光线)。

兰伯特定律

发射光线的强度与表面法线和光源方向之间的夹角余弦值成正比。

漫发射的计算公式

C = (c * m) * max( 0 , n * l )。

小写 c 为光源颜色,m 为漫反射颜色,n 是表面法线,l 是指向光源的单位矢量。需要注意应该防止发现和光源点乘的结果为负值(避免物体被从后面来的光源照亮),所以用 max 函数限制其为正数。

高光反射的计算公式

  • r = 2(n * l)n - l
  • C = (c * m) * (max(0,v * r)) ^ gloss

n,l 代表意义与漫反射公式相同,r 为光的反射方向矢量,m 为高光反射颜色,v 为 视角方向矢量,gloss 为材质的光泽度,gloss 越大亮点就越小。

Blinn 模型的高光反射计算公式

与上述 Phong 模型不同的是,Blinn 模型引入了一个新矢量 h,通过对 v 和 l 的取平均后再归一化得到:h = (v + l) / | v + l |。

公式为:C = (c * m) * (max ( 0, n * h ))^gloss

逐像素与逐顶点光照

在片元着色器中计算,称为逐像素光照。在顶点着色器中计算,称为逐顶点光照(高罗德着色)。逐顶点光照是在每个顶点上计算光照,然后在渲染图元内部进行线性插值,最后输出成像素颜色。由于顶点数目小于像素数目,所以其计算量小于逐像素光照,因此在阴影交界处会出现锯齿,精细度不如逐像素光照。

Unity 的环境光和自发光

环境光可以通过 Shader 的内置变量 UNITY_LIGHTMODEL_AMBIENT 访问

自发光只需要在片元着色器输出最后的颜色之前,把材质的自发光颜色添加到输出颜色上就行。

漫反射和高光反射的 Shader 实现

漫反射光照模型(逐顶点)

Shader "Unity Shader Book/Chapter6/Diffuse Vertex-Level"
{Properties{_Diffuse("Diffuse",Color) = (1.0,1.0,1.0,1.0)}SubShader{Tags { "LightMode"="ForwardBase" }   Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;struct appdata{float4 vertex : POSITION; //顶点在模型空间的坐标float3 normal : NORMAL;  //法线} ;struct v2f{fixed3 color : COLOR;  //输出颜色float4 pos : SV_POSITION;  //输出位置} ;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);  //模型空间转换到裁剪空间fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;  //环境光fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject)); //法线方向nfixed3 worldLight  = normalize(_WorldSpaceLightPos0.xyz); //光源位置fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLight));  //公式计算o.color = ambient + diffuse;return o;}fixed4 frag (v2f i) : SV_Target{return fixed4(i.color,1.0);}ENDCG}}
}

高光反射模型(逐顶点)

Shader "Unity Shader Book/Chapter6/SpecularVertexLevel"
{Properties{_Diffuse("Diffuse",Color) = (1.0,1.0,1.0,1.0)_Specular("Specular",Color) = (1.0,1.0,1.0,1.0)_Gloss("Gloss",Range(8.0,256)) = 20 //镜面反射面积大小}SubShader{Tags { "LightMode"="ForwardBase" }   //小心,如果没有这个光源会反向Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float  _Gloss;struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;} ;struct v2f{float3 color: COLOR;float4 pos : SV_POSITION;} ;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);//等同于 "o.pos = mul(UNITY_MATRIX_MVP,v.vertex);"fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));//或使用 UnityObjectToWorldNormal(v.normal)fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));fixed3 reflectDir = normalize(reflect(-worldLightDir,worldNormal)); //反射方向矢量rfixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld,v.vertex).xyz); //视线方向fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss); //公式计算o.color = ambient + diffuse + specular;return o;}fixed4 frag (v2f i) : SV_Target{return fixed4(i.color,1.0);}ENDCG}}
}

Unity 的基础光照相关推荐

  1. 《Unity 3D 游戏开发技术详解与典型案例》——1.1节Unity 3D基础知识概览

    本节书摘来自异步社区<Unity 3D 游戏开发技术详解与典型案例>一书中的第1章,第1.1节Unity 3D基础知识概览,作者 吴亚峰 , 于复兴,更多章节内容可以访问云栖社区" ...

  2. Unity面试题加强版之二《unity编辑器基础》

    Unity面试题加强版之二Unity编辑器基础 unity超全面试题,掌握轻轻松松拿Offer,码住学习 40.请描述游戏动画有几种,以及其原理. 主要有关节动画.单一网格模型动画(关键帧动画).骨骼 ...

  3. Unity引擎基础补充

    Unity引擎基础补充 本博客将对之前的Unity脚本,3D数学基础博客内容做一定的补充.所以部分知识点可能并不全. 使用Unity的API,我们要清楚各个参数其代表的含义. 文章目录 Unity引擎 ...

  4. Unity Shader入门精要——第3章 Unity Shader基础

    Unity Shader入门精要读书笔记系列 第1章 欢迎来到Shader的世界 第2章 渲染流水线 第3章 Unity Shader基础 文章目录 Unity Shader入门精要读书笔记系列 前言 ...

  5. 《 Unity Shader 入门精要》 第3章 Unity Shader 基础

    第3章 Unity Shader 基础 3.1 Unity Shader 概述 材质与 Unity Shader 在 Unity 中我们通常需要将材质(Material) 和 Unity Shader ...

  6. Unity Mesh基础知识

    Unity Mesh基础知识 什么是Mesh Mesh的组成部分 利用Mesh创建一个Cube 创建Cube 顶点坐标 渲染 转载链接 什么是Mesh     Mesh是指的模型的网格,3D模型是由多 ...

  7. 蓝鸥Unity开发基础二——课时20 接口

    蓝鸥Unity开发基础二--课时20 接口 一.接口 使用interface关键字定义接口 接口定义一组成员单不直接实现它们 二.实现接口 实现接口的任何类都必须实现其所有的成员方法 接口不能直接实例 ...

  8. OpenGL 基础光照ColorsBasic Lighting

    OpenGL 基础光照ColorsBasic Lighting 基础光照ColorsBasic Lighting简介 环境光照 漫反射光照 法向量 计算漫反射光照 最后一件事 镜面光照 基础光照Col ...

  9. 【蓝鸥Unity开发基础三】课时14 刚体

    [蓝鸥Unity开发基础三]课时14 刚体 一.刚体 物理引擎: 物理引擎能够真实的模拟物理效果 Unity中使用的是NVIDIA的PhysX物理引擎 在Unity中使用Rigidbody让游戏对象受 ...

最新文章

  1. 句法分析是什么?成分句法分析、依存句法分析又是什么?他们之间有什么区别?
  2. [业界资讯]腾讯QQ同时在线用户数突破8000万
  3. IT人员健康信号之颈椎病自疗
  4. python之33个关键字详解_Python解析、提取url关键字的实例详解
  5. 前端学习(970):fastclick插件使用
  6. 0pencv——图像腐蚀
  7. python抽荣耀水晶_教你2种免费拿荣耀水晶的方法,获奖概率让人惊喜,一般人我不告诉他...
  8. html5游戏制作入门系列教程(四)
  9. python两个数组合并、找出中位数_leetcode刷题记录-找出这两个有序数组的中位数(python版本)...
  10. 20145328 《信息安全系统设计基础》第2周学习总结
  11. 容器化技术之Docker入门
  12. 都说 Linux 是吃内存大户,可你知道具体是哪些进程吃掉了吗?
  13. Maven项目jar包依赖冲突的原因以及解决办法
  14. CouchBase简单介绍
  15. 计算机专业英语高等教育出版社2013版
  16. 推荐几个好的粉碎文件的软件?这3款软件让你彻底摆脱无法删除文件的烦恼
  17. 解决AndroidStudio报错问题:Missing essential plugin
  18. 【Three.js】十二、three.js摄像机控件
  19. python 状态空间模型_R语言状态空间模型:卡尔曼滤波器KFAS建模时间序列
  20. excel打开很慢_从海量Excel文件中快速高效地提取数据

热门文章

  1. win10配置python环境变量
  2. error: (-215:Assertion failed) size.width0 size.height0 in function 'cv::imshow'解决
  3. 科创板丨西部超导上半年实现营收6.69亿元 同比增长26.69%
  4. mybatis的selectKey的用法
  5. 年度最新!iOS如何申请苹果公司开发者账号流程详细图文介绍
  6. 2022年网络安全比赛--压缩包文件暴力破解中职组(超详细)
  7. Linux-3 常用工具
  8. 3大简历难题,你是否也曾遭遇?
  9. aws sqs java_AWS SQS Java.并非所有消息都从SQS队列中检索
  10. 测试用例设计方法(等价类、边界值等)