Unity自定义后处理——Vignette暗角

文章介绍了Vignette暗角效果在游戏或应用中的用途,通过计算像素点距屏幕中心的距离并进行pow运算,调整边缘形状,实现从中间到四周的渐变压暗。提供了C#代码和Shader实现该效果的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  大家好,我是阿赵。
  继续说一下屏幕后处理的做法,这一期讲的是Vignette暗角效果。

一、Vignette效果介绍

  Vignette暗角的效果可以给画面提供一个氛围,或者模拟一些特殊的效果。
还是拿这个角色作为底图
在这里插入图片描述

添加了Vignette效果后,屏幕的四边会产生一个像老式电视机一样的压暗的效果,
在这里插入图片描述

通过调节参数,可以做出形状比较夸张的压暗效果
在这里插入图片描述

在这里插入图片描述

  如果加上闪烁和横纹之类,也可以模拟老式电影的效果。

二、实现原理

1、以屏幕中心点计算每个像素点的距离

float2 screenUV = abs(i.uv - float2(0.5f,0.5f))*_VignetteIntensity;
float dist = length(screenUV);
col.rgb *= dist;

在这里插入图片描述

  这时候,由于屏幕靠中间的点离屏幕中心点(0.5f,0.5f)近,然后边缘的点里屏幕中心点远,所以得到的效果是中间黑,四周白。

2、给距离做power计算,让边缘形状变成接近矩形

float2 screenUV = abs(i.uv - float2(0.5f,0.5f))*_VignetteIntensity;
screenUV = pow(saturate(screenUV), _VignetteSmoothness);
float dist = length(screenUV);
col.rgb *= dist;

在这里插入图片描述

  经过计算后,现在的黑白变成了比较接近屏幕矩形。当然,这个和pow的参数有关,调节不同的参数,可以得到不同的形状。

3、给黑白做反向

float2 screenUV = abs(i.uv - float2(0.5f,0.5f))*_VignetteIntensity;
screenUV = pow(saturate(screenUV), _VignetteSmoothness);
float dist = length(screenUV);
float vfactor = pow(saturate(1 - dist * dist), _VignetteSmoothness);
col.rgb *= vfactor;

在这里插入图片描述

  这时候,可以看到,暗角的效果就做出来了。

三、完整代码

1、C#代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VignetteCtrl : MonoBehaviour
{
    [Range(0, 3)]
    public float vignetteIntensity = 1.8f;
    [Range(0, 5)]
    public float vignetteSmoothness = 5;
    private Material vignetteMat;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (vignetteMat == null)
        {
            vignetteMat = new Material(Shader.Find("Hidden/AzhaoVignette"));
        }
        if (vignetteMat == null || vignetteMat.shader == null || vignetteMat.shader.isSupported == false)
        {
            return;
        }
        vignetteMat.SetFloat("_VignetteIntensity", vignetteIntensity);
        vignetteMat.SetFloat("_VignetteSmoothness", vignetteSmoothness);
        Graphics.Blit(source, destination, vignetteMat, 0);
    }
}

2、Shader

Shader "Hidden/AzhaoVignette"
{
	CGINCLUDE
#include "UnityCG.cginc"

	sampler2D _MainTex;
	float4 _MainTex_TexelSize;

	float _VignetteIntensity;
	float _VignetteSmoothness;

	half4 fragVignette(v2f_img i) : SV_Target
	{
		half4 col = tex2D(_MainTex, i.uv);


		//暗角
		float2 screenUV = abs(i.uv - float2(0.5f,0.5f))*_VignetteIntensity;
		screenUV = pow(saturate(screenUV), _VignetteSmoothness);
		float dist = length(screenUV);
		float vfactor = pow(saturate(1 - dist * dist), _VignetteSmoothness);
		col.rgb *= vfactor;

		return col;
	}


		ENDCG
		Properties
	{
		_MainTex("Texture", 2D) = "white" {}
		_VignetteIntensity("VignetteIntensity", Range(0, 3)) = 1
		_VignetteSmoothness("VignetteSmoothness", Range(0, 5)) = 1
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always
		//0校色
		Pass
		{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment fragVignette            


			ENDCG
		}
	}
}
<think>嗯,用户想在Unity中实现相机的方形暗角效果。我之前处理过类似的问题,但需要回忆一下具体的方法。首先,暗角效果通常是在后期处理中实现的,所以可能需要用到Unity的Post-Processing Stack。不过用户提到的是方形暗角,这和常见的圆形暗角不同,可能需要自定义着色器。 首先,我需要确认用户是否已经了解如何在Unity中设置后期处理。如果没有,可能需要先指导他们导入Post-Processing包,并添加Post-Processing Layer和Volume组件。然后创建一个新的Volume,并在其中添加一个自定义的效果,或者修改现有的Vignette效果。不过默认的Vignette是圆形的,可能需要调整形状参数,或者自己写一个着色器。 另外,用户想要的是方形暗角,可能需要通过着色器中的距离计算来实现。比如,使用屏幕坐标来计算到屏幕中心的距离,但将圆形半径改为矩形或方形。或者使用一个遮罩纹理,但这样可能需要额外的纹理资源,不够灵活。或许可以通过数学公式在着色器中动态生成方形暗角。 再想一下,Vignette效果的原理通常是根据像素距离屏幕中心的远近来调整亮度或颜色。对于方形,可以考虑将距离计算改为曼哈顿距离或者使用绝对值来创建方形边缘。比如,将传统的欧几里得距离公式替换为max(abs(uv.x - 0.5), abs(uv.y - 0.5)),这样可以得到一个正方形的区域。 另外,Unity的Shader编写需要使用ShaderLab语言,可能需要编写一个自定义的Shader,并将其应用到Post-Processing的效果中。或者,如果使用Shader Graph,可以通过节点来构建这个效果。不过用户可能需要具体的步骤,比如如何创建着色器、如何调整参数,以及如何集成到后期处理中。 还需要考虑屏幕的宽高比,因为方形暗角在不同分辨率下可能会变形。可能需要根据屏幕的宽高比来调整暗角的形状,保持正方形。或者在计算UV时进行归一化处理,确保在不同分辨率下效果一致。 可能还需要调整暗角的强度、平滑度、颜色等参数,让用户可以调节。比如,使用一个参数来控制暗角的范围,另一个参数控制边缘的过渡平滑度。这样用户可以根据需要调整效果的外观。 总结一下步骤:1. 设置Post-Processing Stack;2. 创建自定义着色器或修改现有Vignette;3. 调整距离计算为方形;4. 集成到Post-Processing Volume;5. 调整参数并测试效果。同时要注意屏幕适配和参数的可调节性。 另外,用户可能需要示例代码或着色器代码。需要确保提供的代码正确,比如在片段着色器中计算UV,应用暗角效果。同时,要提醒用户检查相机的投影模式是否正确,比如正交投影和透视投影可能影响效果的表现,可以参考之前的引用内容关于相机的设置[^1]。 最后,验证方法:在场景中添加效果后,运行游戏查看暗角是否呈现方形,调整参数确保效果符合预期。如果遇到问题,可能需要检查着色器的编译错误或后期处理的配置是否正确。</think>在Unity中实现相机方形暗角效果,可以通过以下步骤完成: ### 方法一:使用Shader Graph实现 1. **导入Post-Processing Stack** 确保已安装`Universal RP`或`HDRP`,并在Package Manager中添加`Shader Graph`和`Post-Processing`包。 2. **创建自定义Shader Graph** - 右键菜单选择 **Create > Shader Graph > Universal Render Pipeline > Blank Shader Graph**。 - 添加`Split`节点分离屏幕UV坐标,通过`Multiply`和`Subtract`生成中心对齐的UV(范围[-1,1])。 - 使用`Absolute`和`Maximum`节点计算方形暗角: ```glsl max(abs(uvX), abs(uvY)) // 方形区域计算 ``` - 添加`Smoothstep`控制边缘过渡,使用`Lerp`混合原始颜色与暗角颜色。 3. **创建Post-Process Volume** 新建`Global Volume`,添加`FullScreen Pass Renderer Feature`并绑定自定义Shader Graph。 --- ### 方法二:代码实现(适合非URP项目) ```csharp // C#脚本(挂载到相机) using UnityEngine; [ExecuteInEditMode] public class SquareVignette : MonoBehaviour { public Material vignetteMaterial; void OnRenderImage(RenderTexture src, RenderTexture dest) { Graphics.Blit(src, dest, vignetteMaterial); } } ``` ```glsl // Shader代码 Shader "Custom/SquareVignette" { Properties { _Intensity ("Intensity", Range(0,1)) = 0.5 _Softness ("Softness", Range(0,1)) = 0.2 } SubShader { 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; } float _Intensity; float _Softness; sampler2D _MainTex; fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); float2 centeredUV = (i.uv * 2 - 1); // 转换为[-1,1] float dist = max(abs(centeredUV.x), abs(centeredUV.y)); // 方形距离计算 float vignette = smoothstep(1.0 - _Softness, 1.0, dist * (1.0 + _Intensity)); return col * (1 - vignette); } ENDCG } } } ``` --- ### 关键参数说明 1. **正交投影模式**下暗角边界会更锐利,而**透视投影模式**会产生深度相关的自然过渡(如需要3D场景适配)[^1] 2. `_Intensity`控制暗角强度(建议0.3-0.7) 3. `_Softness`调整边缘模糊程度(建议0.1-0.3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值