UnityShader崩坏渲染解析系列(2)--明暗计算
身体渲染
- 什么是明暗
- 处理明暗
- 崩坏处理
- 资源解析
- 总结
什么是明暗
与实时渲染不一样的地方在于,日式卡通渲染阴影过度有明显的分界线。
没错,左边的明暗变化有一条很明显的交界线,而右边的是有过渡效果的。日式卡通基本采用左边的方式。
可能会有人会说好丑啊,确实因为日式的漫画的明暗变化都是由艺术家完成的,可以说是漫画不可或缺的灵魂,而作为程序员只能按照一定的规律生成阴影,我们按照入射角、视角、法线的关系生成对应的明暗面,肯定 无法满足艺术家的需求,他们肯定会说哦,nonono…你们这里这里不能这样这样,那里那里要那样那样。。。然后我们说,哦,nonono,他们这样是因为那样的。。。。哦,nonono。。哦。。。八嘎。
处理明暗
双方都有道理,都是不能减少的,那么有的游戏会采用的策略相对简单粗暴,美术直接把阴影画到贴图上,那样效果就一致了。但是这样的效果在某一个角度下看上去是完美的,一旦视角发生变化,或者角色旋转就会发现这个明暗关系跟场景不搭,动态效果极差,但是如果我们是3D游戏,显然必须要高大尚,然后这个方向继续延伸,搬砖员登场,我们再此基础上加上程序运算的阴影。由此第一个方案诞生了,美术颜色贴图+程序阴影。显然这种方案制作相对简单,容易理解,但是效果却差强人意,因为美术做的阴影在任何时候都是一样的,可能在灯光直射的情况的这些阴影是不需要存在的。而程序的阴影虽然看起来可以有动态效果,但是美观角度上却可能让美术扣分了。
崩坏处理
为了解决这种尴尬的处境,大佬们使用了遮罩图来处理,明暗关系单独使用贴图处理,程序员使用公式计算阴影,只不过计算的这个地方是不是阴影会通过遮罩图决定。那么这样一来,美术可以按照自己的想去做阴影,又可以实现动态的效果。
资源解析
按照我们上面的理论,崩坏有一个阴影的遮罩图,遮罩图的G通道就是处理的明暗计算,如下:
通过这张图和Lambert的光照系数,共同计算出阴影阀值。代码如下:
//2.采样遮罩图--g通道确订明暗关系
fixed3 lightTexColor = tex2D(_LightMapTex, i.uv.xy).rgb;
//return lightTexColor.g;
fixed3 secondShadowColor = baseTexColor.rgb * _SecondShadowMultColor.rgb;
fixed3 firstShadowColor = baseTexColor.rgb * _FirstShadowMultColor.rgb;
//2.1 通过lambert、阴影衰减和外部设定的明暗面阀值确定明暗面
//-----通过顶点颜色和遮罩图的g通道的乘积来表示,此片元成为暗面的倾向
fixed realMask = lightTexColor.g * i.color.r;
float t1 = (realMask + i.lambert * atten) * 0.5f;
//进行二分色,可以优化使用平滑处理
t1 = 1.0f - step(_SecondShadow, t1); //smoothstep(_SecondShadow, _SecondShadow+0.03, t1) //计算第一次二分色的颜色
secondShadowColor = t1 * secondShadowColor + (1.0f - t1) * firstShadowColor;
float4 outCo;
//对应的做了映射x=1.2x-0.1 y=1.25y-0.125
fixed2 expandMask = realMask * fixed2(1.2f, 1.25f) + fixed2(-0.1f, -0.125f);
//对暗面权重值做映射之后的阀值处理
t1 = 1.0f - step(0.5f, realMask);
t1 = t1 * expandMask.x + (1.0f - t1) * expandMask.y;
//--上面是做了分段的解析t1=1.2x-0.1 {x=[0,0.5]} t1=1.25x-0.125 {x=[0.5,1]} //将设置的阴影和光照信息结合,本次进行的
t1 = (t1 + i.lambert * atten) * 0.5f;
//再次进行二分色
t1 = 1.0f - step(_LightArea, t1);
//这里是在阴影处添加了另一个阴影颜色
firstShadowColor = t1 * firstShadowColor + (1.0f - t1) *baseTexColor;
//处理第一次二分色和第二次二分色的叠加。暗面倾向小于0.09的定义为二次暗面。
fixed t2 = 1.0f - step(0.09f, realMask);
//t2阴影部分为1,亮面为0,而这里亮面使用了
fixed3 diffuseColor = t2 * secondShadowColor + (1.0f - t2) * firstShadowColor;outCo.xyz = diffuseColor;
return outCo;
有代码我们看出,G通道的数据只是一种明暗倾向图,实际操作时会和Lambert计算出的光照系数以及阴影衰减(这个源码中是没有的)混合来计算明暗的差值。第二次做二分色的时候做了一次映射,[0,0.5]对应[-0.1,0.5],[0.5,1]对应[0.5,1.125],单从结果上看就是再次加深了倾向,以0.5为分界,是小于0.5的地方暗面敏感度更高,大于0.5的地方敏感度更低。这种操作更深层次的含义就参详不出来了。然后就是对两次二分色做叠加,以0.09为分界。小于的部分为阴影2,[0.09,_LightArea]的部分为阴影1,其他部分为默认色。致此,明暗计算完毕,我们看下效果(为了更直观,去掉贴图颜色):
遮罩数值(mask.g*vertexcolor.r) | 颜色获取 |
---|---|
0-0.09 | 第一次二分色计算的颜色,图片中绿色 |
0.09-1 | 第二次二分色计算出来的颜色,图片中绿色之外的颜色 |
两次二分色的计算对比:
二分色系数 | 对比数值 | Mask计算 |
---|---|---|
_SecondShadow | (Mask+lambert * atten)*0.5 | Mask= _LightMapTex.g*vertexcolor.r==>[0,1] |
_LightArea(个人理解_FirstShaow更形象) | (Mask+lambert * atten)*0.5 | 令 x=_LightMapTex.g*vertexcolor.r ; Mask=1.2x-0.1 {x=[0,0.5]} Mask=1.25x-0.125 {x=[0.5,1]} |
OK~~明暗计算,其实到这里就结束了,这篇很低产,确实没啥动力写东西了,觉的还是有点浪费时间。无聊的时候写写吧,当个笔记还是不错的,接下来分享的就是高光,Bloom,以及Dither效果、SpecialSstate、RimGlow、Distortion。其实源码中还有一部分是LUT纹理查找的以及双线性插值计算的一些方法,主要是角色颜色贴图的,有时间的话可以分享一下。
总结
分析可能有错的地方,如果有错还请多多指出。
UnityShader崩坏渲染解析系列(2)--明暗计算相关推荐
- UnityShader崩坏渲染解析系列(3)--高光、Dither效果、Rim、特殊状态
身体渲染 高光 Dither效果 Rim 特殊状态 小结 高光 前面介绍了暗面的计算方式,接下来是高光的计算效果.高光计算比较简单,采用了Blinn-Phong的光照模型,明暗计算的时候采用了lamb ...
- 交互式计算机图形学总结:第五章 光照和明暗绘制
第五章 光照和明暗绘制 光照的一些概念 –从光源照射到物体的光传递了反射(Reflective)光[包括漫反射(Diffuse)和镜面(Specular)反射],透明(Transparent)光和吸收 ...
- Redux 源码解析系列(一) -- Redux的实现思想
文章来源: IMweb前端社区 黄qiong(imweb.io) IMweb团队正在招聘啦,简历发至jayccchen@tencent.com Redux 其实是用来帮我们管理状态的一个框架,它暴露给 ...
- 15.真实感图形——光照与明暗+光线跟踪+纹理映射+辐射度方法+阴影
♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥ ...
- 素描教程石膏像明暗素描技法
一.打形 先通过理解形体结构切分块面,再以线描的形式勾出对象全部的轮廓.这种线描应具有如下特征: 1.已经具备一定的体积空间,高低远近层次分明. 2.交代了较为详细的细节,如:眼睑.鼻翼的厚度及其穿插 ...
- Canvas像素调节—调节图片的明暗与对比度
前几周做了一个医疗展示CT图的项目,需要对DICOM文件进行解析展示并且在页面中对图像进行明暗和对比度的调节功能.费了许多精力将此功能做了出来(虽然使用的并不是DICOM文件中的窗宽/窗位,但也算是一 ...
- Baumer工业相机堡盟相机VLXT-90M.I如何做平场校正阴影校正:消除图像明暗不均匀现象
项目场景: 特殊环境类项目,使用高速高稳定并自带高防护的VLXT.90M.IBaumer相机作为相机主体,它属于万兆网系列中的一种,使用该相机可以保证图像质量的前提下提高图像传输速度. 相机型号:VL ...
- 2.0 解析系列 | 一文详解新一代OceanBase云平台
小蚂蚁说: 9月21日,OceanBase 2.0 在云栖大会上重磅发布.我们将在接下来的时间里为大家持续推出 "OceanBase 2.0 技术解析系列" 文章,分别从 可运维性 ...
- Fragment全解析系列
文/YoKey(简书作者) 原文链接:http://www.jianshu.com/p/d9143a92ad94 著作权归作者所有,转载请联系作者获得授权,并标注"简书作者". F ...
最新文章
- 特斯拉亚洲最大超级充电站正式运营,可同时提供20辆车的快充服务
- linux下copy命令c实现,C语言自己实现linux下cp文件复制命令
- linux下安装zmap和zgrab
- vi中 wq 、wq!、x、q、q!区别
- 验证集与测试集的区别
- 计算机win7启动不起来,详解电脑启动不了怎么办
- 论文阅读 | Tackling Adversarial Examples in QA via Answer Sentence Selection
- 结合可变形注意力的视觉Transformer
- bsfl ecx,ecx
- 我是一个flag 侠
- python代码画大白_Python turtle 画个大白
- PDF文档无损去签名去口令
- 云计算架构中的Iaas、Paas、SaaS详解
- 酷狗的krc歌词文件的解析
- office中“Error! Reference source not found.“”错误! 参考源未找到“的问题解决方案...
- Flex 2.0 软件及文档下载
- JVM crash 异常分析
- ASP.NET Core 3.1系列(15)——EFCore之DB First
- 使用 RSA 进行加解密
- 十分钟带你了解mock.js
热门文章
- 低光图像目标检测的研究成果总结
- 常用URL Schema
- 计算机主机电源灯不亮,电脑电源指示灯不亮开不了机怎么办
- 2017 企业「年度十大转型先锋」榜单揭晓!
- mac 桌面分屏软件_如何实现Mac OS 下的分屏显示?
- Unity3D类英雄联盟镜头控制(平移和缩放)
- Python自动生成表情包,python在手,从此斗图无敌手!
- 【动态ppt制作软件】Focusky教程 | 添加背景音乐
- android菜单键 r9,【报Bug】android oppoR9tm 使用subnvue导航栏初始化时 导航栏阴影闪烁...
- 判刑了继续上诉有用吗_觉得判刑判重了上诉有用吗?