Unity地面交互效果——6、地形动态顶点置换和曲面细分
回到目录
Unity置换贴图局部距离曲面细分
大家好,我是阿赵。
这篇文章是我无聊的时候做了一个demo,觉得挺有趣,于是就发上来。这里面包含了4个内容:置换贴图、顶点偏移、局部曲面细分,曲面细分按距离调整强度。
一、考虑的思路
一开始我是在考虑不同的技术手段实现物体的表面凹凸效果的。我能想到的方法大概是这些:
1、凹凸贴图
2、法线贴图
3、视差偏移
4、置换顶点
这几个方法里面,凹凸贴图现在很少有人用了,因为效果不好。法线贴图效果比凹凸贴图好很多,不过他只能模拟光射到表面时,通过不同的法线方向来模拟凹凸感觉,并不会真正的产生凹凸变形。视差偏移的效果比法线贴图好很多,因为他是通过改变采样的位置来模拟遮挡物和被遮挡物之间的关系,所以产生的不止是光影的凹凸感,而是会真正的有遮挡关系。不过视差偏移真的要效果逼真,要采样多次,而且也不适合做太过明显的变形,比如地形大面积凹凸。
最后,就把思考点停留在了置换顶点上面了。这个是一个比较真实的手段,靠一张置换贴图,就能生成出不同高度的模型。
二、实现手段
我这里就简单的准备了一张高度图,黑色是凹陷,白色是凸出,灰色是平地。

通过在顶点程序采样,根据黑白的值来偏移顶点的y轴,就可以做出凹凸的效果:

很明显的问题,顶点数不够,所以凹凸的效果不好。
这个时候,可以使用曲面细分,增加一些面数,就可以看到凹凸的感觉比较正常:

不过这么多面数并不是我想希望看到的,所以最后,再加一个根据高度图决定是否需要细分,只有凹凸的部分做细分。这里需要读取高度图,然后把高度图的0到1范围转换成-1到1的范围,然后然后计算值的绝对值大于一个数值才需要细分。也可以不转换到-1到1,就那0到1的范围减去0.5,再去绝对值比较也想。最后,就能计算出一个范围内才需要细分的效果:

这样在需要凹凸的地方增加一些面数,其他的地方还是保持正常。
最后,我还想根据距离进行细分,如果离镜头远了,那么细分的程度就没那么大,所以把刚才的那个计算细分的值,再用UnityDistanceBasedTess方法,传入距离的最大最小值,就可以计算出根据距离的细分结果了:

这个效果虽然只是我一时想起来做的一个小Demo,但我觉得似乎还是在某些地方挺好用的,你们是否想到在哪些地方用得上呢?
三、Shader代码:
Shader "azhao/DisplacementTest"
{Properties{_heightTex("heightTex", 2D) = "white" {}_heightTexVal("heightTexVal",float) = 0.01_TessValue("Max Tessellation", Range(1, 32)) = 15_normalTex("normalTex", 2D) = "white" {}_height("height", Float) = 0_displacement("displacement",float) = 1_minDist("minDist",float) = 10_maxDist("maxDist",float) = 25[HideInInspector] _texcoord( "", 2D ) = "white" {}[HideInInspector] __dirty( "", Int ) = 1}SubShader{Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+0" }Cull BackCGPROGRAM#include "Tessellation.cginc"#pragma target 4.6#pragma surface surf Standard keepalpha addshadow fullforwardshadows vertex:vertexDataFunc tessellate:tessFunction struct Input{half filler;float2 uv_texcoord;};uniform sampler2D _heightTex;uniform float4 _heightTex_ST;uniform float _height;uniform float _TessValue;uniform sampler2D _normalTex;uniform float4 _normalTex_ST;float _displacement;float _heightTexVal;float _minDist;float _maxDist;float4 tessFunction(appdata_full v0, appdata_full v1, appdata_full v2){//这里要说明一下,传进来三个点,不能直接求平均值,而要逐个点去采样//因为只要有一个点在需要细分的范围内,这整个网格就需要细分,不然凹凸的边缘会和不需要细分的网格裂开float2 uv0 = v0.texcoord * _heightTex_ST.xy + _heightTex_ST.zw;float col0 = (tex2Dlod(_heightTex, float4(uv0, 0, 0.0)).r - 0.5);float2 uv1 = v1.texcoord * _heightTex_ST.xy + _heightTex_ST.zw;float col1 = (tex2Dlod(_heightTex, float4(uv1, 0, 0.0)).r - 0.5);float2 uv2 = v2.texcoord * _heightTex_ST.xy + _heightTex_ST.zw;float col2 = (tex2Dlod(_heightTex, float4(uv2, 0, 0.0)).r - 0.5);float col = max(abs(col0), abs(col1));col = max(col, abs(col2));col = step( _heightTexVal, col);col = col * _displacement;col = max(col, 0.01f);return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, _minDist, _maxDist, col);}void vertexDataFunc( inout appdata_full v ){float2 uv_heightTex = v.texcoord * _heightTex_ST.xy + _heightTex_ST.zw;float temp_output_4_0 = ( tex2Dlod( _heightTex, float4( uv_heightTex, 0, 0.0) ).r - 0.5 );float3 appendResult13 = (float3(0.0 , ( temp_output_4_0 * _height ) , 0.0));v.vertex.xyz += appendResult13;v.vertex.w = 1;}void surf( Input i , inout SurfaceOutputStandard o ){float4 color16 = IsGammaSpace() ? float4(0.5660378,0.5660378,0.5660378,0) : float4(0.280335,0.280335,0.280335,0);float2 uv_normalTex = i.uv_texcoord * _normalTex_ST.xy + _normalTex_ST.zw;o.Normal = UnpackNormal(tex2D(_normalTex, uv_normalTex));o.Albedo = color16.rgb;o.Alpha = 1;}ENDCG}Fallback "Diffuse"
}
相关文章:
Unity地面交互效果——6、地形动态顶点置换和曲面细分
回到目录 Unity置换贴图局部距离曲面细分 大家好,我是阿赵。 这篇文章是我无聊的时候做了一个demo,觉得挺有趣,于是就发上来。这里面包含了4个内容:置换贴图、顶点偏移、局部曲面细分,曲面细分按距离调整强度。 …...
Linux系统服务之一次性服务(2)
接前一篇文章:Linux系统服务之一次性服务(1) 本文内容参考以下文章: Systemd OneShot 系统启动时运行一次特定的命令或脚本,并在执行完毕后自动退出-CSDN博客 oneshot一次性服务_typeoneshot-CSDN博客 systemd.serv…...
Vue项目解决van-calendar 显示白色空白,需滑动一下屏幕,才可正常显示
问题描述,如图 ipad(平板)或者 H5移动端引入Vant组件的日历组件(van-calendar),初始化显示空白,需滚动一下屏幕,才可正常显示 解决方法 需在van-calendar上绑定open"openCalendar"事件…...
Linux:可视化管理工具Webmin的安装
一、下载 地址:Webmin官网 我这里下载的是1.700-1版本 二、安装 1、在虚拟机上新建目录并安装软件 mkdir /opt/webmin rpm -ivh webmin-1.700-1.noarch.rpm2、修改webmin的root密码 /usr/libexec/webmin/changepass.pl /etc/webmin root 1234563、修改端口(可…...
WARNING: Access control is not enabled for the database.
MongoDB shell version v3.4.24 WARNING: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted. 1)未启用访问控制 2)读写访问不受限制 D:\MongoDB\Server\3.4\bin>mongo MongoDB shell version v3.4.24 c…...
JavaScript编程进阶 – Return语句
JavaScript编程进阶 – Return语句 JavaScript Programming Advanced – Return Statement By JacksonML 就像人们习惯的函数一样,总觉得在函数体最后需要一个return语句,标志着函数的结束,就像下面这个函数 theFunc() 那样。 function theFunc() { re…...
Python与设计模式--备忘录模式
23种计模式之 前言 (5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、(11)策略模式、责任链模式、命令模式、中介者模…...
04_Flutter自定义Slider滑块
04_Flutter自定义Slider滑块 一.Slider控件基本用法 Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[Text("sliderValue: ${_sliderValue.toInt()}"),Slider(value: _sliderValue,min: 0,max: 100,divisions: 10,thumbColor: Colors.…...
服务器数据恢复—EMC存储raid5故障导致上层应用崩溃的数据恢复案例
服务器存储数据恢复环境: EMC某型号存储,8块组建一组raid5磁盘阵列。上层操作系统采用zfs文件系统。 服务器存储故障&分析: raid5阵列中有2块硬盘未知原因离线,raid5阵列崩溃,上层应用无法正常使用。 服务器数据恢…...
7.1 Windows驱动开发:内核监控进程与线程回调
在前面的文章中LyShark一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以监控进程线程创建为例,在Win10系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原…...
基于ssm的汽车论坛管理系统设计与实现
基于ssm的汽车论坛管理系统设计与实现 摘要:信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题…...
实习开发日志经验总结(一)
文章目录 前言实习日志经验总结 前言 自己之前实习过程中遇到的问题以及相应的解决过程,我都有记录形成比较凌乱的实习日志。故想在整个实习日志的基础上,提炼一些技术知识点或者是解决问题的思路。考虑到实习项目的不方便公开性,所以会隐去…...
【Unity基础】8.简单场景的搭建
【Unity基础】8.简单场景的搭建 大家好,我是Lampard~~ 欢迎来到Unity基础系列博客,所学知识来自B站阿发老师~感谢 (一)场景资源 (1)Import资源包 今天我们将手动去搭一个简单的场景,当…...
傅里叶变换及其在机器学习中的应用
一、介绍 傅立叶变换是一种数学技术,在各个科学和工程领域发挥着关键作用,其应用范围从信号处理到量子力学。近年来,它在机器学习领域发现了新的意义。本文探讨了傅里叶变换的基础知识及其在机器学习应用中日益增长的重要性。 …...
xorm源码学习
文章目录 XORM源码浅析及实践ORMORM vs. SQLXORM软件架构 ORM 引擎 Engine——DBM*core.DB Golang:database/sql 源码基本结构连接复用,提高性能。增加数据库连接池数量连接管理 database/sql主要内容:sql.DB创建数据库连接sql.Open()DB.conn…...
Vue3中的<script setup>和<script>的区别
相同点 在一个 Vue3 单文件组件 (SFC)中,<script setup> 和 <script> 它们各自最多只能存在一个。 不同点 <script setup> 这个脚本块将被预处理为组件的 setup() 函数,这意味着它将为每一个(也可以说每一次)组件实例都执行。 <…...
Docker笔记-Docker搭建最新版zabbix服务端(2023-07-31)
前言 一开始问chartgpt上,搭建的思路是对的,但命令和细节有问题,最后还是依靠StackOverflow解决的。一开始在amd的linux上搭建好docker版的zabbix,但放到arm的机器上就报错了,原因是指令集不匹配,最后跑到…...
QT配合CSS隐藏按钮
第一种方法 在Qt的CSS样式表中,使用 visibility 属性来隐藏按钮。设置 visibility 为 hidden 不可见,而设置为 visible 则可见。 隐藏所有 QPushButton QPushButton {visibility: hidden; }隐藏特定的按钮,用按钮的名称或样式类进行定位就…...
2023亚太地区数学建模C题思路分析+模型+代码+论文
目录 1.2023亚太地区各题思路模型:比赛开始后,第一时间更新,获取见文末名片 3 常见数模问题常见模型分类 3.1 分类问题 3.2 优化问题 详细思路见此名片,开赛第一时间更新 1.亚太地区数学建模ABC题思路模型:9比赛开…...
Linguistic Steganalysis in Few-Shot Scenario论文阅读笔记
TIFS期刊 A类期刊 新知识点 Introduction Linguistic Steganalysis in Few-Shot Scenario模型是个预训练方法。 评估了四种文本加密分析方法,TS-CSW、TS-RNN、Zou、SeSy,用于分析和训练的样本都由VAE-Stego生产(编码方式使用AC编码)。 实验是对比在少样…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
