如何解决如何在此 splat 贴图着色器 (Unity3D) 中为每个通道添加单独的凹凸贴图?
我有这个着色器,用于 Unity3D 中的 splat 贴图。这是一个弗兰肯斯坦式的怪物,我发现我终于开始工作了。问题是它没有在纹理上进行凹凸贴图的能力。
如果有人能告诉我要更改/添加到此着色器代码的哪些内容,使其能够为每个 RGBA 通道纹理提供单独的凹凸贴图,我将不胜感激。
Shader "Custom/Texture Splatting" {
Properties {
_MainTex ("Splat Map",2D) = "white" {}
[NoScaleOffset] _Texture1 ("R",2D) = "white" {}
[NoScaleOffset] _Texture2 ("G",2D) = "white" {}
[NoScaleOffset] _Texture3 ("B",2D) = "white" {}
[NoScaleOffset] _Texture4 ("A",2D) = "white" {}
_BumpMap1 ("BumpMapR",2D) = "bump" {}
_BumpMap2 ("BumpMapG",2D) = "bump" {}
_BumpMap3 ("BumpMapB",2D) = "bump" {}
_BumpMap4 ("BumpMapA",2D) = "bump" {}
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex MyVertexProgram
#pragma fragment MyFragmentProgram
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _Texture1,_Texture2,_Texture3,_Texture4;
struct VertexData {
float4 position : POSITION;
float2 uv : TEXCOORD0;
};
struct Interpolators {
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uvSplat : TEXCOORD1;
};
Interpolators MyVertexProgram (VertexData v) {
Interpolators i;
i.position = UnityObjectToClipPos(v.position);
i.uv = TRANSFORM_TEX(v.uv,_MainTex);
i.uvSplat = v.uv;
return i;
}
float4 MyFragmentProgram (Interpolators i) : SV_TARGET {
float4 splat = tex2D(_MainTex,i.uvSplat);
return
tex2D(_Texture1,i.uv) * splat.r +
tex2D(_Texture2,i.uv) * splat.g +
tex2D(_Texture3,i.uv) * splat.b +
tex2D(_Texture4,i.uv) * (1 - splat.r - splat.g - splat.b);
}
ENDCG
}
}
}
解决方法
凹凸贴图通常用于影响光照在表面上的表现,增加表面不平坦的印象。然而,你上面的例子是一个没有光照的顶点着色器,它没有任何光照模拟,所以你不能只添加凹凸贴图,你首先需要把着色器变成一个光照着色器。我建议改用表面着色器。
如果您仍想使用顶点着色器进行照明,那是完全不同的研究。您可以在此 Unity thread 中看到有关此的一些解释,但除非您确实需要,否则我不会推荐它:
也就是说,这是我制作的一个 splat 表面着色器,它使用 splat 贴图来混合两个纹理并包括一个凹凸贴图。我建议您根据需要调整它(使用 4 个通道而不是 2 个),而不是尝试从头开始构建一个光照着色器。
Shader "Custom/TerrainTwoTexturesBlend" {
Properties {
_Color("Tint",Color) = (0.5,0.5,1)
_MainTex("Albedo",2D) = "white" {}
_BumpMap("Normal Map",2D) = "bump" {}
_MainTex2("Albedo 2",2D) = "white" {}
_BumpMap2("Normal Map 2",2D) = "bump" {}
_Mask("Mask",2D) = "white" {}
_Glossiness ("Smoothness",Range(0,1)) = 0.5
_Specular ("Specular",1)) = 0.0
}
SubShader {
Tags {
"Queue" = "Geometry-4"
"RenderType" = "Opaque"
"PreviewType" = "Plane"
"ForceNoShadowCasting" = "True"
}
LOD 200
ZWrite Off
CGPROGRAM
// Physically based Standard lighting model,and enable shadows on all light types
#pragma surface surf StandardSpecular
// Use shader model 3.0 target,to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _MainTex2;
sampler2D _BumpMap2;
sampler2D _Mask;
struct Input {
float2 uv_MainTex: TEXCOORD0;
float2 uv2_MainTex2: TEXCOORD2;
float2 uv3_Mask: TEXCOORD1;
};
half _Glossiness;
half _Specular;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN,inout SurfaceOutputStandardSpecular o) {
float2 uvterrain1 = IN.uv_MainTex;
float2 uvterrain2 = IN.uv2_MainTex2;
float2 uvmask = IN.uv3_Mask;
fixed4 c1 = tex2D(_MainTex,uvterrain1);
fixed4 n1 = tex2D(_BumpMap,uvterrain1);
fixed4 c2 = tex2D(_MainTex2,uvterrain2);
fixed4 n2 = tex2D(_BumpMap2,uvterrain2);
fixed4 m = tex2D(_Mask,uvmask);
o.Albedo = _Color * (c1 * m.r + c2 * (1 - m.r));
float3 fn1 = UnpackScaleNormal(n1,_BumpScale);
float3 fn2 = UnpackScaleNormal(n2,_BumpScale2);
o.Normal = fn1 * m.r + fn2 * (1 - m.r);
// Metallic and smoothness come from slider variables
o.Specular = _Specular;
o.Smoothness = _Glossiness;
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。