如何在 Unity 中创建一个可以显示由许多小图像组成的纹理的着色器

2024-02-11

所以我想做的是从 SQL 表加载卫星图像并将它们包裹在一个球体周围以创建一个地球仪。我知道我已经加载了所涵盖的图像,我只是不确定如何使我的着色器以正确的方向显示图像。

我去了 Unity 论坛并查看了这段代码 https://docs.unity3d.com/Manual/SL-TextureArrays.html?_ga=2.76391829.1408735510.1568984793-2059966846.1560883833来自 Unity 文档。

使用链接的着色器代码和我在论坛上收到的帮助,这是我最终得到的代码:

Properties
    {
        _MainTexArray("Tex", 2DArray) = "" {}
        _SliceRange("Slices", Range(0,32)) = 6
        _UVScale("UVScale", Float) = 1
        _COLUMNS("Columns", Range(0, 5)) = 1
        _ROWS("Rows", Range(0, 5)) = 1
        _CELLS("Cells", Range(0, 32)) = 16
    }
        SubShader
        {
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                // texture arrays are not available everywhere,
                // only compile shader on platforms where they are
                #pragma require 2darray

                #include "UnityCG.cginc"

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

                float _SliceRange;
                float _UVScale;

                v2f vert(float4 vertex : POSITION)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(vertex);
                    o.uv.xy = (vertex.xy + 0.5) * _UVScale;
                    o.uv.z = (vertex.z + 0.5) * _SliceRange;
                    return o;
                }
                float _COLUMNS; //Columns and rows only go between 0 and 1
                float _ROWS;
                float _CELLS;
                UNITY_DECLARE_TEX2DARRAY(_MainTexArray);        
                half4 frag(v2f i) : SV_Target
                {
                    float3 uv = float3(i.uv.x * _CELLS, i.uv.y * _CELLS, 0);
                    uv.z = floor(i.uv.x / _COLUMNS) * floor(i.uv.y / _ROWS);
                    return UNITY_SAMPLE_TEX2DARRAY(_MainTexArray, uv / _CELLS); 
                }
                ENDCG
            }
        }

Using that I've gotten my materials to look like this: distorted texture on plane and sphere

这是我用来加载 SQL 图像的代码:

textures = new Texture2D[size];
            for (int x = 0; x <= 7; x++) 
            {
                for (int y = 0; y <= 3; y++)
                {
                    textures[count] = tiler.Read(x, y, 2); //The z determines the zoom level, so I wouldn't want them all loaded at once
                    if (textures[count] != null) TextureScale.Bilinear(textures[count], 256, 256);
                    count++;
                }
            }


        texArr = new Texture2DArray(256, 256, textures.Length, TextureFormat.RGBA32, true, true);
        texArr.filterMode = FilterMode.Bilinear;
        texArr.wrapMode = TextureWrapMode.Repeat;
        for (int i = 0; i < textures.Length; i++)
        {
            if (textures[i] == null) continue;
            texArr.SetPixels(textures[i].GetPixels(0), i, 0);
        }    
        texArr.Apply();
        mat.SetTexture("_MainTexArray", texArr);

在 SQL 表中,x 和 y 确定图块的位置,z 确定缩放级别。我现在只使用一种缩放级别。

抱歉链接整个着色器类,但我对着色器不是很有经验,所以我不太知道问题出在哪里。


如果您可以索引到照片数组,以便有效地获得地球的等距柱状投影,您可以尝试使用着色器代码的修改形式:远离 Unity 论坛 https://forum.unity.com/threads/what-is-wrong-with-unitys-spherical-mapping-how-to-fix-it.321205/#post-2083408复制并稍作修改如下:

Shader "Custom/Equirectangular" {
    Properties{
        _MainTexArray("Tex", 2DArray) = "" {}
        _COLUMNS("Columns", Int) = 2
        _ROWS("Rows", Int) = 2
    }

        SubShader{
            Pass {
                Tags {"LightMode" = "Always"}

                CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma require 2darray

                    #include "UnityCG.cginc"

                    struct appdata {
                       float4 vertex : POSITION;
                       float3 normal : NORMAL;
                    };

                    struct v2f
                    {
                        float4    pos : SV_POSITION;
                        float3    normal : TEXCOORD0;
                    };

                    v2f vert(appdata v)
                    {
                        v2f o;
                        o.pos = UnityObjectToClipPos(v.vertex);
                        o.normal = v.normal;
                        return o;
                    }

                    UNITY_DECLARE_TEX2DARRAY(_MainTexArray);

                    int _ROWS;
                    int _COLUMNS;

                    #define PI 3.141592653589793

                    inline float2 RadialCoords(float3 a_coords)
                    {
                        float3 a_coords_n = normalize(a_coords);
                        float lon = atan2(a_coords_n.z, a_coords_n.x);
                        float lat = acos(a_coords_n.y);
                        float2 sphereCoords = float2(lon, lat) * (1.0 / PI);
                        return float2(sphereCoords.x * 0.5 + 0.5, 1 - sphereCoords.y);
                    }

                    float4 frag(v2f IN) : COLOR
                    {
                        float2 equiUV = RadialCoords(IN.normal);

                        float2 texIndex;
                        float2 uvInTex = modf(equiUV * float2(_COLUMNS,_ROWS), texIndex);

                        int flatTexIndex = texIndex.x * _ROWS + texIndex.y;

                        return UNITY_SAMPLE_TEX2DARRAY(_MainTexArray,
                                float3(uvInTex, flatTexIndex));
                    }
                ENDCG
            }
        }
    FallBack "VertexLit"
}

您还需要使用

texArr = new Texture2DArray(256, 256, textures.Length, TextureFormat.RGBA32, false, true);

代替

texArr = new Texture2DArray(256, 256, textures.Length, TextureFormat.RGBA32, true, false); 

如果我将此脚本附加到球体上,它对我有用:

Material myMat;
public List<Texture2D> texes;

IEnumerator Start()
{
    yield return null;
    myMat = GetComponent<Renderer>().material;

    Texture2DArray texArr = new Texture2DArray(256, 256, 9, 
            TextureFormat.RGBA32, false, true);
    texArr.filterMode = FilterMode.Bilinear;
    texArr.wrapMode = TextureWrapMode.Clamp;

    for (int i = 0 ; i < texes.Count ; i++)
    {
        texArr.SetPixels(texes[i].GetPixels(), i, 0);
    }

    texArr.Apply();

    myMat.SetTexture("_MainTexArray", texArr);
}

and in texes我按顺序添加这些纹理:

0: bottom left at index 0

1: center left at index 1

2: top left at index 2

3: bottom center at index 3

4: center at index 4

5: top center at index 5

6: bottom right at index 6

7: center right at index 7

8: top right at index 8

并将行和列设置为 3,它会产生不错的结果:

如果启用双线性过滤,纹理边界处仍然存在一些伪影。但这些文物必须放大得很近才能看到。由于双线性过滤缺乏相邻像素,它们大多显示为混合不当或丢失像素:

当然,这个示例没有正确平铺,因此沿着一条经线有明显的接缝:

由于此设置需要来自球体的法线,因此这只适用于法线接近球体的物体。因此,例如,它无法在平面上正确渲染。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Unity 中创建一个可以显示由许多小图像组成的纹理的着色器 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 按成员序列化

    我已经实现了template
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 重载<<的返回值

    include
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现

随机推荐

  • 确定android CPU速度?

    我的一位朋友从事手机游戏开发 那么他面临的问题是这样的 在他的游戏中 一些 root 的手机用户能够获得非常高的分数 这是完全不可能的 除非 Android 设备的 CPU 或系统时钟速度很慢 情况就是如此 这些用户使用一些第三方应用程序
  • PyQt5 按钮未连接

    我正在尝试使用 PyQT5 构建一个简单的 GUI 其中有 3 个按钮用于打开文件浏览器 还有一个按钮用于对所选文件进行处理 但我无法让按钮连接到执行此操作所需的功能 In the Ctrl类 该 connect signals函数似乎没有
  • 如何使用字符串值获取 NSArray 中对象的索引?

    我想获取类别 NSMutableArray 中对象的索引 类别对象有一个属性 category title 我希望能够通过传递category title 的值来获取索引 我浏览了文档 找不到解决此问题的简单方法 NSArray不保证您只能
  • C++11 变量缩小,没有 GCC 编译器警告

    缩小范围的概念似乎非常简单 但是 有人可以解释一下为什么下面的某些代码会导致 缩小 编译器错误而其他代码则不会 此代码会按预期产生错误 constexpr int a 255 unsigned char b a OK unsigned ch
  • 这种生产者/消费者实现有什么问题?

    所以我正在考虑在 C 中使用简单的生产者 消费者队列 我最终将使用 boost 进行线程处理 但此示例仅使用 pthreads 我最终还将使用一种更加面向对象的方法 但我认为这会掩盖我目前感兴趣的细节 无论如何 我担心的具体问题是 由于此代
  • 如何获取循环发送的每条短信的发送报告android?

    我正在开发短信应用程序 我需要循环发送短信 注册了 SENT 和 DELIVERED 状态的广播接收器 但问题是如何区分哪个送达通知是针对我发送的哪条短信 我正在使用 SMSMANAGER 类发送短信 我的问题与这里讨论的类似 如何监控每条
  • Python 在 Windows 7 上启动非常慢

    在我的 Windows 7 计算机上加载 Python 所需的时间比在虚拟机 在 Windows 内部相同硬件上 上运行的 Ubuntu 14 04 长 17 倍 Anaconda3发行版在Windows和Ubuntu上使用默认的pytho
  • 将图像添加到项目(旋转器)

    您好 我是 Android 爱好者 我想将图像添加到我的微调项目中 不幸的是 我不知道该怎么做 下面是我的 xml 文件和 MainActivity 谢谢阅读 XML FILE
  • 如何确定UIBarButtonItem在UIToolbar中的位置?

    确定 UIToolbar 中 UIBarButtonItem 的 x y 位置的最简单方法是什么 我找到的唯一答案是有什么方法可以知道 uibarbuttonitem 被绘制在哪里 http www cocoabuilder com arc
  • 如何在 jQuery 中编辑 CSS 规则?

    目的是动态地将行添加到表中 并且稍后手动应用规则不太好 而且更慢 具体的例子是我正在创建一个树表来表示文件夹目录 每个文件夹都是一个div 每一个div 有一个ul与li对于每列的信息 这些li有一个与列名相同的类名 这提供了列宽 但是我想
  • 在 bash 中解析 mobileprovision 文件?

    我正在构建一个 php bash mysql 系统 用于自动分配 iPhone 应用程序 但我想读取项目的 mobileprovision 文件中的应用程序标识符密钥 并据此更改它的 info plist 文件 如果 cfbundleide
  • C语言中printf函数是如何工作的?

    我在测试printf函数时遇到了一个问题 首先我写这样的代码 int main void char a a printf a f n a return 0 输出是 然后我写代码 int main void float b a printf
  • PHP 大括号,这段代码的含义是什么

    我有这段代码 用于从数据库获取查询 在MyBB http www mybb com来源 query SELECT fields FROM this gt table prefix table 我的问题是 什么意思 table table 和
  • 如何使用管道运行命令?

    我正在尝试使用 execvp 运行 ls wc 所以我创建了一个管道 然后创建了一个子管道 我关闭父 子中适当的 读 写 端 然后将另一端映射到标准输出 标准输入 然后我在父级中使用 execvp 运行 ls 在子级中使用 wc 当我运行程
  • Visual Studio Code 不使用池映射将调试器附加到 python 中的多进程

    你好 我正在尝试在 python 中调试多进程 下面是我使用 Pool 运行多进程的一部分 pool Pool num half logical cpus pool result dict pool starmap process batc
  • 将 NSArray 转换为 NSMutableArray Swift

    我正在尝试转换self assets NSArray to NSMutableArray并将其添加到picker selectedAssets这是一个NSMutableArray 这段代码在 swift 中会是什么样子 Objective
  • 如何强制用户下载图像(如下载 pdf)?

    因此 我编写了一个图像库 其中包含下载原始图像的选项 默认情况下 它显示图像的调整大小版本 我很想知道如何 下面的代码将强制用户保存 pdf 而不是使用浏览器查看它 我希望通过将单击操作与 jQuery 绑定来实现图像 jpg gif pn
  • Material-UI [v0.x] 悬停样式上的 RaisingButton

    我想更改悬停时 Material UI RaisingButton 的样式 但似乎没有特定的选项可以做到这一点 因为悬停时发生的情况是由材料设计指南定义的 然而 当鼠标悬停在按钮上时 有什么方法可以更改按钮的样式 主要是颜色和背景颜色 吗
  • C# 中 itextsharp 中的文本格式设置

    我正在尝试使用我的 C 软件创建 pdf 文件 我在用itextsharp库来创建客户账单收据 但是我无法格式化文本 我们如何格式化pdf文件中的文本 仅新行字符 n似乎正在工作 我们如何使用制表符格式化文本 附件是 pdf 文件中文本的屏
  • 如何在 Unity 中创建一个可以显示由许多小图像组成的纹理的着色器

    所以我想做的是从 SQL 表加载卫星图像并将它们包裹在一个球体周围以创建一个地球仪 我知道我已经加载了所涵盖的图像 我只是不确定如何使我的着色器以正确的方向显示图像 我去了 Unity 论坛并查看了这段代码 https docs unity