Scene_Blend.shader · 21415 B · ext
.shader · seen 34× in SWHvia unique-primary
swh:1:cnt:0e1d66248b50ecf9234f421147102e40487c394e;origin=https://github.com/Superppig/Ghost-Doc;anchor=swh:1:rev:388457b96ab6a04246ce793e6a8ea11c83d8f3f4;path=/Assets/Shader/Scene_Blend.shader
Show source
Shader "XinY/Scene_Blend"
{
Properties
{
_Weight ("Weight", Range(0.0001, 1)) = 0.5
_Control ("Control", 2D) = "red" { }
_Splat0 ("Splat0", 2D) = "white" { }
_Splat0_Normal ("Slpat0_Normal", 2D) = "bump" { }
_Splat0_MRA ("Splat0_MRA", 2D) = "white" { }
_Splat1 ("Splat1", 2D) = "white" { }
_Splat1_Normal ("Slpat1_Normal", 2D) = "bump" { }
_Splat1_MRA ("Splat1_MRA", 2D) = "white" { }
_Splat2 ("Splat2", 2D) = "white" { }
_Splat2_Normal ("Slpat2_Normal", 2D) = "bump" { }
_Splat2_MRA ("Splat2_MRA", 2D) = "white" { }
_Splat3 ("Splat3", 2D) = "white" { }
_Splat3_Normal ("Slpat3_Normal", 2D) = "bump" { }
_Splat3_MRA ("Splat3_MRA", 2D) = "white" { }
_MetallicAd ("MetallicAd", Range(0, 2)) = 1
_RoughnessAd ("RoughnessAd", Range(0, 2)) = 1
_AOAd ("AOAd", Range(0, 2)) = 1
_NormalScale ("NormalScale", Range(0, 5)) = 1
_SpecIntensity ("SpecIntensity", float) = 1
}
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque" "Queue" = "Geometry" }
LOD 100
AlphaTest Off
Pass
{
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ LIGHTMAP_ON
//先别用实时GI
//#pragma multi_compile _ DYNAMICLIGHTMAP_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "../Shader/Include/XinY_Include_URP.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
struct appdata
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
float2 texcoord2 : TEXCOORD1;
float2 staticLightmapUV : TEXCOORD1;
float2 dynamicLightmapUV : TEXCOORD2;
};
struct v2f
{
float4 LayerUV01 : TEXCOORD0;
float4 LayerUV23 : TEXCOORD11;
float3 positionWS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
half3 tangentWS : TEXCOORD3;
float4 shadowCoord : TEXCOORD4;
DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 5);
float4 positionCS : SV_POSITION;
float4 positionNDC : TEXCOORD6;
float3 positionVS : TEXCOORD7;
half3 binormalWS : TEXCOORD8;
half3 normalOS : TEXCOORD9;
float2 ControlUV : TEXCOORD10;
};
CBUFFER_START(UnityPerMaterial)
half _MetallicAd;
half _AOAd;
half _RoughnessAd;
half _NormalScale;
half _SpecIntensity;
half4 _Splat0_ST;
half4 _Splat1_ST;
half4 _Splat2_ST;
half4 _Splat3_ST;
half _Weight;
CBUFFER_END
TEXTURE2D(_Control);
SAMPLER(sampler_Control);
TEXTURE2D(_Splat0);
SAMPLER(sampler_Splat0);
TEXTURE2D(_Splat1);
SAMPLER(sampler_Splat1);
TEXTURE2D(_Splat2);
SAMPLER(sampler_Splat2);
TEXTURE2D(_Splat3);
SAMPLER(sampler_Splat3);
TEXTURE2D(_Splat0_Normal);
SAMPLER(sampler_Splat0_Normal);
TEXTURE2D(_Splat1_Normal);
SAMPLER(sampler_Splat1_Normal);
TEXTURE2D(_Splat2_Normal);
SAMPLER(sampler_Splat2_Normal);
TEXTURE2D(_Splat3_Normal);
SAMPLER(sampler_Splat3_Normal);
TEXTURE2D(_Splat0_MRA);
SAMPLER(sampler_Splat0_MRA);
TEXTURE2D(_Splat1_MRA);
SAMPLER(sampler_Splat1_MRA);
TEXTURE2D(_Splat2_MRA);
SAMPLER(sampler_Splat2_MRA);
TEXTURE2D(_Splat3_MRA);
SAMPLER(sampler_Splat3_MRA);
v2f vert(appdata v)
{
v2f output = (v2f)0;;
//坐标获取
output.positionWS = TransformObjectToWorld(v.positionOS);
output.positionVS = TransformWorldToView(output.positionWS);
output.positionCS = TransformWorldToHClip(output.positionWS);
float4 ndc = output.positionCS * 0.5f;
output.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
output.positionNDC.zw = output.positionCS.zw;
//法线获取
output.normalOS = v.normalOS;
real sign = real(v.tangentOS.w) * GetOddNegativeScale();
output.normalWS = TransformObjectToWorldNormal(v.normalOS);
output.tangentWS = real3(TransformObjectToWorldDir(v.tangentOS.xyz));
output.binormalWS = real3(cross(output.normalWS, float3(output.tangentWS))) * sign;
//UV相关
output.LayerUV01 = float4(TRANSFORM_TEX(v.texcoord, _Splat0), TRANSFORM_TEX(v.texcoord, _Splat1));
output.LayerUV23 = float4(TRANSFORM_TEX(v.texcoord, _Splat2), TRANSFORM_TEX(v.texcoord, _Splat3));
output.ControlUV=v.texcoord;
OUTPUT_LIGHTMAP_UV(v.staticLightmapUV, unity_LightmapST, output.staticLightmapUV);
#ifdef DYNAMICLIGHTMAP_ON
output.dynamicLightmapUV = v.dynamicLightmapUV.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#endif
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
//阴影
//上面的方法可以算屏幕阴影
output.shadowCoord = XinY_GetShadowCoord(output.positionCS, output.positionWS);
return output;
}
float4 frag(v2f i) : SV_TARGET
{
half2 LayerUV0 = i.LayerUV01.xy;
half2 LayerUV1 = i.LayerUV01.zw;
half2 LayerUV2 = i.LayerUV23.xy;
half2 LayerUV3 = i.LayerUV23.zw;
half4 slpat0 = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, LayerUV0);
half4 slpat1 = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat1, LayerUV1);
half4 slpat2 = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat2, LayerUV2);
half4 slpat3 = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat3, LayerUV3);
half4 control = SAMPLE_TEXTURE2D(_Control, sampler_Control, i.ControlUV);
half4 slpat0_MRA = SAMPLE_TEXTURE2D(_Splat0_MRA, sampler_Splat0_MRA, LayerUV0);
half4 slpat1_MRA = SAMPLE_TEXTURE2D(_Splat1_MRA, sampler_Splat1_MRA, LayerUV1);
half4 slpat2_MRA = SAMPLE_TEXTURE2D(_Splat2_MRA, sampler_Splat2_MRA, LayerUV2);
half4 slpat3_MRA = SAMPLE_TEXTURE2D(_Splat3_MRA, sampler_Splat3_MRA, LayerUV3);
half4 blend = half4(slpat0.a, slpat1.a, slpat2.a, slpat3.a) * control;
half maxHeight = max(blend.r, max(blend.g, max(blend.b, blend.a)));
blend = max(blend - maxHeight + _Weight, 0) * control;
blend /= (blend.r + blend.g + blend.b + blend.a);
half3 slpat0_NormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_Splat0_Normal, sampler_Splat0_Normal, LayerUV0), _NormalScale);
half3 slpat1_NormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_Splat1_Normal, sampler_Splat1_Normal, LayerUV1), _NormalScale);
half3 slpat2_NormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_Splat2_Normal, sampler_Splat2_Normal, LayerUV2), _NormalScale);
half3 slpat3_NormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_Splat3_Normal, sampler_Splat3_Normal, LayerUV3), _NormalScale);
half3 normalTS = blend.r * slpat0_NormalTS + blend.g * slpat1_NormalTS + blend.b * slpat2_NormalTS + blend.a * slpat3_NormalTS;
half3 baseMap = blend.r * slpat0.rgb + blend.g * slpat1.rgb + blend.b * slpat2.rgb + blend.a * slpat3.rgb;
half3 MRA = blend.r * slpat0_MRA.rgb + blend.g * slpat1_MRA.rgb + blend.b * slpat2_MRA.rgb + blend.a * slpat3_MRA.rgb;
//Shadowmask的烘焙模式才会使用
//half4 shadowMask = SAMPLE_SHADOWMASK(i.staticLightmapUV);
half4 shadowMask = unity_ProbesOcclusion;
//ShadowMask烘焙模式或者烘焙阴影会用到shadowMask,联级阴影会用到posWS,开启联级阴影一定到在frag中计算shadowcoord
Light light = GetMainLight(XinY_GetShadowCoord(i.positionCS, i.positionWS), i.positionWS, 0);
half3x3 TBN = half3x3(i.tangentWS, i.binormalWS, i.normalWS);
half3 V = normalize(_WorldSpaceCameraPos - i.positionWS);
half3 N = mul(normalTS, TBN);
half3 viewDirTS = XinY_GetViewDirectionTangentSpace(i.tangentWS, i.binormalWS, i.normalWS, V);
half3 R = reflect(-V, N);
half NdotV = saturate(dot(N, V));
half fresnelTerm = Pow4(1.0 - NdotV);
half NdotL = saturate(dot(N, light.direction));
half3 H = SafeNormalize(light.direction + V);
half NdotH = saturate(dot(N, H));
half LdotH = saturate(dot(light.direction, H));
float fogCoord = XinY_InitializeFog(float4(i.positionWS, 1.0));
//GI
//关于bakedGI,动态物体使用sh,静态物体使用lightmap
half3 bakedGI = 0;
#if defined(DYNAMICLIGHTMAP_ON)
bakedGI = SAMPLE_GI(i.staticLightmapUV, i.dynamicLightmapUV, i.vertexSH, N);
#else
bakedGI = SAMPLE_GI(i.staticLightmapUV, i.vertexSH, N);
#endif
half2 screenUV = GetNormalizedScreenSpaceUV(i.positionCS);
//BrdfData
half metallic = max(lerp(0.04, MRA.r, _MetallicAd), 0);
half oneMinusReflectivity = OneMinusReflectivityMetallic(metallic);
half3 albedo = baseMap.rgb;
half3 diffuse = albedo * oneMinusReflectivity;;
half3 specular = lerp(kDieletricSpec.rgb, albedo, metallic);;
half reflectivity = half(1.0) - oneMinusReflectivity;
half perceptualRoughness = lerp(0, MRA.g, _RoughnessAd);
half smoothness = 1 - perceptualRoughness;
half roughness = max(perceptualRoughness * perceptualRoughness, HALF_MIN_SQRT);
half roughness2 = max(roughness * roughness, HALF_MIN);;
half grazingTerm = saturate(smoothness + reflectivity);;
half normalizationTerm = roughness * half(4.0) + half(2.0);; // roughness * 4.0 + 2.0
half roughness2MinusOne = roughness2 - half(1.0);; // roughness^2 - 1.0
half alpha = oneMinusReflectivity + reflectivity;
half3 emission = 0;
half occlusion = max(lerp(0, MRA.b, _AOAd), 0);
//AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(screenUV, occlusion);
MixRealtimeAndBakedGI(light, i.normalWS, bakedGI);
//LightingData
half3 giColor = bakedGI;
half3 mainLightColor = 0;
half3 additionLightColor = 0;
half3 emissionColor = emission;
half3 indirectDiffuse = bakedGI * diffuse;
//间接高光的实现载体是反射探针
//这里没有支持反射探针混合和盒投影
half3 indirectSpecular = 0;
half mip = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness) * 6;
indirectSpecular = DecodeHDREnvironment(half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, R, mip)), unity_SpecCube0_HDR);
float surfaceReduction = 1.0 / (roughness2 + 1.0);
indirectSpecular *= half3(surfaceReduction * lerp(specular, grazingTerm, fresnelTerm));
giColor = (indirectDiffuse + indirectSpecular) * occlusion;
half lightAtten = light.distanceAttenuation * light.shadowAttenuation;
half diffuseTerm = light.color * (lightAtten * NdotL);
float d = NdotH * NdotH * roughness2MinusOne + 1.00001f;
half LdotH2 = LdotH * LdotH;
half specularTerm = roughness2 / ((d * d) * max(0.1h, LdotH2) * normalizationTerm);
mainLightColor = (diffuse + specular * specularTerm * _SpecIntensity) * diffuseTerm;
//额外灯
uint pixelLightCount = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN(pixelLightCount)GetMainLight(i.shadowCoord, i.positionWS, shadowMask);
Light addLight = GetAdditionalLight(lightIndex, i.positionWS, shadowMask);
half addHalfLambert = dot(N, addLight.direction) * 0.5 + 0.5;
additionLightColor += addHalfLambert * diffuse * addLight.color * addLight.shadowAttenuation * addLight.distanceAttenuation;
LIGHT_LOOP_END
half4 finalColor = 0;
finalColor.a = alpha;
finalColor.rgb = giColor + mainLightColor + additionLightColor + emissionColor;
return finalColor;
}
ENDHLSL
}
//外描线
Pass
{
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque" }
Cull Front
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normalOS : NORMAL;
half4 tangentOS : TANGENT;
float4 color : COLOR;//顶点色
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 color : TEXCOORD1;
};
float _OutLineWdith;
float4 _OutlineColor;
v2f vert(appdata v)
{
//模型顶点沿法线外拓
v2f o;
float3 posWS = TransformObjectToWorld(v.vertex);
float3 posVS = TransformWorldToView(posWS);
float3 normalTS = v.color * 2 - 1;
real sign = real(v.tangentOS.w) * (unity_WorldTransformParams.w >= 0.0 ? 1.0 : - 1.0);
half3 normalWS = TransformObjectToWorldNormal(v.normalOS);
half3 tangentWS = real3(TransformObjectToWorldDir(v.tangentOS.xyz));
half3 binormalWS = real3(cross(normalWS, float3(tangentWS))) * sign;
half3x3 TBN = half3x3(tangentWS, binormalWS, normalWS);
float3 normal = mul(normalTS, TBN);
float3 normalVS = mul((float3x3)UNITY_MATRIX_V, normal);
// float3 normalWS=TransformObjectToWorldNormal(v.normalOS);
// float3 normalVS=TransformWorldToViewDir(normalWS);
posVS = (posVS + normalVS * _OutLineWdith * 0.001) * max(1, posVS.z);
o.pos = TransformWViewToHClip(posVS);
…(truncated)…