这个Unity特效是在单独的层中使用软精灵来伪造照明,在游戏画面中叠加一层遮罩从而达到突出主角的位置,当然还有其他方法可以制作更好的照明,但这是一个比较简单的设置,对于2D游戏效果有点帮助。


它们是图像效果着色器,所以它们可以在 URP 中工作。
设置方法:

1. 添加新相机作为主相机的子相机并重置位置

2. 确保新相机呈现黑色

3.创建 新的层 由新相机渲染,设置 Light-Sprites 到这个层

4. 设置 Main camera 不渲染该层,设置 Lighting Camera 只渲染这个新层
5. 将 光照渲染纹理 脚本添加到主相机
脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class LightingRenderTexture : MonoBehaviour
{
[SerializeField]
Material ScreenMat;
[SerializeField]
Camera lightingCam;
RenderTexture rt;
private void Start()
{
rt = new RenderTexture(Screen.width, Screen.height, 24);
lightingCam.targetTexture = rt;
ScreenMat.SetTexture("_RenderTexture", rt);
}
void OnRenderImage(RenderTexture src, RenderTexture dst)
{
if (ScreenMat != null)
Graphics.Blit(src, dst, ScreenMat);
}
}
该脚本将为照明相机创建一个渲染纹理,将其发送到着色器,然后在主相机上绘制一个材质。
6. 在进一步导入其中一个着色器

7. 从 Shader 中新建一个 Unity材质,拖入脚本中
8. 将 Lighting Camera 拖到脚本的另一个插槽中
基本叠加着色器

此部分只取精灵及其着色并覆盖它,没有额外的任何效果。

此着色器采用渲染纹理,即主相机输出。
然后用阴影颜色调整相机输出,并在灯光渲染纹理上正常输出。
带注释的着色器代码:
Shader "Hidden/Simple Sprite Overlay"
{
Properties
{
[HideInInspector]_MainTex("Texture", 2D) = "white" {}
_RenderTexture("Render Texture", 2D) = "black" {}
_ShadowC("ShadowColor", Color) = (0.1, 0.1, 0.1, 0.1)
_LightMultiplier("Light Circle Smoothness", Range(0, 5)) = 3
_ExtraLight("Light Strength", Range(0.5, 5)) = 1
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex, _RenderTexture;
float4 _ShadowC;
float _LightMultiplier, _ExtraLight;
fixed4 frag(v2f i) : SV_Target
{
fixed4 lights = (tex2D(_RenderTexture, i.uv)) * _LightMultiplier; // lighting layer
fixed4 col = tex2D(_MainTex, i.uv); // normal camera view
lights = saturate(lights); // saturate so it's not extra bright where the lights are
col = lerp(col * _ShadowC, col , lights * _ExtraLight); // lerp normal view multiplied by shadow color, with normal camera view over the lights layer
return col;
}
ENDCG
}
}
}
为叠加添加不规则噪波

此部分是为了在模拟灯光遮罩的周围屏幕添加一些不规则的噪波。
此版本创建滚动噪波并将其添加到灯光渲染纹理中,然后通过平滑步创建截止,因此可以控制柔和度。

带注释的着色器代码:
Shader "Hidden/Noise Sprite Overlay"
{
Properties
{
[HideInInspector]_MainTex("Texture", 2D) = "white" {}
_RenderTexture("Render Texture", 2D) = "black" {}
_Noise("Noise", 2D) = "white" {}
_ShadowC("ShadowColor", Color) = (0.1, 0.1, 0.1, 0.1)
_NScale("Noise Scale", Range(0,10)) = 2
_LightMultiplier("Light Circle Smoothness", Range(0, 5)) = 3
_ExtraLight("Light Strength", Range(0.5, 5)) = 1
_Cutoff("Cutoff Noise", Range(0, 1)) = 1
_SmoothEdge("Smooth Edge", Range(0, 1)) = 0.1
_SPeedX("Scroll Speed X", Range(-5, 5)) = 0
_SPeedY("Scroll Speed Y", Range(-5, 5)) = -1
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex, _RenderTexture, _Noise;
float4 _ShadowC;
float _Cutoff, _SmoothEdge;
float _LightMultiplier, _NScale, _ExtraLight;
float _SPeedX, _SPeedY;
fixed4 frag(v2f i) : SV_Target
{
// scrolling speed
float scrollSpeedX = _Time.x * _SPeedX;
float scrollSpeedY = _Time.y * _SPeedY;
float2 scrolling = float2(scrollSpeedX, scrollSpeedY);
// noise
fixed4 noise = tex2D(_Noise, i.uv * _NScale + scrolling);
fixed4 noise2 = tex2D(_Noise, i.uv * (_NScale * 2) + scrolling);
float combNoise = (noise + noise2)* 0.5; // combine different scale noise
fixed4 lights = (tex2D(_RenderTexture, i.uv) * combNoise * 2) * _LightMultiplier;// lighting layer with added noise
lights = smoothstep(_Cutoff, _Cutoff + _SmoothEdge, lights);// create cutoff
lights = saturate(lights); // saturate so it's not extra bright where the lights are
fixed4 col = tex2D(_MainTex, i.uv);// normal camera view
col = lerp(col * _ShadowC, col , lights * _ExtraLight);// lerp normal view multiplied by shadow color, with normal camera view over the noise lights layer
return col;
}
ENDCG
}
}
}
添加失真效果

此部分的着色器将噪波(Noise)区域作为失真对象并添加到主UV,这样可以增加视觉特效。
通过将平滑步长与反向平滑步长相乘,可以在灯光周围抓取一个环作为失真基础。
带注释的着色器代码:
Shader "Hidden/Distort Overlay"
{
Properties
{
[HideInInspector]_MainTex("Texture", 2D) = "white" {}
_RenderTexture("Render Texture", 2D) = "black" {}
_Noise("Noise", 2D) = "white" {}
_DistortStrength("Distort Strength", Range(0,0.2)) = 0.1
_ShadowC("ShadowColor", Color) = (0.1, 0.1, 0.1, 0.1)
_NScale("Noise Scale", Range(0,10)) = 2
_LightMultiplier("Light Circle Smoothness", Range(0, 5)) = 3
_ExtraLight("Light Strength", Range(0.5, 5)) = 1
_OuterEdge("Outer distort Edge", Range(0, 10)) = 0.8
_InnerEdge("Inner distort Edge", Range(0, 10)) = 0.8
_SPeedX("Scroll Speed X", Range(-5, 5)) = 0
_SPeedY("Scroll Speed Y", Range(-5, 5)) = -1
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex, _RenderTexture, _Noise;
float4 _ShadowC;
float _OuterEdge, _InnerEdge;
float _LightMultiplier, _NScale, _DistortStrength;
float _SPeedX, _SPeedY;
float _ExtraLight;
fixed4 frag(v2f i) : SV_Target
{
// scrolling speed
float scrollSpeedX = _Time.x * _SPeedX;
float scrollSpeedY = _Time.y * _SPeedY;
float2 scrolling = float2(scrollSpeedX, scrollSpeedY);
// noise
fixed4 noise = tex2D(_Noise, i.uv * _NScale + scrolling);
fixed4 noise2 = tex2D(_Noise, i.uv * (_NScale * 2) + scrolling);
float combNoise = (noise + noise2)* 0.5; // combine different scale noise
fixed4 lights = (tex2D(_RenderTexture, i.uv) * combNoise * 5) * _LightMultiplier;// lighting layer with added noise
// make lights greyscale
float greyscaleLights = dot(lights, float3(0.3, 0.59, 0.11));
float distortionEdge = smoothstep(combNoise, combNoise + _OuterEdge, greyscaleLights) * (1 - smoothstep(combNoise, combNoise + _InnerEdge, greyscaleLights)); //multiply smoothstep with inversed smoothstep with different offset
fixed4 col = tex2D(_MainTex, i.uv + (distortionEdge * _DistortStrength));// add distortion to main camera output
lights = saturate(lights);// saturate so it's not extra bright where the lights are
col = lerp(col * _ShadowC, col, lights * _ExtraLight);// lerp normal view multiplied by shadow color, with normal camera view over the noise lights layer
return col;
}
ENDCG
}
}
}
其他效果
通过设置此照明边界,当然可以使用其他效果,也许重新着色灯光外的风景,反转颜色,模糊它们。
或者通过交换 lerp 的前两个值来设置圆圈内的效果,最终看大家如何组合了。