您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

263 行
10 KiB

Shader "LightweightPipeline/Standard Terrain"
{
Properties
{
// 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] _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] _MainTex("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" }
Pass
{
Tags { "LightMode" = "LightweightForward" }
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SpatmapFragment
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _MAIN_LIGHT_DIRECTIONAL _MAIN_LIGHT_SPOT
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ FOG_LINEAR FOG_EXP2
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
// LW doesn't support dynamic GI. So we save 30% shader variants if we assume
// LIGHTMAP_ON when DIRLIGHTMAP_COMBINED is set
#ifdef DIRLIGHTMAP_COMBINED
#define LIGHTMAP_ON
#endif
#include "LWRP/ShaderLibrary/Lighting.hlsl"
CBUFFER_START(_Terrain)
half _Metallic0;
half _Metallic1;
half _Metallic2;
half _Metallic3;
half _Smoothness0;
half _Smoothness1;
half _Smoothness2;
half _Smoothness3;
float4 _Control_ST;
half4 _Splat0_ST, _Splat1_ST, _Splat2_ST, _Splat3_ST;
CBUFFER_END
sampler2D _Control;
sampler2D _Splat0, _Splat1, _Splat2, _Splat3;
#ifdef _TERRAIN_NORMAL_MAP
sampler2D _Normal0, _Normal1, _Normal2, _Normal3;
#endif
struct VertexInput
{
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
struct VertexOutput
{
float4 uvSplat01 : TEXCOORD0; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD1; // xy: splat2, zw: splat3
float4 uvControlAndLM : TEXCOORD2; // xy: control, zw: lightmap
half3 normal : TEXCOORD3;
#if _TERRAIN_NORMAL_MAP
half3 tangent : TEXCOORD4;
half3 binormal : TEXCOORD5;
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float3 positionWS : TEXCOORD7;
#ifdef _SHADOWS_ENABLED
float4 shadowCoord : TEXCOORD8;
#endif
float4 clipPos : SV_POSITION;
};
void InitializeInputData(VertexOutput IN, half3 normalTS, out InputData input)
{
input = (InputData)0;
input.positionWS = IN.positionWS;
#ifdef _TERRAIN_NORMAL_MAP
input.normalWS = TangentToWorldNormal(normalTS, IN.tangent, IN.binormal, IN.normal);
#else
input.normalWS = normalize(IN.normal);
#endif
input.viewDirectionWS = SafeNormalize(GetCameraPositionWS() - IN.positionWS);
#ifdef _SHADOWS_ENABLED
input.shadowCoord = IN.shadowCoord;
#endif
input.fogCoord = IN.fogFactorAndVertexLight.x;
#ifdef LIGHTMAP_ON
input.bakedGI = SampleLightmap(IN.uvControlAndLM.zw, input.normalWS);
#endif
}
void SplatmapMix(VertexOutput IN, half4 defaultAlpha, out half4 splat_control, out half weight, out half4 mixedDiffuse, inout half3 mixedNormal)
{
splat_control = tex2D(_Control, IN.uvControlAndLM.xy);
weight = dot(splat_control, half4(1, 1, 1, 1));
#if !defined(SHADER_API_MOBILE) && defined(TERRAIN_SPLAT_ADDPASS)
clip(weight == 0.0f ? -1 : 1);
#endif
// Normalize weights before lighting and restore weights in final modifier functions so that the overal
// lighting result can be correctly weighted.
splat_control /= (weight + 1e-3f);
mixedDiffuse = 0.0f;
mixedDiffuse += splat_control.r * tex2D(_Splat0, IN.uvSplat01.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.r);
mixedDiffuse += splat_control.g * tex2D(_Splat1, IN.uvSplat01.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.g);
mixedDiffuse += splat_control.b * tex2D(_Splat2, IN.uvSplat23.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.b);
mixedDiffuse += splat_control.a * tex2D(_Splat3, IN.uvSplat23.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.a);
#ifdef _TERRAIN_NORMAL_MAP
half4 nrm = 0.0f;
nrm += splat_control.r * tex2D(_Normal0, IN.uvSplat01.xy);
nrm += splat_control.g * tex2D(_Normal1, IN.uvSplat01.zw);
nrm += splat_control.b * tex2D(_Normal2, IN.uvSplat23.xy);
nrm += splat_control.a * tex2D(_Normal3, IN.uvSplat23.zw);
mixedNormal = UnpackNormal(nrm);
#else
mixedNormal = half3(0, 0, 1);
#endif
}
VertexOutput SplatmapVert(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
float3 positionWS = TransformObjectToWorld(v.vertex.xyz);
float4 clipPos = TransformWorldToHClip(positionWS);
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);
o.uvControlAndLM.xy = TRANSFORM_TEX(v.texcoord, _Control);
o.uvControlAndLM.zw = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
#ifdef _TERRAIN_NORMAL_MAP
float4 vertexTangent = float4(cross(v.normal, float3(0, 0, 1)), -1.0);
OutputTangentToWorld(vertexTangent, v.normal, o.tangent, o.binormal, o.normal);
#else
o.normal = TransformObjectToWorldNormal(v.normal);
#endif
o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
o.fogFactorAndVertexLight.yzw = VertexLighting(positionWS, o.normal);
o.positionWS = positionWS;
o.clipPos = clipPos;
#if defined(_SHADOWS_ENABLED) && !defined(_SHADOWS_CASCADE)
o.shadowCoord = ComputeShadowCoord(o.positionWS.xyz);
#endif
return o;
}
half4 SpatmapFragment(VertexOutput IN) : SV_TARGET
{
half4 splat_control;
half weight;
half4 mixedDiffuse;
half4 defaultSmoothness = half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
half3 normalTS;
SplatmapMix(IN, defaultSmoothness, splat_control, weight, mixedDiffuse, normalTS);
half3 albedo = mixedDiffuse.rgb;
half smoothness = mixedDiffuse.a;
half metallic = dot(splat_control, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
half3 specular = half3(0, 0, 0);
half alpha = weight;
InputData inputData;
InitializeInputData(IN, normalTS, inputData);
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, specular, smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
ApplyFog(color.rgb, inputData.fogCoord);
return color;
}
ENDHLSL
}
Pass
{
Tags{"Lightmode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#include "LWRP/ShaderLibrary/Core.hlsl"
float4 vert(float4 pos : POSITION) : SV_POSITION
{
return TransformObjectToHClip(pos.xyz);
}
half4 frag() : SV_TARGET
{
return 0;
}
ENDHLSL
}
}
Fallback "Hidden/InternalErrorShader"
}