106 lines
3.9 KiB
GLSL
106 lines
3.9 KiB
GLSL
Shader "Custom/SphereGradientShader"
|
|
{
|
|
Properties
|
|
{
|
|
[HDR] _BaseColor("Base Color", Color) = (1,1,1,1)
|
|
[HDR] _HeadColor("Head Color (Facing End)", Color) = (1,1,1,1)
|
|
[HDR] _TailColor("Tail Color (Facing Start)", Color) = (1,1,1,1)
|
|
[Toggle(_EMISSION_ON)] _UseEmission("Enable Emission", Float) = 0
|
|
[HDR] _EmissionColor("Emission Color", Color) = (0,0,0,0)
|
|
_EmissionIntensity("Emission Intensity", Range(0, 10)) = 1.0
|
|
_MoveDir("Movement Direction", Vector) = (0,0,1,0)
|
|
_GradientScale("Gradient Scale", Range(0, 2)) = 1.0
|
|
_GradientPower("Gradient Power", Range(0.5, 5)) = 2.0
|
|
|
|
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend", Float) = 1
|
|
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend", Float) = 0
|
|
[Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Float) = 1
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "Queue" = "Geometry" }
|
|
LOD 100
|
|
|
|
Pass
|
|
{
|
|
Blend [_SrcBlend] [_DstBlend]
|
|
ZWrite [_ZWrite]
|
|
|
|
HLSLPROGRAM
|
|
#pragma shader_feature _EMISSION_ON
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
|
|
struct Attributes
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float3 normalOS : NORMAL;
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float3 normalWS : TEXCOORD1;
|
|
float3 positionWS : TEXCOORD2;
|
|
};
|
|
|
|
CBUFFER_START(UnityPerMaterial)
|
|
float4 _BaseColor;
|
|
float4 _HeadColor;
|
|
float4 _TailColor;
|
|
float4 _EmissionColor;
|
|
float _EmissionIntensity;
|
|
float4 _MoveDir;
|
|
float _GradientScale;
|
|
float _GradientPower;
|
|
CBUFFER_END
|
|
|
|
Varyings vert(Attributes input)
|
|
{
|
|
Varyings output;
|
|
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
output.positionCS = TransformWorldToHClip(output.positionWS);
|
|
output.uv = input.uv;
|
|
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
|
|
return output;
|
|
}
|
|
|
|
half4 frag(Varyings input) : SV_Target
|
|
{
|
|
float3 normal = normalize(input.normalWS);
|
|
float3 moveDir = normalize(_MoveDir.xyz);
|
|
|
|
// 计算空间渐变:-1 到 1 映射到 0 到 1
|
|
// 面向 endPoint (moveDir) 时 dot 接近 1,使用 HeadColor
|
|
// 面向 startPoint (-moveDir) 时 dot 接近 -1,使用 TailColor
|
|
// 反转:使用 -dot 或者 1.0 - spatialLerp
|
|
float spatialLerp = dot(normal, -moveDir) * 0.5 + 0.5;
|
|
|
|
// 应用幂函数调整渐变分布
|
|
spatialLerp = clamp(spatialLerp, 0.0, 1.0);
|
|
|
|
half4 color = lerp(_TailColor, _HeadColor, spatialLerp);
|
|
|
|
// 叠加一个基础的菲涅尔效果增加立体感
|
|
float3 viewDir = normalize(GetWorldSpaceViewDir(input.positionWS));
|
|
float fresnel = 1.0 - saturate(dot(normal, viewDir));
|
|
fresnel = pow(fresnel, _GradientPower) * _GradientScale;
|
|
|
|
color.rgb += fresnel * color.rgb * 0.5; // 边缘轻微提亮
|
|
|
|
// 自发光叠加
|
|
#if defined(_EMISSION_ON)
|
|
color.rgb += _EmissionColor.rgb * _EmissionIntensity;
|
|
#endif
|
|
|
|
return color;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|