当前位置: 首页 > news >正文

草的渲染理论

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距离计算粗摇晃度即可。

可能还需要:

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

风动画

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

相关文章:

草的渲染理论

Unity引擎提供了基础的terrain工具,可以制作地形,在上面刷树刷草。对于树,Unity是支持带LOD的Prefab,不同距离显示不同细节的模型,效果还不错。对于草,Unity支持两种方式来刷草,一种是Add Grass…...

Redis:十大数据类型

键(key) 常用命令 1. 字符串(String) 1.1 基本命令 set key value 如下:设置kv键值对,存货时长为30秒 get key mset key value [key value ...]mget key [key ...] 同时设置或者获取多个键值对 getrange…...

bugku-web-source

kali中先用dirsearch工具扫描后台目录,然后用wget -r url/.git命令递归下载后,进入txt文件使用git reflog命令然后只用git show查看作者提交flag日志,用git show 一个一个去尝试,很多假的flag git reflog 是一个 Git 命令&#x…...

一键生成视频并批量上传视频抖音、bilibili、腾讯(已打包)

GenerateAndAutoupload Github地址:https://github.com/cmdch2017/GenerateAndAutoupload 如何下载(找到最新的release) https://github.com/cmdch2017/GenerateAndAutoupload/releases/download/v1.0.1/v1.0.1.zip 启动必知道 conf.py …...

Python WSGI服务器库之gunicorn使用详解

概要 在部署 Python Web 应用程序时,选择合适的 WSGI 服务器是关键的一步。Gunicorn(Green Unicorn)是一个高性能、易于使用的 Python WSGI HTTP 服务器,适用于各种应用部署场景。Gunicorn 设计简洁,支持多种工作模式,能够有效地管理和处理大量并发请求。本文将详细介绍…...

Java编程达人:每日一练,提升自我

目录 题目1.以下哪个单词不是 Java 的关键字?2.boolean 类型的默认值为?3.以下代码输出正确的是?4.以下代码,输出结果为:5.以下代码输出结果为:6.以下代码输出结果为?7.float 变量的默认值为&am…...

(35)远程识别(又称无人机识别)(二)

文章目录 前言 4 ArduRemoteID 5 终端用户数据的设置和使用 6 测试 7 为OEMs添加远程ID到ArduPilot系统的视频教程 前言 在一些国家,远程 ID 正在成为一项法律要求。以下是与 ArduPilot 兼容的设备列表。这里(here)有一个关于远程 ID 的很好解释和常见问题列表…...

提供三方API接口、调用第三方接口API接口、模拟API接口(一)通过signature签名验证,避免参数恶意修改

为什么要设计安全的api接口 运行在外网服务器的接口暴露在整个互联网中,可能会受到各种攻击,例如恶意爬取服务器数据、恶意篡改请求数据等,因此需要一个机制去保证api接口是相对安全的。 本项目api接口安全设计 本项目api接口的安全性主要…...

CDO学习

1.备份instie.mdb文件 2....

奥运会Ⅱ---谁会先抢走你的工作?

Devin AI 与 Microsoft AutoDev,谁会先抢走你的工作? 软件开发领域正处于一场革命的风口浪尖。Devin AI和Microsoft AutoDev 的出现,是人工智能编码领域的两项突破性进步,有望重塑软件构建方式。但是,在如此截然不同的…...

用Python打造精彩动画与视频,4.3 创建动态文本和字幕

第四章:深入MoviePy 4.3 创建动态文本和字幕 在视频编辑中,动态文本和字幕是传达信息、增强观众体验的重要元素。MoviePy 提供了丰富的工具来添加和自定义文本和字幕,包括字体、颜色、动画效果等。本节将介绍如何在视频中添加动态文本和字幕…...

spring boot + vue3 接入钉钉实现扫码登录

1:准备工作 1.1:进入钉钉开放平台创建开发者应用。应用创建和类型介绍,参考下方。 应用类型介绍 - 钉钉开放平台 (dingtalk.com) 应用能力介绍 - 钉钉开放平台 (dingtalk.com) 扫码登录第三方网站 - 钉钉开放平台 (dingtalk.com) 1.2&…...

二叉树构建(从3种遍历中构建)python刷题记录

R3-树与二叉树篇. 目录 从前序与中序遍历序列构造二叉树 算法思路: 灵神套路 从中序与后序遍历序列构造二叉树 算法思路: 灵神套路 从前序和后序遍历序列构造二叉树 算法思路: 灵神套路 从前序与中序遍历序列构造二叉树 算法…...

计算机网络中协议与报文的关系

协议和报文在网络通信中扮演着不同的角色,但它们是紧密相关的。 协议是计算机网络中实现通信的“约定”,它规定了计算机之间如何进行通信,包括数据传输的格式、步骤和规则。协议确保了不同厂商的设备、不同的CPU和操作系统之间的计算机能够相…...

机器学习 第8章-集成学习

机器学习 第8章-集成学习 8.1 个体与集成 集成学习(ensemble learning)通过构建并结合多个学习器来完成学习任务,有时也被称为多分类器系统(multi-classifersystem)、基于委员会的学习(committee-based learning)等。 图8.1显示出集成学习的一般结构:先产生一组“…...

Docker 安装 GitLab教程

本章教程,主要介绍如何在Docker 中安装GitLab。 GitLab 是一个开源的 DevOps 平台,提供了一整套工具,用于软件开发生命周期的各个阶段,从代码管理到 CI/CD(持续集成和持续交付/部署),再到监控和安全分析。 一、拉取镜像 docker pull gitlab/gitlab-ce:latest二、创建 G…...

如何在生产环境中千万表添加索引并保证数据一致性

技术分享文档:如何在生产环境中千万表添加索引并保证数据一致性 目录 引言添加索引的挑战解决方案概述详细步骤 4.1 创建新表并添加索引 4.2 批量导入数据 4.3 处理增量数据 4.4 表名切换确保数据一致性 5.1 暂停写操作 5.2 记录增量数据 5.3 应用增量数据设置回滚…...

Uni-APP页面跳转问题(十六)

【背景】最近在做公司一个PAD端,谁被点检功能,主要时为了移动端点检设备和打印标签,需求比较简单就是扫描设备二维码,问题在于扫描后要能够重复进行多设备的扫描;早期开发的设备点检能够满足需求但是当连续扫描五六十个设备后,APP卡死,必须重启才能使用。 界面原图: 输…...

Java新特性(二) Stream与Optional详解

Java8新特性(二) Stream与Optional详解 一. Stream流 1. Stream概述 1.1 基本概念 Stream(java.util.stream) 是Java 8中新增的一种抽象流式接口,主要用于配合Lambda表达式提高批量数据的计算和处理效率。Stream不是…...

springboot系列教程(三十一):springboot整合Nacos组件,环境搭建和入门案例详解

一、Nacos基础简介 1、概念简介 Nacos 是构建以“服务”为中心的现代应用架构,如微服务范式、云原生范式等服务基础设施。聚焦于发现、配置和管理微服务。Nacos提供一组简单易用的特性集,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管…...

从高通市值超越英特尔看半导体IP价值与Fabless模式

1. 从一则旧闻谈起:当高通市值超越英特尔2012年11月9日,对于全球半导体行业而言,是一个值得被记住的日子。那天,一则消息在业界引发了不小的震动:高通(Qualcomm)的市值首次超越了英特尔&#xf…...

专业级macOS歌词同步方案:LyricsX核心功能深度解析

专业级macOS歌词同步方案:LyricsX核心功能深度解析 【免费下载链接】LyricsX 🎶 Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX LyricsX是一款专为macOS设计的专业级歌词同步工具,通过智能歌词…...

做定制开发的定制软件开发公司平台

在数字化转型浪潮下,“定制软件开发”几乎成了每一家力图通过技术构建壁垒的企业的必选项。然而,一个令人尴尬的现实是:很多企业在数字化上砸了重金,不仅没换来效率,反而陷入了“开发超预算、交付总延期、上线全是坑”…...

互联网大厂 Java 求职面试技巧揭秘

互联网大厂 Java 求职面试技巧揭秘 在当今互联网大厂求职面试中,技术与场景的交汇点常常成为面试官考察的重点。本文将通过一位搞笑的程序员燕双非与严肃的面试官的对话,展示 Java 技术栈下的面试问题,并深入解答其中的技术要点。第一轮面试 …...

如何将Claude Code的配置无缝迁移至Taotoken平台以解决封号困扰

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 如何将Claude Code的配置无缝迁移至Taotoken平台以解决封号困扰 Claude Code 作为一款高效的编程助手,其核心能力依赖于…...

ClawGuard:为Clawdbot AI智能体打造的安全监控与熔断防护系统

1. 项目概述:ClawGuard 是什么,以及为什么你需要它如果你正在使用或开发基于 Clawdbot 框架的 AI 智能体,那么“安全”和“可控”这两个词,大概率已经在你脑海里盘旋过无数次了。我接触过不少团队,从最初的兴奋于 AI 智…...

Encounter/Innovus GIFT TCL 脚本流程索引清单

目录 一、 布局阶段 (Placement) 二、 布线阶段 (Routing) 三、 时序阶段 (Timing) 四、 电源阶段 (Power) 五、 IO 与端口处理 六、 调试与辅助工具 一、 布局阶段 (Placement) 脚本名称 核心用途 调用场景 userAddAllHInsts.tcl 为源模块中的每个扇出添加缓冲器 解决高扇…...

从电机控制到呼吸灯:用STM32CubeMX玩转TIM高级定时器的互补PWM与死区时间配置

从电机控制到呼吸灯:用STM32CubeMX玩转TIM高级定时器的互补PWM与死区时间配置 在嵌入式开发中,定时器是最基础也最强大的外设之一。对于STM32开发者来说,掌握高级定时器的互补PWM输出和死区时间配置,意味着可以解锁从电机控制到LE…...

共筑智能传播信息安全域,新华社国家重点实验室与北京时光不语达成合作

新华社媒体融合生产技术与系统国家重点实验室与北京时光不语科技有限公司(TIMUS.AI)正式建立研发生态伙伴关系,并联合推出面向智能传播环境的“新华智信感知平台”,深化智能传播领域科研创新与成果转化,共同构建负责任…...

Claude AI代码扩展工具:在IDE中无缝集成智能编程助手

1. 项目概述:一个为Claude AI设计的代码扩展工具最近在折腾AI编程助手的时候,发现了一个挺有意思的项目——dliedke/ClaudeCodeExtension。这玩意儿说白了,就是一个专门为Claude(就是Anthropic家那个AI)设计的代码扩展…...