unity3d - 有时我的网格对于纹理数组中的大纹理是黑色的,有时纹理渲染
问题描述
我正在尝试使用纹理数组对使用噪声高度图生成的网格进行着色。使用较小的纹理尺寸(例如 512px*512px),一切正常。但是,如果我使用更大的纹理,例如 1024px*1024px 或 2048px*2048px,我的网格通常会呈现黑色。不时地,纹理将在大约 5% 的时间内正确渲染,而在大约 20% 的时间里,它们似乎在第一帧正确渲染,然后切换为黑色。
无论我的纹理数组有多长,这个问题似乎都会出现。(大小为 1 的数组仍然会导致相同的行为)无论图像是 JPG 还是 PNG,我也会看到相同的问题。我还尝试了各种不同的图像作为纹理并重现了相同的问题。我的控制台中没有错误或警告。
以下是相关代码的简化版本,它们也存在同样的问题。这只是添加混合纹理,但在完整版本的代码中,网格的高度用于确定要使用的纹理以及附近纹理之间的混合程度。我的代码基于 Sebastian Lague 的 procedural landmass generation youtube 教程系列,该教程仅处理 512px*512px 纹理。
将纹理数组和层号放入着色器的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
[CreateAssetMenu()]
public class TextureData : UpdatableData {
const int textureSize = 2048;
const TextureFormat textureFormat = TextureFormat.RGB565;
public Layer[] layers;
public void UpdateMeshHeights(Material material, float minHeight, float maxHeight) {
material.SetInt("layerCount", layers.Length);
Texture2DArray texturesArray = GenerateTextureArray(layers.Select(x => x.texture).ToArray());
material.SetTexture("baseTextures", texturesArray);
}
Texture2DArray GenerateTextureArray(Texture2D[] textures) {
Texture2DArray textureArray = new Texture2DArray(textureSize, textureSize, textures.Length, textureFormat, true);
for (int i=0; i < textures.Length; i++) {
textureArray.SetPixels(textures[i].GetPixels(), i);
}
textureArray.Apply();
return textureArray;
}
[System.Serializable]
public class Layer {
public Texture2D texture;
}
}
着色器本身:
Shader "Custom/Terrain" {
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
int layerCount;
UNITY_DECLARE_TEX2DARRAY(baseTextures);
struct Input {
float3 worldPos;
float3 worldNormal;
};
float3 triplanar(float3 worldPos, float scale, float3 blendAxes, int textureIndex) {
float3 scaledWorldPos = worldPos / scale;
float3 xProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.y, scaledWorldPos.z, textureIndex)) * blendAxes.x;
float3 yProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.z, textureIndex)) * blendAxes.y;
float3 zProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.y, textureIndex)) * blendAxes.z;
return xProjection + yProjection + zProjection;
}
void surf (Input IN, inout SurfaceOutputStandard o) {
float3 blendAxes = abs(IN.worldNormal);
blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
for (int i = 0; i < layerCount; i++) {
float3 textureColor = triplanar(IN.worldPos, 1, blendAxes, i);
o.Albedo += textureColor;
}
}
ENDCG
}
FallBack "Diffuse"
}
以下是实际问题的屏幕截图:
解决方案
推荐阅读
- github - Github 多个分支/开发者
- sql - 用数据外推表
- ngxs - 在 switchMap 中调度 ngxs 操作忽略返回值
- python - 如何使用 Redis scan_iter() 排除键?
- python-3.x - 如何检查条目小部件是否为空,如果它只接受 int 值
- python - 如何在pandas DataFame中保留重复n次的重复行
- ruby-on-rails - Rails 检测移动或网络设备的方法
- ruby - 如何使用 ruby on rails 将 excel 文件上传到 S3 存储桶
- r - 将两个数据帧相互绘制以进行相关性
- python - 检查随机数是否已经存在