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 还可以正 ...
随机推荐
- #矩阵乘法#洛谷 3702 [SDOI2017]序列计数
题目链接 分析 考虑容斥,用总方案减去全是合数的方案数, 可以发现 \(n\) 很大,\(p\) 很小,直接用矩阵乘法转移即可 代码 #include <cstdio> #include ...
- #链表#洛谷 3794 签到题IV
题目 给出一个长度为\(n\)的数列\(a\),求 \[\sum_{i=1}^n\sum_{j=i}^n[\gcd(a_{i\sim j})\;xor\;or(a_{i\sim j})=k] \] 分 ...
- #线性筛,质数#LOJ 6165 一道水题
题目 \((lcm_{i=1}^ni)\bmod 10^8+7,n\leq 10^8\) 分析 考虑对于某个质数\(p\),在\(n\)范围内做出的最大贡献为\(p^k(p^k\leq n)\), 线 ...
- ABA问题的本质及其解决办法
目录 简介 第一类问题 第二类问题 第一类问题的解决 第二类问题的解决 总结 简介 CAS的全称是compare and swap,它是java同步类的基础,java.util.concurrent中 ...
- openGauss支持国密SM3和SM4算法
国密算法介绍 国密即国家密码局认定的国产密码算法,主要有 SM1,SM2,SM3,SM4.密钥长度和分组长度均为 128 位.针对银行客户对数据库安全能力的诉求以及提高产品安全竞争力的要求,进行数据库 ...
- 文档在线预览(一)通过将txt、word、pdf、ppt转成图片实现在线预览功能
@ 目录 一.前言 1.aspose 2 .poi + pdfbox 3 spire 二.将文件转换成图片,并生成到本地 1.将word文件转成图片 (1)使用aspose (2)使用pdfbox ( ...
- input 去除默认样式
前言 如何不自己写框架,基本用不上. 正文 input{ border: 0px; background-color: none; outline: none; } input:focus{ outl ...
- steam社区留言红小作文模板
steam社区留言红小作文模板 Dear steam: Im a steam user which most play csgo.i saw i had be banned in steam comm ...
- Oracle使用存储过程实现多行对同行数据排列组合
Oracle使用存储过程实现同行数据排列组合 对多行的同一行的多列数据进行排列组合 假设获取的原来的数据如下表 A B C D aa ab ac ad 现在我们需要对数据进行处理,将每一行的数据,类似 ...
- 暑期集训 Day12 —— 模拟赛复盘
${\color{Green} \mathrm{Problem\ 1 :Subarray }} $ Map. ${\color{Green} \mathrm{Problem\ 2 :小z玩游戏 }} ...