浏览代码

Fix LWRP terrain instancing.

/main
Yao Xiaoling 6 年前
当前提交
afba3908
共有 7 个文件被更改,包括 177 次插入46 次删除
  1. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitData.hlsl
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitData_Basemap.hlsl
  3. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl
  4. 155
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl
  5. 22
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrain.shader
  6. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainAddPass.shader
  7. 34
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainBase.shader

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitData.hlsl


#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL
{
float3 normalOS = SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_Control0, (input.texCoord0 + 0.5f) * _TerrainHeightmapRecipSize.xy).rgb * 2 - 1;
float3 normalWS = ((float3x3)GetObjectToWorldMatrix(), normalOS);
float3 normalWS = mul((float3x3)GetObjectToWorldMatrix(), normalOS);
float3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS);
float renormFactor = 1.0 / length(normalWS);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitData_Basemap.hlsl


#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL
{
float3 normalOS = SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_MainTex, (input.texCoord0 + 0.5f) * _TerrainHeightmapRecipSize.xy).rgb * 2 - 1;
float3 normalWS = ((float3x3)GetObjectToWorldMatrix(), normalOS);
float3 normalWS = mul((float3x3)GetObjectToWorldMatrix(), normalOS);
float3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS);
float renormFactor = 1.0 / length(normalWS);

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl


TEXTURE2D(_Splat2);
TEXTURE2D(_Splat3);
#ifdef _TERRAIN_NORMAL_MAP
#ifdef _NORMALMAP
TEXTURE2D(_Normal0); SAMPLER(sampler_Normal0);
TEXTURE2D(_Normal1);
TEXTURE2D(_Normal2);

155
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl


float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
float4 uvSplat01 : TEXCOORD0; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD1; // xy: splat2, zw: splat3
float4 uvControlAndLM : TEXCOORD2; // xy: control, zw: lightmap
float4 uvMainAndLM : TEXCOORD0; // xy: control, zw: lightmap
#ifndef TERRAIN_SPLAT_BASEPASS
float4 uvSplat01 : TEXCOORD1; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD2; // xy: splat2, zw: splat3
#endif
#if _TERRAIN_NORMAL_MAP
#ifdef _NORMALMAP
half3 tangent : TEXCOORD4;
half3 binormal : TEXCOORD5;
#endif

input.positionWS = IN.positionWS;
#ifdef _TERRAIN_NORMAL_MAP
#ifdef _NORMALMAP
input.normalWS = TangentToWorldNormal(normalTS, IN.tangent, IN.binormal, IN.normal);
#else
input.normalWS = normalize(IN.normal);

input.vertexLighting = IN.fogFactorAndVertexLight.yzw;
#ifdef LIGHTMAP_ON
input.bakedGI = SampleLightmap(IN.uvControlAndLM.zw, input.normalWS);
input.bakedGI = SampleLightmap(IN.uvMainAndLM.zw, input.normalWS);
#ifndef TERRAIN_SPLAT_BASEPASS
splat_control = SAMPLE_TEXTURE2D(_Control, sampler_Control, IN.uvControlAndLM.xy);
splat_control = SAMPLE_TEXTURE2D(_Control, sampler_Control, IN.uvMainAndLM.xy);
weight = dot(splat_control, 1);
#if !defined(SHADER_API_MOBILE) && defined(TERRAIN_SPLAT_ADDPASS)

mixedDiffuse += splat_control.b * SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, IN.uvSplat23.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.b);
mixedDiffuse += splat_control.a * SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, IN.uvSplat23.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.a);
#ifdef _TERRAIN_NORMAL_MAP
#ifdef _NORMALMAP
half4 nrm = 0.0f;
nrm += splat_control.r * SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, IN.uvSplat01.xy);
nrm += splat_control.g * SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, IN.uvSplat01.zw);

#endif
}
#endif
void SplatmapFinalColor(inout half4 color, half fogCoord)
{
color.rgb *= color.a;

ApplyFog(color.rgb, fogCoord);
#endif
}
#ifdef UNITY_INSTANCING_ENABLED
TEXTURE2D(_TerrainHeightmapTexture);
TEXTURE2D(_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
#define API_HAS_GURANTEED_R16_SUPPORT 0 //!(SHADER_API_VULKAN)
float UnpackHeightmap(float4 height)
{
#if (API_HAS_GURANTEED_R16_SUPPORT)
return height.r;
#else
return (height.r + height.g * 256.0f) / 257.0f; // (255.0f * height.r + 255.0f * 256.0f * height.g) / 65535.0f
#endif
}
UNITY_INSTANCING_BUFFER_START(Terrain)
UNITY_DEFINE_INSTANCED_PROP(float4, _TerrainPatchInstanceData) // float4(xBase, yBase, skipScale, ~)
UNITY_INSTANCING_BUFFER_END(Terrain)
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;
normal = _TerrainNormalmapTexture.Load(int3(sampleCoords, 0)).rgb * 2 - 1;
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 //

{
VertexOutput o = (VertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
TerrainInstancing(v.vertex, v.normal, v.texcoord);
o.uvMainAndLM.xy = v.texcoord;
o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
#ifndef TERRAIN_SPLAT_BASEPASS
o.uvControlAndLM.xy = TRANSFORM_TEX(v.texcoord, _Control);
o.uvControlAndLM.zw = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
#ifdef _TERRAIN_NORMAL_MAP
#endif
#ifdef _NORMALMAP
float4 vertexTangent = float4(cross(v.normal, float3(0, 0, 1)), -1.0);
OutputTangentToWorld(vertexTangent, v.normal, o.tangent, o.binormal, o.normal);
#else

return o;
}
TEXTURE2D(_MetallicTex); SAMPLER(sampler_MetallicTex);
half4 SpatmapFragment(VertexOutput IN) : SV_TARGET
half4 SplatmapFragment(VertexOutput IN) : SV_TARGET
#ifdef TERRAIN_SPLAT_BASEPASS
half3 normalTS = float3(0, 1, 0);
half3 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).rgb;
half smoothness = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).a;
half metallic = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, IN.uvMainAndLM.xy).r;
half alpha = 1;
#else
half4 splat_control;
half weight;
half4 mixedDiffuse;

half3 albedo = mixedDiffuse.rgb;
half smoothness = mixedDiffuse.a;
half metallic = dot(splat_control, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
half3 specular = half3(0, 0, 0);
#endif
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, specular, smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, half3(0, 0, 0), smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
}
// Shadow pass
// x: global clip space bias, y: normal world space bias
float4 _ShadowBias;
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);
float invNdotL = 1.0 - saturate(dot(_LightDirection, normalWS));
float scale = invNdotL * _ShadowBias.y;
// normal bias is negative since we want to apply an inset normal offset
positionWS = normalWS * scale.xxx + positionWS;
float4 clipPos = TransformWorldToHClip(positionWS);
// _ShadowBias.x sign depens on if platform has reversed z buffer
clipPos.z += _ShadowBias.x;
#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 // LIGHTWEIGHT_PASS_LIT_TERRAIN_INCLUDED

22
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrain.shader


#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SpatmapFragment
#pragma fragment SplatmapFragment
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1

#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
#pragma shader_feature _NORMALMAP
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"

#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
ENDHLSL
}

#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
UsePass "Hidden/Nature/Terrain/Picking/TERRAINPICKING"
}
Dependency "AddPassShader" = "Hidden/LightweightPipeline/Terrain/Standard Terrain Add Pass"
Dependency "BaseMapShader" = "Hidden/LightweightPipeline/Terrain/Standard Terrain Base"

6
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainAddPass.shader


#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SpatmapFragment
#pragma fragment SplatmapFragment
// -------------------------------------
// Lightweight Pipeline keywords

#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
#pragma shader_feature _NORMALMAP
#define TERRAIN_SPLAT_ADDPASS 1
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"

34
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainBase.shader


#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
#pragma shader_feature _NORMALMAP
#define TERRAIN_SPLAT_BASEPASS 1
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassLit.hlsl"
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
ENDHLSL
}

#pragma exclude_renderers d3d11_9x
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
ENDHLSL
}

#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
//--------------------------------------
// GPU Instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
ENDHLSL
}

ENDHLSL
}
UsePass "Hidden/Nature/Terrain/Picking/TERRAINPICKING"
}
FallBack "Hidden/InternalErrorShader"
CustomEditor "LightweightStandardGUI"
正在加载...
取消
保存