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 还可以正 ...
随机推荐
- .Net单元测试xUnit和集成测试指南(1)
引言 在现代化的软件开发中,单元测试和集成测试是确保代码质量和可靠性的关键部分.ASP.NET Core 社区内提供了强大的单元测试框架,xUnit 是其中之一,它提供了简单.清晰和强大的测试功能,编 ...
- [Android开发学iOS系列] 删除storyboard需要几步
删除iOS项目中的storyboard 删除项目中的storyboard, (变成一个纯代码的iOS UIKit项目), 需要几步? 找到storyboard, 删掉它. 直接用ViewControl ...
- 3D Object Detection Essay Reading 2024.04.01
Swin Transformer paper: https://arxiv.org/abs/2103.14030 (ICCV 2021) code:https://github.com/microso ...
- #高精度,卡特兰数#洛谷 2532 [AHOI2012]树屋阶梯
题目 分析 设\(dp[n]\)表示大小为\(n\)的树屋阶梯方案数,如何不算重也不算漏 考虑在左下角填充一个尽量大的矩形,一共有\(n\)种方法, 然后剩下的两头就可以用前面的结果表示 也就是\(d ...
- Go 语言学习:了解 const 关键字及常量声明
如果一个变量应该有一个固定的.不能改变的值,你可以使用const关键字. const关键字将变量声明为"常量",这意味着它是不可改变和只读的. 语法 const CONSTNAME ...
- java集合源码详解
一 Collection接口 1.List 1.1ArrayList 特点 1.底层实现基于动态数组,数组特点根据下表查找元素速度所以查找速度较快.继承自接口 Collection ->Lis ...
- 玩转HarmonyOS专项测试,轻松上架“五星”高品质应用
作者:David,华为测试服务专家 随着信息技术的高速发展,移动应用与人们生活日益紧密,面向各类场景的应用层出不穷,什么样的应用更受用户青睐呢?在满足用户功能需求之上,一个好的应用要能运行稳定.流 ...
- 可视化学习:使用WebGL绘制圆形,实现色盘
前言 在Canvas2D中实现圆形的绘制比较简单,只要调用arc指令就能在Canvas画布上绘制出一个圆形,类似的,在SVG中我们也只需要一个<circle>标签就能在页面上绘制一个圆形. ...
- C++ 解引用与函数基础:内存地址、调用方法及声明
C++ 解引用 获取内存地址和值 在上一页的示例中,我们使用了指针变量来获取变量的内存地址(与引用运算符 & 一起使用).但是,你也可以使用指针来获取变量的值,这可以通过使用 * 运算符(解引 ...
- 国产GOWIN实现低成本实现CSI MIPI转换DVP
CSI MIPI转换DVP,要么就是通用IC操作,如龙讯芯片和索尼芯片,但是复杂的寄存器控制器实在开发太累.对于FPGA操作,大部分都是用xilinx的方案,xilinx方案成本太高,IP复杂. 而用 ...