testss
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Main Texture", 2D) = "white" { }
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Unlit" "IgnoreProjector" = "True"}
|
||||
LOD 100
|
||||
|
||||
ZWrite On
|
||||
|
||||
// Lightmapped
|
||||
Pass
|
||||
{
|
||||
Name "TerrainDetailVertex"
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
|
||||
#pragma multi_compile _ SHADOWS_SHADOWMASK
|
||||
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
|
||||
float4 _MainTex_ST;
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 PositionOS : POSITION;
|
||||
float2 UV0 : TEXCOORD0;
|
||||
float2 UV1 : TEXCOORD1;
|
||||
float3 NormalOS : NORMAL;
|
||||
half4 Color : COLOR;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float2 UV01 : TEXCOORD0; // UV0
|
||||
float2 LightmapUV : TEXCOORD1; // Lightmap UVs
|
||||
half4 Color : TEXCOORD2; // Vertex Color
|
||||
half4 LightingFog : TEXCOORD3; // Vetex Lighting, Fog Factor
|
||||
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
|
||||
float4 ShadowCoords : TEXCOORD4; // Shadow UVs
|
||||
#endif
|
||||
float4 PositionCS : SV_POSITION; // Clip Position
|
||||
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
Varyings Vert(Attributes input)
|
||||
{
|
||||
Varyings output = (Varyings)0;
|
||||
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
|
||||
// Vertex attributes
|
||||
output.UV01 = TRANSFORM_TEX(input.UV0, _MainTex);
|
||||
output.LightmapUV = input.UV1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
|
||||
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.PositionOS.xyz);
|
||||
output.Color = input.Color;
|
||||
output.PositionCS = vertexInput.positionCS;
|
||||
|
||||
// Shadow Coords
|
||||
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
|
||||
output.ShadowCoords = GetShadowCoord(vertexInput);
|
||||
#endif
|
||||
|
||||
// Vertex Lighting
|
||||
half3 NormalWS = input.NormalOS;
|
||||
Light mainLight = GetMainLight();
|
||||
half3 attenuatedLightColor = mainLight.color * mainLight.distanceAttenuation;
|
||||
half3 diffuseColor = LightingLambert(attenuatedLightColor, mainLight.direction, NormalWS);
|
||||
|
||||
#if defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX)
|
||||
int pixelLightCount = GetAdditionalLightsCount();
|
||||
for (int i = 0; i < pixelLightCount; ++i)
|
||||
{
|
||||
Light light = GetAdditionalLight(i, vertexInput.positionWS);
|
||||
half3 attenuatedLightColor = light.color * light.distanceAttenuation;
|
||||
diffuseColor += LightingLambert(attenuatedLightColor, light.direction, NormalWS);
|
||||
}
|
||||
#endif
|
||||
|
||||
output.LightingFog.xyz = diffuseColor;
|
||||
|
||||
// Fog factor
|
||||
output.LightingFog.w = ComputeFogFactor(output.PositionCS.z);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 Frag(Varyings input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
|
||||
half3 bakedGI = SampleLightmap(input.LightmapUV, half3(0.0, 1.0, 0.0));
|
||||
|
||||
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
|
||||
half3 lighting = input.LightingFog.rgb * MainLightRealtimeShadow(input.ShadowCoords) + bakedGI;
|
||||
#else
|
||||
half3 lighting = input.LightingFog.rgb + bakedGI;
|
||||
#endif
|
||||
|
||||
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.UV01);
|
||||
half4 color = 1.0;
|
||||
color.rgb = input.Color.rgb * tex.rgb * lighting;
|
||||
|
||||
color.rgb = MixFog(color.rgb, input.LightingFog.w);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// GBuffer
|
||||
Pass
|
||||
{
|
||||
Name "TerrainDetailVertex - GBuffer"
|
||||
Tags{"LightMode" = "UniversalGBuffer"}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma exclude_renderers gles
|
||||
#pragma target 2.0
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX //_ADDITIONAL_LIGHTS
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
|
||||
float4 _MainTex_ST;
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 PositionOS : POSITION;
|
||||
float2 UV0 : TEXCOORD0;
|
||||
float2 UV1 : TEXCOORD1;
|
||||
float3 NormalOS : NORMAL;
|
||||
half4 Color : COLOR;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float2 UV01 : TEXCOORD0; // UV0
|
||||
float2 LightmapUV : TEXCOORD1; // Lightmap UVs
|
||||
half4 Color : TEXCOORD2; // Vertex Color
|
||||
half4 LightingFog : TEXCOORD3; // Vetex Lighting, Fog Factor
|
||||
float4 ShadowCoords : TEXCOORD4; // Shadow UVs
|
||||
float4 PositionCS : SV_POSITION; // Clip Position
|
||||
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
Varyings Vert(Attributes input)
|
||||
{
|
||||
Varyings output = (Varyings)0;
|
||||
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
|
||||
// Vertex attributes
|
||||
output.UV01 = TRANSFORM_TEX(input.UV0, _MainTex);
|
||||
output.LightmapUV = input.UV1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
|
||||
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.PositionOS.xyz);
|
||||
output.Color = input.Color;
|
||||
output.PositionCS = vertexInput.positionCS;
|
||||
|
||||
// Shadow Coords
|
||||
output.ShadowCoords = GetShadowCoord(vertexInput);
|
||||
|
||||
// Vertex Lighting
|
||||
half3 NormalWS = input.NormalOS;
|
||||
Light mainLight = GetMainLight();
|
||||
half3 attenuatedLightColor = mainLight.color * mainLight.distanceAttenuation;
|
||||
half3 diffuseColor = LightingLambert(attenuatedLightColor, mainLight.direction, NormalWS);
|
||||
#ifdef _ADDITIONAL_LIGHTS
|
||||
int pixelLightCount = GetAdditionalLightsCount();
|
||||
for (int i = 0; i < pixelLightCount; ++i)
|
||||
{
|
||||
Light light = GetAdditionalLight(i, vertexInput.positionWS);
|
||||
half3 attenuatedLightColor = light.color * light.distanceAttenuation;
|
||||
diffuseColor += LightingLambert(attenuatedLightColor, light.direction, NormalWS);
|
||||
}
|
||||
#endif
|
||||
output.LightingFog.xyz = diffuseColor;
|
||||
|
||||
// Fog factor
|
||||
output.LightingFog.w = ComputeFogFactor(output.PositionCS.z);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
FragmentOutput Frag(Varyings input)
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
|
||||
half3 bakedGI = SampleLightmap(input.LightmapUV, half3(0.0, 1.0, 0.0));
|
||||
|
||||
half3 lighting = input.LightingFog.rgb * MainLightRealtimeShadow(input.ShadowCoords) + bakedGI;
|
||||
|
||||
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.UV01);
|
||||
half4 color = 1.0;
|
||||
color.rgb = input.Color.rgb * tex.rgb * lighting;
|
||||
|
||||
SurfaceData surfaceData = (SurfaceData)0;
|
||||
surfaceData.alpha = 1.0;
|
||||
|
||||
InputData inputData = (InputData)0;
|
||||
inputData.normalWS = half3(0, 1, 0); // need some default to avoid division by 0.
|
||||
|
||||
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingInvalid);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags{"LightMode" = "DepthOnly"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthOnlyVertex
|
||||
#pragma fragment DepthOnlyFragment
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthNormals"
|
||||
Tags{"LightMode" = "DepthNormals"}
|
||||
|
||||
ZWrite On
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
#pragma vertex DepthNormalOnlyVertex
|
||||
#pragma fragment DepthNormalOnlyFragment
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "Meta"
|
||||
Tags{ "LightMode" = "Meta" }
|
||||
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex UniversalVertexMeta
|
||||
#pragma fragment UniversalFragmentMetaSimple
|
||||
|
||||
#pragma shader_feature_local_fragment _SPECGLOSSMAP
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl"
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
//Fallback "VertexLit"
|
||||
}
|
@@ -0,0 +1,239 @@
|
||||
Shader "Universal Render Pipeline/Terrain/Lit"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[HideInInspector] [ToggleUI] _EnableHeightBlend("EnableHeightBlend", Float) = 0.0
|
||||
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
|
||||
// Layer count is passed down to guide height-blend enable/disable, due
|
||||
// to the fact that heigh-based blend will be broken with multipass.
|
||||
[HideInInspector] [PerRendererData] _NumLayersCount ("Total Layer Count", Float) = 1.0
|
||||
|
||||
// set by terrain engine
|
||||
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
|
||||
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "grey" {}
|
||||
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "grey" {}
|
||||
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "grey" {}
|
||||
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "grey" {}
|
||||
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
|
||||
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
|
||||
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
|
||||
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
|
||||
[HideInInspector] _Mask3("Mask 3 (A)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask2("Mask 2 (B)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask1("Mask 1 (G)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask0("Mask 0 (R)", 2D) = "grey" {}
|
||||
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 0.5
|
||||
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 0.5
|
||||
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 0.5
|
||||
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 0.5
|
||||
|
||||
// used in fallback on old cards & base map
|
||||
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "grey" {}
|
||||
[HideInInspector] _BaseColor("Main Color", Color) = (1,1,1,1)
|
||||
|
||||
[HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
|
||||
|
||||
[ToggleUI] _EnableInstancedPerPixelNormal("Enable Instanced per-pixel normal", Float) = 1.0
|
||||
}
|
||||
|
||||
HLSLINCLUDE
|
||||
|
||||
#pragma multi_compile_fragment __ _ALPHATEST_ON
|
||||
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "False" "TerrainCompatible" = "True"}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
HLSLPROGRAM
|
||||
#pragma target 3.0
|
||||
|
||||
#pragma vertex SplatmapVert
|
||||
#pragma fragment SplatmapFragment
|
||||
|
||||
#define _METALLICSPECGLOSSMAP 1
|
||||
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
|
||||
#pragma multi_compile _ SHADOWS_SHADOWMASK
|
||||
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined 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 shader_feature_local_fragment _TERRAIN_BLEND_HEIGHT
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
#pragma shader_feature_local_fragment _MASKMAP
|
||||
// Sample normal in pixel shader when doing instancing
|
||||
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags{"LightMode" = "ShadowCaster"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex ShadowPassVertex
|
||||
#pragma fragment ShadowPassFragment
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
|
||||
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
|
||||
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GBuffer"
|
||||
Tags{"LightMode" = "UniversalGBuffer"}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma exclude_renderers gles
|
||||
#pragma target 3.0
|
||||
#pragma vertex SplatmapVert
|
||||
#pragma fragment SplatmapFragment
|
||||
|
||||
#define _METALLICSPECGLOSSMAP 1
|
||||
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
|
||||
//#pragma multi_compile_fog
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#pragma shader_feature_local _TERRAIN_BLEND_HEIGHT
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
#pragma shader_feature_local _MASKMAP
|
||||
// Sample normal in pixel shader when doing instancing
|
||||
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
|
||||
#define TERRAIN_GBUFFER 1
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags{"LightMode" = "DepthOnly"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthOnlyVertex
|
||||
#pragma fragment DepthOnlyFragment
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// This pass is used when drawing to a _CameraNormalsTexture texture
|
||||
Pass
|
||||
{
|
||||
Name "DepthNormals"
|
||||
Tags{"LightMode" = "DepthNormals"}
|
||||
|
||||
ZWrite On
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
#pragma vertex DepthNormalOnlyVertex
|
||||
#pragma fragment DepthNormalOnlyFragment
|
||||
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SceneSelectionPass"
|
||||
Tags { "LightMode" = "SceneSelectionPass" }
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthOnlyVertex
|
||||
#pragma fragment DepthOnlyFragment
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#define SCENESELECTIONPASS
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
UsePass "Hidden/Nature/Terrain/Utilities/PICKING"
|
||||
}
|
||||
Dependency "AddPassShader" = "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)"
|
||||
Dependency "BaseMapShader" = "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)"
|
||||
Dependency "BaseMapGenShader" = "Hidden/Universal Render Pipeline/Terrain/Lit (Basemap Gen)"
|
||||
|
||||
CustomEditor "UnityEditor.Rendering.Universal.TerrainLitShaderGUI"
|
||||
|
||||
Fallback "Hidden/Universal Render Pipeline/FallbackError"
|
||||
}
|
@@ -0,0 +1,134 @@
|
||||
Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
// Layer count is passed down to guide height-blend enable/disable, due
|
||||
// to the fact that heigh-based blend will be broken with multipass.
|
||||
[HideInInspector] [PerRendererData] _NumLayersCount ("Total Layer Count", Float) = 1.0
|
||||
|
||||
// set by terrain engine
|
||||
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
|
||||
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
|
||||
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
|
||||
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
|
||||
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
|
||||
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
|
||||
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
|
||||
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
|
||||
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
|
||||
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector] _Mask3("Mask 3 (A)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask2("Mask 2 (B)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask1("Mask 1 (G)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask0("Mask 0 (R)", 2D) = "grey" {}
|
||||
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 1.0
|
||||
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 1.0
|
||||
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 1.0
|
||||
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 1.0
|
||||
|
||||
// used in fallback on old cards & base map
|
||||
[HideInInspector] _BaseMap("BaseMap (RGB)", 2D) = "white" {}
|
||||
[HideInInspector] _BaseColor("Main Color", Color) = (1,1,1,1)
|
||||
|
||||
[HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
HLSLINCLUDE
|
||||
|
||||
#pragma multi_compile_fragment __ _ALPHATEST_ON
|
||||
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags { "Queue" = "Geometry-99" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True"}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "TerrainAddLit"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
Blend One One
|
||||
HLSLPROGRAM
|
||||
#pragma target 3.0
|
||||
|
||||
#pragma vertex SplatmapVert
|
||||
#pragma fragment SplatmapFragment
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
|
||||
#pragma multi_compile _ SHADOWS_SHADOWMASK
|
||||
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined 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 shader_feature_local_fragment _TERRAIN_BLEND_HEIGHT
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
#pragma shader_feature_local_fragment _MASKMAP
|
||||
// Sample normal in pixel shader when doing instancing
|
||||
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
|
||||
#define TERRAIN_SPLAT_ADDPASS
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GBuffer"
|
||||
Tags{"LightMode" = "UniversalGBuffer"}
|
||||
|
||||
Blend One One
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma exclude_renderers gles
|
||||
#pragma target 3.0
|
||||
#pragma vertex SplatmapVert
|
||||
#pragma fragment SplatmapFragment
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
|
||||
//#pragma multi_compile_fog
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#pragma shader_feature_local _TERRAIN_BLEND_HEIGHT
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
#pragma shader_feature_local _MASKMAP
|
||||
// Sample normal in pixel shader when doing instancing
|
||||
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
|
||||
#define TERRAIN_SPLAT_ADDPASS 1
|
||||
#define TERRAIN_GBUFFER 1
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
Fallback "Hidden/Universal Render Pipeline/FallbackError"
|
||||
}
|
@@ -0,0 +1,208 @@
|
||||
Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[MainColor] _BaseColor("Color", Color) = (1,1,1,1)
|
||||
_MainTex("Albedo(RGB), Smoothness(A)", 2D) = "white" {}
|
||||
_MetallicTex ("Metallic (R)", 2D) = "black" {}
|
||||
[HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
HLSLINCLUDE
|
||||
|
||||
#pragma multi_compile_fragment __ _ALPHATEST_ON
|
||||
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True"}
|
||||
LOD 200
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Forward pass. Shades all light in a single pass. GI + emission + Fog
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
// Lightmode matches the ShaderPassName set in UniversalPipeline.cs. SRPDefaultUnlit and passes with
|
||||
// no LightMode tag are also rendered by Universal Pipeline
|
||||
Tags{"LightMode" = "UniversalForward"}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
// -------------------------------------
|
||||
// Material Keywords
|
||||
#define _METALLICSPECGLOSSMAP 1
|
||||
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
|
||||
#pragma multi_compile _ SHADOWS_SHADOWMASK
|
||||
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined 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 vertex SplatmapVert
|
||||
#pragma fragment SplatmapFragment
|
||||
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
// Sample normal in pixel shader when doing instancing
|
||||
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
|
||||
#define TERRAIN_SPLAT_BASEPASS 1
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags{"LightMode" = "ShadowCaster"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#pragma vertex ShadowPassVertex
|
||||
#pragma fragment ShadowPassFragment
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// GBuffer pass. Does GI + emission. All additional lights are done deferred as well as fog
|
||||
Pass
|
||||
{
|
||||
Name "GBuffer"
|
||||
Tags{"LightMode" = "UniversalGBuffer"}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma exclude_renderers gles
|
||||
#pragma target 2.0
|
||||
|
||||
// -------------------------------------
|
||||
// Material Keywords
|
||||
#define _METALLICSPECGLOSSMAP 1
|
||||
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#pragma vertex SplatmapVert
|
||||
#pragma fragment SplatmapFragment
|
||||
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
// Sample normal in pixel shader when doing instancing
|
||||
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
|
||||
#define TERRAIN_SPLAT_BASEPASS 1
|
||||
#define TERRAIN_GBUFFER 1
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags{"LightMode" = "DepthOnly"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthOnlyVertex
|
||||
#pragma fragment DepthOnlyFragment
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthNormals"
|
||||
Tags{"LightMode" = "DepthNormals"}
|
||||
|
||||
ZWrite On
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthNormalOnlyVertex
|
||||
#pragma fragment DepthNormalOnlyFragment
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
|
||||
#pragma shader_feature_local _NORMALMAP
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// This pass it not used during regular rendering, only for lightmap baking.
|
||||
Pass
|
||||
{
|
||||
Name "Meta"
|
||||
Tags{"LightMode" = "Meta"}
|
||||
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex TerrainVertexMeta
|
||||
#pragma fragment TerrainFragmentMeta
|
||||
|
||||
#define _METALLICSPECGLOSSMAP 1
|
||||
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitMetaPass.hlsl"
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
UsePass "Hidden/Nature/Terrain/Utilities/PICKING"
|
||||
UsePass "Universal Render Pipeline/Terrain/Lit/SceneSelectionPass"
|
||||
}
|
||||
FallBack "Hidden/Universal Render Pipeline/FallbackError"
|
||||
//CustomEditor "LitShaderGUI"
|
||||
}
|
@@ -0,0 +1,207 @@
|
||||
Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Basemap Gen)"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
// Layer count is passed down to guide height-blend enable/disable, due
|
||||
// to the fact that heigh-based blend will be broken with multipass.
|
||||
[HideInInspector] [PerRendererData] _NumLayersCount ("Total Layer Count", Float) = 1.0
|
||||
[HideInInspector] _Control("AlphaMap", 2D) = "" {}
|
||||
|
||||
[HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
|
||||
[HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
|
||||
[HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
|
||||
[HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
|
||||
[HideInInspector] _Mask3("Mask 3 (A)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask2("Mask 2 (B)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask1("Mask 1 (G)", 2D) = "grey" {}
|
||||
[HideInInspector] _Mask0("Mask 0 (R)", 2D) = "grey" {}
|
||||
[HideInInspector] [Gamma] _Metallic0 ("Metallic 0", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector] [Gamma] _Metallic1 ("Metallic 1", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector] [Gamma] _Metallic2 ("Metallic 2", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector] [Gamma] _Metallic3 ("Metallic 3", Range(0.0, 1.0)) = 0.0
|
||||
[HideInInspector] _Smoothness0 ("Smoothness 0", Range(0.0, 1.0)) = 1.0
|
||||
[HideInInspector] _Smoothness1 ("Smoothness 1", Range(0.0, 1.0)) = 1.0
|
||||
[HideInInspector] _Smoothness2 ("Smoothness 2", Range(0.0, 1.0)) = 1.0
|
||||
[HideInInspector] _Smoothness3 ("Smoothness 3", Range(0.0, 1.0)) = 1.0
|
||||
|
||||
[HideInInspector] _DstBlend("DstBlend", Float) = 0.0
|
||||
}
|
||||
|
||||
Subshader
|
||||
{
|
||||
HLSLINCLUDE
|
||||
#pragma target 3.0
|
||||
|
||||
#define _METALLICSPECGLOSSMAP 1
|
||||
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
|
||||
#define _TERRAIN_BASEMAP_GEN
|
||||
|
||||
#pragma shader_feature_local _TERRAIN_BLEND_HEIGHT
|
||||
#pragma shader_feature_local _MASKMAP
|
||||
|
||||
#include "TerrainLitInput.hlsl"
|
||||
#include "TerrainLitPasses.hlsl"
|
||||
|
||||
ENDHLSL
|
||||
|
||||
Pass
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Name" = "_MainTex"
|
||||
"Format" = "ARGB32"
|
||||
"Size" = "1"
|
||||
}
|
||||
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
Blend One [_DstBlend]
|
||||
HLSLPROGRAM
|
||||
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
|
||||
Varyings Vert(Attributes IN)
|
||||
{
|
||||
Varyings output = (Varyings) 0;
|
||||
|
||||
output.clipPos = TransformWorldToHClip(IN.positionOS.xyz);
|
||||
|
||||
// NOTE : This is basically coming from the vertex shader in TerrainLitPasses
|
||||
// There are other plenty of other values that the original version computes, but for this
|
||||
// pass, we are only interested in a few, so I'm just skipping the rest.
|
||||
output.uvMainAndLM.xy = IN.texcoord;
|
||||
output.uvSplat01.xy = TRANSFORM_TEX(IN.texcoord, _Splat0);
|
||||
output.uvSplat01.zw = TRANSFORM_TEX(IN.texcoord, _Splat1);
|
||||
output.uvSplat23.xy = TRANSFORM_TEX(IN.texcoord, _Splat2);
|
||||
output.uvSplat23.zw = TRANSFORM_TEX(IN.texcoord, _Splat3);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 Frag(Varyings IN) : SV_Target
|
||||
{
|
||||
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
|
||||
half4 splatControl;
|
||||
half weight;
|
||||
half4 mixedDiffuse = 0.0h;
|
||||
half4 defaultSmoothness = 0.0h;
|
||||
|
||||
half4 masks[4];
|
||||
float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
|
||||
splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
|
||||
|
||||
masks[0] = 1.0h;
|
||||
masks[1] = 1.0h;
|
||||
masks[2] = 1.0h;
|
||||
masks[3] = 1.0h;
|
||||
|
||||
#ifdef _MASKMAP
|
||||
masks[0] = SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy);
|
||||
masks[1] = SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw);
|
||||
masks[2] = SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy);
|
||||
masks[3] = SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw);
|
||||
|
||||
#ifdef _TERRAIN_BLEND_HEIGHT
|
||||
HeightBasedSplatModify(splatControl, masks);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
|
||||
|
||||
half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
|
||||
|
||||
half4 maskSmoothness = half4(masks[0].a, masks[1].a, masks[2].a, masks[3].a);
|
||||
maskSmoothness *= half4(_MaskMapRemapScale0.a, _MaskMapRemapScale1.a, _MaskMapRemapScale2.a, _MaskMapRemapScale3.a);
|
||||
maskSmoothness += half4(_MaskMapRemapOffset0.a, _MaskMapRemapOffset1.a, _MaskMapRemapOffset2.a, _MaskMapRemapOffset3.a);
|
||||
|
||||
defaultSmoothness = lerp(defaultSmoothness, maskSmoothness, hasMask);
|
||||
half smoothness = dot(splatControl, defaultSmoothness);
|
||||
|
||||
return half4(mixedDiffuse.rgb, smoothness);
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Name" = "_MetallicTex"
|
||||
"Format" = "R8"
|
||||
"Size" = "1/4"
|
||||
"EmptyColor" = "FF000000"
|
||||
}
|
||||
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
Blend One [_DstBlend]
|
||||
|
||||
HLSLPROGRAM
|
||||
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
|
||||
Varyings Vert(Attributes IN)
|
||||
{
|
||||
Varyings output = (Varyings)0;
|
||||
|
||||
output.clipPos = TransformWorldToHClip(IN.positionOS.xyz);
|
||||
|
||||
// This is just like the other in that it is from TerrainLitPasses
|
||||
output.uvMainAndLM.xy = IN.texcoord;
|
||||
output.uvSplat01.xy = TRANSFORM_TEX(IN.texcoord, _Splat0);
|
||||
output.uvSplat01.zw = TRANSFORM_TEX(IN.texcoord, _Splat1);
|
||||
output.uvSplat23.xy = TRANSFORM_TEX(IN.texcoord, _Splat2);
|
||||
output.uvSplat23.zw = TRANSFORM_TEX(IN.texcoord, _Splat3);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 Frag(Varyings IN) : SV_Target
|
||||
{
|
||||
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
|
||||
half4 splatControl;
|
||||
half weight;
|
||||
half4 mixedDiffuse;
|
||||
half4 defaultSmoothness;
|
||||
|
||||
half4 masks[4];
|
||||
float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
|
||||
splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
|
||||
|
||||
masks[0] = 1.0h;
|
||||
masks[1] = 1.0h;
|
||||
masks[2] = 1.0h;
|
||||
masks[3] = 1.0h;
|
||||
|
||||
#ifdef _MASKMAP
|
||||
masks[0] = SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy);
|
||||
masks[1] = SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw);
|
||||
masks[2] = SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy);
|
||||
masks[3] = SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw);
|
||||
|
||||
#ifdef _TERRAIN_BLEND_HEIGHT
|
||||
HeightBasedSplatModify(splatControl, masks);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
|
||||
|
||||
half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
|
||||
|
||||
half4 defaultMetallic = half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3);
|
||||
half4 maskMetallic = half4(masks[0].r, masks[1].r, masks[2].r, masks[3].r);
|
||||
maskMetallic *= half4(_MaskMapRemapScale0.r, _MaskMapRemapScale1.r, _MaskMapRemapScale3.r, _MaskMapRemapScale3.r);
|
||||
maskMetallic += half4(_MaskMapRemapOffset0.r, _MaskMapRemapOffset1.r, _MaskMapRemapOffset2.r, _MaskMapRemapOffset3.r);
|
||||
|
||||
defaultMetallic = lerp(defaultMetallic, maskMetallic, hasMask);
|
||||
half metallic = dot(splatControl, defaultMetallic);
|
||||
|
||||
return metallic;
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
#ifndef UNIVERSAL_TERRAIN_LIT_INPUT_INCLUDED
|
||||
#define UNIVERSAL_TERRAIN_LIT_INPUT_INCLUDED
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
half4 _BaseColor;
|
||||
half _Cutoff;
|
||||
CBUFFER_END
|
||||
|
||||
#define _Surface 0.0 // Terrain is always opaque
|
||||
|
||||
CBUFFER_START(_Terrain)
|
||||
half _NormalScale0, _NormalScale1, _NormalScale2, _NormalScale3;
|
||||
half _Metallic0, _Metallic1, _Metallic2, _Metallic3;
|
||||
half _Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3;
|
||||
half4 _DiffuseRemapScale0, _DiffuseRemapScale1, _DiffuseRemapScale2, _DiffuseRemapScale3;
|
||||
half4 _MaskMapRemapOffset0, _MaskMapRemapOffset1, _MaskMapRemapOffset2, _MaskMapRemapOffset3;
|
||||
half4 _MaskMapRemapScale0, _MaskMapRemapScale1, _MaskMapRemapScale2, _MaskMapRemapScale3;
|
||||
|
||||
float4 _Control_ST;
|
||||
float4 _Control_TexelSize;
|
||||
half _DiffuseHasAlpha0, _DiffuseHasAlpha1, _DiffuseHasAlpha2, _DiffuseHasAlpha3;
|
||||
half _LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3;
|
||||
half4 _Splat0_ST, _Splat1_ST, _Splat2_ST, _Splat3_ST;
|
||||
half _HeightTransition;
|
||||
half _NumLayersCount;
|
||||
|
||||
#ifdef UNITY_INSTANCING_ENABLED
|
||||
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
|
||||
#ifdef SCENESELECTIONPASS
|
||||
int _ObjectId;
|
||||
int _PassValue;
|
||||
#endif
|
||||
CBUFFER_END
|
||||
|
||||
|
||||
TEXTURE2D(_Control); SAMPLER(sampler_Control);
|
||||
TEXTURE2D(_Splat0); SAMPLER(sampler_Splat0);
|
||||
TEXTURE2D(_Splat1);
|
||||
TEXTURE2D(_Splat2);
|
||||
TEXTURE2D(_Splat3);
|
||||
|
||||
#ifdef _NORMALMAP
|
||||
TEXTURE2D(_Normal0); SAMPLER(sampler_Normal0);
|
||||
TEXTURE2D(_Normal1);
|
||||
TEXTURE2D(_Normal2);
|
||||
TEXTURE2D(_Normal3);
|
||||
#endif
|
||||
|
||||
#ifdef _MASKMAP
|
||||
TEXTURE2D(_Mask0); SAMPLER(sampler_Mask0);
|
||||
TEXTURE2D(_Mask1);
|
||||
TEXTURE2D(_Mask2);
|
||||
TEXTURE2D(_Mask3);
|
||||
#endif
|
||||
|
||||
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
|
||||
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
|
||||
TEXTURE2D(_MetallicTex); SAMPLER(sampler_MetallicTex);
|
||||
|
||||
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)
|
||||
{
|
||||
half4 specGloss;
|
||||
specGloss = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, uv);
|
||||
specGloss.a = albedoAlpha;
|
||||
return specGloss;
|
||||
}
|
||||
|
||||
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
|
||||
{
|
||||
outSurfaceData = (SurfaceData)0;
|
||||
half4 albedoSmoothness = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
|
||||
outSurfaceData.alpha = 1;
|
||||
|
||||
half4 specGloss = SampleMetallicSpecGloss(uv, albedoSmoothness.a);
|
||||
outSurfaceData.albedo = albedoSmoothness.rgb;
|
||||
|
||||
outSurfaceData.metallic = specGloss.r;
|
||||
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
|
||||
|
||||
outSurfaceData.smoothness = specGloss.a;
|
||||
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
|
||||
outSurfaceData.occlusion = 1;
|
||||
outSurfaceData.emission = 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,45 @@
|
||||
#ifndef TERRAIN_LIT_META_PASS_INCLUDED
|
||||
#define TERRAIN_LIT_META_PASS_INCLUDED
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float2 uv0 : TEXCOORD0;
|
||||
float2 uv1 : TEXCOORD1;
|
||||
float2 uv2 : TEXCOORD2;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
Varyings TerrainVertexMeta(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2,
|
||||
unity_LightmapST, unity_DynamicLightmapST);
|
||||
output.uv = TRANSFORM_TEX(input.uv0, _MainTex);
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 TerrainFragmentMeta(Varyings input) : SV_Target
|
||||
{
|
||||
SurfaceData surfaceData;
|
||||
InitializeStandardLitSurfaceData(input.uv, surfaceData);
|
||||
|
||||
BRDFData brdfData;
|
||||
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
|
||||
|
||||
MetaInput metaInput;
|
||||
metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5;
|
||||
metaInput.SpecularColor = surfaceData.specular;
|
||||
metaInput.Emission = surfaceData.emission;
|
||||
|
||||
return MetaFragment(metaInput);
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,592 @@
|
||||
|
||||
#ifndef UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED
|
||||
#define UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.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);
|
||||
#endif
|
||||
|
||||
UNITY_INSTANCING_BUFFER_START(Terrain)
|
||||
UNITY_DEFINE_INSTANCED_PROP(float4, _TerrainPatchInstanceData) // float4(xBase, yBase, skipScale, ~)
|
||||
UNITY_INSTANCING_BUFFER_END(Terrain)
|
||||
|
||||
#ifdef _ALPHATEST_ON
|
||||
TEXTURE2D(_TerrainHolesTexture);
|
||||
SAMPLER(sampler_TerrainHolesTexture);
|
||||
|
||||
void ClipHoles(float2 uv)
|
||||
{
|
||||
float hole = SAMPLE_TEXTURE2D(_TerrainHolesTexture, sampler_TerrainHolesTexture, uv).r;
|
||||
clip(hole == 0.0f ? -1 : 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
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 defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
|
||||
float4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
|
||||
float4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
|
||||
float4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
|
||||
#else
|
||||
float3 normal : TEXCOORD3;
|
||||
float3 viewDir : TEXCOORD4;
|
||||
half3 vertexSH : TEXCOORD5; // SH
|
||||
#endif
|
||||
|
||||
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
|
||||
float3 positionWS : TEXCOORD7;
|
||||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||||
float4 shadowCoord : TEXCOORD8;
|
||||
#endif
|
||||
float4 clipPos : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
void InitializeInputData(Varyings IN, half3 normalTS, out InputData input)
|
||||
{
|
||||
input = (InputData)0;
|
||||
|
||||
input.positionWS = IN.positionWS;
|
||||
half3 SH = half3(0, 0, 0);
|
||||
|
||||
#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));
|
||||
SH = SampleSH(input.normalWS.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));
|
||||
SH = SampleSH(input.normalWS.xyz);
|
||||
#else
|
||||
half3 viewDirWS = IN.viewDir;
|
||||
input.normalWS = IN.normal;
|
||||
SH = IN.vertexSH;
|
||||
#endif
|
||||
|
||||
#if SHADER_HINT_NICE_QUALITY
|
||||
viewDirWS = SafeNormalize(viewDirWS);
|
||||
#endif
|
||||
|
||||
input.normalWS = NormalizeNormalPerPixel(input.normalWS);
|
||||
|
||||
input.viewDirectionWS = viewDirWS;
|
||||
|
||||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||||
input.shadowCoord = IN.shadowCoord;
|
||||
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
|
||||
input.shadowCoord = TransformWorldToShadowCoord(input.positionWS);
|
||||
#else
|
||||
input.shadowCoord = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
input.fogCoord = IN.fogFactorAndVertexLight.x;
|
||||
input.vertexLighting = IN.fogFactorAndVertexLight.yzw;
|
||||
|
||||
input.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, SH, input.normalWS);
|
||||
input.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.clipPos);
|
||||
input.shadowMask = SAMPLE_SHADOWMASK(IN.uvMainAndLM.zw)
|
||||
}
|
||||
|
||||
#ifndef TERRAIN_SPLAT_BASEPASS
|
||||
|
||||
void SplatmapMix(float4 uvMainAndLM, float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, out half weight, out half4 mixedDiffuse, out half4 defaultSmoothness, inout half3 mixedNormal)
|
||||
{
|
||||
half4 diffAlbedo[4];
|
||||
|
||||
diffAlbedo[0] = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, uvSplat01.xy);
|
||||
diffAlbedo[1] = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, uvSplat01.zw);
|
||||
diffAlbedo[2] = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, uvSplat23.xy);
|
||||
diffAlbedo[3] = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, uvSplat23.zw);
|
||||
|
||||
// This might be a bit of a gamble -- the assumption here is that if the diffuseMap has no
|
||||
// alpha channel, then diffAlbedo[n].a = 1.0 (and _DiffuseHasAlphaN = 0.0)
|
||||
// Prior to coming in, _SmoothnessN is actually set to max(_DiffuseHasAlphaN, _SmoothnessN)
|
||||
// This means that if we have an alpha channel, _SmoothnessN is locked to 1.0 and
|
||||
// otherwise, the true slider value is passed down and diffAlbedo[n].a == 1.0.
|
||||
defaultSmoothness = half4(diffAlbedo[0].a, diffAlbedo[1].a, diffAlbedo[2].a, diffAlbedo[3].a);
|
||||
defaultSmoothness *= half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
|
||||
|
||||
#ifndef _TERRAIN_BLEND_HEIGHT
|
||||
// 20.0 is the number of steps in inputAlphaMask (Density mask. We decided 20 empirically)
|
||||
half4 opacityAsDensity = saturate((half4(diffAlbedo[0].a, diffAlbedo[1].a, diffAlbedo[2].a, diffAlbedo[3].a) - (half4(1.0, 1.0, 1.0, 1.0) - splatControl)) * 20.0);
|
||||
opacityAsDensity += 0.001h * splatControl; // if all weights are zero, default to what the blend mask says
|
||||
half4 useOpacityAsDensityParam = { _DiffuseRemapScale0.w, _DiffuseRemapScale1.w, _DiffuseRemapScale2.w, _DiffuseRemapScale3.w }; // 1 is off
|
||||
splatControl = lerp(opacityAsDensity, splatControl, useOpacityAsDensityParam);
|
||||
#endif
|
||||
|
||||
// Now that splatControl has changed, we can compute the final weight and normalize
|
||||
weight = dot(splatControl, 1.0h);
|
||||
|
||||
#ifdef TERRAIN_SPLAT_ADDPASS
|
||||
clip(weight <= 0.005h ? -1.0h : 1.0h);
|
||||
#endif
|
||||
|
||||
#ifndef _TERRAIN_BASEMAP_GEN
|
||||
// Normalize weights before lighting and restore weights in final modifier functions so that the overal
|
||||
// lighting result can be correctly weighted.
|
||||
splatControl /= (weight + HALF_MIN);
|
||||
#endif
|
||||
|
||||
mixedDiffuse = 0.0h;
|
||||
mixedDiffuse += diffAlbedo[0] * half4(_DiffuseRemapScale0.rgb * splatControl.rrr, 1.0h);
|
||||
mixedDiffuse += diffAlbedo[1] * half4(_DiffuseRemapScale1.rgb * splatControl.ggg, 1.0h);
|
||||
mixedDiffuse += diffAlbedo[2] * half4(_DiffuseRemapScale2.rgb * splatControl.bbb, 1.0h);
|
||||
mixedDiffuse += diffAlbedo[3] * half4(_DiffuseRemapScale3.rgb * splatControl.aaa, 1.0h);
|
||||
|
||||
#ifdef _NORMALMAP
|
||||
half3 nrm = 0.0f;
|
||||
nrm += splatControl.r * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, uvSplat01.xy), _NormalScale0);
|
||||
nrm += splatControl.g * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, uvSplat01.zw), _NormalScale1);
|
||||
nrm += splatControl.b * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal2, sampler_Normal0, uvSplat23.xy), _NormalScale2);
|
||||
nrm += splatControl.a * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal3, sampler_Normal0, uvSplat23.zw), _NormalScale3);
|
||||
|
||||
// avoid risk of NaN when normalizing.
|
||||
#if HAS_HALF
|
||||
nrm.z += 0.01h;
|
||||
#else
|
||||
nrm.z += 1e-5f;
|
||||
#endif
|
||||
|
||||
mixedNormal = normalize(nrm.xyz);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _TERRAIN_BLEND_HEIGHT
|
||||
void HeightBasedSplatModify(inout half4 splatControl, in half4 masks[4])
|
||||
{
|
||||
// heights are in mask blue channel, we multiply by the splat Control weights to get combined height
|
||||
half4 splatHeight = half4(masks[0].b, masks[1].b, masks[2].b, masks[3].b) * splatControl.rgba;
|
||||
half maxHeight = max(splatHeight.r, max(splatHeight.g, max(splatHeight.b, splatHeight.a)));
|
||||
|
||||
// Ensure that the transition height is not zero.
|
||||
half transition = max(_HeightTransition, 1e-5);
|
||||
|
||||
// This sets the highest splat to "transition", and everything else to a lower value relative to that, clamping to zero
|
||||
// Then we clamp this to zero and normalize everything
|
||||
half4 weightedHeights = splatHeight + transition - maxHeight.xxxx;
|
||||
weightedHeights = max(0, weightedHeights);
|
||||
|
||||
// We need to add an epsilon here for active layers (hence the blendMask again)
|
||||
// so that at least a layer shows up if everything's too low.
|
||||
weightedHeights = (weightedHeights + 1e-6) * splatControl;
|
||||
|
||||
// Normalize (and clamp to epsilon to keep from dividing by zero)
|
||||
half sumHeight = max(dot(weightedHeights, half4(1, 1, 1, 1)), 1e-6);
|
||||
splatControl = weightedHeights / sumHeight.xxxx;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SplatmapFinalColor(inout half4 color, half fogCoord)
|
||||
{
|
||||
color.rgb *= color.a;
|
||||
|
||||
#ifndef TERRAIN_GBUFFER // Technically we don't need fogCoord, but it is still passed from the vertex shader.
|
||||
|
||||
#ifdef TERRAIN_SPLAT_ADDPASS
|
||||
color.rgb = MixFogColor(color.rgb, half3(0,0,0), fogCoord);
|
||||
#else
|
||||
color.rgb = MixFog(color.rgb, fogCoord);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void TerrainInstancing(inout float4 positionOS, inout float3 normal, inout float2 uv)
|
||||
{
|
||||
#ifdef UNITY_INSTANCING_ENABLED
|
||||
float2 patchVertex = 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)));
|
||||
|
||||
positionOS.xz = sampleCoords * _TerrainHeightmapScale.xz;
|
||||
positionOS.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 positionOS, inout float3 normal)
|
||||
{
|
||||
float2 uv = { 0, 0 };
|
||||
TerrainInstancing(positionOS, normal, uv);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Vertex and Fragment functions //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Used in Standard Terrain shader
|
||||
Varyings SplatmapVert(Attributes v)
|
||||
{
|
||||
Varyings o = (Varyings)0;
|
||||
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
TerrainInstancing(v.positionOS, v.normalOS, v.texcoord);
|
||||
|
||||
VertexPositionInputs Attributes = GetVertexPositionInputs(v.positionOS.xyz);
|
||||
|
||||
o.uvMainAndLM.xy = v.texcoord;
|
||||
o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
|
||||
#ifndef TERRAIN_SPLAT_BASEPASS
|
||||
o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
|
||||
o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
|
||||
o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
|
||||
o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
|
||||
#endif
|
||||
|
||||
half3 viewDirWS = GetWorldSpaceViewDir(Attributes.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.normalOS), 1.0);
|
||||
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, 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.normalOS);
|
||||
o.viewDir = viewDirWS;
|
||||
o.vertexSH = SampleSH(o.normal);
|
||||
#endif
|
||||
o.fogFactorAndVertexLight.x = ComputeFogFactor(Attributes.positionCS.z);
|
||||
o.fogFactorAndVertexLight.yzw = VertexLighting(Attributes.positionWS, o.normal.xyz);
|
||||
o.positionWS = Attributes.positionWS;
|
||||
o.clipPos = Attributes.positionCS;
|
||||
|
||||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||||
o.shadowCoord = GetShadowCoord(Attributes);
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
void ComputeMasks(out half4 masks[4], half4 hasMask, Varyings IN)
|
||||
{
|
||||
masks[0] = 0.5h;
|
||||
masks[1] = 0.5h;
|
||||
masks[2] = 0.5h;
|
||||
masks[3] = 0.5h;
|
||||
|
||||
#ifdef _MASKMAP
|
||||
masks[0] = lerp(masks[0], SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy), hasMask.x);
|
||||
masks[1] = lerp(masks[1], SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw), hasMask.y);
|
||||
masks[2] = lerp(masks[2], SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy), hasMask.z);
|
||||
masks[3] = lerp(masks[3], SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw), hasMask.w);
|
||||
#endif
|
||||
|
||||
masks[0] *= _MaskMapRemapScale0.rgba;
|
||||
masks[0] += _MaskMapRemapOffset0.rgba;
|
||||
masks[1] *= _MaskMapRemapScale1.rgba;
|
||||
masks[1] += _MaskMapRemapOffset1.rgba;
|
||||
masks[2] *= _MaskMapRemapScale2.rgba;
|
||||
masks[2] += _MaskMapRemapOffset2.rgba;
|
||||
masks[3] *= _MaskMapRemapScale3.rgba;
|
||||
masks[3] += _MaskMapRemapOffset3.rgba;
|
||||
}
|
||||
|
||||
// Used in Standard Terrain shader
|
||||
#ifdef TERRAIN_GBUFFER
|
||||
FragmentOutput SplatmapFragment(Varyings IN)
|
||||
#else
|
||||
half4 SplatmapFragment(Varyings IN) : SV_TARGET
|
||||
#endif
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
|
||||
#ifdef _ALPHATEST_ON
|
||||
ClipHoles(IN.uvMainAndLM.xy);
|
||||
#endif
|
||||
|
||||
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
|
||||
#ifdef TERRAIN_SPLAT_BASEPASS
|
||||
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;
|
||||
half occlusion = 1;
|
||||
#else
|
||||
|
||||
half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
|
||||
half4 masks[4];
|
||||
ComputeMasks(masks, hasMask, IN);
|
||||
|
||||
float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
|
||||
half4 splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
|
||||
|
||||
#ifdef _TERRAIN_BLEND_HEIGHT
|
||||
// disable Height Based blend when there are more than 4 layers (multi-pass breaks the normalization)
|
||||
if (_NumLayersCount <= 4)
|
||||
HeightBasedSplatModify(splatControl, masks);
|
||||
#endif
|
||||
|
||||
half weight;
|
||||
half4 mixedDiffuse;
|
||||
half4 defaultSmoothness;
|
||||
SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
|
||||
half3 albedo = mixedDiffuse.rgb;
|
||||
|
||||
half4 defaultMetallic = half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3);
|
||||
half4 defaultOcclusion = half4(_MaskMapRemapScale0.g, _MaskMapRemapScale1.g, _MaskMapRemapScale2.g, _MaskMapRemapScale3.g) +
|
||||
half4(_MaskMapRemapOffset0.g, _MaskMapRemapOffset1.g, _MaskMapRemapOffset2.g, _MaskMapRemapOffset3.g);
|
||||
|
||||
half4 maskSmoothness = half4(masks[0].a, masks[1].a, masks[2].a, masks[3].a);
|
||||
defaultSmoothness = lerp(defaultSmoothness, maskSmoothness, hasMask);
|
||||
half smoothness = dot(splatControl, defaultSmoothness);
|
||||
|
||||
half4 maskMetallic = half4(masks[0].r, masks[1].r, masks[2].r, masks[3].r);
|
||||
defaultMetallic = lerp(defaultMetallic, maskMetallic, hasMask);
|
||||
half metallic = dot(splatControl, defaultMetallic);
|
||||
|
||||
half4 maskOcclusion = half4(masks[0].g, masks[1].g, masks[2].g, masks[3].g);
|
||||
defaultOcclusion = lerp(defaultOcclusion, maskOcclusion, hasMask);
|
||||
half occlusion = dot(splatControl, defaultOcclusion);
|
||||
half alpha = weight;
|
||||
#endif
|
||||
|
||||
InputData inputData;
|
||||
InitializeInputData(IN, normalTS, inputData);
|
||||
|
||||
#ifdef TERRAIN_GBUFFER
|
||||
|
||||
BRDFData brdfData;
|
||||
InitializeBRDFData(albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, alpha, brdfData);
|
||||
|
||||
// Baked lighting.
|
||||
half4 color;
|
||||
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
|
||||
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
|
||||
color.rgb = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
|
||||
color.a = alpha;
|
||||
SplatmapFinalColor(color, inputData.fogCoord);
|
||||
|
||||
// Dynamic lighting: emulate SplatmapFinalColor() by scaling gbuffer material properties. This will not give the same results
|
||||
// as forward renderer because we apply blending pre-lighting instead of post-lighting.
|
||||
// Blending of smoothness and normals is also not correct but close enough?
|
||||
brdfData.diffuse.rgb *= alpha;
|
||||
brdfData.specular.rgb *= alpha;
|
||||
inputData.normalWS = inputData.normalWS * alpha;
|
||||
smoothness *= alpha;
|
||||
|
||||
return BRDFDataToGbuffer(brdfData, inputData, smoothness, color.rgb);
|
||||
|
||||
#else
|
||||
|
||||
half4 color = UniversalFragmentPBR(inputData, albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, occlusion, /* emission */ half3(0, 0, 0), alpha);
|
||||
|
||||
SplatmapFinalColor(color, inputData.fogCoord);
|
||||
|
||||
return half4(color.rgb, 1.0h);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Shadow pass
|
||||
|
||||
// Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
|
||||
// For Directional lights, _LightDirection is used when applying shadow Normal Bias.
|
||||
// For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
|
||||
float3 _LightDirection;
|
||||
float3 _LightPosition;
|
||||
|
||||
struct AttributesLean
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
#ifdef _ALPHATEST_ON
|
||||
float2 texcoord : TEXCOORD0;
|
||||
#endif
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct VaryingsLean
|
||||
{
|
||||
float4 clipPos : SV_POSITION;
|
||||
#ifdef _ALPHATEST_ON
|
||||
float2 texcoord : TEXCOORD0;
|
||||
#endif
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
VaryingsLean ShadowPassVertex(AttributesLean v)
|
||||
{
|
||||
VaryingsLean o = (VaryingsLean)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
TerrainInstancing(v.position, v.normalOS);
|
||||
|
||||
float3 positionWS = TransformObjectToWorld(v.position.xyz);
|
||||
float3 normalWS = TransformObjectToWorldNormal(v.normalOS);
|
||||
|
||||
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
|
||||
float3 lightDirectionWS = normalize(_LightPosition - positionWS);
|
||||
#else
|
||||
float3 lightDirectionWS = _LightDirection;
|
||||
#endif
|
||||
|
||||
float4 clipPos = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
|
||||
|
||||
#if UNITY_REVERSED_Z
|
||||
clipPos.z = min(clipPos.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#else
|
||||
clipPos.z = max(clipPos.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#endif
|
||||
|
||||
o.clipPos = clipPos;
|
||||
|
||||
#ifdef _ALPHATEST_ON
|
||||
o.texcoord = v.texcoord;
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 ShadowPassFragment(VaryingsLean IN) : SV_TARGET
|
||||
{
|
||||
#ifdef _ALPHATEST_ON
|
||||
ClipHoles(IN.texcoord);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Depth pass
|
||||
|
||||
VaryingsLean DepthOnlyVertex(AttributesLean v)
|
||||
{
|
||||
VaryingsLean o = (VaryingsLean)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
TerrainInstancing(v.position, v.normalOS);
|
||||
o.clipPos = TransformObjectToHClip(v.position.xyz);
|
||||
#ifdef _ALPHATEST_ON
|
||||
o.texcoord = v.texcoord;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 DepthOnlyFragment(VaryingsLean IN) : SV_TARGET
|
||||
{
|
||||
#ifdef _ALPHATEST_ON
|
||||
ClipHoles(IN.texcoord);
|
||||
#endif
|
||||
#ifdef SCENESELECTIONPASS
|
||||
// We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
|
||||
return half4(_ObjectId, _PassValue, 1.0, 1.0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// DepthNormal pass
|
||||
struct AttributesDepthNormal
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct VaryingsDepthNormal
|
||||
{
|
||||
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 defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
|
||||
float4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
|
||||
float4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
|
||||
float4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
|
||||
#else
|
||||
float3 normal : TEXCOORD3;
|
||||
#endif
|
||||
|
||||
float4 clipPos : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
VaryingsDepthNormal DepthNormalOnlyVertex(AttributesDepthNormal v)
|
||||
{
|
||||
VaryingsDepthNormal o = (VaryingsDepthNormal)0;
|
||||
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
TerrainInstancing(v.positionOS, v.normalOS, v.texcoord);
|
||||
|
||||
VertexPositionInputs Attributes = GetVertexPositionInputs(v.positionOS.xyz);
|
||||
|
||||
o.uvMainAndLM.xy = v.texcoord;
|
||||
o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
|
||||
#ifndef TERRAIN_SPLAT_BASEPASS
|
||||
o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
|
||||
o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
|
||||
o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
|
||||
o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
|
||||
#endif
|
||||
|
||||
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
|
||||
half3 viewDirWS = GetWorldSpaceViewDir(Attributes.positionWS);
|
||||
#if !SHADER_HINT_NICE_QUALITY
|
||||
viewDirWS = SafeNormalize(viewDirWS);
|
||||
#endif
|
||||
float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0);
|
||||
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, 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.normalOS);
|
||||
#endif
|
||||
|
||||
o.clipPos = Attributes.positionCS;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 DepthNormalOnlyFragment(VaryingsDepthNormal IN) : SV_TARGET
|
||||
{
|
||||
#ifdef _ALPHATEST_ON
|
||||
ClipHoles(IN.uvMainAndLM.xy);
|
||||
#endif
|
||||
|
||||
half3 normalWS = IN.normal;
|
||||
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(normalWS, true)), 0.0, 0.0);
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,112 @@
|
||||
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
|
||||
Shader "Hidden/TerrainEngine/Details/UniversalPipeline/WavingDoublePass"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
|
||||
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
|
||||
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
|
||||
_Cutoff ("Cutoff", float) = 0.5
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags {"Queue" = "Geometry+200" "RenderType" = "Grass" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" }//"DisableBatching"="True"
|
||||
Cull Off
|
||||
LOD 200
|
||||
AlphaTest Greater [_Cutoff]
|
||||
ColorMask RGB
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
|
||||
#pragma multi_compile _ SHADOWS_SHADOWMASK
|
||||
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fog
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#pragma vertex WavingGrassVert
|
||||
#pragma fragment LitPassFragmentGrass
|
||||
#define _ALPHATEST_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags{"LightMode" = "DepthOnly"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthOnlyVertex
|
||||
#pragma fragment DepthOnlyFragment
|
||||
|
||||
// -------------------------------------
|
||||
// Material Keywords
|
||||
#define _ALPHATEST_ON
|
||||
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// This pass is used when drawing to a _CameraNormalsTexture texture
|
||||
Pass
|
||||
{
|
||||
Name "DepthNormals"
|
||||
Tags{"LightMode" = "DepthNormals"}
|
||||
|
||||
ZWrite On
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthNormalOnlyVertex
|
||||
#pragma fragment DepthNormalOnlyFragment
|
||||
|
||||
// -------------------------------------
|
||||
// Material Keywords
|
||||
#define _ALPHATEST_ON
|
||||
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
|
||||
Shader "Hidden/TerrainEngine/Details/UniversalPipeline/BillboardWavingDoublePass"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
|
||||
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
|
||||
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
|
||||
_Cutoff ("Cutoff", float) = 0.5
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags {"Queue" = "Geometry+200" "RenderType" = "GrassBillBoard" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" }//"DisableBatching"="True"
|
||||
Cull Off
|
||||
LOD 200
|
||||
AlphaTest Greater [_Cutoff]
|
||||
ColorMask RGB
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
// -------------------------------------
|
||||
// Universal Pipeline keywords
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
|
||||
#pragma multi_compile _ SHADOWS_SHADOWMASK
|
||||
|
||||
// -------------------------------------
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
||||
#pragma multi_compile _ LIGHTMAP_ON
|
||||
#pragma multi_compile_fog
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#pragma vertex WavingGrassBillboardVert
|
||||
#pragma fragment LitPassFragmentGrass
|
||||
#define _ALPHATEST_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags{"LightMode" = "DepthOnly"}
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthOnlyVertex
|
||||
#pragma fragment DepthOnlyFragment
|
||||
|
||||
// -------------------------------------
|
||||
// Material Keywords
|
||||
#define _ALPHATEST_ON
|
||||
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DepthNormals"
|
||||
Tags{"LightMode" = "DepthNormals"}
|
||||
|
||||
ZWrite On
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 2.0
|
||||
|
||||
#pragma vertex DepthNormalOnlyVertex
|
||||
#pragma fragment DepthNormalOnlyFragment
|
||||
|
||||
// -------------------------------------
|
||||
// Material Keywords
|
||||
#define _ALPHATEST_ON
|
||||
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
|
||||
|
||||
//--------------------------------------
|
||||
// GPU Instancing
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
#ifndef UNIVERSAL_WAVING_GRASS_INPUT_INCLUDED
|
||||
#define UNIVERSAL_WAVING_GRASS_INPUT_INCLUDED
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
half4 _BaseColor;
|
||||
half4 _SpecColor;
|
||||
half4 _EmissionColor;
|
||||
half _Cutoff;
|
||||
half _Shininess;
|
||||
CBUFFER_END
|
||||
|
||||
#define _Surface 0.0 // Grass is always opaque
|
||||
|
||||
// Terrain engine shader helpers
|
||||
CBUFFER_START(TerrainGrass)
|
||||
half4 _WavingTint;
|
||||
float4 _WaveAndDistance; // wind speed, wave size, wind amount, max sqr distance
|
||||
float4 _CameraPosition; // .xyz = camera position, .w = 1 / (max sqr distance)
|
||||
float3 _CameraRight, _CameraUp;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
|
||||
|
||||
// ---- Grass helpers
|
||||
|
||||
// Calculate a 4 fast sine-cosine pairs
|
||||
// val: the 4 input values - each must be in the range (0 to 1)
|
||||
// s: The sine of each of the 4 values
|
||||
// c: The cosine of each of the 4 values
|
||||
void FastSinCos (float4 val, out float4 s, out float4 c) {
|
||||
val = val * 6.408849 - 3.1415927;
|
||||
// powers for taylor series
|
||||
float4 r5 = val * val; // wavevec ^ 2
|
||||
float4 r6 = r5 * r5; // wavevec ^ 4;
|
||||
float4 r7 = r6 * r5; // wavevec ^ 6;
|
||||
float4 r8 = r6 * r5; // wavevec ^ 8;
|
||||
|
||||
float4 r1 = r5 * val; // wavevec ^ 3
|
||||
float4 r2 = r1 * r5; // wavevec ^ 5;
|
||||
float4 r3 = r2 * r5; // wavevec ^ 7;
|
||||
|
||||
|
||||
//Vectors for taylor's series expansion of sin and cos
|
||||
float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841};
|
||||
float4 cos8 = {-0.5, 0.041666666, -0.0013888889, 0.000024801587};
|
||||
|
||||
// sin
|
||||
s = val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
|
||||
|
||||
// cos
|
||||
c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
|
||||
}
|
||||
|
||||
half4 TerrainWaveGrass (inout float4 vertex, float waveAmount, half4 color)
|
||||
{
|
||||
half4 _waveXSize = half4(0.012, 0.02, 0.06, 0.024) * _WaveAndDistance.y;
|
||||
half4 _waveZSize = half4 (0.006, .02, 0.02, 0.05) * _WaveAndDistance.y;
|
||||
half4 waveSpeed = half4 (1.2, 2, 1.6, 4.8);
|
||||
|
||||
half4 _waveXmove = half4(0.024, 0.04, -0.12, 0.096);
|
||||
half4 _waveZmove = half4 (0.006, .02, -0.02, 0.1);
|
||||
|
||||
float4 waves;
|
||||
waves = vertex.x * _waveXSize;
|
||||
waves += vertex.z * _waveZSize;
|
||||
|
||||
// Add in time to model them over time
|
||||
waves += _WaveAndDistance.x * waveSpeed;
|
||||
|
||||
float4 s, c;
|
||||
waves = frac (waves);
|
||||
FastSinCos (waves, s,c);
|
||||
|
||||
s = s * s;
|
||||
|
||||
s = s * s;
|
||||
|
||||
half lighting = dot (s, normalize (half4 (1,1,.4,.2))) * 0.7;
|
||||
|
||||
s = s * waveAmount;
|
||||
|
||||
half3 waveMove = 0;
|
||||
waveMove.x = dot (s, _waveXmove);
|
||||
waveMove.z = dot (s, _waveZmove);
|
||||
|
||||
vertex.xz -= waveMove.xz * _WaveAndDistance.z;
|
||||
|
||||
// apply color animation
|
||||
half3 waveColor = lerp (real3(0.5, 0.5, 0.5), _WavingTint.rgb, lighting);
|
||||
|
||||
// Fade the grass out before detail distance.
|
||||
// Saturate because Radeon HD drivers on OS X 10.4.10 don't saturate vertex colors properly.
|
||||
half3 offset = vertex.xyz - _CameraPosition.xyz;
|
||||
color.a = saturate (2 * (_WaveAndDistance.w - dot (offset, offset)) * _CameraPosition.w);
|
||||
|
||||
return half4(2 * waveColor * color.rgb, color.a);
|
||||
}
|
||||
|
||||
void TerrainBillboardGrass( inout float4 pos, float2 offset )
|
||||
{
|
||||
float3 grasspos = pos.xyz - _CameraPosition.xyz;
|
||||
if (dot(grasspos, grasspos) > _WaveAndDistance.w)
|
||||
offset = 0.0;
|
||||
pos.xyz += offset.x * _CameraRight.xyz;
|
||||
pos.y += offset.y;
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,297 @@
|
||||
#ifndef UNIVERSAL_WAVING_GRASS_PASSES_INCLUDED
|
||||
#define UNIVERSAL_WAVING_GRASS_PASSES_INCLUDED
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl"
|
||||
|
||||
struct GrassVertexInput
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
half4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float2 lightmapUV : TEXCOORD1;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct GrassVertexOutput
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
|
||||
|
||||
float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
|
||||
|
||||
half3 normal : TEXCOORD3;
|
||||
half3 viewDir : TEXCOORD4;
|
||||
|
||||
half4 fogFactorAndVertexLight : TEXCOORD5; // x: fogFactor, yzw: vertex light
|
||||
|
||||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||||
float4 shadowCoord : TEXCOORD6;
|
||||
#endif
|
||||
half4 color : TEXCOORD7;
|
||||
|
||||
float4 clipPos : SV_POSITION;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
void InitializeInputData(GrassVertexOutput input, out InputData inputData)
|
||||
{
|
||||
inputData.positionWS = input.posWSShininess.xyz;
|
||||
|
||||
half3 viewDirWS = input.viewDir;
|
||||
#if SHADER_HINT_NICE_QUALITY
|
||||
viewDirWS = SafeNormalize(viewDirWS);
|
||||
#endif
|
||||
|
||||
inputData.normalWS = NormalizeNormalPerPixel(input.normal);
|
||||
inputData.viewDirectionWS = viewDirWS;
|
||||
|
||||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||||
inputData.shadowCoord = input.shadowCoord;
|
||||
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
|
||||
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
|
||||
#else
|
||||
inputData.shadowCoord = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
inputData.fogCoord = input.fogFactorAndVertexLight.x;
|
||||
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
|
||||
|
||||
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
|
||||
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
|
||||
inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
|
||||
}
|
||||
|
||||
|
||||
void InitializeVertData(GrassVertexInput input, inout GrassVertexOutput vertData)
|
||||
{
|
||||
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
|
||||
|
||||
vertData.uv = input.texcoord;
|
||||
vertData.posWSShininess.xyz = vertexInput.positionWS;
|
||||
vertData.posWSShininess.w = 32;
|
||||
vertData.clipPos = vertexInput.positionCS;
|
||||
|
||||
vertData.viewDir = GetCameraPositionWS() - vertexInput.positionWS;
|
||||
|
||||
#if !SHADER_QUALITY_NICE_HINT
|
||||
vertData.viewDir = SafeNormalize(vertData.viewDir);
|
||||
#endif
|
||||
|
||||
vertData.normal = TransformObjectToWorldNormal(input.normal);
|
||||
|
||||
// We either sample GI from lightmap or SH.
|
||||
// Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
|
||||
// see DECLARE_LIGHTMAP_OR_SH macro.
|
||||
// The following funcions initialize the correct variable with correct data
|
||||
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, vertData.lightmapUV);
|
||||
OUTPUT_SH(vertData.normal, vertData.vertexSH);
|
||||
|
||||
half3 vertexLight = VertexLighting(vertexInput.positionWS, vertData.normal.xyz);
|
||||
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
|
||||
vertData.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
|
||||
|
||||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||||
vertData.shadowCoord = GetShadowCoord(vertexInput);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Vertex and Fragment functions //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Grass: appdata_full usage
|
||||
// color - .xyz = color, .w = wave scale
|
||||
// normal - normal
|
||||
// tangent.xy - billboard extrusion
|
||||
// texcoord - UV coords
|
||||
// texcoord1 - 2nd UV coords
|
||||
|
||||
GrassVertexOutput WavingGrassVert(GrassVertexInput v)
|
||||
{
|
||||
GrassVertexOutput o = (GrassVertexOutput)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
|
||||
// _WaveAndDistance.z == 0 for MeshLit
|
||||
float waveAmount = v.color.a * _WaveAndDistance.z;
|
||||
o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
|
||||
|
||||
InitializeVertData(v, o);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
GrassVertexOutput WavingGrassBillboardVert(GrassVertexInput v)
|
||||
{
|
||||
GrassVertexOutput o = (GrassVertexOutput)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
TerrainBillboardGrass (v.vertex, v.tangent.xy);
|
||||
// wave amount defined by the grass height
|
||||
float waveAmount = v.tangent.y;
|
||||
o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
|
||||
|
||||
InitializeVertData(v, o);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
inline void InitializeSimpleLitSurfaceData(GrassVertexOutput input, out SurfaceData outSurfaceData)
|
||||
{
|
||||
half4 diffuseAlpha = SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
|
||||
half3 diffuse = diffuseAlpha.rgb * input.color.rgb;
|
||||
|
||||
half alpha = diffuseAlpha.a;
|
||||
AlphaDiscard(alpha, _Cutoff);
|
||||
alpha *= input.color.a;
|
||||
|
||||
outSurfaceData = (SurfaceData)0;
|
||||
outSurfaceData.alpha = alpha;
|
||||
outSurfaceData.albedo = diffuse;
|
||||
outSurfaceData.metallic = 0.0; // unused
|
||||
outSurfaceData.specular = 0.1;// SampleSpecularSmoothness(uv, diffuseAlpha.a, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
|
||||
outSurfaceData.smoothness = input.posWSShininess.w;
|
||||
outSurfaceData.normalTS = 0.0; // unused
|
||||
outSurfaceData.occlusion = 1.0; // unused
|
||||
outSurfaceData.emission = 0.0;
|
||||
}
|
||||
|
||||
|
||||
// Used for StandardSimpleLighting shader
|
||||
#ifdef TERRAIN_GBUFFER
|
||||
FragmentOutput LitPassFragmentGrass(GrassVertexOutput input)
|
||||
#else
|
||||
half4 LitPassFragmentGrass(GrassVertexOutput input) : SV_Target
|
||||
#endif
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
|
||||
SurfaceData surfaceData;
|
||||
InitializeSimpleLitSurfaceData(input, surfaceData);
|
||||
|
||||
InputData inputData;
|
||||
InitializeInputData(input, inputData);
|
||||
|
||||
|
||||
#ifdef TERRAIN_GBUFFER
|
||||
half4 color = half4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha);
|
||||
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingSimpleLit);
|
||||
#else
|
||||
half4 color = UniversalFragmentBlinnPhong(inputData, surfaceData.albedo, half4(surfaceData.specular, surfaceData.smoothness), surfaceData.smoothness, surfaceData.emission, surfaceData.alpha);
|
||||
color.rgb = MixFog(color.rgb, inputData.fogCoord);
|
||||
return color;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct GrassVertexDepthOnlyInput
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float4 tangent : TANGENT;
|
||||
half4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct GrassVertexDepthOnlyOutput
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
half4 color : TEXCOORD1;
|
||||
float4 clipPos : SV_POSITION;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
void InitializeVertData(GrassVertexDepthOnlyInput input, inout GrassVertexDepthOnlyOutput vertData)
|
||||
{
|
||||
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
|
||||
|
||||
vertData.uv = input.texcoord;
|
||||
vertData.clipPos = vertexInput.positionCS;
|
||||
}
|
||||
|
||||
GrassVertexDepthOnlyOutput DepthOnlyVertex(GrassVertexDepthOnlyInput v)
|
||||
{
|
||||
GrassVertexDepthOnlyOutput o = (GrassVertexDepthOnlyOutput)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
|
||||
// _WaveAndDistance.z == 0 for MeshLit
|
||||
float waveAmount = v.color.a * _WaveAndDistance.z;
|
||||
o.color = TerrainWaveGrass(v.vertex, waveAmount, v.color);
|
||||
|
||||
InitializeVertData(v, o);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 DepthOnlyFragment(GrassVertexDepthOnlyOutput input) : SV_TARGET
|
||||
{
|
||||
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct GrassVertexDepthNormalInput
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
half4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct GrassVertexDepthNormalOutput
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
half3 normal : TEXCOORD1;
|
||||
half4 color : TEXCOORD2;
|
||||
float4 clipPos : SV_POSITION;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
void InitializeVertData(GrassVertexDepthNormalInput input, inout GrassVertexDepthNormalOutput vertData)
|
||||
{
|
||||
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
|
||||
|
||||
vertData.uv = input.texcoord;
|
||||
vertData.normal = TransformObjectToWorldNormal(input.normal);
|
||||
vertData.clipPos = vertexInput.positionCS;
|
||||
}
|
||||
|
||||
GrassVertexDepthNormalOutput DepthNormalOnlyVertex(GrassVertexDepthNormalInput v)
|
||||
{
|
||||
GrassVertexDepthNormalOutput o = (GrassVertexDepthNormalOutput)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
|
||||
// _WaveAndDistance.z == 0 for MeshLit
|
||||
float waveAmount = v.color.a * _WaveAndDistance.z;
|
||||
o.color = TerrainWaveGrass(v.vertex, waveAmount, v.color);
|
||||
|
||||
InitializeVertData(v, o);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 DepthNormalOnlyFragment(GrassVertexDepthNormalOutput input) : SV_TARGET
|
||||
{
|
||||
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff);
|
||||
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(NormalizeNormalPerPixel(input.normal), true)), 0.0, 0.0);
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user