在 Substance Painter中实现Unity Standard Shader

由于有需要在Substance Painter中显示什么样的效果,在Unity就要显示什么样的效果的需求,最近研究了几天,总算在Substance Painter中实现Unity standard的材质的渲染效果。具体效果如下:
在Unity中:
在这里插入图片描述

Substance Painter中:
在这里插入图片描述
相识度能够达到百分之八九十吧。主要是Unity的项目使用的是Gamma颜色空间,还是有很大的出入,而且还不好修改。

这一篇不再讲基础的如何在Substance Painter中自定义Shader了,不了解的可以翻一翻我之前写的。

版本相关

Unity 2019.4.40 内置渲染管线 Gamma颜色空间
Substance Painter 9

痛点

  1. 阴影问题,在sp里面,阴影是取环境光里面最亮的点作为主光源位置,这个我的解决方案就是自己调,设置主光源朝向配置项,可以同步unity和sp里面的主光源朝向,那么自动生成的shadow也是一个方向的。
  2. 间接光源的镜面反射,其它文章里面也说这个问题了,大都没有很好的解决方案,我这里的解决方案是通过shader去实现动态Mipmap实现,作为调试最终效果时使用。

接下来梳理一下实现过程

模型朝向同步

两个软件使用的坐标系不同,unity是左手坐标系,而sp是右手坐标系,解决方案是,在unity里面在y轴旋转180度。
在这里插入图片描述

保证天空球的位置正确

在unity里面,我专门搭建了一个测试环境,环境反射,直接设置了一张环境反射Cubemap
在这里插入图片描述
在sp里面,需要打开显示设置,然后设置背景贴图,背景曝光设置0,背景旋转设置为270,这样设置完,两个场景去采样环境全景图时,采样的位置是一致的。
在这里插入图片描述
贴图直接用的sp里面的,位置在项目文件夹下面
在这里插入图片描述

相机同步

在unity里面使用默认的透视相机,Field of View 为60
在这里插入图片描述
在sp里面,视角设置60度,与unity相同,记得把后期特效关闭
在这里插入图片描述

主光源同步

主光源同步我的思路是,在SP里面设置主光源参数,主光源参数需要一个旋转参数,主光源颜色,以及强度,主光源默认是方向光。
在这里插入图片描述
在SP里面,我们需要先在shader里面定义参数
在这里插入图片描述
显示效果
在这里插入图片描述
接下来比较重要的就是,在SP里面将主光源的旋转,修改为朝向,实现函数这里要感谢文心一言,它总算干了一件正事
在这里插入图片描述
由此获得主光源朝向。

定义一些Unity常量

要同步shader,需要将一些常量设置
在这里插入图片描述
SP是线性空间的,所以Standard里面一些Gamma相关的代码自动摒弃。
贴图直接使用内置的方法去获取
在这里插入图片描述
还有一些和Standard对应的参数
在这里插入图片描述
间接光漫反射的球谐光照参数,是直接写死在shader里面的
在这里插入图片描述
还有像在unity里面常用的一些函数,比如saturate和lerp,都直接定义出来
在这里插入图片描述

从SP导出贴图设置

我的设置是导出四张贴图,以后需要再加,分别是Albedo贴图,Normal,Emissive,MRA
在这里插入图片描述
MRA贴图由三张贴图拼接而成,三个通道分别是Metallic,Roughness,AO

在unity里面,也重写了FragmentSetup函数,修改了里面一些逻辑
在这里插入图片描述
本来standard比较笨重,所以,我们可以将一些没必要的设置改掉,比如工作流我确定使用金属工作里,那就不需要判断了,直接使用金属工作流
在这里插入图片描述
在SP里面,直接使用内置库函数去获取贴图,思路直接按照standard的思路来即可。
在这里插入图片描述

实现直接光照

直接光照在standard里面有多种方式,为了保证效果,我这里直接使用了效果最好,渲染最昂贵的双向表面分布函数实现,代码渲染逻辑没动,还是standard的哪一套
在这里插入图片描述
在SP里面,直接复制过来即可,除了一些没用的代码删除掉了,缺少什么函数,在unity复制过来改改就能用,glsl和cg区别不大。
在这里插入图片描述
最后,输出时,我只使用了内置diffuseShadingOutput函数输出渲染。
在这里插入图片描述
同样参数下,两个模型的渲染效果
在这里插入图片描述
在这里插入图片描述

实现间接光漫反射

间接光漫反射都是直接使用SH球谐光照,我在SP里面是直接写死的参数,参数是在unityframedebug里面抄的
在这里插入图片描述
直接将它抄给SP
在这里插入图片描述
实现很简单,直接用standard的函数实现即可
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

实现间接光镜面反射

间接光镜面反射是这里面最难实现的,主要还是mipmap的问题,如果粗糙度为0,也就是最光滑的平面的时候,可以看到,获取到的镜面反射的效果是一致的。
Unity Roughness=0
在这里插入图片描述
Substance Painter Roughness=0
在这里插入图片描述
如果Roughness加大,mipmap层级上去以后,区别就很明显了。
Unity Roughness=0.5
在这里插入图片描述
Substance Painter Roughness=0.5
在这里插入图片描述
造成这样的结果的原因是两个引擎内部的对Cubemap的mipmap采样造成的,看一下Roughness=1的结果,更加明显。
Unity Roughness= 1
在这里插入图片描述
Substance Painter Roughness=1
在这里插入图片描述
在这里,我还是先列一下实现方式,两个引擎都是通过采样环境反射球来实现的环境光的镜面反射。unity里面是通过Unity_GlossyEnvironment函数实现,支持两个Cubemap采样结果混合。
在这里插入图片描述
在Substance Painter里面,则是直接使用的SP内置的函数库 lib-env.glsl,里面有个方法envSample,传入方向和mipmap即可实现
在这里插入图片描述
在这里插入图片描述
粗糙度转Mipmap和Unity的也有所不同,这个代码抄至 nagnae blog

#define UNITY_SPECCUBE_LOD_STEPS_CUSTOM 6
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness)
{half mip = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness);//mip = pow( mip, 0.53 );mip = pow( mip, 0.4 );//mip = pow( mip, 0.3 );mip *= 0.97;//float unity_environment_lod_count = float(unity_specularprobe_lod_count);#if 0float mipmap_end = environment_max_lod - environment_mipmap_bias;float mipmap_start = mipmap_end - UNITY_SPECCUBE_LOD_STEPS_CUSTOM;#elif 0	float mipmap_start = max( 0, environment_max_lod - unity_environment_lod_count );float mipmap_end = min( unity_environment_lod_count, mipmap_start + UNITY_SPECCUBE_LOD_STEPS_CUSTOM );#elif 0float mipmap_start = 0;float mipmap_scale = environment_max_lod / unity_environment_lod_count;float mipmap_tail = ( unity_environment_lod_count - UNITY_SPECCUBE_LOD_STEPS_CUSTOM ) * mipmap_scale - 1;float mipmap_end = min( environment_max_lod, environment_max_lod - mipmap_tail*1.2 );#elif 1float mipmap_start = 0;float mipmap_end = environment_max_lod - 1.5;#endifreturn mip * ( mipmap_end - mipmap_start ) + mipmap_start;
}

如果按照Substance Painter 默认的效果,结果是不理想的,环境反射越强烈,效果区别越明显,所以,我的解决方案,就是在shader里面进行一次mipmap,这是我在learnopengl学习的结果,地址:https://learnopengl.com/PBR/IBL/Specular-IBL,我实现的原理也是粗暴的进行多重采样
在这里插入图片描述
每个片元要进行1024次采样,这样性能很低,所以,我增加了一个配置项,可以进行一次采样,如果开启配置,实现多重采样,实现Unity内的那种顺滑的mipmap
在这里插入图片描述
在Roughness=0时,效果还是一致,这里不再展示。
Unity Roughness= 1
在这里插入图片描述
Substance Painter Roughness=1
在这里插入图片描述
可以看的出来,在Roughness为1时,颜色基本上相近了,只有高光范围还是有一些不同,那先这样,这也算一种解决方案。如果有更好的解决方案,欢迎小伙伴们告诉我。
Unity Roughness=0.5
在这里插入图片描述

Substance Painter Roughness=0.5
在这里插入图片描述
最终,实现了所有的直接光漫反射,直接光镜面反射 和间接光漫反射 间接光镜面反射,我们最后按照Unity的standard将颜色合并到一起,就实现了对应的效果。
在这里插入图片描述
Substance Painter Combie Roughness = 0.5 Metallic = 1
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/115246.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小米笔试题——01背包问题变种

这段代码的主要思路是使用动态规划来构建一个二维数组 dp,其中 dp[i][j] 表示前 i 个产品是否可以组合出金额 j。通过遍历产品列表和可能的目标金额,不断更新 dp 数组中的值,最终返回 dp[N][M] 来判断是否可以组合出目标金额 M。如果 dp[N][M…

错过成考报名,今年你还有这两种方式升学!

2023年广东成人高考已经报名结束啦 错过报名或没有抢到考位的同学不用伤心 你还有另外两个提升学历的机会 开放大学or小自考 今天一起来了解一下吧~ 什么是开放大学? 开放教育其实也就是开放大学,也就是我们所说的中央广播电视大学,现在…

【电源专题】什么是充电芯片的Shipping Mode(船运模式)

现在越来越多电子产品小型化,手持化,这样就需要电池来为产品供电。但电池供电造成的另一个难题就是产品的续航能力的强与弱。 如果想提升续航能力,有一种方法是提高电池容量。如果电池体积没有变化的情况下,可能使用了新型材料、高级技术来增加电池容量,但这势必会增加电池…

工作【当van-tab不满足固定在顶部】

背景 需要H5实现一下滑动列表,顶部tab栏可以切换,当向下滑动列表的时候tab栏固定到顶部。果断的看了一下官方文档: 就是这个,我一看还有扩展属性,非常友好。向下滑动查看文档 使用sticky实现的。众所周知&#xff0…

【数据库】Sql Server 2022通过临时表和游标遍历方式逻辑处理获取目标数据

2023年,第39周。给自己一个目标,然后坚持总会有收货,不信你试试! 今天有个小伙伴咨询一个Sql Server处理数据的问题,刚好重温下SqlServer临时表和游标的知识点 目录 一、需求点描述二、临时表2.1、局部临时表&#xff…

第8章 MySQL的数据目录

8.1 数据库和文件系统的关系 像 InnoDB 、 MyISAM 这样的存储引擎都是把表存储在磁盘上的,而操作系统用来管理磁盘的又被称为 文件系统 ,所以用专业一点的话来表述就是:像 InnoDB 、 MyISAM 这样的存储引擎都是把表存储在文件系统上的。当我…

Python 计算三角形面积

"""计算三角形面积介绍:已知三角形边长分别为x、y、z,可以计算三角形半周长q,然后根据海伦公式计算三角形面积S三角形半周长:q (x y z) / 2三角形面积:S (q * (q-x) * (q-y) * (q-z)) ** 0.5知识点…

Mac 上安装yt-dlp 和下载视频的操作

安装 打开终端,在终端输入 cd python的路径,然后输入pip3 install yt-dlp,如下图; 出现 如Successfully installed yt-dlp-2023.7.6 的时候,说明下载成功 下载 下载命令: yt-dlp --list-formats https…

数据变换:数据挖掘的准备工作之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…

提高接口自动化测试效率:使用 JMESPath 实现断言和数据提取!

前言 做接口自动化,断言是比不可少的。如何快速巧妙的提取断言数据就成了关键,当然也可以提高用例的编写效率。笔者在工作中接触到了JMESPath,那到底该如何使用呢?带着疑惑一起往下看。 JMESPath是啥? JMESPath 是一…

LeetCode01

LeetCode01 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和 为目标值 target 的那两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你…

LabVIEW在运行时调整表控件列宽

LabVIEW在运行时调整表控件列宽 如何在LabIEW中运行时调整表控件的列宽大小? 在VI运行时,有两种不同的方法可以更改表中列的宽度。首先,可以使用鼠标手动更改它们;其次,可以从框图中以编程方式更改它们。 手动更改列宽 只有在…