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编码)。 实验是对比在少样…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
