Unity中后处理 脚本 和 Shader


前言

我们在上篇文章中提到,在Unity中实现后处理效果,需要同时结合 脚本 和 Shader,我们在这篇文章中编写所需要使用的C#脚本 和 Shader。


一、我们先创建一个默认的后处理Shader,用于脚本测试

在这里插入图片描述

  • 在该Shader的片元着色器中,我们可以看出,这个Shader主要做了一个反色处理。

在这里插入图片描述

二、在脚本中使用Graphics.Blit();

该语句需要在OnRenderImage生命周期函数内使用。
而该生命周期只对我们的摄像机生效

1、我们先公开一个材质,用于测试后处理效果

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

//后处理脚本
public class P2_7_3 : MonoBehaviour
{
    public Material Mat;
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source,destination,Mat);
    }
}

  • 把该脚本挂载在摄像机上
    在这里插入图片描述

  • 开启游戏后,我们看见我们的后处理Shader生效了

请添加图片描述

2、因为在实际开发中,我们不可能为每一个后处理Shader创建对应的材质球。所以,需要对该脚本进行修改,让脚本直接使用Shader

  • 创建一个公共成员变量,用于接收Shader

public Shader PostProcessingShader;

  • 创建一个成员属性,对其get方法进行修改,使其返回一个用我们Shader创建的材质
	private Material mat;

    public Material Mat
    {
        get
        {
            if (PostProcessingShader == null)
            {
                Debug.LogError("没有赋予Shader");
                return null;
            }

            if (!PostProcessingShader.isSupported)
            {
                Debug.LogError("当前Shader不支持");
                return null;
            }

            Material _newMaterial = new Material(PostProcessingShader);
            _newMaterial.hideFlags = HideFlags.HideAndDontSave;
            return _newMaterial;
        }
    }
  • 把我们的脚本挂载在摄像机,把Shader赋予脚本,我们看看效果

在这里插入图片描述

请添加图片描述

  • 使用[ExecuteInEditMode]特性给我们的Mono脚本,能使我们的脚本在编辑器模式下运行。

三、后处理Shader

1、后处理Shader需要遵守的条件

因为,后处理效果处理的是摄像机前的一个面片效果。
所以,是不需要面片剔除 和 深度效果的。需要把这两个功能相关的东西关闭,防止影响处理后的效果

Cull Off
ZWrite Off
ZTest Always

2、后处理效果 几乎都是 在片元着色器中实现的

因为后处理效果几乎都是在片元着色器中实现。所以,其余部分的功能几乎都没有变化。Unity对此进行了一些优化,我们可以直接使用。

  • Unity在 UnityCG.cginc 中帮我们定义了后处理中常用的 appdata 结构体

在这里插入图片描述

  • Unity在 UnityCG.cginc 中帮我们定义了后处理中常用的 v2f 结构体

在这里插入图片描述

  • Unity在 UnityCG.cginc 中帮我们定义了后处理中常用的 顶点着色器

在这里插入图片描述

3、这是简化后的 后处理Shader代码

Shader "Hidden/P2_7_4"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        // No culling or depth
        Cull Off 
        ZWrite Off 
        ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag

            #include "UnityCG.cginc"
            
            sampler2D _MainTex;

            fixed4 frag (v2f_img i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // just invert the colors
                col.rgb = 1 - col.rgb;
                return col;
            }
            ENDCG
        }
    }
}

三、最终测试脚本

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

//后处理脚本
public class P2_7_3 : MonoBehaviour
{
    public Shader PostProcessingShader;

    private Material mat;

    public Material Mat
    {
        get
        {
            if (PostProcessingShader == null)
            {
                Debug.LogError("没有赋予Shader");
                return null;
            }

            if (!PostProcessingShader.isSupported)
            {
                Debug.LogError("当前Shader不支持");
                return null;
            }

            Material _newMaterial = new Material(PostProcessingShader);
            _newMaterial.hideFlags = HideFlags.HideAndDontSave;
            return _newMaterial;
        }
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source,destination,Mat);
    }
}

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用以下代码在 Unity 使用 Shader 处理并保存图片: ```csharp using UnityEngine; public class SaveImageWithShader : MonoBehaviour { public Texture2D inputTexture; public Shader imageEffectShader; public string outputPath = "Output.png"; private void Start() { // 创建一个临时的 RenderTexture RenderTexture renderTexture = new RenderTexture(inputTexture.width, inputTexture.height, 0); Graphics.Blit(inputTexture, renderTexture); // 创建一个用于保存图片的 Texture2D Texture2D outputTexture = new Texture2D(renderTexture.width, renderTexture.height); // 创建一个用于保存结果的 RenderTexture RenderTexture outputRenderTexture = new RenderTexture(renderTexture.width, renderTexture.height, 0); // 使用 Shader 处理图片 Material imageEffectMaterial = new Material(imageEffectShader); Graphics.Blit(renderTexture, outputRenderTexture, imageEffectMaterial); // 将结果保存到 Texture2D RenderTexture.active = outputRenderTexture; outputTexture.ReadPixels(new Rect(0, 0, outputRenderTexture.width, outputRenderTexture.height), 0, 0); outputTexture.Apply(); // 将 Texture2D 保存为 PNG 文件 byte[] bytes = outputTexture.EncodeToPNG(); System.IO.File.WriteAllBytes(outputPath, bytes); // 释放资源 RenderTexture.active = null; Destroy(renderTexture); Destroy(outputRenderTexture); Destroy(outputTexture); Destroy(imageEffectMaterial); Debug.Log("Image saved to " + outputPath); } } ``` 将上述脚本附加到一个 GameObject 上,并在 Inspector 面板指定输入的 Texture2D、要应用的 Shader 和输出路径。运行场景后,脚本会将经过 Shader 处理后的图片保存为 PNG 文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠溪泽岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值