本文介绍了如何将简单的高度贴图实现为Unity Shader的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
首先让我说我对着色器编程知之甚少。我这里的很多东西都是从在线资源和现有资产中拼凑而成的。我只需要知道如何正确地将高度贴图集成到unity着色器中。它不必比标准的Unity着色器更复杂。我不能使用标准着色器,因为我需要一个将多个纹理平铺在一起的着色器,这可能是我还没有找到这个问题的解决方案的原因。
我混合并移动了代码,删除了一些变量,重命名了一些变量,并在网上寻找有类似问题的任何人。
Shader "Unlit/TRUE_EARTH"
{
Properties
{
_TexA1 ("Tex A1", 2D) = "white" {}
_TexA2 ("Tex A2", 2D) = "white" {}
_TexB1 ("Tex B1", 2D) = "white" {}
_TexB2 ("Tex B2", 2D) = "white" {}
_TexC1 ("Tex C1", 2D) = "white" {}
_TexC2 ("Tex C2", 2D) = "white" {}
_TexD1 ("Tex D1", 2D) = "white" {}
_TexD2 ("Tex D2", 2D) = "white" {}
_BumpScale("Scale", Float) = 1.0
[Normal] _BumpMap("Normal Map", 2D) = "bump" {}
_Height("Height Scale", Range(0.005, 0.08)) = 0.02
_HeightMap("Height Map", 2D) = "black" {}
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
_OcclusionMap("Occlusion", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
Lighting Off
ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _TexA1;
sampler2D _TexA2;
sampler2D _TexB1;
sampler2D _TexB2;
sampler2D _TexC1;
sampler2D _TexC2;
sampler2D _TexD1;
sampler2D _TexD2;
sampler2D _NormalMap;
sampler2D _HeightMap;
half _BumpAmount;
half _Height;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
half3 normal: TEXCOORD1;
#if WPM_BUMPMAP_ENABLED
half3 tspace0 : TEXCOORD2; // tangent.x, bitangent.x, normal.x
half3 tspace1 : TEXCOORD3; // tangent.y, bitangent.y, normal.y
half3 tspace2 : TEXCOORD4; // tangent.z, bitangent.z, normal.z
#endif
};
v2f vert (float4 vertex : POSITION, half3 normal : NORMAL, half4 tangent : TANGENT, float2 uv : TEXCOORD5, appdata_full v) {
v2f o;
float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
vertex.z += heightMap.b * _Height;
o.pos = UnityObjectToClipPos (vertex);
o.uv = uv;
half3 wNormal = UnityObjectToWorldNormal(normal);
o.normal = wNormal;
#if WPM_BUMPMAP_ENABLED
half3 wTangent = UnityObjectToWorldDir(tangent.xyz);
half tangentSign = tangent.w * unity_WorldTransformParams.w;
half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
//output the tangent space matrix
o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
#endif
return o;
}
half4 frag (v2f i) : SV_Target
{
// compute Earth pixel color
half4 color;
// compute Earth pixel color
if (i.uv.x<0.25)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexA1, float4(i.uv.x * 4.0, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexA2, float4(i.uv.x * 4.0, i.uv.y * 2.0, 0, 0));
}
}
else if (i.uv.x < 0.5)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexB1, float4((i.uv.x - 0.25) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexB2, float4((i.uv.x - 0.25) * 4.0f, i.uv.y * 2.0, 0, 0));
}
}
else if (i.uv.x < 0.75)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexC1, float4((i.uv.x - 0.50) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexC2, float4((i.uv.x - 0.50) * 4.0f, i.uv.y * 2.0, 0, 0));
}
}
else if (i.uv.x < 1.01)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexD1, float4((i.uv.x - 0.75) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexD2, float4((i.uv.x - 0.75) * 4.0f, i.uv.y * 2.0, 0, 0));
}
}
// sphere normal (without bump-map)
half3 snormal = normalize(i.normal);
// transform normal from tangent to world space
#if WPM_BUMPMAP_ENABLED
half3 tnormal = UnpackNormal(tex2D(_NormalMap, i.uv));
half3 worldNormal;
worldNormal.x = dot(i.tspace0, tnormal);
worldNormal.y = dot(i.tspace1, tnormal);
worldNormal.z = dot(i.tspace2, tnormal);
half3 normal = normalize(lerp(snormal, worldNormal, _BumpAmount));
#else
half3 normal = snormal;
#endif
return color;
}
ENDCG
}
}
}
纹理效果很好,但没有高度贴图的外观。都是平的。
推荐答案
有3个部分需要更改。
确保属性与变量匹配:
_Height("Height Scale", Range(0.005, 0.08)) = 0.02 _HeightMap("Height Map", 2D) = "black" {} .... sampler2D _HeightMap; half _Height;
在将顶点存储到
o
之前对其进行修改
修改顶点的y分量,而不是z:
float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0)); vertex.y += heightMap.b * _Height; o.pos = UnityObjectToClipPos (vertex);
这篇关于如何将简单的高度贴图实现为Unity Shader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!