Unity Shader后处理-搜索灰度效果
如U3D中Hierarchy面板下的搜索效果:
讲解分析:
1.这种PostEffect效果其实就是指Unity shader的后处理,即游戏中实现屏幕特效的常见方法。顾名思义屏幕后处理就是指在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效。
2.要实现这种屏幕后处理的基础在于得到渲染后的屏幕图像,即抓取屏幕,Unity中提供给我们一个方便接口——OnRenderImage函数。
3.OnRenderImage函数定义为MonoBehaviour.OnRenderImage (RenderTexture src, RenderTexture dest); Unity会把当前渲染得到的图像存储在第一个参数对应的源渲染纹理中,通过该函数一系列操作后,再把目标渲染纹理,即第二个参数对应的渲染纹理显示到屏幕上。在OnRenderImage函数中,通常利用Graphics.Blit函数来完成对渲染纹理的处理。(若dest为null,就会直接将结果显示到屏幕上)。
src纹理是源纹理,在屏幕后处理技术中,该参数就是当前屏幕的渲染纹理或者是上一步处理后得到的渲染纹理。参数mat是材质,此材质使用的Unity Shader将会进行各种屏幕后处理操作,而src纹理将会被传递给材质的shader中名为_MainTex的纹理属性。参数pass的默认值为-1,即依次执行shader中的所有Pass,否则 仅会调用给定索引的Pass。
4.整个过程如下:
首先在摄像机中添加一个用于屏幕后处理的脚本。在该脚本中,我们会实现OnRenderImage函数来获取当前屏幕的渲染纹理。其次,再调用Graphics.Blit函数使用特定的Unity Shader来对当前图像进行处理,再把返回的渲染纹理显示到屏幕上。对于一些复杂的屏幕特效,可能多次调用Graphics.Blit函数对上一步输出结果进行下一步处理。
详细代码:
PostEffect.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering; [ExecuteInEditMode]
public class PostEffect : MonoBehaviour
{ #region Variables
public float grayScaleAmout = 1.0f; //主相机
public Camera sourceCamera; //操作相机(为了结合另一个PostEffect,(OutlineEffect操作的相机))
public Camera outlineCamera; //渲染纹理
RenderTexture renderTexture; //开始灰色渲染效果标志
public bool isStart = false; //材质
Material material = null; #endregion void Start()
{
if (material == null)
{
material = new Material(Resources.Load<Shader>("NewUnlitShader"));
}
} void OnPreRender()
{
if (renderTexture == null || renderTexture.width != sourceCamera.pixelWidth || renderTexture.height != sourceCamera.pixelHeight)
{
renderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, , RenderTextureFormat.Default);
outlineCamera.targetTexture = renderTexture;
}
outlineCamera.Render();
} void OnRenderImage(RenderTexture source, RenderTexture target)
{
if (isStart)
{
if (material != null)
{
material.SetTexture("_OutLine", outlineCamera.targetTexture);
material.SetFloat("_LuminosityAmount", grayScaleAmout);
Graphics.Blit(source, target, material);
}
}
else
{
Graphics.Blit(source, target);
}
} void OnDisable()
{
if (material)
{
DestroyImmediate(material);
}
}
}
shader部分:
Shader "Custom/GrayScale" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_LuminosityAmount ("GrayScale Amount", Range(0.0, )) = 1.0
}
SubShader {
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc" uniform sampler2D _MainTex;
fixed _LuminosityAmount; uniform sampler2D _OutLine;
fixed _NumPixelH;
fixed _NumPixelV; fixed4 frag(v2f_img i) : COLOR
{
fixed4 outlineTex = tex2D(_OutLine, i.uv);
fixed4 renderTex = tex2D(_MainTex, i.uv); if((outlineTex.r+outlineTex.b+outlineTex.g+outlineTex.a)<0.1f)
{
float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
return finalColor;
}
else
{
return renderTex;
}
} ENDCG
}
}
FallBack "Diffuse"
}
注释:
判断纹理顶点色值,我的源纹理初始色为黑色,所以搜索的物体附上色值,判断rgba的和是否为0,0为黑色,1为白色,黑色部分置灰(没选中的物体及场景其他部分),有色差的部分为选中部分返回当前color。
这效果结合上一篇的Outline效果,源纹理为上一篇处理的纹理,即_OutLine ,_MainTex为主纹理,即当前屏幕纹理。
测试代码:
using cakeslice;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI; public class test : MonoBehaviour
{
public InputField Txt; GameObject go = null; public void OnClick()
{
var chr = Txt.text.ToCharArray();
StringBuilder stringBuilder = new StringBuilder();
for (int i = ; i < chr.Length; i++)
{
if (i == )
{
stringBuilder.Append(chr[].ToString().ToUpper());
}
else
{
stringBuilder.Append(chr[i].ToString().ToLower());
}
}
Debug.Log(stringBuilder.ToString()); go = GameObject.Find(stringBuilder.ToString());
if (go != null)
{
go.GetComponent<cakeslice.Outline>().Add();
Camera.main.GetComponent<PostEffect>().isStart = true;
}
else
{
Debug.Log("根据 "+ Txt.text + " 未找到搜索物体,请查看是否输入错误");
}
} public void UnDo()
{
if (go!=null)
{
go.GetComponent<cakeslice.Outline>().Remove();
Camera.main.GetComponent<PostEffect>().isStart = false;
go = null;
}
}
}
实现效果如下:
Unity Shader后处理-搜索灰度效果的更多相关文章
- Unity shader UI的3D效果
原创,转载请标明出处 1.效果 scene视图中的效果: game视图中效果: 2.核心思想:改变UI的顶点坐标 3.好处:可以用正交相机来实现3D效果. 4.Shader 实现 // Unity b ...
- Unity shader学习之轮廓效果
将物体描一层边可以使游戏看起来具有卡通风格,一种简单的实现方法如下: 将物体渲染2次,即使用2个通道. 第一个通道将顶点沿法线(或中心点到顶点的方向)做一个偏移,即将模型扩大一点,并将颜色渲染成轮廓的 ...
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
建立一个基本的屏幕后处理脚本系统 屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效.使用这种技术,可以为游戏画面添加更多艺术效果,例如景深. ...
- Unity Shader实现描边效果
http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...
- Unity Shader - 消融效果原理与变体
基本原理与实现 主要使用噪声和透明度测试,从噪声图中读取某个通道的值,然后使用该值进行透明度测试. 主要代码如下: fixed cutout = tex2D(_NoiseTex, i.uvNoiseT ...
- Unity3D学习(八):《Unity Shader入门精要》——透明效果
前言 在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道. Unity中通常使用两种方法来实现透明 :(1)透明度测试(AlphaTest)(2)透明度混合(AlphaBlend).前者往 ...
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
- 【Unity Shader】(五) ------ 透明效果之半透明效果的实现及原理
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题 [Unity Shader学习笔记](三) -- ...
- 【Unity Shader】(九) ------ 高级纹理之渲染纹理及镜子与玻璃效果的实现
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...
随机推荐
- git 关于commit命令的修改
1 修改最后一次提交的信息 git commit --amend 2 对于历史提交 git rebase -i HEAD~5 没毛病,
- mvnw简介
- HBase优化——读写优化
Hbase2.0查询优化 1)设置scan缓存 HBase中Scan查询可以设置缓存,方法是setCaching(),这样可以有效的减少服务端与客户端的交互,更有效的提升扫描查询的性能. Scan s ...
- Promise篇
Promise 原理解析与实现(遵循Promise/A+规范) 1 什么是Promise? Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解 ...
- Django中的缓存机制
概述 对于中等流量网站来说,尽可能的减少开销是必要的.缓存数据就是为了保存那些需要很多计算资源大的结果,这样的的话就不必在下次重复消耗计算资源. Django自带了一个健壮的缓存系 ...
- Matplotlib ValueError: _getfullpathname: embedded null character
Traceback (most recent call last): File "<stdin>", line 1, in <module> File &q ...
- Shell内置命令 eval
- webpack output.publicPath
output.publicPath string function 对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片.文件等)来说,outpu ...
- vuex之module的使用
一.module的作用 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿. 为了解决以上问题,Vuex 允许我们将 store 分 ...
- 服务注册与发现---spring cloud
Eureka基本架构 Register Service :服务注册中心,它是一个 Eureka Server ,提供服务注册和发现的功能. Provider Service :服务提供者,它是 Eur ...