UnityShader 如何采样及创建2D纹理数组 (Texture2DArray)

目录

一、纹理数组

纹理数组的导入

 平台支持

在着色器中使用纹理数组

二、在脚本中创建二维纹理数组

在unity中的创建步骤

代码展示

三、采样2D纹理数组贴图

代码展示


一、纹理数组

2D纹理数组的元素也称为切片或图层,它们可以用于实现自定义地形渲染系统或其他特殊效果。并不是所有平台都支持2D纹理数组,因为纹理数组需要受到底层图形 API 和 GPU 的支持。

纹理数组的导入

1、将源纹理导入unity ,在项目视图选择生成的纹理资源。unity在Inspector中显示纹理导入设置。
2、在 Inspector 中,将 Texture Shape 设置为 2D Array。Unity 显示 Columns 和 Rows 属性。
3、把 Columns 和 Rows 设置为适用于翻页纹理的值。
4、单击 Apply确认。

(有关更多信息,请参阅纹理导入设置

平台支持

支持的平台:

1、Direct3D 11/12 (Windows)                       

2、OpenGL Core(Mac OS X、Linux)

3、Metal(iOS、Mac OS X)                       

4、OpenGL ES 3.0(Android、WebGL 2.0)

不支持的平台:

1、OpenGL ES 2.0                                       

 2、WebGL 1.0

(可使用 SystemInfo.supports2DArrayTextures 在运行时确定纹理数组支持情况)

在着色器中使用纹理数组

使用以下宏可声明和采样纹理数组:

UNITY_DECLARE_TEX2DARRAY(name) 在 HLSL 代码中声明纹理数组采样器变量。
UNITY_SAMPLE_TEX2DARRAY(name,uv) 使用 float3 UV 采样纹理数组;坐标的 z 分量是数组元素索引。
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) 使用显式 Mipmap 级别采样纹理数组。

由于纹理数组并非适用于所有平台,因此着色器需要使用适当的编译目标或功能要求来访问纹理数组。支持纹理数组的最低着色器模型编译目标为 3.5,功能名称为 2darray。

二、在脚本中创建二维纹理数组

在unity中的创建步骤

把脚本放到unity中,在顶部菜单栏中会显示Examples菜单栏,点击创建2DTextureArray,它会默认存储到你的工程中。 (这张图可以使用在shader中)

代码展示

using System.Collections;
using UnityEditor;
using UnityEngine;

public class Create2DTexArray : MonoBehaviour
{
    [MenuItem("Examples/Create2DTextureArray")]
    static void Create2DTextureArray()
    {
        // 设置纹理参数
        int width = 32;
        int height = 32;
        int slices = 3;
        TextureFormat format = TextureFormat.RGBA32;
        bool mipChain = false;

        // 创建纹理数组并应用参数 
        Texture2DArray textureArray = new Texture2DArray(width, height, slices, format, mipChain);

        // 创建一个2D颜色数组,用于存储切片中每个像素的颜色数据 
        Color[] colors = new Color[width * height];

        // 遍历每个切片
        for (int slice = 0; slice < slices; slice++)
        {
            // 生成一个随机颜色
            Color randomColor = new Color(Random.value, Random.value, Random.value, 1f);

            // 将颜色数组中的所有像素设置为随机颜色 
            for (int color = 0; color < colors.Length; color++)
            {
                colors[color] = randomColor;
            }

            // 将切片的像素设置为颜色数组 
            textureArray.SetPixels(colors, slice);
        }

        // 通过将更新的像素上传到GPU,将更改应用于纹理数组 
        textureArray.Apply();

        // 保存纹理数组到你的Unity项目中
        AssetDatabase.CreateAsset(textureArray, "Assets/Example2DTextureArray.asset");
    }
}

三、采样2D纹理数组贴图


代码展示


Shader "Example/Sample2DArrayTexture"
{
    Properties
    {
        // 声明2D纹理数组
        _MyArr ("Tex", 2DArray) = "" {}
        // 声明一维变量
        _SliceRange ("Slices", Range(0,16)) = 6
        _UVScale ("UVScale", Float) = 1.0
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // 纹理数组并非在任何地方都可用,只能在它们所在的平台上编译着色器
            #pragma require 2darray
            
            #include "UnityCG.cginc"

            struct v2f
            {
                float3 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            float _SliceRange;
            float _UVScale;
            UNITY_DECLARE_TEX2DARRAY(_MyArr);

            v2f vert (float4 vertex : POSITION)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(vertex);
                // 2D纹理数组uv是一个三维向量 
                o.uv.xy = (vertex.xy + 0.5) * _UVScale;
                o.uv.z = (vertex.z + 0.5) * _SliceRange;
                return o;
            }
            

            half4 frag (v2f i) : SV_Target
            {
                // 采样2D纹理数组贴图
                float4 myArr = UNITY_SAMPLE_TEX2DARRAY(_MyArr, i.uv);
                return myArr;
            }
            ENDCG
        }
    }
}

文献

OpenGL ES中,纹理数组是一组纹理的集合,可以一次性加载多个纹理并进行处理。使用纹理数组可以提高渲染效率,减少内存占用。 纹理数组创建和使用主要有以下几个步骤: 1. 创建纹理数组对象:使用glGenTextures函数创建纹理数组对象,并使用glBindTexture函数绑定到OpenGL ES上下文中。 2. 加载纹理数据:使用glTexImage2D函数将纹理数据加载到纹理数组中。 3. 设置纹理参数:使用glTexParameter函数设置纹理参数,如过滤模式、纹理环绕模式等。 4. 绑定纹理数组:使用glBindTexture函数将纹理数组绑定到OpenGL ES上下文中。 5. 使用纹理数组:在渲染时,使用glActiveTexture函数激活纹理单元,并使用glBindTexture函数将纹理数组绑定到激活的纹理单元上,然后在着色器中使用sampler2DArray类型的变量进行采样。 需要注意的是,在使用纹理数组时,每个纹理的大小和格式必须相同。 下面是一个使用纹理数组的示例代码: ``` GLuint texArray; glGenTextures(1, &texArray); glBindTexture(GL_TEXTURE_2D_ARRAY, texArray); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, width, height, numTextures, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D_ARRAY, texArray); glUniform1i(textureLoc, 0); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值