在过去的几天里,我一直在关注 Sebastian Lague 关于程序生成的视频。由于我的项目基于 URP,并且负责在网格上渲染纹理的自定义着色器只是为 SRP 编写的,因此我必须进行转换。我一直在修补着色器图,并找到了一种可能的转换解决方案。但是,色调和纹理都没有被渲染。我将添加两个代码:一个原始代码和尝试覆盖。
编辑:我从修修补补中得到的唯一一件事是,当我在着色图中手动设置“层”值时,它允许我去更改所述层的基色。尽管如此,它只影响一个单层,不应用任何纹理,并且只能在全局空间中的某个特定值下工作
这是设置变量的代码。两者相同:
public void ApplyToMaterial(Material material)
{
material.SetInt("layerCount", layers.Length);
material.SetColorArray("baseColours", layers.Select(x => x.tint).ToArray());
material.SetFloatArray("baseStartHeights", layers.Select(x => x.startHeight).ToArray());
material.SetFloatArray("baseBlends", layers.Select(x => x.blendStrength).ToArray());
material.SetFloatArray("baseColourStrength", layers.Select(x => x.tintStrength).ToArray());
material.SetFloatArray("baseTextureScales", layers.Select(x => x.textureScale).ToArray());
Texture2DArray texturesArray = GenerateTextureArray(layers.Select(x => x.texture).ToArray());
material.SetTexture("baseTextures", texturesArray);
UpdateMeshHeights(material, savedMinHeight, savedMaxHeight);
}
public void UpdateMeshHeights(Material material, float minHeight, float maxHeight)
{
savedMaxHeight = maxHeight;
savedMinHeight = minHeight;
material.SetFloat("minHeight", minHeight);
material.SetFloat("maxHeight", maxHeight);
}
原始着色器:
Shader "Custom/Terrain" {
Properties{
testTexture("Texture", 2D) = "white"{}
testScale("Scale", Float) = 1
}
SubShader{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
const static int maxLayerCount = 8;
const static float epsilon = 1E-4;
int layerCount;
float3 baseColours[maxLayerCount];
float baseStartHeights[maxLayerCount];
float baseBlends[maxLayerCount];
float baseColourStrength[maxLayerCount];
float baseTextureScales[maxLayerCount];
float minHeight;
float maxHeight;
sampler2D testTexture;
float testScale;
UNITY_DECLARE_TEX2DARRAY(baseTextures);
struct Input {
float3 worldPos;
float3 worldNormal;
};
float inverseLerp(float a, float b, float value) {
return saturate((value - a) / (b - a));
}
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) {
float heightPercent = inverseLerp(minHeight,maxHeight, IN.worldPos.y);
float3 blendAxes = abs(IN.worldNormal);
blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
for (int i = 0; i < layerCount; i++) {
float drawStrength = inverseLerp(-baseBlends[i] / 2 - epsilon, baseBlends[i] / 2, heightPercent - baseStartHeights[i]);
float3 baseColour = baseColours[i] * baseColourStrength[i];
float3 textureColour = triplanar(IN.worldPos, baseTextureScales[i], blendAxes, i) * (1 - baseColourStrength[i]);
o.Albedo = o.Albedo * (1 - drawStrength) + (baseColour + textureColour) * drawStrength;
}
}
ENDCG
}
FallBack "Diffuse"
}
尝试加上着色器图:
const static int maxLayerCount = 8;
const static float epsilon = 1E-4;
float layerCount;
float3 baseColours[maxLayerCount];
float baseStartHeights[maxLayerCount];
float baseBlends[maxLayerCount];
float baseColourStrength[maxLayerCount];
float baseTextureScales[maxLayerCount];
float3 triplanar(float3 worldPos, float scale, float3 blendAxes, Texture2DArray textures, SamplerState ss, int textureIndex) {
float3 scaledWorldPos = worldPos / scale;
float3 xProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.y, scaledWorldPos.z), textureIndex) * blendAxes.x;
float3 yProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.x, scaledWorldPos.z), textureIndex) * blendAxes.y;
float3 zProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.x, scaledWorldPos.y), textureIndex) * blendAxes.z;
return xProjection + yProjection + zProjection;
}
float inverseLerp(float a, float b, float c)
{
return saturate((c - a) / (b - a));
}
void layer_terrain_float(float3 worldPos, float heightPercent, float3 worldNormal, Texture2DArray textures, SamplerState ss, int layerCount, out float3 albedo) {
float3 blendAxes = abs(worldNormal);
blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
albedo = 0.0f;
for (int i = 0; i < layerCount; i++) {
float drawStrength = inverseLerp(-baseBlends[i] / 2 - epsilon, baseBlends[i] / 2, heightPercent - baseStartHeights[i]);
float3 baseColour = baseColours[i] * baseColourStrength[i];
float3 textureColour = triplanar(worldPos, baseTextureScales[i], blendAxes, textures, ss, i) * (1 - baseColourStrength[i]);
albedo = albedo * (1 - drawStrength) + (baseColour + textureColour) * drawStrength;
}
}
我连续几天在这里撞墙。所以非常感谢帮助