浏览代码

Implemented terrain instancing. Updated UnityInstancing.hlsl for SRP.

/main
Yao Xiaoling 7 年前
当前提交
10c48c2c
共有 10 个文件被更改,包括 94 次插入46 次删除
  1. 44
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/UnityInstancing.hlsl
  2. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLit.shader
  3. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLitData.hlsl
  4. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataMeshModification.hlsl
  5. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassVelocity.hlsl
  6. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/VertMesh.hlsl
  7. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl
  8. 3
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/CoreFunctions.hlsl
  9. 51
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLitDataMeshModification.hlsl
  10. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLitDataMeshModification.hlsl.meta

44
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/UnityInstancing.hlsl


#define UNITY_SUPPORT_STEREO_INSTANCING
#endif
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN) || defined(SHADER_API_XBOXONE) || defined(SHADER_API_PSSL) || defined(SHADER_API_METAL) || defined(SHADER_API_SWITCH)
#define UNITY_INSTANCING_AOS
#endif
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3) || defined(SHADER_API_METAL) || defined(SHADER_API_PSSL) || defined(SHADER_API_VULKAN)
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3) || defined(SHADER_API_METAL) || defined(SHADER_API_PSSL) || defined(SHADER_API_VULKAN) || defined(SHADER_API_SWITCH)
#define UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE
#endif

#endif
#endif
#ifdef UNITY_INSTANCING_AOS
#define UNITY_INSTANCING_BUFFER_START(buf) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf) struct {
#define UNITY_INSTANCING_BUFFER_END(arr) } arr##Array[UNITY_INSTANCED_ARRAY_SIZE]; UNITY_INSTANCING_CBUFFER_SCOPE_END
#define UNITY_DEFINE_INSTANCED_PROP(type, var) type var;
#define UNITY_ACCESS_INSTANCED_PROP(arr, var) arr##Array[unity_InstanceID].var
#else
#define UNITY_INSTANCING_BUFFER_START(buf) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf)
#define UNITY_INSTANCING_BUFFER_END(arr) UNITY_INSTANCING_CBUFFER_SCOPE_END
#define UNITY_DEFINE_INSTANCED_PROP(type, var) type var[UNITY_INSTANCED_ARRAY_SIZE];
#define UNITY_ACCESS_INSTANCED_PROP(arr, var) var[unity_InstanceID]
#endif
#define UNITY_INSTANCING_BUFFER_START(buf) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf) struct {
#define UNITY_INSTANCING_BUFFER_END(arr) } arr##Array[UNITY_INSTANCED_ARRAY_SIZE]; UNITY_INSTANCING_CBUFFER_SCOPE_END
#define UNITY_DEFINE_INSTANCED_PROP(type, var) type var;
#define UNITY_ACCESS_INSTANCED_PROP(arr, var) arr##Array[unity_InstanceID].var
// Put worldToObject array to a separate CB if UNITY_ASSUME_UNIFORM_SCALING is defined. Most of the time it will not be used.
#ifdef UNITY_ASSUME_UNIFORM_SCALING

#endif
UNITY_INSTANCING_BUFFER_START(PerDraw0)
UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_ObjectToWorldArray)
#if UNITY_WORLDTOOBJECTARRAY_CB == 0
UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_WorldToObjectArray)
#ifndef UNITY_DONT_INSTANCE_OBJECT_MATRICES
UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_ObjectToWorldArray)
#if UNITY_WORLDTOOBJECTARRAY_CB == 0
UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_WorldToObjectArray)
#endif
#endif
#if defined(UNITY_USE_LODFADE_ARRAY) && defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE)
UNITY_DEFINE_INSTANCED_PROP(float, unity_LODFadeArray)

UNITY_INSTANCING_BUFFER_END(unity_Builtins0)
UNITY_INSTANCING_BUFFER_START(PerDraw1)
#if UNITY_WORLDTOOBJECTARRAY_CB == 1
#if !defined(UNITY_DONT_INSTANCE_OBJECT_MATRICES) && UNITY_WORLDTOOBJECTARRAY_CB == 1
UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_WorldToObjectArray)
#endif
#if defined(UNITY_USE_LODFADE_ARRAY) && !defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE)

#endif
UNITY_INSTANCING_BUFFER_END(unity_Builtins2)
#undef UNITY_MATRIX_M
#define UNITY_MATRIX_M UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_ObjectToWorldArray)
#ifndef UNITY_DONT_INSTANCE_OBJECT_MATRICES
#undef UNITY_MATRIX_M
#define UNITY_MATRIX_M UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_ObjectToWorldArray)
#define MERGE_UNITY_BUILTINS_INDEX(X) unity_Builtins##X
#undef UNITY_MATRIX_I_M
#define UNITY_MATRIX_I_M UNITY_ACCESS_INSTANCED_PROP(MERGE_UNITY_BUILTINS_INDEX(UNITY_WORLDTOOBJECTARRAY_CB), unity_WorldToObjectArray)
#define MERGE_UNITY_BUILTINS_INDEX(X) unity_Builtins##X
#undef UNITY_MATRIX_I_M
#define UNITY_MATRIX_I_M UNITY_ACCESS_INSTANCED_PROP(MERGE_UNITY_BUILTINS_INDEX(UNITY_WORLDTOOBJECTARRAY_CB), unity_WorldToObjectArray)
#endif
#else // UNITY_INSTANCING_ENABLED

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLit.shader


//enable GPU instancing support
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
//-------------------------------------------------------------------------------------
// Define

// Use surface gradient normal mapping as it handle correctly triplanar normal mapping and multiple UVSet
#define SURFACE_GRADIENT
// This shader support vertex modification
#define HAVE_VERTEX_MODIFICATION // TODO: Implement ApplyVertexModification for terrain heightmap sampling
#define HAVE_VERTEX_MODIFICATION
//-------------------------------------------------------------------------------------
// Include

#define _MAX_LAYER 4 // TODO: expand to 8?
// Explicitely said that we are a layered shader as we share code between lit and layered lit
// Explicitly said that we are a layered shader as we share code between lit and layered lit
#define LAYERED_LIT_SHADER
//-------------------------------------------------------------------------------------

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLitData.hlsl


// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------
#ifdef ATTRIBUTES_NEED_TANGENT
#define COMPUTE_TANGENT
float4 ComputeTangent(AttributesMesh input)
{
return float4(cross(input.normalOS, float3(0, 0, 1)), 1);
}
#endif
#include "../Lit/LitData.hlsl"
#if defined(_TERRAINLIT_4_LAYERS)

GetBuiltinData(input, surfaceData, alpha, bentNormalWS, depthOffset, builtinData);
}
#include "../Lit/LitDataMeshModification.hlsl"
#include "TerrainLitDataMeshModification.hlsl"

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataMeshModification.hlsl


return ComputePerVertexDisplacement(layerTexCoord, vertexColor, lod) * normalWS;
}
void ApplyPreVertexModification(inout AttributesMesh input)
{
}
void ApplyVertexModification(AttributesMesh input, float3 normalWS, inout float3 positionWS, float4 time)
{
#if defined(_VERTEX_DISPLACEMENT)

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassVelocity.hlsl


return normalize(mul((float3x3)unity_MatrixPreviousM, normalOS));
#else
// Normal need to be multiply by inverse transpose
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
return normalize(mul(normalOS, (float3x3)unity_MatrixPreviousMI));
#endif
}

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/VertMesh.hlsl


#endif
// TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16)
VaryingsMeshType VertMesh(AttributesMesh input)
// Make it inout so that VelocityPass can get the modified input values later.
VaryingsMeshType VertMesh(inout AttributesMesh input)
{
VaryingsMeshType output;

#if defined(HAVE_VERTEX_MODIFICATION)
ApplyPreVertexModification(input);
#endif
float3 positionWS = TransformObjectToWorld(input.positionOS);
#ifdef ATTRIBUTES_NEED_NORMAL
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);

#ifdef COMPUTE_TANGENT
input.tangentOS = ComputeTangent(input);
#endif
#ifdef ATTRIBUTES_NEED_TANGENT
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
#endif

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl


float3 TransformObjectToWorldNormal(float3 normalOS)
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return UnityObjectToWorldDir(normalOS);
return TransformObjectToWorldDir(normalOS);
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
return normalize(mul(normalOS, (float3x3)GetWorldToObjectMatrix()));
#endif
}

3
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/CoreFunctions.hlsl


real3 TransformObjectToWorldNormal(real3 normalOS)
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return UnityObjectToWorldDir(normalOS);
return TransformObjectToWorldDir(normalOS);
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
return normalize(mul(normalOS, (real3x3)GetWorldToObjectMatrix()));
#endif
}

51
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLitDataMeshModification.hlsl


#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 ApplyPreVertexModification(inout AttributesMesh input)
{
#ifdef UNITY_INSTANCING_ENABLED
float2 patchVertex = input.positionOS.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)));
input.positionOS.xz = sampleCoords * _TerrainHeightmapScale.xz;
input.positionOS.y = height * _TerrainHeightmapScale.y;
#ifdef ATTRIBUTES_NEED_NORMAL
input.normalOS = _TerrainNormalmapTexture.Load(int3(sampleCoords, 0)).rgb * 2 - 1;
#endif
#if defined(VARYINGS_NEED_TEXCOORD0) || defined(VARYINGS_DS_NEED_TEXCOORD0)
input.uv0 = sampleCoords * _TerrainHeightmapRecipSize.zw;
#endif
#endif
#ifdef ATTRIBUTES_NEED_TANGENT
input.tangentOS.xyz = cross(float3(0,0,1), input.normalOS);
input.tangentOS.w = 1;
#endif
}
void ApplyVertexModification(AttributesMesh input, float3 normalWS, inout float3 positionWS, float4 time)
{
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/TerrainLitDataMeshModification.hlsl.meta


fileFormatVersion: 2
guid: e40269e9634b7d641b4531338187e495
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存