Firstborn/Library/PackageCache/com.unity.terrain-tools@4.0.5/Shaders/Visualization/URP/URP_TerrainVisualizationLit...
Schaken-Mods 4ff395c862 Finished the NPC Creator tool
Finished the NPC Creator tool
2023-04-27 18:37:28 -05:00

235 lines
7.9 KiB
HLSL

#ifndef TERRAIN_VISUALIZATION_PASSES_INCLUDED
#define TERRAIN_VISUALIZATION_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#if defined(UNITY_INSTANCING_ENABLED) && defined(_TERRAIN_INSTANCED_PERPIXEL_NORMAL)
#define ENABLE_TERRAIN_PERPIXEL_NORMAL
#endif
#ifdef UNITY_INSTANCING_ENABLED
TEXTURE2D(_TerrainHeightmapTexture);
TEXTURE2D(_TerrainNormalmapTexture);
SAMPLER(sampler_TerrainNormalmapTexture);
float4 _TerrainHeightmapRecipSize; // float4(1.0f/width, 1.0f/height, 1.0f/(width-1), 1.0f/(height-1))
float4 _TerrainHeightmapScale; // float4(hmScale.x, hmScale.y / (float)(kMaxHeight), hmScale.z, 0.0f)
#endif
UNITY_INSTANCING_BUFFER_START(Terrain)
UNITY_DEFINE_INSTANCED_PROP(float4, _TerrainPatchInstanceData) // float4(xBase, yBase, skipScale, ~)
UNITY_INSTANCING_BUFFER_END(Terrain)
struct VertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput
{
float4 uvMainAndLM : TEXCOORD0; // xy: control, zw: lightmap
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
half4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
half4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
half3 normal : TEXCOORD3;
half3 viewDir : TEXCOORD4;
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float3 positionWS : TEXCOORD7;
float4 shadowCoord : TEXCOORD8;
float4 clipPos : SV_POSITION;
};
void InitializeInputData(VertexOutput IN, half3 normalTS, out InputData input)
{
input = (InputData)0;
input.positionWS = IN.positionWS;
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
half3 viewDirWS = half3(IN.normal.w, IN.tangent.w, IN.bitangent.w);
input.normalWS = TransformTangentToWorld(normalTS, half3x3(IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz));
#elif defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
half3 viewDirWS = IN.viewDir;
float2 sampleCoords = (IN.uvMainAndLM.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy;
half3 normalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1));
half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS);
input.normalWS = TransformTangentToWorld(normalTS, half3x3(tangentWS, cross(normalWS, tangentWS), normalWS));
#else
half3 viewDirWS = IN.viewDir;
input.normalWS = IN.normal;
#endif
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
input.normalWS = NormalizeNormalPerPixel(input.normalWS);
input.viewDirectionWS = viewDirWS;
#ifdef _MAIN_LIGHT_SHADOWS
input.shadowCoord = IN.shadowCoord;
#else
input.shadowCoord = float4(0, 0, 0, 0);
#endif
input.fogCoord = IN.fogFactorAndVertexLight.x;
input.vertexLighting = IN.fogFactorAndVertexLight.yzw;
#ifdef LIGHTMAP_ON
input.bakedGI = SampleLightmap(IN.uvMainAndLM.zw, input.normalWS);
#endif
}
void TerrainInstancing(inout float4 vertex, inout float3 normal, inout float2 uv)
{
#ifdef UNITY_INSTANCING_ENABLED
float2 patchVertex = vertex.xy;
float4 instanceData = UNITY_ACCESS_INSTANCED_PROP(Terrain, _TerrainPatchInstanceData);
float2 sampleCoords = (patchVertex.xy + instanceData.xy) * instanceData.z; // (xy + float2(xBase,yBase)) * skipScale
float height = UnpackHeightmap(_TerrainHeightmapTexture.Load(int3(sampleCoords, 0)));
vertex.xz = sampleCoords * _TerrainHeightmapScale.xz;
vertex.y = height * _TerrainHeightmapScale.y;
#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL
normal = float3(0, 1, 0);
#else
normal = _TerrainNormalmapTexture.Load(int3(sampleCoords, 0)).rgb * 2 - 1;
#endif
uv = sampleCoords * _TerrainHeightmapRecipSize.zw;
#endif
}
void TerrainInstancing(inout float4 vertex, inout float3 normal)
{
float2 uv = { 0, 0 };
TerrainInstancing(vertex, normal, uv);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard Terrain shader
VertexOutput SplatmapVert(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
TerrainInstancing(v.vertex, v.normal, v.texcoord);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
o.uvMainAndLM.xy = v.texcoord;
o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
half3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS;
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normal), 1.0);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, vertexTangent);
o.normal = half4(normalInput.normalWS, viewDirWS.x);
o.tangent = half4(normalInput.tangentWS, viewDirWS.y);
o.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
#else
o.normal = TransformObjectToWorldNormal(v.normal);
o.viewDir = viewDirWS;
#endif
o.fogFactorAndVertexLight.x = ComputeFogFactor(vertexInput.positionCS.z);
o.fogFactorAndVertexLight.yzw = VertexLighting(vertexInput.positionWS, o.normal.xyz);
o.positionWS = vertexInput.positionWS;
o.clipPos = vertexInput.positionCS;
#ifdef _MAIN_LIGHT_SHADOWS
o.shadowCoord = GetShadowCoord(vertexInput);
#endif
return o;
}
// Used in Standard Terrain shader
half4 SplatmapFragment(VertexOutput IN) : SV_TARGET
{
#ifdef _HEATMAP
#ifdef LOCAL_SPACE
half height = UnpackHeightmap(SAMPLE_TEXTURE2D(_HeatHeightmap, sampler_HeatHeightmap, IN.uvMainAndLM.xy)) * 2;
#else
half height = ((IN.positionWS.y - _HeatmapData.z) - _HeatmapData.x) / (_HeatmapData.y - _HeatmapData.x);
#endif
half3 albedo = SAMPLE_TEXTURE2D(_HeatmapGradient, sampler_HeatmapGradient, height.xx).rgb;
#elif _SPLATMAP_PREVIEW
half3 albedo = SAMPLE_TEXTURE2D(_SplatmapTex, sampler_SplatmapTex, IN.uvMainAndLM.xy).rgb;
#else
half3 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).rgb;
#endif
InputData inputData;
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
InitializeInputData(IN, normalTS, inputData);
half4 color = LightweightFragmentPBR(inputData, albedo, 0, half3(0.0h, 0.0h, 0.0h), 0, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), 1);
return half4(color.rgb, 1.0h);
}
// Shadow pass
// x: global clip space bias, y: normal world space bias
float3 _LightDirection;
struct VertexInputLean
{
float4 position : POSITION;
float3 normal : NORMAL;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
float4 ShadowPassVertex(VertexInputLean v) : SV_POSITION
{
VertexOutput o;
UNITY_SETUP_INSTANCE_ID(v);
TerrainInstancing(v.position, v.normal);
float3 positionWS = TransformObjectToWorld(v.position.xyz);
float3 normalWS = TransformObjectToWorldDir(v.normal);
float4 clipPos = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection));
#if UNITY_REVERSED_Z
clipPos.z = min(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
#else
clipPos.z = max(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
#endif
return clipPos;
}
half4 ShadowPassFragment() : SV_TARGET
{
return 0;
}
// Depth pass
float4 DepthOnlyVertex(VertexInputLean v) : SV_POSITION
{
VertexOutput o = (VertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
TerrainInstancing(v.position, v.normal);
return TransformObjectToHClip(v.position.xyz);
}
half4 DepthOnlyFragment() : SV_TARGET
{
return 0;
}
#endif