当前位置:网站首页>Unity3D study notes 10 - texture array
Unity3D study notes 10 - texture array
2022-08-01 01:10:00 【charlee44】
1. 概述
个人认为,纹理数组是一个非常有用的图形特性.纹理本质上是一个二维的图形数据;通过纹理数组,给图形数据再加上了一个维度.这无疑会带来一个巨大的性能提升:一次性传输大量的数据总是比分批次传输数据要快.
2. 详论
2.1. 实现
创建一个GameObject对象,并且加入Mesh Filter组件和Mesh Renderer组件.Mesh Filter我们可以设置Mesh为Quad,同时在Mesh Filter上挂一个我们新建的材质:

在这个GameObject对象上挂接一个我们创建的C#脚本:
using Unity.Collections;
using UnityEngine;
[ExecuteInEditMode]
public class Note10Main : MonoBehaviour
{
public Texture2D texture1;
public Texture2D texture2;
[Range(0.0f, 1.0f)]
public float weight;
Material material;
// Start is called before the first frame update
void Start()
{
MeshRenderer mr = GetComponent<MeshRenderer>();
material = mr.sharedMaterial;
Texture2DArray texture2DArray = CreateTexture2DArray();
material.mainTexture = texture2DArray;
material.SetFloat("_Weight", weight);
}
Texture2DArray CreateTexture2DArray()
{
Texture2DArray texture2DArray = new Texture2DArray(texture1.width, texture1.height, 2,
texture1.format, false);
NativeArray<byte> pixelData1 = texture1.GetPixelData<byte>(0);
NativeArray<byte> pixelData2 = texture2.GetPixelData<byte>(0);
texture2DArray.SetPixelData(pixelData1, 0, 0, 0);
texture2DArray.SetPixelData(pixelData2, 0, 1, 0);
texture2DArray.Apply(false, false);
return texture2DArray;
}
// Update is called once per frame
void Update()
{
material.SetFloat("_Weight", weight);
}
}
这段C#脚本的意思是,通过传入两个Texture2d,生成一个texture2DArray;并且,将这个texture2DArray传入到材质中.需要注意的是纹理数组中的每个纹理的参数如宽、高等参数都需要一致,否则不能组成纹理数组.
材质使用我们自定义的Shader:
Shader "Custom/TextureArrayShader"
{
Properties
{
_MainTex ("Texture", 2DArray) = "" {
}
_Weight ("Weight", float) = 0.0
}
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;
};
UNITY_DECLARE_TEX2DARRAY(_MainTex);
float _Weight;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col0 = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(i.uv, 0));
fixed4 col1 = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(i.uv, 1));
return lerp(col0, col1, _Weight);
}
ENDCG
}
}
}
这里实现的效果是,将纹理数组中的两个纹理根据权重进行混合.权重值也是在C#脚本中传入到Shader中的.在编辑器中将权重调整到中间一点的位置(例如0.5):
Shader代码也很好理解,关键在于纹理数组相关的宏,其实是对hlsl或者glsl的封装:
#define UNITY_DECLARE_TEX2DARRAY(tex) Texture2DArray tex; SamplerState sampler##tex
#define UNITY_SAMPLE_TEX2DARRAY(tex,coord) tex.Sample (sampler##tex,coord)
#define UNITY_DECLARE_TEX2DARRAY(tex) sampler2DArray tex
#define UNITY_SAMPLE_TEX2DARRAY(tex,coord) tex2DArray (tex,coord)
2.2. 注意
- 关于纹理数组的创建,也可以使用Graphics.CopyTexture()这个接口.这个接口是纯走GPU端的,效率应该回更高.
- 纹理数组这个特性在低端显卡上可能不支持,但是不一定就会非常耗费性能.可以考虑通过纹理数组的方式来合并渲染的批次.
- 纹理数组个数的限制并不是纹理单元个数.实际上一个纹理数组只会绑定到一个纹理单元上,而在本人GTX 1660 Ti的显卡上,纹理数组个数的限制是4096个.
3. 参考
边栏推荐
猜你喜欢

MYSQL逻辑架构

Likou Binary Tree

虹科分享|如何用移动目标防御技术防范未知因素

RTL8762DK PWM (seven)

两院院士直言:不要迷信院士
![[AMEX] LGBM Optuna American Express Credit Card Fraud Contest kaggle](/img/64/55af53a3d9dc1162490d613fe8a436.png)
[AMEX] LGBM Optuna American Express Credit Card Fraud Contest kaggle
![leetcode: 1562. Find latest grouping of size M [simulation + endpoint record + range merge]](/img/72/f52b5d3dcdb271f096c3e5108f0042.png)
leetcode: 1562. Find latest grouping of size M [simulation + endpoint record + range merge]

Modern Enterprise Architecture Framework 1

Introduction to machine learning how to?

vector的基本实现
随机推荐
C字符串数组反转
WebApi 打个Attribute 统一处理异常
Web3.0: Building an NFT Market (1)
机器学习应该如何入门?
Key Points Estimation and Point Instance
WAASAP WebClient UI页面标签的决定逻辑介绍
精心总结十三条建议,帮你创建更合适的MySQL索引
现代企业架构框架1
OSF understands the agile development model in one minute
七月集训(第31天) —— 状态压缩
pycaret源码分析:下载数据集\Lib\site-packages\pycaret\datasets.py
继承的注意事项
Design the message queue storage MySQL form of message data
MYSQL关键字Explain解析
Rainbow share | how to use moving targets defense technology to guard against the unknown
Rasa 3.x 学习系列- Rasa - Issues 4898 学习笔记
Force buckle 2326, 197
RTL8762DK Lighting/LED (3)
leetcode:1648. 销售价值减少的颜色球【二分找边界】
Nmap Operation Manual - Full Version