一、色调映射(Tone Mapping)

  • 为什么需要色调映射?

高动态范围图像(HDR)能够达到甚至更高数量级的亮度,而一般显示器只能表示的亮度值,因此往往会因为光照强度过大而造成的过暗/过曝光问题。

  • 色调映射在做什么?

色调映射能够将原本大幅度的亮度与对比度衰减至显示器可以显示的范围内,同时仍然保存有原本图像细节与颜色等重要信息。

通常在后处理阶段使用。

  • 色调映射的一种函数:ACES

  • 使用小技巧(我不理解,但我先记)
//对Diffuse接收的color做线性空间的转换
base_color = pow(base_color, 2.2);
//再把最后的结果转回伽马空间
tone_color = pow(tone_color, 1.0 / 2.2);//拿取Unity内置环境光
//Windows → Rendering → Lighting调整光源设置
float3 Ambient_color = UNITY_LIGHTMODEL_AMBIENT.rgb * base_color;

二、视差贴图(Parallax Mapping)

  •  为什么需要视差贴图?

法线贴图只能在明暗效果上作假(模拟凹凸),而无法控制表面的凹凸程度,因此法线贴图无法模拟物体与物体间的遮挡关系。这就是视差贴图所要解决的问题,它可以让背面被遮挡住的部分完全不显示出来,除此之外还能在一定范围内调整砖块凹凸的程度。但视差贴图也只是模拟作假,并没有真的改变模型表面。

  • 什么是视差贴图?

视差贴图本质上,也是一种位移贴图(Displacement Mapping)。它的原理是根据视线方向,对当前看到的像素位置进行一定的坐标偏移,显示偏移过后的像素颜色。

我们想要观察到物体间的遮挡信息,当我们看向点A时,应该显示的是点B的纹理信息,然而单单存在法线贴图无法实现这一点,于是,我们就需要通过某种计算方法,将真正看到的点A计算到应该看到的点B,对点B的纹理采样显示。

  • 怎样实现纹理坐标的偏移?

我们需要使用一张高度贴图来读取模型本身的高度信息,将视线方向从世界空间转换到切线空间内,对UV方向进行偏移操作。

利用TBN矩阵将世界空间的vDir转换成切线空间下的向量P,计算出uv方向上的偏移长度。

//采样一张高度图
float height = tex2D(_ParallaxMap, i.uv);//构建TBN矩阵
float3 nDir = normalize(i.normal_Dir);
float3 tDir = normalize(i.tangent_Dir);
float3 bDir = normalize(i.binormal_Dir);
float3x3 TBN = float3x3(tDir, bDir, nDir);//将vDir转换到切线空间下
float3 vDir = normalize(_WorldSpaceCameraPos.xyz - i.pos_WS);
float3 vDir_TS = normalize(mul(TBN, vDir));//偏移值计算,_ParallaxModify为修正值
float2 uv_parallax = i.uv - vDir_TS.xy / vDir_TS.z * height * _ParallaxModify;

在实际应用中,往往更多的利用深度图(即1-height得到凹凸信息) 来进行偏移计算,因为在平面的理解上,深度比高度更具有实际意义。

参考:LearnOpenGL - Parallax Mapping

三、实时阴影

  • 传统实时阴影(Shadow Map)

1.阴影生成Pass:

①额外设置一个摄像机在光源位置(Light Camera,光源摄像机),并且朝光照方向看去。

②用一张 Texture(称为阴影贴图 Shadow Map)来记录 Light Camera 所看到的像素深度(每个像素位置只记录所见最近深度,而不用做别的 shading 计算)来作为遮挡深度。

2.渲染Pass:

①主摄像机需要渲染屏幕每个像素时,该像素对应的世界坐标进行 Light Camera 的MVP变换后能得到在 Light Camera 屏幕空间中的对应位置

②Shadow Map 里用采样得到的遮挡深度 depthdepth 与深度值做比较: 若 (意味着该像素的光被遮挡),这时就可以对该像素降低可见度(Visibility)。

//Unity内置函数实现1 → 该方法不带光源衰减
//输出结构
struct v2f
{SHADOW_COORDS(5)
};//输出函数
v2f vert (appdata v)
{v2f o;TRANSFER_SHADOW(o);return o;
}//片元Shader
fixed4 frag (v2f i) : SV_Target
{float shadow = SHADOW_ATTENUATION(i);float3 diffuse_term = min(shadow, max(0.0, dot(nDir, lDir)));float3 Diffuse = diffuse_term * base_color * _LightColor0;float3 Specular = pow(max(0.0, dot(lrDir, vDir)), _SpecPow) * _SpecIntensity * _LightColor0 * diffuse_term;float3 finalRGB = Diffuse + Specular + Ambient_color;return float4(finalRGB, 1.0);
}//加上Fallback
Fallback "Diffuse"//Unity内置函数实现2 → 该方法能够处理光源衰减
//输出结构
struct v2f
{LIGHTING_COORDS(5,6)
};//输出函数
v2f vert (appdata v)
{v2f o;TRANSFER_VERTEX_TO_FRAGMENT(o);return o;
}//片元Shader
fixed4 frag (v2f i) : SV_Target
{float attenuation = LIGHT_ATTENUATION(i);float3 lDir = normalize(_WorldSpaceLightPos0.xyz);float3 lDir_point = normalize(_WorldSpaceLightPos0.xyz - i.pos_WS);//_WorldSpaceLightPos0.w可以帮助判断光源类型lDir = lerp(lDir, lDir_point, _WorldSpaceLightPos0.w);float3 diffuse_term = min(attenuation, max(0.0, dot(nDir, lDir)));float3 Diffuse = diffuse_term * base_color * _LightColor0;float3 Specular = pow(max(0.0, dot(lrDir, vDir)), _SpecPow) * _SpecIntensity * _LightColor0 * diffuse_term;float3 finalRGB = Diffuse + Specular + Ambient_color;return float4(finalRGB, 1.0);
}//加上Fallback
Fallback "Diffuse"
  • 联级阴影(Cascaded Shadow Map,CSM)

当 Shadow Mapping 应用在大型场景中时,一张正常分辨率大小(如1024×1024)的贴图用来记录整个大型场景的阴影深度信息是非常不精确的,尤其是在靠近主摄像机的地方所看到的阴影将是严重失真的(一块块栅格)。

        Cascade Shadow Map(CSM) 借鉴了 LOD 的思想,对主摄像机的视锥体范围进行了划分,然后对每个划分区域采用相同分辨率大小的 Shadow Map,这意味着:离主摄像机比较近的地方往往区域面积是比较小的,这样 Shadow Map 能够表示的深度信息就更精确些,看到的阴影效果也更真实;离主摄像机比较远的地方往往区域面积是比较大的,虽然使用相同分辨率的 Shadow Map 能够表示的深度信息比较不精确,但对于远处的物体来说,这种不准确是可以接受的。

CSM 的代价很明显,即划分了多少层区域,就要使用多少倍数量的 Shadow Map。

参考:实时阴影技术(Real-time Shadows) - KillerAery - 博客园

【Shader】色调映射、视差贴图与实时阴影相关推荐

  1. python 深度 视差 计算_2,Learn about Parallax(视差贴图)

    接上文 : https://zhuanlan.zhihu.com/p/128682162 浮雕视差贴图: 浮雕视差贴图是陡峭视差贴图的进阶版.并允许GLSLshader更加精确地找到偏移的UV坐标.首 ...

  2. OpenGL 视差贴图 Parallax Mapping

    OpenGL 视差贴图 Parallax Mapping 视差贴图 Parallax Mapping简介 视差贴图 陡峭视差映射 视差遮蔽映射 视差贴图 Parallax Mapping简介 视差贴图 ...

  3. Shader视差贴图

    视差贴图相关理论介绍 粗略的视差效果: 本文就不陈述视差贴图相关描述了, 此处只记录说明一下两点 (1) 在求uv的偏移量的时候 :在切线空间下的 viewDir.xy / viewDir.z , 这 ...

  4. opengl高级光照之视差贴图(陡峭视差贴图以及视差遮蔽映射)

    视差贴图 视差贴图官方文档 视差贴图 视差贴图(Parallax Mapping)技术和法线贴图差不多,但它有着不同的原则.和法线贴图一样视差贴图能够极大提升表面细节,使之具有深度感.它也是利用了视错 ...

  5. 实时渲染:Tone Mapping 色调映射

    詹令 lealzhan@126.com 2017.12.28 文章目录 Tone Mapping 色调映射 全局色调映射 局部色调映射 基于分离压缩思想 Durand02 Reference 书籍 论 ...

  6. UE4 Material 101学习笔记——08-12 凹凸和视差贴图/纹理压缩/布料/体积冰/摇曳树叶

    UE4 Material 101学习笔记--08-12 凹凸和视差贴图/纹理压缩/布料/体积冰/摇曳树叶 Lec08 凹凸和视差贴图 Bump Offset and Parallax Occlusio ...

  7. 在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping)

    在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping) 视差贴图 最近一直在研究如何在我的 iPad 2(只支持 OpenGL ES 2.0, 不支持 3.0) 上实现 视 ...

  8. HDR 色调映射线性压缩(matlab)

    HDR 色调映射线性压缩(matlab) 目录 HDR 色调映射学习(matlab) 1.介绍 2.matlab在HDR上的应用 参考文章: 1.介绍 即使在引入数码相机之后,多年来,专业摄影师还是更 ...

  9. 【UE4 Material 101学习笔记】 :Lec08/10/11/12 视差贴图的应用/布料着色/体积冰效果/树叶摇动

    Lec08 视差贴图 原理 LearnOpenGL视差贴图 1. 使用高度图偏移UV 未使用高度贴图偏移UV时 使用之后,表面不平坦产生的阴影会更为明显一些. 当角度较大时,失真比较明显. 2. 视差 ...

最新文章

  1. oracle 查看连接数
  2. mysql2012用户名_SQL Server 登录名、服务器角色、用户名和数据库角色 --- 解释
  3. tp5.1升级指导---控制器调整 _initialize方法更改为initialize
  4. jenkins安装环境搭建(3)
  5. Oracle为JDK 8寻求社区参与
  6. java nbsp_引用了实体 nbsp
  7. ViewPager PagerAdapter未更新视图
  8. 通过minicom传送文件的相关配置及使用方法
  9. python核心编程第三版课后习题一
  10. java人脸识别怎么写-------源码附上
  11. 深度可分离卷积(Depthwise seperable convolution)
  12. 高频故障-桌面图标变成白纸图标的恢复方案
  13. MySQL事务 - 自增ID的回滚以及Auto Increment在InnoDB的实现
  14. Latex和word相互转换。word表格制作
  15. US Domain Center域名注册| 域名注册商
  16. Orkut被XSS蠕虫击中
  17. 电子书——人类进步的电梯
  18. 写给那些表面笑嘻嘻的人
  19. 【织女星RISC-V】TSTMR(类ARM的SYSTICK)功能
  20. CompareNoCase 比较两个字符串,不区分大小写

热门文章

  1. Golang 027. 佩尔数列Pell(n)
  2. 开源MPEG-4编码器 XviD简介
  3. 草图溜溜到底是如何进行草图大师建模的呢?
  4. 51单片机学习:红外遥控实验
  5. net start mysql命令 显示拒绝访问
  6. Ubuntu安装及Ubuntu下常用软件安装(不断补充)及Windows相关--软件开发用途
  7. python ctypes总结
  8. 用KEIL5打开KEIL4的文件
  9. matlab怎么把命令窗口里的运行结果放到gui界面上,如何将命令窗口出现的结果,直接显示在gui的listbox里面...
  10. Java线程生命周期及常用方法说明