能量罩(URP)
贴图
//URP基础Shader
Shader "Kino/EnergyHood"
{
Properties
{
[Header(Blend)]
[Enum(UnityEngine.Rendering.BlendMode)]_SrcFactor("SrcFactor",int) = 0
[Enum(UnityEngine.Rendering.BlendMode)]_DstFactor("DstFactor",int) = 0
[Header(Main)]
_MainTex("MainTex",2D) = "white"{}
_MainTexIntensity("MainTex Intensity",Range(0,2)) = 0.05
[Header(OffsetDepth)]
_OffsetDepthScale("OffsetDepthScale",Range(0,20)) = 20
_OffsetDepthColor("OffsetDepthColor",Color) = (0.0125845,0.9528302,0.6928285,1)
[Header(Emission)]
[PowerSlider(3)]_EmissionScale("EmissionScale",Range(0,5)) = 1.2
_EmissionColor("EmissionColor",Color) = (1,0.5669756,0.9245283,1)
[Header(FlowLight)]
[IntRange]_FlowLightLevel("FlowLightLevel",Range(1,10)) = 5
_FlowSpeed("Flow Speed",Range(0,20)) = 1
_FlowDistort("Flow Distort",Range(0,1)) = 0.1
}
//URP
SubShader
{
Tags
{
"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline"
}
Pass
{
Name "Unlit"
Blend [_SrcFactor] [_DstFactor]
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex vert
#pragma fragment frag
#define REQUIRE_DEPTH_TEXTURE
#define REQUIRE_OPAQUE_TEXTURE
#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"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float4 uv : TEXCOORD0;
float3 positionVS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float3 viewWS : TEXCOORD3;
};
CBUFFER_START(UnityPerMaterial)
TEXTURE2D(_MainTex);SAMPLER(sampler_MainTex);float4 _MainTex_ST;
half _OffsetDepthScale;
half4 _OffsetDepthColor;
half _EmissionScale;
half4 _EmissionColor;
half _MainTexIntensity;
half _FlowLightLevel;
half _FlowSpeed;
half _FlowDistort;
CBUFFER_END
Varyings vert(Attributes v)
{
Varyings o = (Varyings)0;
float3 positionWS = TransformObjectToWorld(v.positionOS.xyz);
o.positionVS = TransformWorldToView(positionWS);
o.positionCS = TransformWViewToHClip(o.positionVS);
o.normalWS = TransformObjectToWorldNormal(v.normal);
o.viewWS = normalize(_WorldSpaceCameraPos - positionWS);
o.uv.xy = v.uv.xy;
o.uv.zw = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
half4 frag(Varyings i) : SV_Target
{
half4 c;
half2 uv = i.positionCS.xy / _ScreenParams.xy;
// 高亮相交物体
half3 depthTex = SampleSceneDepth(uv);
half depth = LinearEyeDepth(depthTex.r, _ZBufferParams);
// depth深度贴图的下的 观察空间的z值(值域[near(0)-fear])- 顶点坐标再观察空间下的z值(-0,-n),因为观察空间是右手坐标系 z值是负值 所以为+
half offsetDepth = depth + i.positionVS.z;
offsetDepth *= _OffsetDepthScale;
offsetDepth = 1 - offsetDepth;
half4 offsetDepthColor = _OffsetDepthColor * saturate(offsetDepth);
//外发光
half3 normalWS = i.normalWS;
half3 viewWS = i.viewWS;
half dotNV = pow(abs(1 -saturate(dot(normalWS, viewWS))), _EmissionScale);
half4 emissionCol = _EmissionColor * dotNV;
// half4 baseMap = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.zw);
half4 baseMap = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.zw + half2(0,_Time.y));
c = emissionCol + offsetDepthColor + baseMap *_MainTexIntensity ;
//流光
half flowV = frac(i.uv.y * _FlowLightLevel + _Time.y*_FlowSpeed);
half2 gradUv = lerp(uv,baseMap.rr,_FlowDistort);
half4 gradScreenCol = half4(SampleSceneColor(gradUv),1);
gradScreenCol *= flowV;
c += gradScreenCol;
return c;
}
ENDHLSL
}
}
//BuildIn
SubShader
{
Tags
{
"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"
}
GrabPass {"_GrabTex"}
Pass
{
Name "Unlit BuildIn"
Blend [_SrcFactor] [_DstFactor]
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#define REQUIRE_DEPTH_TEXTURE
#define REQUIRE_OPAQUE_TEXTURE
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float4 uv : TEXCOORD0;
float3 positionVS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float3 viewWS : TEXCOORD3;
};
sampler2D _MainTex;float4 _MainTex_ST;
sampler2D _CameraDepthTexture;
sampler2D _GrabTex;
half _OffsetDepthScale;
half4 _OffsetDepthColor;
half _EmissionScale;
half4 _EmissionColor;
half _MainTexIntensity;
half _FlowLightLevel;
half _FlowSpeed;
half _FlowDistort;
Varyings vert(Attributes v)
{
Varyings o = (Varyings)0;
//本地转世界
float3 positionWS = mul(unity_ObjectToWorld,v.positionOS);
//世界转观察
o.positionVS = mul(UNITY_MATRIX_V,float4(positionWS,1));
//观察转齐次裁剪
o.positionCS = mul(UNITY_MATRIX_P,float4(o.positionVS,1));
o.normalWS = UnityObjectToWorldNormal(v.normal);
o.viewWS = normalize(_WorldSpaceCameraPos - positionWS);
o.uv.xy = v.uv.xy;
o.uv.zw = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
half4 frag(Varyings i) : SV_Target
{
half4 c;
half2 uv = i.positionCS.xy / _ScreenParams.xy;
// 高亮相交物体
half3 depthTex = tex2D(_CameraDepthTexture,uv);
half depth = LinearEyeDepth(depthTex.r);
// depth深度贴图的下的 观察空间的z值(值域[near(0)-fear])- 顶点坐标再观察空间下的z值(-0,-n),因为观察空间是右手坐标系 z值是负值 所以为+
half offsetDepth = depth + i.positionVS.z;
offsetDepth *= _OffsetDepthScale;
offsetDepth = 1 - offsetDepth;
half4 offsetDepthColor = _OffsetDepthColor * saturate(offsetDepth);
//外发光
half3 normalWS = i.normalWS;
half3 viewWS = i.viewWS;
half dotNV = pow(abs(1 -saturate(dot(normalWS, viewWS))), _EmissionScale);
half4 emissionCol = _EmissionColor * dotNV;
// half4 baseMap = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.zw);
half4 baseMap = tex2D(_MainTex, i.uv.zw + half2(0,_Time.y));
c = emissionCol + offsetDepthColor + baseMap *_MainTexIntensity ;
//流光
half flowV = frac(i.uv.y * _FlowLightLevel + _Time.y*_FlowSpeed);
half2 gradUv = lerp(uv,baseMap.rr,_FlowDistort);
float3 gradCol = tex2D(_GrabTex,gradUv);
half4 gradScreenCol = half4(gradCol,1);
gradScreenCol *= flowV;
c += gradScreenCol;
return c;
}
ENDCG
}
}
}