Wang Tile的Shader简易实现
在使用大面积的平铺纹理时,会导致重复感较强的贴图呈现在画面中。我们可以通过许多方法进行优化,WangTile就是其中一种。
WangTile(王浩瓷砖)方法通过对每条边标记颜色,并在平铺时将相同颜色的边拼接在一起,最终铺满整个平面。
参考《GPU Gems2》中的做法,但这里使用一组预先设定好的可循环组合值,以及一个4x4的瓷砖纹理。
4x4纹理图:

假设y坐标朝向为从下到上,x坐标朝向为从左到右,则索引(0,0)表示数字16的色块,索引(2,3)表示数字3的色块,以此类推。
这里首先配置好可循环的组合,他们的x轴和y轴不同的序列为:
X_seq: 1, 2, 2, 3, 0, 1, 3, 1, 2, 3, 0, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3
Y_seq: 0, 1, 2, 3, 0, 1, 3, 1, 2, 3, 1, 2, 2, 2, 3, 0, 1, 3, 0, 1, 3
这个序列可以给不同的瓷砖贴图重复使用,我们把这个作为数组传入Shader,数组长度写死为21,其Shader如下:
Shader "Unlit/WangTileTesGPU"
{
Properties
{
_TileTex("Tile Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100 Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
}; sampler2D _TileTex; uniform float _WangTile_X_Seq[21];
uniform float _WangTile_Y_Seq[21]; #define MAIN_TEX_TILE_SIZE half2(21, 21)
#define TILE_TEX_SIZE half2(4, 4) v2f vert (appdata v)
{
v2f o = (v2f)0;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
} fixed4 SampleTile(half2 uv, half2 index, half2 mainTexTileTexSize, half2 tileTexSize)
{
float xIndex = _WangTile_X_Seq[index.x % 21] / tileTexSize.x;
float yIndex = _WangTile_Y_Seq[index.y % 21] / tileTexSize.y; half2 large_uv = frac(uv * mainTexTileTexSize);
half2 sub_uv = large_uv / tileTexSize; return tex2D(_TileTex, half2(xIndex, yIndex) + sub_uv, ddx(uv), ddy(uv));
//使用ddx,ddy参数去除接缝问题
} fixed4 frag (v2f i) : SV_Target
{
half2 sub_uv_index = floor(i.uv * MAIN_TEX_TILE_SIZE);//Index: 1,2,3,4... return SampleTile(i.uv, sub_uv_index, MAIN_TEX_TILE_SIZE, TILE_TEX_SIZE);
}
ENDCG
}
}
}
传入数组的csharp脚本如下:
public class WangTileGPU : MonoBehaviour
{
public Material mat; void Start()
{
float[] index_x_loop = new float[] { 1, 2, 2, 3, 0, 1, 3, 1, 2, 3, 0, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3 };
float[] index_y_loop = new float[] { 0, 1, 2, 3, 0, 1, 3, 1, 2, 3, 1, 2, 2, 2, 3, 0, 1, 3, 0, 1, 3 }; mat.SetFloatArray("_WangTile_X_Seq", index_x_loop);
mat.SetFloatArray("_WangTile_Y_Seq", index_y_loop);
}
}
最终效果:

带贴图的效果(未做连续处理):

Wang Tile的Shader简易实现的更多相关文章
- Stage3d 由浅到深理解AGAL的管线vertex shader和fragment shader || 简易教程 学习心得 AGAL 非常非常好的入门文章
Everyday Stage3D (一) Everyday Stage3D (二) Triangle Everyday Stage3D (三) AGAL的基本概念 Everyday Stage3D ( ...
- 基于OpenGL编写一个简易的2D渲染框架-09 重构渲染器-Shader
Shader 只是进行一些简单的封装,主要功能: 1.编译着色程序 2.绑定 Uniform 数据 3.根据着色程序的顶点属性传递顶点数据到 GPU 着色程序的编译 GLuint Shader::cr ...
- 关于着色器LinearGradient的使用
LinearGradient我们可以将之译为线型渐变.线型渲染等,译成什么不重要,重要的是它的显示效果是什么样子,今天我们就一起来看看. 先来看看LinearGradient的构造方法: /** Cr ...
- Android Paint、Canvas、Matrix使用讲解(一、Paint)
http://blog.csdn.net/tianjian4592/article/details/44336949 好了,前面主要讲了Animation,Animator 的使用,以及桌面火箭效果和 ...
- Paint、Canvas、Matrix使用解说(一、Paint)
username=tianjian4592">我正在參加 CSDN 2015博客之星评选 感恩分享活动,假设认为文章还不错,请投个票鼓舞下吧:http://vote.blog.csdn ...
- 自定义View实战
PS:上一篇从0开始学自定义View有博友给我留言说要看实战,今天我特意写了几个例子,供大家参考,所画的图案加上动画看着确实让人舒服,喜欢的博友可以直接拿到自己的项目中去使用,由于我这个写的是demo ...
- opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰
认识着色器 理解OpenGL渲染管线,对于学习OpenGL非常重要.下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段) 此图是从wiki中拿过来的,OpenGL的渲染管线主要包括: ...
- 【Unity Shader】(十) ------ UV动画原理及简易实现
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...
- libgdx自制简易版Don't Touch The White Tile
Don't Toutch The White说来也奇快,本来没什么难的,但是在欧美ios榜上却雄踞榜首好长时间.即使是在国内,也很火,还真是想不通,谁能解释下,难道真是所谓的抓住了用户的G点,或是这些 ...
- metal tile shader
刚发现了个问题 tileshader的memory不需要和attachement对应 imageblock被tileshader读写 fragmentshader也可以写imageblock 还可以正 ...
随机推荐
- Jetpack Compose(4)——重组
目录 一.状态变化 1.1 状态变化是什么 1.2 mutableStateListOf 和 mutableStateMapOf 二.重组的特性 2.1 Composable 重组是智能的 2.2 C ...
- #博弈论,贪心#AT2376 [AGC014D] Black and White Tree
题目传送门 分析 考虑到先手放一个白点后手必将在相邻位置放一个黑点, 如果没有合适的位置放黑点先手必胜,也就是问是否存在完美匹配, 直接从叶子节点到根贪心匹配即可 代码 #include <cs ...
- nginx集成brotli压缩算法
本文于2017年2月中旬完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. Google开源Brotli压缩算法 Brotli是一种全新的数据 ...
- go~istio加载wasm的步骤
参考 https://github.com/higress-group/proxy-wasm-go-sdk/tree/main/proxywasm https://github.com/tetrate ...
- HE琥珀虚颜破解自由安装程序教程(001)
HE琥珀虚颜破解自由安装程序教程(001) 前言 自从狗尾草跑路后,HE琥珀就没法用了,当前APP还没法破解,但是笔者找到了HE琥珀存在的一些漏洞,可以实现安装自己的APP. 所需工具 所需工具 1. ...
- HarmonyOS卡片刷新服务,信息实时更新一目了然
如今衣食住行娱乐影音等App占据了大多数人的手机,一部手机可以满足日常大多需求,但对需要经常查看或进行简单操作的场景来说,总需要用户点开App操作未免过于繁琐. 针对该问题, HarmonyOS SD ...
- 树模型-CART树
分类回归树CART CART树是后面所有模型的基础,也是核心树 在ID3算法中我们使用了信息增益来选择特征,信息增益大的优先选择.在C4.5算法中,采用了信息增益比来选择特征,以减少信息增益容易选择特 ...
- leetcode:763. 划分字母区间
763. 划分字母区间 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段.返回一个表示每个字符串片段的长度的列表. 示例 1: 输入: S = & ...
- Elasticsearch与kibana的单机安装
前言 本文为纯实操记录,以供需要时查阅. 对应版本为7.3,jdk版本1.8 Elasticsearch安装 Elasticsearch官网:https://www.elastic.co/cn/pro ...
- python性能测试,请求QPS测试
QPS = (1000ms/平均响应时间ms)*服务并行数量 #!/user/bin/env python #coding=utf-8 import requests import datetime ...