草的渲染理论

news2024/9/21 8:04:09

Unity引擎提供了基础的terrain工具,可以制作地形,在上面刷树刷草。对于,Unity是支持带LOD的Prefab,不同距离显示不同细节的模型,效果还不错。对于草,Unity支持两种方式来刷草,一种是Add Grass Texture,一种是Add Detail Mesh。第一种实际上就是放一张图片,可以支持billboard,目的是营造一片草的错觉,这个只能远看,但是离得近,就穿帮了,尤其是在俯视的情况下,如下图。第二种是Add Detail Mesh,类似刷树,但是不支持LOD。

  • 面片:最传统的一种做法,用一片方形的网格贴一张草的贴图插在地上就行,原神里也可以看到用面片表现的小黄花。缺点很明显,俯视的时候穿帮很严重 

  • CPU生成网格:其实就是想办法用代码绘制点线面拼出一棵(或者一大片)草。相比于3d软件中建模再导入,用代码画的草在体现摇摆动画的时候可能会方便些,不像建模出来的草想摇摆的话可能还得k个形态键啥的。https://github.com/ECHibiki/WindSway-HDRP
  • VIsualEffectGraph这方案也是在Github上偶然看到的,而且它好像还上架unity商店了,如果是用HDRP来做游戏的话可以直接用:https://github.com/SirMishMash/Unity-StylizedGrass
  • VEG粒子
  • 几何着色器

1.使用面片+贴图 性能好但效果不好

2.使用模型草,用GPUInstance来做渲染优化,并且使用ComputeShader做剔除,再结合Lod做分级。

草的着色

基于现实的观察,草的光照主要收以下光照模型影响:

1.漫反射

2.高光

3.透射

4.次表面散射

事实上,任何你不知道怎么去做光照模型的渲染,都可以尝试将这光照渲染四兄弟用上去。比如头发,水,树,云,雪,冰等等。接下来就是怎么具体去实现这四兄弟。

单个草有自己的光照表现,而多个草组成草堆,草堆也有自己的光照表现。在做草的光照时,需要考虑到,局部的“单草” 与 整体的“草丛”。对于单草部分,使用单个草的法线做光照计算;对于草丛部分可以使用地形的法线来近似草丛的法线。总体的思路是,高光用来表现草个体的差异性,漫反射 透射 用来表现草丛的整体性。不同的部位,不同的光照方向,可以营造出“体积感”,有局部也有整体的效果是符合美术感官的。

对于草的观察,我们可以做出以下假设:

越年轻的草,水越多,颜色更鲜艳,重量大,弯曲程度小,摇晃小,光照越丰富(漫反射+高光+透射+SSS)。

越老的草,水越少,颜色扁暗,重量轻,弯曲程度大,摇晃大,光照越简陋(越多的漫反射)。

因为草颜色偏绿色块 即使在VS里计算光照模型 与PS里计算出的效果也基本一致,所以可以做一个优化:直接在VS里计算光照模型。因为草的顶点数量比较少,这可以节省大量的计算资源。这是一个基于美术观察的优化Trick。

具体实现

漫反射

对于“草”这方面,使用PBR光照模型的草效果不好。其在于漫反射是Lambert,在暗部就是一片死黑,即使换成了DisneyDiffuse效果也没能更好。为了达到风格化的效果,我们可以借鉴“日式卡通渲染”中漫反射的Trick表现。

float NL = dot(N,L);
float v1 = NL+1;
float v2 = NL;
float3 D1 = lerp(DiffuseColorLow,DiffuseColorMid,v1);
float3 D2 = lerp(DiffuseColorMid,DiffuseColorHigh,v2);
float3 DiffuseGrass = lerp(D1,D2,NL>0);

 高光

PBR高光GGX三兄弟DFG中的G项被我干掉,因为G项本质上就是将高光在暗部裁剪掉,但是由于草非常薄,光可以直接透过,所以对于G项来说,不能把草当成球直接将高光暗部裁剪!但是如果不做任何处理,又会导致满屏的高光,基于现实与美学上的考量,越靠近人眼处,高光越弱,越远的地方,高光可以越强。我们可以重构一个G项,叫做CameraFade,根据到相机的距离衰减高光。

float GGX_DistanceFade(float3 N,float3 V,float3 L,float Roughness,float DistanceFade)
{
    float3 H = normalize(L+V);
    float D = D_DistributionGGX(N,H,Roughness);
    float F = F_FrenelSchlick(saturate( dot(N,V)),0.04);
    float G = G_GeometrySmith(N,V,L,Roughness);

    return D*F*DistanceFade;//Kill G for more natural looking
}

用单草模型的顶点法线做 初级高光表现局部,草的高光在草尖端比在底部更明显

用草丛(地形法线)做次级高光表现整体。

草丛+单草高光(Width DistanceFade)

高光波瓣

一层高光看起来缺少细节层次感,那么就多加几层,Siggraph上的大佬管这种方式叫做高光波瓣,那么我们可以使用多层不同水分的高光相叠加,但要保证能量守恒。我们可以构建出如下高光波瓣叠加方式:

float3 g1 = GrassSpecular(GrassWater)
float3 g2 = GrassSpecular(GrassWater*0.5)
float3 g3 = GrassSpecular(GrassWater*0.5*0.5)
float3 grassSpecular = g1*0.5+g2*0.3+g3*0.2;//高光能量守恒

能量守恒

我们可以使用GrassWater来调合,这符合我们前面的所讨论的,草水份越多光照表现越丰富,否则就更偏向于漫反射。艺术家可以预设不同水分的草,从而使一片草原中,草的光照表现更丰富。

FinalColor = lerp(Diffuse,Specular+Transmission+SSS,GrassWater);

草的AO

通过周围草的数量来决定该草AO信息,而不是通过后处理深度与法线来计算AO!

为此可以构造出一个二维高斯采样算子(或其他算子),快速计算出AO信息。离线计算出AO信息后直接写入到草的Data中,读取的时候就可以不占用计算资源。

透射

单草很薄,但是很多草组合起来又很厚。因此透射对于这两种情况都要考虑到。AO信息也包含着一块区域草的“密度”,如果越密那么意味着,光越少会透过该区域。因此在计算透射的时候也要将AO信息考虑进去。

float SimpleTransmission(float3 N,float3 L,float3 V,float TransLerp,float TransExp,float TransIntensity,float ThicknessFade)
{
    float3 fakeN = -normalize(lerp(N,L,TransLerp));
    float trans = TransIntensity * pow( saturate( dot(fakeN,V)),TransExp);
    return trans*ThicknessFade;
}

草的次表面散射

Siggraph上的大佬说,做次表面散射需要考虑三点:

  1. -大曲率处的SSS:
  2. -小曲率处的SSS
  3. -阴影处的SSS

1.大曲率处的SSS

草的曲率可以用地形的曲率来近似。那么用NL以及曲率采样Lut图就可以近似地模拟出草的SSS,但是草不需要像皮肤那么精细,我们在实现草的漫反射时,其实已经将这一步给近似模拟了,因为NL小于零的部分可以自定义出透过的颜色。

2.小曲率处的SSS

小曲率处的SSS在皮肤渲染中是直接用模糊法线贴图来解决。在草地渲染上我们也可以模糊地形的法线来近似模拟草丛的模糊法线。这一步可以离线在TerrainData里预处理好并且保存为草的数据。在使用时可以直接使用这个插值来模拟草SSS的程度

float3 GrassNoraml = lerp(TerrainNoraml,TerrainBlurNormal,sssIntensity);

3.阴影处的SSS

因为草地阴影处的SSS其实并没有皮肤那么明显,因此我们忽略这项处理。

草的弯曲

草的弯曲程度我们做出以下假设

1.取决于地形

草的弯曲程度,取决于地形的法线。

2.取决于周围草的高度与密度

如果一个草它周围有很高很密的草存在,那么意味着该草得到的阳光会更少,为了获取到更多的阳光,它会横向生长而不是纵向发展。横向生在的越长那么越容易摇晃。

3.取决于生长素

根据高中所学的生物知识,植物的生长素是由尖端产生,适量的生长素有助于生长,过量的生长素抑生长。被抑制部分比较矮。越靠近主杆部分,摇晃程度小,反之则摇晃程度大。在代码实现上,我们只需要根据顶点的Y值以及该顶点到坐标中心的XZ距离计算粗摇晃度即可。

可能还需要:

与地形表面进行颜色混合(支持平铺设置和网格地形)

风动画

透视校正,实现从上而下的最佳覆盖视觉效果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汇凯金业:解读区块链概念、类型与独特优势

区块链作为一种具有革命性的创新技术,正在逐渐改变我们的生活和商业模式。它的去中心化、安全可靠、不可篡改等特性,为解决许多传统领域中的问题提供了新的思路和方法。 一、区块链的基本概念 区块链是一种具有创新性的计算机技术应用模式,…

C#复习之类和对象

知识点一:什么是类 基本概念: 具有相同特征 具有相同行为 一类事物的抽象 类是对象的模板 可以通过类创建出对象 类的关键字 Class 知识点二:类声明在哪里 类一般声明在namespace语句块中 知识点三:类声明的语法 知识点四&#xf…

html+css 实现文字滚动的按钮

前言:哈喽,大家好,今天给大家分享htmlcss 绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 文…

2024年前端趋势:全栈或许是不容错过的选择!

近年来,前端开发的技术不断推陈出新,2024年也不例外。在这个变化迅速的领域,全栈开发逐渐成为一股不容忽视的趋势。无论你是经验丰富的开发者,还是刚刚入门的新手,掌握全栈技术都能让你在竞争中脱颖而出。而在这个过程…

Spring -- 拦截器

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 文章目录 1. 自定义拦截器2. 注册配置拦截器3. 拦截器详解3.1 拦截路径3.2 拦截器执行流程 3.3 DispatcherServlet源码分析3.3.1 初始化:3.3.2 处理请求3.3.3 适配器 拦截器是Spring框架提供的…

vue项目删除无用的依赖

1.安装依赖检查工具 npm i depcheck 2.查看无用的依赖 npx depcheck 3.手动删除pageage.json中的无用的依赖(如果有sass和sass-loader不要删,会引起项目报错) 4.全部删除完成之后,删除package-lock.json和yarn.lock文件&#x…

【文件解析漏洞复现】

一.IIS解析漏洞复现 1.IIS6.X 方式一:目录解析 搭建IIS环境 在网站下建立文件夹的名字为.asp/.asa 的文件夹,其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。 访问成功被解析 方式一:目录解析 在IIS 6处理文件解…

图纸加密与零信任沙箱:构建企业数据安全的双重保障

在这个信息爆炸的时代,数据安全如同一场没有硝烟的战争。深信达SDC沙盒防泄密系统,以其零信任沙盒技术,为企业提供了一个坚不可摧的“金钟罩铁布衫”,确保企业图纸安全“坚如磐石”。 一、数据安全的“冰与火之歌” 数据安全是一…

如何简便改文件名

在出OI题的时候,有时候想要方便地把输入输出文件的文件名都改掉,类似于将a1.in,a2.in,…,a50.in都改成b1.in,b2.in,…,b50.in 我用gpt写了一个python代码 import osdef rename_files(base_name, new_name, num_files):for i in range(1, num_files 1)…

函数实例讲解 (一)

文章目录 函数中的引用、运算符、通配符1、引用2、运算符3、通配符 函数的类别、输入方式、结果检查1、函数类别2、输入方式3、结果检查 数组的基本概念1、数组极其元素的概念2、数组的书写3、数组的类型4、内存数组的存储位置5、数组公式与普通公式的区别 逻辑判断函数之IF1、…

【工具】-gdb-学习笔记

准备工作 程序的发布方式有两种,debug模式和release模式 Linux gcc/g出来的二进制程序,默认是release模式 要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项,发布成debug模式 如下源代码经过编译: #…

VS Code C/C++ MSVC编译器

官方教程 通过快捷方式打开VS Code是编译不了的,需要对tasks.json修改(Tasks: Configure default build task) 先创建tasks.json 复制这段配置到tasks.json,记得修改VsDevCmd.bat的路径 {"version": "2.0.0","windows": {"options"…

深度学习中卷积算子和dropout算子的作用

笔者在调网络的时候,有时调细一些在想不同卷积核尺寸的卷积操作有啥区别,在哪些算子后用dropout会比较好呢?于是有了下面一段总结。 文章目录 一、卷积核尺寸1X1和3X3的区别1x1卷积核3x3卷积核 二、dropout的作用使用情况算子组合注意事项 一…

[读论文]-FreeU: Free Lunch in Diffusion U-Net 提高生成质量

摘要 In this paper, we uncover the untapped potential of diffusion U-Net, which serves as a “free lunch” that substantially improves the generation quality on the fly. We initially investigate the key contributions of the U-Net architecture to the denois…

《计算机网络》(第8版)第9章 无线网络和移动网络 复习笔记

第 9 章 无线网络和移动网络 一、无线局域网 WLAN 1 无线局域网的组成 无线局域网提供移动接入的功能,可分为两大类:有固定基础设施的和无固定基础设 施的。 (1)IEEE 802.11 IEEE 802.11 是无线以太网的标准,是有固定…

SQL数据库备份

转载:数据库备份与还原 1. 以下过程为记录客户单位备份过程。 一般有E盘选择E盘备份,否则选择D盘备份。选中备份文件需要重命名,以防原文件被覆盖。切换选项,选中压缩备份。

IoTDB 入门教程 问题篇④——外网攻击导致OOM内存溢出,服务崩溃

文章目录 一、前文二、思考问题三、验证问题五、深入思考六、总结 一、前文 IoTDB入门教程——导读 二、思考问题 从上一篇博客得知,因为内存大小设置的不合理,容易导致OOM内存溢出,最终导致服务崩溃。 事后转念一想,又在思考&…

【ADC】欠采样的基本理论及其应用中的抗混叠滤波器设计原则

概述 之前的两篇文章:信号采样中的频谱混叠现象、频谱混叠的MATLAB仿真与抗混叠滤波器设计 介绍了关于 ADC 采样时,有关奈奎斯特采样定律的基本理论、频谱混叠现象的由来,以及抗混叠滤波器的设计与仿真。但这都是基于过采样的情况&#xff0…

如何理解进程?

前言: 我们在前面的对操作系统的学习,目的是为了让我们加深操作系统对“管理”的描述。我们在上一节了解到操作系统存在许多管理,今天我们就来初次了解一下——进程管理。 进程概念: 课本概念:程序的一个执行实例&…