c# - 如何像 Unity 编辑器一样以编程方式将纹理加载到图像中?

标签 c# unity3d textures sprite

Texture loaded from disk comparison

在上图中,第一张图片是通过 C# 脚本加载的。第二个是通过 Unity 编辑器中的检查器分配的。注意第一张图片周围的深灰色边框。如何通过 C# 加载图像并使其没有边框?

源图像是透明 PNG 512x512 像素的白色。它显示在大小为 30x30 的 UnityEngine.UI.Image 中,并分配了红色。上面两个示例的源图像是相同的(磁盘上的相同位置)。

我为第一张图片使用的代码如下;

var texture = new Texture2D(512, 512);
texture.LoadImage(File.ReadAllBytes(Path.Combine(TexturePath, name)));
image.sprite = Sprite.Create(texture, new Rect(0,0, texture.width, texture.height), new Vector2(.5f,.5f), 100);

其中 image 是合适的 UnityEngine.UI.Image

注意事项

使用上述代码的优点是图像不需要嵌入到 unity 最终构建的游戏中。这意味着这些图像可以与游戏分开分发。使用 Resources.Load 并不能解决这个问题,我怀疑这与通过检查器分配图像相同,这意味着 unity 在分配之前已经对纹理做了一些事情(可能是UnityEditor.TextureImporter)

更新

jagged edges

我进一步研究了 Texture2D 构造函数并确定以下代码会产生上图,其中 Sprite 的边缘不再有灰色边框,但现在呈现锯齿状。 (将最后一个参数设置为 true 会保留灰色边框)。

var texture = new Texture2D(512, 512, TextureFormat.Alpha8, false);

一些谷歌搜索让我认为这个问题与 mipmap 相关,并且由于 UnityEditor.TextureImporter.borderMipMap 发生的任何事情,Unity 编辑器可能会在导入时解决这个问题,如 here 所示。 .但是,UnityEditor 命名空间在构建项目时不可用。

最佳答案

问题是 PNG 格式使用 non-premultiplied Alpha Unity 使用直接alpha 混合,旨在与预乘 alpha 颜色一起使用。

可以从以下位置找到关于 Pre 与非 Pre 的更深入的描述:

可以找到Unity 特定的讨论 Here (但是请注意,此问题与 mip-mapping 无关,但会因过滤和调整大小技术而加剧)

您还可以在 alpha importing 上查看 Unity 的文档查看此问题的常见解决方案的可视化示例,如果您有权访问这些 PNG 的管道端创建(我通常通过在 PNG 之后/期间应用后处理来修改 PNG 来解决此问题创建)。

使用剪切着色器也是一种解决方案,但它可能会导致锯齿/视觉伪影。

您可能认为使用 Unity 支持的主要运行时加载图像文件格式的功能渲染 Sprite 会是一件简单的事情,但是,唉,它比这复杂得多。我不知道 UnityEditor.TextureImporter.borderMipMap 的内部工作原理,但我怀疑它的开始是围绕一个类似的问题构建的(边缘像素 alpha 和过滤中使用的任何邻居之间的权重)

关于c# - 如何像 Unity 编辑器一样以编程方式将纹理加载到图像中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29034892/

相关文章:

c# - 获取 c# 碰撞形状的高度(不是 gdscript)

c# - 如何将值从 Controller 方法传递给另一个?

c# - 使用 EmguCV QueryGrayFrame() 处理视频时如何修复此内存不足异常

c# - (Unity) 使用 BuildPipeline 构建时启用 App Bundle (Google Play) 选项?

c++ - OpenGL 中天空盒的程序/动态着色

c# - StringTemplate:从磁盘加载模板?

unity3d - 放大统一移动

c# - 在Unity3D中管理复杂的预制层级

r - 为 gganimate 绘图添加渐变和手绘效果

matlab - 图像处理中频域高斯LPF和理想LPF的区别