基于高度的纹理混合shader

基于高度的纹理混合shader

原文:基于高度的纹理混合shader - 知乎 (zhihu.com) 

最近支持一个使用unity2021的项目,发现urp自带的Terrain/Lit shader已经自带高度混合了,看了下和我当初写的那个基本差不多,感觉稍微要比我的严谨一些,大家感兴趣的可以参考下,代码如下:

#ifdef _TERRAIN_BLEND_HEIGHT
void HeightBasedSplatModify(inout half4 splatControl, in half4 masks[4])
{// heights are in mask blue channel, we multiply by the splat Control weights to get combined heighthalf4 splatHeight = half4(masks[0].b, masks[1].b, masks[2].b, masks[3].b) * splatControl.rgba;half maxHeight = max(splatHeight.r, max(splatHeight.g, max(splatHeight.b, splatHeight.a)));// Ensure that the transition height is not zero.half transition = max(_HeightTransition, 1e-5);// This sets the highest splat to "transition", and everything else to a lower value relative to that, clamping to zero// Then we clamp this to zero and normalize everythinghalf4 weightedHeights = splatHeight + transition - maxHeight.xxxx;weightedHeights = max(0, weightedHeights);// We need to add an epsilon here for active layers (hence the blendMask again)// so that at least a layer shows up if everything's too low.weightedHeights = (weightedHeights + 1e-6) * splatControl;// Normalize (and clamp to epsilon to keep from dividing by zero)half sumHeight = max(dot(weightedHeights, half4(1, 1, 1, 1)), 1e-6);splatControl = weightedHeights / sumHeight.xxxx;
}
#endif


纹理混合(Texture Blend)是非常常见的着色器需求,在很多实时游戏中都需要它来实现复杂的地面纹理,参考了Advanced Terrain Texture Splatting这篇文章写了一个基于高度进行混合的shader,这里分享一下自己的理解,效果如下:

动图封面

(动图请点这里:https://pic4.zhimg.com/v2-5ebb57038515b3659a7b50c7976fe7e3_b.gif)

说到贴图混合,也许你已经听说过Texture Splatting技术了,这个术语是Charles Bloom创造的,他在http://www.cbloom.com/3d/techdocs/splatting.txt里对这个技术进行了阐述;

混合的最简单做法就是,用一个通道对贴图进行插值 ,效果如下

核心代码如下

void surf (Input IN, inout SurfaceOutput o) {fixed4 splat_control = tex2D (_Control, IN.uv_Control).rgba;	fixed3 lay1 = tex2D (_Splat0, IN.uv_Splat0);fixed3 lay2 = tex2D (_Splat1, IN.uv_Splat1);fixed3 lay3 = tex2D (_Splat2, IN.uv_Splat2);fixed3 lay4 = tex2D (_Splat3, IN.uv_Splat3);o.Alpha = 0.0;o.Albedo.rgb = (lay1 * splat_control.r + lay2 * splat_control.g + lay3 * splat_control.b+ lay4 * splat_control.a);} 


这端代码很好理解,通过splat_control这张贴图的四个通道控制_Splat0~_Splat3这四张贴图的混合,如果splat_control对应通道的值为1,那么这个通道对应的贴图就完全显示,为0则完全不显示,通过修改splat_control贴图就可以实现想要的混合效果了;

这种技术在Unity3D的标准地形编辑器中有使用。

如你所见,过渡很平滑,但不太自然。石头看起来就好像被沙子污染了,但在现实世界中这是不可能发生的情况。沙子不会粘着石头,相反地,沙子会落下来,填补到石头之间的缝隙里,而石头表面仍是干净的。

我们希望沙子会更多的在缝隙里面出现,而石头越高的地方沙子应该要越少,那么我们需要知道每一张贴图的深度信息,这里我把贴图对应的高度图保存在每张贴图的alpha通道。通过对比每张贴图的高度差,就可以知道应该显示哪张贴图了,为了简化,我们先计算两张贴图混合的情况,代码如下:

float3 blend(float3 lay1, float3 lay2)
{return lay1.a > lay2.a ? lay1.rgb : lay2.rgb;
}

`得到的是这么样的效果

其中用于混合的两张贴图和他们的透明通道分别是这样的:

我们加上splat_control 贴图的影响试试

float3 blend(float3 lay1, float3 lay2, float4 splat_control)
{return lay1.a * splat_control > lay2.a *splat_control ? lay1.rgb : lay2.rgb;
} 

得到这样的效果:


相比原来的线性混合,现在看起来已经自然很多了,沙子落在石砖路的缝隙里,并慢慢减少;但因为目前只是单纯的判断显示那个贴图,所以边缘看起来太硬了,人工痕迹比较明显,

为了改进效果,我们给边缘增加一点过渡。

float3 blend(float3 lay1, float3 lay2, float4 splat_control)
{float b1 = lay1.a * splat_control.r;float b2 = lay2.a * splat_control.g;float ma = max(b1,b2);b1 = max(b1 - (ma – 0.3), 0) * splat_control.r;b2 = max(b2 - (ma – 0.3), 0) * splat_control.g;return (lay1.rgb * b1 + lay2.rgb * b2)/(b1 + b2);
}

解释一下这段代码,先对比两张贴图的高度,高度差超过0.3的会被舍弃掉,为了防止在边缘以外的地方也被保留下来了,所以后面再乘一次splat_control,最后做一个标准化处理,把他们按比例缩放到0-1这个区间。

于是,我们就得到了下面的这个效果

看起来非常自然,沙子慢慢过渡到石砖路,砖面上的沙子比较少,缝隙里的沙子更多 。

我们把这个算法拓展到4张贴图,并通过一个值来控制混合的权重,完整代码如下:

Shader "mya/terrainTextrueBlend" {Properties {_Splat0 ("Layer 1(RGBA)", 2D) = "white" {}_Splat1 ("Layer 2(RGBA)", 2D) = "white" {}_Splat2 ("Layer 3(RGBA)", 2D) = "white" {}_Splat3 ("Layer 4(RGBA)", 2D) = "white" {}_Tiling3("_Tiling4 x/y", Vector)=(1,1,0,0)_Control ("Control (RGBA)", 2D) = "white" {}_Weight("Blend Weight" , Range(0.001,1)) = 0.2}SubShader {Tags {"RenderType"="Opaque""Queue"="Geometry"}CGPROGRAM#pragma surface surf BlinnPhong#pragma target 3.0struct Input {float2 uv_Control : TEXCOORD0;float2 uv_Splat0 : TEXCOORD1;float2 uv_Splat1 : TEXCOORD2;float2 uv_Splat2 : TEXCOORD3;//float2 uv_Splat3 : TEXCOORD4;};sampler2D _Control;sampler2D _Splat0,_Splat1,_Splat2,_Splat3;float _Weight;float4 _Tiling3;inline half4 Blend(half high1 ,half high2,half high3,half high4 , half4 control) {half4 blend = half4(high1, high2, high3, high4) * control;half ma = max(blend.r, max(blend.g, max(blend.b, blend.a)));//与权重最大的通道进行对比,高度差在_Weight范围内的将会保留,_Weight不可以为0blend = max(blend - ma +_Weight , 0) * control;return blend/(blend.r + blend.g + blend.b + blend.a);}void surf (Input IN, inout SurfaceOutput o) {half4 splat_control = tex2D (_Control, IN.uv_Control).rgba;half4 lay1 = tex2D (_Splat0, IN.uv_Splat0);half4 lay2 = tex2D (_Splat1, IN.uv_Splat1);half4 lay3 = tex2D (_Splat2, IN.uv_Splat2);half4 lay4 = tex2D (_Splat3, IN.uv_Control*_Tiling3.xy);//纯色测试代码//lay1.rgb = fixed3(1,0,0);//lay2.rgb = fixed3(0,1,0);//lay3.rgb = fixed3(0,0,1);//lay4.rgb = fixed3(0,0,0);half4 blend = Blend(lay1.a,lay2.a,lay3.a,lay4.a,splat_control);o.Alpha = 0.0;o.Albedo.rgb = blend.r * lay1 + blend.g * lay2 + blend.b * lay3 + blend.a * lay4;//混合}ENDCG }FallBack "Diffuse"
}

最终效果:

左边混合权重为0.2,右边为1,混合权重为1的时候其实就是普通的线性混合了。

加上法线和高光的效果

最后附上文中所用的贴图:链接:http://pan.baidu.com/s/1cKodFg 密码:5kvi

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

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

相关文章

A股探底回升,跑出惊天大阳,你们知道为什么吗?

今天的A股,探底回升,让人惊呆了,你们知道是为什么吗?盘面上出现3个重要信号,一起来看看: 1、今天A股市场炸锅了,AI人工智能、国产软件、存储芯片迎来了涨停潮,惊呆了,科技…

阿里提出MS-Diffusion:一键合成你喜爱的所有图像元素,个性化生成新思路!

文本到图像生成模型的最新进展极大地增强了从文本提示生成照片级逼真图像的能力,从而增加了人们对个性化文本到图像应用的兴趣,尤其是在多主题场景中。然而,这些进步受到两个主要挑战的阻碍: 需要根据文本描述准确维护每个参考主题…

力扣:59. 螺旋矩阵 II(Java,模拟)

目录 题目描述示例 1:代码实现 题目描述 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 输入:n 3 输出:[[1,2,3],[8,9,4],[7,6,5…

前端新手小白的第一个AI全栈项目---AI聊天室

前言 ok,大家好。- ̗̀(๑ᵔ⌔ᵔ๑)最近也是想做自己的第一个前后端分离的项目,刚好最近学了一点AI接口的实现。想着用接口做一个自己的ai聊天室并且尝试一下全栈式开发。中间真的解决了很多问题,也是成功之后也是想要将实现过程分享一下&a…

基于CNN卷积神经网络的MQAM调制识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 CNN模型结构 4.2 损失函数与优化 4.3 训练与测试 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff0…

d3dx9_42.dll找不到怎么正确处理?教学级修复d3dx9_42.dll的方法分享

d3dx9_42.dll找不到?别着急,这只是普普通通的dll文件找不到而已,它可能因为各种原因而导致丢失,我们只要直接对d3dx9_42.dll进行修复就可以了。下面我们一起来了解一下d3dx9_42.dll找不到的正确处理方法。 一.d3dx9_42.dll找不到是…

深度学习方法在谣言检测中的研究现状

摘要 管理社交媒体上的谣言,减少谣言对社会的危害。许多研究使用深度学习方法来检测开放网络中的谣言。为了从多个角度全面梳理谣言检测的研究现状,本文从特征选择、模型结构和研究方法三个角度分析了这一高度集中的工作。从特征选择的角度,将…

七天速通javaSE:第二天 基础:标识符与数据类型

文章目录 前言一、注释与标识符1. 注释2. 标识符2.1 标识符2.2 关键字 二、数据类型1. 语言类型2. 数据类型2.1 基本数据类型2.2引用数据类型 三、类型转换1. 自动转换2. 强制转换(不建议) 四、代码规范 前言 今天将学习Java语法的基础,认识…

c语言学习记录(十)———函数

文章目录 前言一、函数的基本用法二、函数的参数传递1.基本方式2 数组在函数中的传参 前言 一个学习C语言的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、函数的基本用法 函数是一个完成特定功能的代码模块&…

海外代理IP哪个可靠?如何测试代理的稳定性?

在数字化时代,互联网已成为我们日常生活的重要组成部分。然而,随着网络活动的增加,我们面临的安全威胁也随之增加。 黑客攻击、数据泄露、网络钓鱼等安全事件频发,严重威胁着我们的个人隐私和网络安全。代理服务器在当今的互联网世…

深入学习Java1415新特性

一、超实用的Java14新特性 1.Java14新特性概述 2.环境安装 3.超实用新特性

LLM大模型算法学习资源持续整理

文章目录 waytoagiLLM101llm-coursellm-cookbook waytoagi 飞书文档写的AGI知识库。 https://www.waytoagi.com/ LLM101 karpathy更新中的大模型教程: https://github.com/karpathy/LLM101n llm-course Course to get into Large Language Models (LLMs) wi…

node mySql 实现数据的导入导出,以及导入批量插入的sql语句

node 实现导出, 在导出excel中包含图片(附件) node 实现导出, 在导出excel中包含图片(附件)-CSDN博客https://blog.csdn.net/snows_l/article/details/139999392?spm1001.2014.3001.5502 一、效果 如图: 二、导入 …

iOS 实现类似抖音滚动效果

效果图 思路 整体上我们使用tableView实现,为了预留内容的缓冲,我们将tableView 的contentinset设置为上面一个屏幕的高度,下面一个屏幕的高度,左右为0,这样保证我们滚动过去的时候 都是准备好的内容 然后就是滑动效果…

25届最近4年中国科学技术大学自动化考研院校分析

中国科学技术大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近4年考研分数情况 四、近4年招生录取情况 五、最新一年分数段图表 六、历年真题PDF 七、初试大纲复试大纲 八、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、…

Java:从嵌入式到云时代的编程语言传奇

Java,自1995年面世以来,已成为全球最受欢迎的编程语言之一。起初,Sun Microsystems公司为了解决嵌入式设备编程的难题,开发了Oak语言,这便是Java的前身。随着互联网的兴起,Oak更名为Java,并迅速…

ONLYOFFICE 8.1版本桌面编辑器测评:超越想象的办公体验!

在当今数字化办公时代,一个功能强大、操作便捷的办公套件对于提高工作效率至关重要。ONLYOFFICE 8.1作为一款备受瞩目的办公软件,凭借其全面的功能、优异的性能和出色的用户体验,为用户带来了超越想象的办公体验。下面,我们将对ON…

SHELL/2024/6/26

1.统计家目录下.c文件的个数 #!/bin/bash count0 for filename in $(ls ~ *.c) do ((count)) done echo count$count 2.终端输入一个.sh文件,判断文件是否具有可执行权限/然后运行脚本,没有可执行权限,添加可执行权运行脚本 #!/bi…

ue 材质贴图Tiling repeat

材质问题,如下 贴图显然不符合逻辑,太大,并且是一次性贴图 换一个红砖纹理,就看清了,砖太大了 修改: 拖出一个TexCoord,代表坐标,拖出一个参数,代表次数,如…

6.22套题

B. Dark 题意:每次能在数列中能使相邻两个数-1,求当数列没有连续非0值的最小贡献 解法:设表示前i个数中前i-1个数是否为0,当前数是j的最小贡献。表示i1以后减掉d的最小贡献。 C. 幸运值 D. 凤凰院真凶