百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

零基础带你看游戏内灰度效果实现原理

liuian 2025-05-08 02:45 76 浏览

前言

在Unity中实现后处理效果有两种方式:一种是通过使用Unity官方提供的Post-Processing插件。另外一种方式就是使用脚本获取到渲染后帧缓冲区的图像,再通过shader写后处理的效果,最后合并输出图像到屏幕上。


一,Post Processing

1.1 设置组件

Post Processing后处理插件的工程配置:Unity 之 Post Processing后处理不同项目配置(UPR项目配置)

这里我们用到的只有:Color Grading 色彩调整

此组件可以使一个用到的特效,用于校正镜头中的颜色与亮度,来实现电影或海报效果,可以理解为手机中的何种滤镜。

这个组件设置项很多,此篇文章中介绍的灰度效果只需要使用到一个,那就是:Saturation 饱和度

Saturation值调整为-100,则可以实现灰度效果。随便大家一个界面测试一下:


1.2 代码控制

我这里创建了一个Slider,来动态控制Saturation 饱和度的值。创建代码命名为PostProcessingProfile 将其挂载到场景中PostProcessProfile的物体上,就可以实现开篇看到的滑动条控制灰度效果了:

具体代码如下,

using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.UI;

public class PostProcessingProfile : MonoBehaviour
{
    public Slider Slider_Profile;
    
    // 后处理的配置容器
    private PostProcessVolume _volume;
    // 根据Inspector面板上的组件创建对应类型变量
    private ColorGrading _colorGrading;
    
    void Start()
    {
        // 获取容器
        _volume = GetComponent<PostProcessVolume>();
        // 获取此容器下添加的组件
        _volume.profile.TryGetSettings(out _colorGrading);
        
        Slider_Profile.onValueChanged.AddListener(OnValueChangedSlider);
    }

    void OnValueChangedSlider(float progress)
    {
        Debug.Log(progress + " " + (progress * 100 - 100));
        // 控制灰度值的变化 (-100 0 -> 0-1)
        _colorGrading.saturation.Override(progress * 100 - 100);
    }
}

二,Shader材质实现

2.1 原理API

Unity在摄影机完成渲染后调用的事件函数,允许您修改摄影机的最终图像。

Unity后处理OnRenderImage

在内置渲染管道中,Unity在摄影机完成渲染后,调用MonoBehaviours上的OnRenderImage,该MonoBeh aviours作为已启用的摄影机组件附加到同一GameObject。您可以使用OnRenderImage创建全屏后处理效果。这些效果通过从源图像读取像素,使用Unity着色器修改像素的外观,然后将结果渲染到目标图像中来实现。通常使用图形。Blit执行这些步骤。

Graphics.Blit 官方文档:使用着色器将源纹理复制到目标渲染纹理。 Blit将dest设置为渲染目标,在材质上设置source_MainTex属性,并绘制全屏四边形。

若要blit到内置渲染管道中的屏幕后缓冲区,必须确保dest为空,并且摄影机为空。Camera的targetTexture属性。main也为空。如果dest为空,Unity将尝试使用Camera.main.targetTexture作为目标。


2.2 编写Shader

当输出的RGB值相同的时候,就变成了灰度图。所以只要在渲染输出颜色值的地方,将RGB输出为相同的值就可以实现了。

实现相同值的我们一般使用是加权平均值的做法,目前最常用的一组灰色RGB值是(0.299,0.587,0.114)。

具体怎么来的我也算不明白,感兴趣的同学可以搜索:在使彩色图变灰RGB的权重会固定为(R:0.299 G:0.587 B:0.114)? 学习一下。

最终Shader如下:

Shader "Custom/GrayAll"
{
    Properties
    {
        _MainTex("Base (RGB)", 2D) = "white" {}
        // 灰度值
        _Color("GaryScale Amount", Range(0.0, 1.0)) = 1.0
 
    }
 
    SubShader
    {    
        Pass{
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            
            uniform sampler2D _MainTex;
            fixed _Color;
     
            fixed4 frag(v2f_img i) : COLOR
            {
                fixed4 renderTexture = tex2D(_MainTex, i.uv);
                
                float grayValue = 0.299 * renderTexture.r + 0.587 * renderTexture.g + 0.114 * renderTexture.b;
                
                fixed4 finalColor = lerp(renderTexture, grayValue, _Color);
                
                return finalColor;
            }        
            ENDCG
        }
    }
    FallBack "Diffuse"
}

最后创建一个材质球使用上面创建的这个Shader,待下面使用:


2.3 编写代码

创建代码SetGrayScene,并将其挂载到摄像机上,通过2.1中介绍的OnRenderImageGraphics.Blit实现,具体代码如下:

using UnityEngine;

public class SetGrayScene : MonoBehaviour
{
    public Material grayMaterial;
    [Range(0f,1f)]
    public float grayScaleAmount = 1.0f;
    
    void Start()
    {
        // 判断终端是否支持
        if (grayMaterial != null && grayMaterial.shader.isSupported == false)
        {
            enabled = false;
        }
    }

    void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
    {
        if (grayMaterial != null)
        {
            grayMaterial.SetFloat("_Color", grayScaleAmount);
            Graphics.Blit(sourceTexture, destTexture, grayMaterial);
        }
        else
        {
            Graphics.Blit(sourceTexture, destTexture);
        }
    }
}

最后将2.2中创建的材质球,赋值给挂到摄像机的脚本上:


2.4 实现效果

运行游戏,调整grayScaleAmount值即可看到效果。

实现效果:

grayScaleAmount值调整到1


效果展示

使用Post Processing的效果:

使用Shade的效果:

相关推荐

快速关机(快速关机按什么键)
快速关机(快速关机按什么键)

1、我们直接长按手机右侧的电源键,大概5秒的时间,这时候手机页面会直接显示是否关机,选择关机就可以直接关机了。2、找到手机一侧的音量“+”键,再找到电源按键,之后只需同时按住音量“+”键和电源按钮,直到手机屏幕关闭即可强制关机。3、点击【设...

2025-12-25 08:05 liuian

云电脑免登录破解版(“云电脑破解版”)

虎牙YOWA云游戏平台便是一款完全免费的产品,只要玩家在自己的账号上购买过相关的产品即可通过云游戏平台直接登陆。但云游戏平台终归只是改变玩家的游戏方式,用户最终还是要回归于游戏中,如果难以保证游戏体验...

联想家庭版win7(联想家庭版笔记本电脑)

1、开机到欢迎界面时,按Ctrl+Alt+Delete,跳出帐号窗口,输入用户名:administrator,回车。2、如果这个帐号也有密码采用开机启动时按F8选“带命令行的安全模式”。3、选“Ad...

两台电脑怎么传文件最快(两台电脑怎么传文件比较快)

两台电脑之间传递文件可以有很多种方法。如果两台电脑同时在1栋楼或者一间办公室内,可以用U盘拷贝的方法传递文件。另外最快的方法还可以用通过邮箱、微信、QQ传送文件,那样速度更快,节省时间,又节省距离。将...

win7计算机图标怎么弄出来(win7怎么设置计算机图标)

您好,如果您的Win7桌面图标不见了,可以尝试以下方法:1.右键点击桌面的空白处,点击查看之后点击显示桌面图标。2.如果第一种方法不起作用,可以使用组合键“ctrl键+alt键+delete键”,...

usb打印机改wifi打印机(usb打印机改无线网络打印机)

首先要把打印机通过USB端口连接到路由器上,连接成功后路由器上的USB指示灯会亮。然后在需要使用网络打印机的电脑上安装打印机的驱动程序,这样才能够正常使用打印服务器连接的打印机。登录路由器,在左侧的系...

windows7没pdf打印机(win7系统自带的打印pdf找不到了)

建议安装Acrobat9,并安装9.1.3的AdobeReader/Acrobat的更新,去官网搜索即可,如果现有版本是9.1.0,则9.1.2和9.1.3的更新均需要安装.我实验的结果时9.0...

有两台iphone一台忘记密码(有两台iphone一台忘记锁屏密码)

iphone的锁屏密码输入错误次数过多,显示iphone已停用。解决办法:第一步:电脑上装好iTunes,并打开。第二步:关手机,插上数据线,注意只插手机这一端,先不接电脑。第三步:按住手机上的Hom...

快用苹果助手官网进不去(快用苹果助手怎么下载不了)

要在指定的网址上登录下载,苹果手机没有自动授信不能下载

电脑桌面图标的隐藏方法(电脑桌面图标的隐藏方法)
  • 电脑桌面图标的隐藏方法(电脑桌面图标的隐藏方法)
  • 电脑桌面图标的隐藏方法(电脑桌面图标的隐藏方法)
  • 电脑桌面图标的隐藏方法(电脑桌面图标的隐藏方法)
  • 电脑桌面图标的隐藏方法(电脑桌面图标的隐藏方法)
安装本地打印机的方法和步骤
  • 安装本地打印机的方法和步骤
  • 安装本地打印机的方法和步骤
  • 安装本地打印机的方法和步骤
  • 安装本地打印机的方法和步骤
复制快捷键ctrl+c(复制快捷键ctrl+c还有什么)

ctrl+c:复制;ctrl+v:粘贴,其他快捷键如下:Ctrl+Z撤消操作Ctrl+Y:恢复操作Delete(或Ctrl+D):删除所选的项目,将其移至回收站Shift+Delet...

微信主页背景墙壁纸怎么设置
  • 微信主页背景墙壁纸怎么设置
  • 微信主页背景墙壁纸怎么设置
  • 微信主页背景墙壁纸怎么设置
  • 微信主页背景墙壁纸怎么设置
校园网wifi免认证软件(校园网统一身份认证平台)

这个不存在犯法不犯法的问题,也就是说学校的网络是给你便捷使用的,反正都是给你使用的,你如何登录都没有任何的关系,其次就是你自己办的网的话,你有权利随意的更改,没办网的话那你就用学校的。1这是不道德和...

如何查看windows激活密钥(查看windows激活密钥命令)

可以按照以下步骤查看Windows系统的激活密钥:1.首先打开命令提示符,可通过在搜索栏中输入"cmd",然后右键管理员身份打开。2.在打开的命令提示符窗口中输入指令:slmgr/d...