android - Unity 法线贴图不适用于 Android 设备

标签 android unity3d graphics 3d normals

我是一位经验丰富的原生 iOS 开发人员,通过 Unity 首次涉足 Android。我正在尝试设置自定义着色器,但我在使用法线贴图时遇到了一些问题。我已经让它们在我计算机上的 Unity 模拟器中完美运行,但是当我构建到实际设备(Samsung Galaxy S8+)时,法线贴图根本不起作用。

我使用火星作为我的测试用例。这是在我的计算机上的模拟器中运行的模型:

Computer version

这是我设备的屏幕截图,运行完全相同的代码。

Android device version

我做了很多研究,显然在 Android 和 Unity 上使用法线贴图并不是一件容易的事。有很多人问这个问题,但我找到的几乎每个答案都说诀窍是覆盖纹理导入设置,并强制它为“Truecolor”,根据 Unity's documentation 似乎是“RGBA 32 位” .不过,这对我没有帮助。

另一个帖子建议将 Asino 级别降低到零,另一个建议关闭 Mip 贴图。我不知道其中任何一个是什么,但都没有帮助。

Texture Import Settings

这是我的着色器代码,经过简化但包含对法线贴图的所有引用:

void surf (Input IN, inout SurfaceOutputStandard o) {
        half4 d = tex2D (_MainTex , IN.uv_MainTex);
        half4 n = tex2D (_BumpMap , IN.uv_BumpMap);

        o.Albedo = d.rgb;
        o.Normal = UnpackNormal(n);
        o.Metallic = 0.0;
        o.Smoothness = 0.0;
    }

我看到一些线程建议替换着色器代码中的“UnpackNormal()”函数,这表明它可能不是一般在 Android 或移动设备上要做的事情,但是建议的替换都没有改变任何东西无论好坏:法线贴图继续在模拟器中工作,但在设备上却不行。

我什至尝试过从灰度高度图以编程方式制作我自己的法线贴图,以尝试规避我可能做错的任何导入设置。这是我使用的代码,它再次在模拟器中运行,但在设备上运行不正常。

public Texture2D NormalMap(Texture2D source, float strength = 10.0f) {
    Texture2D normalTexture;
    float xLeft;
    float xRight;
    float yUp;
    float yDown;
    float yDelta;
    float xDelta;

    normalTexture = new Texture2D (source.width, source.height, TextureFormat.RGBA32, false, true);

    for (int y=0; y<source.height; y++) {
        for (int x=0; x<source.width; x++) {
            xLeft = source.GetPixel (x - 1, y).grayscale * strength;
            xRight = source.GetPixel (x + 1, y).grayscale * strength;
            yUp = source.GetPixel (x, y - 1).grayscale * strength;
            yDown = source.GetPixel (x, y + 1).grayscale * strength;
            xDelta = ((xLeft - xRight) + 1) * 0.5f;
            yDelta = ((yUp - yDown) + 1) * 0.5f;
            normalTexture.SetPixel(x,y,new Color(xDelta,yDelta,1.0f,yDelta));
        }
    }
    normalTexture.Apply();

    return normalTexture;
}

最后,在 Build Settings 中,我将 Platform 设置为 Android,并尝试将 Texture Compression 设置为“Don't Override”和“ETC (default)”。前者是原始设置,后者从名称和文档中似乎都是 Unity 的建议。

我确定只有一些我没有检查过的标志或一些我没有翻转的开关,但我终究无法弄清楚我在这里做错了什么,或者为什么会有模拟器和设备之间如此顽固的差异。

谁能帮助 Unity 新手,告诉我这些该死的法线贴图应该如何在 Android 上工作?

最佳答案

检查下:

Edit -> Project Settings -> Quality

Android 通常设置为 Fastest。

关于android - Unity 法线贴图不适用于 Android 设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45382884/

相关文章:

android - 如何在 Kotlin 中将字节附加到 ByteArray

android - 如何创建自定义 UI 组件(例如响应式搜索栏)?

Java JFrame/图形驱动程序

安卓电视盒子WebView

unity3d - 在 Unity3D C# 中签署 AWS Api 网关请求

c# - 使用 var 设置组件属性

c# - C++ 17 中的 std::byte 是否等同于 C# 中的字节?

c# - 绘制多条徒手折线或曲线图 - 添加撤消功能

c# - silverlight 可以支持的最大分辨率图像文件是多少?

android - 待定 Intent : why only one of the 2 works?