unity3d 老电影式的屏幕特效
做出这种古老效果,需要: 颜色发黄, 晕影效果, 灰尘与刮痕的效果。
建立一个c#脚本,将要放在摄像头中
先声明变量
oldFilmShader 所需shader(一会需要编写)
OldFilmEffectAmount 古老的程度(最后做插值的程度值)
sepiaColor 屏幕的颜色(调至黑黄)
vigentteTexture 老电影式基本贴图
vigentteAmount 所占比重
scratchesTexture 刮痕贴图
scratchesYspeed 刮痕y方向移动速度
scratchesXspeed 刮痕x方向移动速度
Texture2D dustTexture; 灰尘贴图
dustYSpeed 灰尘y方向移动速度
dustXSpeed 灰尘x方向移动速度
randomValue 随机值
public Shader oldFilmShader;public float OldFilmEffectAmount = 1.0f;public Color sepiaColor = Color.white;public Texture2D vigentteTexture;public float vigentteAmount = 1.0f;public Texture2D scratchesTexture;public float scratchesYspeed = 10.0f;public float scratchesXspeed = 10.0f;public Texture2D dustTexture;public float dustYSpeed = 10.0f;public float dustXSpeed = 10.0f;private Material curMaterial;private float randomValue;
依旧需要 OnRenderImage()这个函数抓取摄像机的图像
把所需变量传入shader
最后拷贝源纹理到目的渲染纹理
Graphics.Blit()
void OnRenderImage(RenderTexture sourceTex, RenderTexture destTex){if (oldFilmShader != null){material.SetColor("_SepiaColor", sepiaColor);material.SetFloat("_VigentteAmount", vigentteAmount);material.SetFloat("_OldFilmEffectAmount", OldFilmEffectAmount);if (vigentteTexture){material.SetTexture("_VigentteTex", vigentteTexture);}if (scratchesTexture){material.SetTexture("_ScratchesTex", scratchesTexture);material.SetFloat("_ScratchesYSpeed", scratchesYspeed);material.SetFloat("_ScratchesXSpeed", scratchesXspeed);}if (dustTexture){material.SetTexture("_DustTex", dustTexture);material.SetFloat("_DustXSpeed", dustXSpeed);material.SetFloat("_DustYSpeed", dustYSpeed);material.SetFloat("_RandomValue", randomValue);}Graphics.Blit(sourceTex, destTex, material);}else{Graphics.Blit(sourceTex, destTex);}}
再看shader
声明变量
distortion 扭曲程度
cubicDistortion 三维扭曲程度
Properties {_MainTex ("Base(RGB)", 2D) = "white" {}_VignetteTex ("VignetteTexture", 2D) = "white"{}_ScratchesTex ("ScartchesTexture", 2D) = "white"{}_DustTex ("DustTexture", 2D) = "white"{}_SepiaColor ("SepiaColor", Color) = (1,1,1,1)_EffectAmount ("OldFilmEffectAmount", Range(0,1)) = 1.0_VignetteAmount ("Vignette Opacity", Range(0,1)) = 1.0_ScratchesYSpeed ("ScratchesYSpeed", Float) = 10.0_ScratchesXSpeed ("ScratchesXSpeed", Float) = 10.0_dustXSpeed ("DustXSpeed", Float) = 10.0_dustYSpeed ("DustYSpeed", Float) = 10.0_RandomValue ("RandomValue", Float) = 1.0_Contrast ("Contrast", Float) = 3.0_distortion ("Distortion", Float) = 0.2_cubicDistortion ("CubicDistortion", Float) = 0.6_scale ("Scale(Zoom)", Float) = 0.8}
镜头桶形失真校正算法,产生桶形畸变效果
将矩形物体拍摄成四边向外凸形成桶形的影像,就称镜头具有负畸变,或桶形畸变
一会需要用此对uv进行变换
传入uv值float2 coord
传出扭曲的uv值
float2 barrelDistortion(float2 coord) {// Inspired by SynthEyes lens distortion algorithm// See http://www.ssontech.com/content/lensalg.htmfloat2 h = coord.xy - float2(0.5, 0.5);float r2 = h.x * h.x + h.y * h.y;float f = 1.0 + r2 * (_distortion + _cubicDistortion * sqrt(r2));return f * _scale * h + 0.5;}
从v2f_img i中获取图像的颜色和uv值
通过上面的barrelDistortion()函数获得扭曲的uv
刮痕的uv
对刮痕的uv进行变换,使之随时间移动
lum 求图像的饱和度
最终颜色初定义 = 饱和度+所定义颜色(浮动的明暗度(线性插值))
求颜色的对比度次方
不同的层合在一起构成屏幕最终特效
先与老电影式基本贴图做插值混合
然后与刮痕混合,与白色的插值来制造刮痕的闪烁效果
与灰尘相乘混合,与白色的插值来制造灰尘的闪烁效果
最后与图像的本来面貌做插值
得到最终颜色
fixed4 frag(v2f_img i) : COLOR{
//Get the colors from the RenderTexture and the uv's//from the v2f_img structhalf2 distortedUV = barrelDistortion(i.uv);distortedUV = half2(i.uv.x, i.uv.y + (_RandomValue * _SinTime.z * 0.005));fixed4 renderTex = tex2D(_MainTex, i.uv);//Get the pixels from the Vignette Texturefixed4 vignetteTex = tex2D(_VignetteTex, i.uv);//Process the Scratches UV and pixelshalf2 scratchesUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _ScratchesXSpeed),i.uv.y + (_Time.x * _ScratchesYSpeed));fixed4 scratchesTex = tex2D(_ScratchesTex, scratchesUV);//Process the Dust UV and pixelshalf2 dustUV = half2(i.uv.x + (_RandomValue * (_SinTime.z * _dustXSpeed)), i.uv.y + (_RandomValue * (_SinTime.z * _dustYSpeed)));fixed4 dustTex = tex2D(_DustTex, dustUV);// get the luminosity values from the render texture using the YIQ values.fixed lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);//Add the constant color to the lum valuesfixed4 finalColor = lum + lerp(_SepiaColor, _SepiaColor +fixed4(0.1f,0.1f,0.1f,1.0f), _RandomValue);finalColor = pow(finalColor, _Contrast);//Create a constant white color we can use to adjust opacity of effectsfixed3 constantWhite = fixed3(1,1,1);//Composite together the different layers to create finsl Screen EffectfinalColor = lerp(finalColor, finalColor * vignetteTex, _VignetteAmount);finalColor.rgb *= lerp(scratchesTex, constantWhite, (_RandomValue));finalColor.rgb *= lerp(dustTex.rgb, constantWhite, (_RandomValue * _SinTime.z));finalColor = lerp(renderTex, finalColor, _EffectAmount);return finalColor;}
代码如下
using UnityEngine;
using System.Collections;public class ShaderTest : MonoBehaviour
{#region Variablespublic Shader oldFilmShader;public float OldFilmEffectAmount = 1.0f;public Color sepiaColor = Color.white;public Texture2D vigentteTexture;public float vigentteAmount = 1.0f;public Texture2D scratchesTexture;public float scratchesYspeed = 10.0f;public float scratchesXspeed = 10.0f;public Texture2D dustTexture;public float dustYSpeed = 10.0f;public float dustXSpeed = 10.0f;private Material curMaterial;private float randomValue;#endregion#region Propertiespublic Material material{get{if (curMaterial == null){curMaterial = new Material(oldFilmShader);curMaterial.hideFlags = HideFlags.HideAndDontSave;}return curMaterial;}}#endregionvoid OnRenderImage(RenderTexture sourceTex, RenderTexture destTex){if (oldFilmShader != null){material.SetColor("_SepiaColor", sepiaColor);material.SetFloat("_VigentteAmount", vigentteAmount);material.SetFloat("_OldFilmEffectAmount", OldFilmEffectAmount);if (vigentteTexture){material.SetTexture("_VigentteTex", vigentteTexture);}if (scratchesTexture){material.SetTexture("_ScratchesTex", scratchesTexture);material.SetFloat("_ScratchesYSpeed", scratchesYspeed);material.SetFloat("_ScratchesXSpeed", scratchesXspeed);}if (dustTexture){material.SetTexture("_DustTex", dustTexture);material.SetFloat("_DustXSpeed", dustXSpeed);material.SetFloat("_DustYSpeed", dustYSpeed);material.SetFloat("_RandomValue", randomValue);}Graphics.Blit(sourceTex, destTex, material);}else{Graphics.Blit(sourceTex, destTex);}}// Use this for initializationvoid Start(){if (SystemInfo.supportsImageEffects == false){enabled = false;return;}if (oldFilmShader != null && oldFilmShader.isSupported == false){enabled = false;}}// Update is called once per framevoid Update(){vigentteAmount = Mathf.Clamp01(vigentteAmount);OldFilmEffectAmount = Mathf.Clamp(OldFilmEffectAmount, 0f, 1.5f);randomValue = Random.Range(-1f, 1f);}
}
shader:
Shader "Custom/TestShader" {Properties {_MainTex ("Base(RGB)", 2D) = "white" {}_VignetteTex ("VignetteTexture", 2D) = "white"{}_ScratchesTex ("ScartchesTexture", 2D) = "white"{}_DustTex ("DustTexture", 2D) = "white"{}_SepiaColor ("SepiaColor", Color) = (1,1,1,1)_EffectAmount ("OldFilmEffectAmount", Range(0,1)) = 1.0_VignetteAmount ("Vignette Opacity", Range(0,1)) = 1.0_ScratchesYSpeed ("ScratchesYSpeed", Float) = 10.0_ScratchesXSpeed ("ScratchesXSpeed", Float) = 10.0_dustXSpeed ("DustXSpeed", Float) = 10.0_dustYSpeed ("DustYSpeed", Float) = 10.0_RandomValue ("RandomValue", Float) = 1.0_Contrast ("Contrast", Float) = 3.0_distortion ("Distortion", Float) = 0.2_cubicDistortion ("CubicDistortion", Float) = 0.6_scale ("Scale(Zoom)", Float) = 0.8}SubShader {Pass{CGPROGRAM#pragma vertex vert_img#pragma fragment frag#pragma fragmentoption ARB_precision_hint_fastest#include "UnityCG.cginc"
uniform sampler2D _MainTex;uniform sampler2D _VignetteTex;uniform sampler2D _ScratchesTex;uniform sampler2D _DustTex;fixed4 _SepiaColor;fixed _VignetteAmount;fixed _ScratchesYSpeed;fixed _ScratchesXSpeed;fixed _dustXSpeed;fixed _dustYSpeed;fixed _EffectAmount;fixed _RandomValue;fixed _Contrast;float _distortion;float _cubicDistortion;float _scale;float2 barrelDistortion(float2 coord) {// Inspired by SynthEyes lens distortion algorithm// See http://www.ssontech.com/content/lensalg.htmfloat2 h = coord.xy - float2(0.5, 0.5);float r2 = h.x * h.x + h.y * h.y;float f = 1.0 + r2 * (_distortion + _cubicDistortion * sqrt(r2));return f * _scale * h + 0.5;}fixed4 frag(v2f_img i) : COLOR{
//Get the colors from the RenderTexture and the uv's//from the v2f_img structhalf2 distortedUV = barrelDistortion(i.uv);distortedUV = half2(i.uv.x, i.uv.y + (_RandomValue * _SinTime.z * 0.005));fixed4 renderTex = tex2D(_MainTex, i.uv);//Get the pixels from the Vignette Texturefixed4 vignetteTex = tex2D(_VignetteTex, i.uv);//Process the Scratches UV and pixelshalf2 scratchesUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _ScratchesXSpeed),i.uv.y + (_Time.x * _ScratchesYSpeed));fixed4 scratchesTex = tex2D(_ScratchesTex, scratchesUV);//Process the Dust UV and pixelshalf2 dustUV = half2(i.uv.x + (_RandomValue * (_SinTime.z * _dustXSpeed)), i.uv.y + (_RandomValue * (_SinTime.z * _dustYSpeed)));fixed4 dustTex = tex2D(_DustTex, dustUV);// get the luminosity values from the render texture using the YIQ values.fixed lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);//Add the constant color to the lum valuesfixed4 finalColor = lum + lerp(_SepiaColor, _SepiaColor +fixed4(0.1f,0.1f,0.1f,1.0f), _RandomValue);finalColor = pow(finalColor, _Contrast);//Create a constant white color we can use to adjust opacity of effectsfixed3 constantWhite = fixed3(1,1,1);//Composite together the different layers to create finsl Screen EffectfinalColor = lerp(finalColor, finalColor * vignetteTex, _VignetteAmount);finalColor.rgb *= lerp(scratchesTex, constantWhite, (_RandomValue));finalColor.rgb *= lerp(dustTex.rgb, constantWhite, (_RandomValue * _SinTime.z));finalColor = lerp(renderTex, finalColor, _EffectAmount);return finalColor;}ENDCG}} FallBack off
}
图片资源:
vigentteTexture
scratchesTexture
<span style="font-size:14px;color:#FF6600;">dustTexture</span>
--------by wolf96
unity3d 老电影式的屏幕特效相关推荐
- 【Unity Shaders】游戏性和画面特效——创建一个老电影式的画面特效
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 怎么实现EDIUS中“老电影”特效的制作
小编今天来贡献一篇EDIUS教程文章,为初学EDIUS视频编辑软件的小伙伴提供一些知识点做学习参考用,相信聪明的你们肯定会很快掌握新知识的. 当我们需要制作一些怀旧主题的题材时,该怎么用EDIUS快速 ...
- 怎样在EDIUS中做出“老电影”特效
小编今天来贡献一篇EDIUS教程文章,为初学EDIUS视频编辑软件的小伙伴提供一些知识点做学习参考用,相信聪明的你们肯定会很快掌握新知识的. 当我们需要制作一些怀旧主题的题材时,该怎么用EDIUS快速 ...
- Unity3D屏幕特效合成
Unity3D可以使用屏幕合成效果,估计很多人都知道,因为自带的屏幕特效包里面有很多这样的例子. 比如原来摄像机渲染出来的效果是这样的: 通过合成,你可以把它做颜色的偏移或者反转: 或者可以在上面合成 ...
- Photoshop轻松制作简单老电影画面特效
网上有一些介绍用Photoshop外挂滤镜间照片处理为老电影效果的文章,个人感觉外挂滤镜用得太多会影响程序运行的速度,其实我们用Photoshop中自带的功能也一样能够轻松完成这种特效. 我们先来看一 ...
- Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果
全屏特效 黑白(对于<着色器和屏幕特效开发秘籍>的学习) 可实现死亡效果或需要黑白特效的效果 原理是通过OnRenderImage()函数在摄像机渲染的时候,改变颜色(饱和度) 新建一个c ...
- w7计算机显卡,老电脑老显卡开Windows7 Aero特效,强!
Win7之家( www.win7china.com):老电脑老显卡开Windows7 Aero特效,强! 其实,本文标题也完全可以写成:玩转BIOS设置 - 老电脑老显卡开Win7 Aero特效,大家 ...
- Shader攻占笔记(八)屏幕特效
屏幕特效 前言 脚本基类 景深效果 脚本部分 着色器部分 碎屏效果 动态模糊 前言 [关于作业的狡辩] 本周内容与前几周相比,难度提高了一些,本章的shader需要配合相应的脚本使用.脚本基本上承担两 ...
- Unity Shader——夜晚视觉屏幕特效(night vision Screen Effect)
本文参考<Unity Shaders and Effects CookBook>. 这一篇夜晚视觉的效果跟上篇的老电影特效效果很类似,首先看下什么是夜晚视觉的效果: 分析下操作思路: 需要 ...
最新文章
- CrazyWing:Python自动化运维开发实战 六、流程控制
- Redis:Redis集群实战
- Visual Studio 2013或2015工程属性中包含目录和库目录的添加方法,附加依赖项,相对路径
- network重启失败原因
- 【原理图操作】原理图更新PCB时未改动元器件布局变动问题?
- 工作流实战_05_flowable 流程定义的挂起与激活
- VS Code 1.18版本更新内容整理(2017年10月 October 2017)
- 经典面试题之 TCP三次握手 和 TCP四次挥手过程----详解
- Oracle私网mtu滚动修改实施方案
- 编写asp.net程序,当编译调试比较频繁的时候,很容易经常地出现访问被拒绝
- 【Flink】Flink 写入 AnalyticDB MySQL
- drf 安装_drf 安装与配置
- 8.Kubernetes Service(服务)
- 即刻app暂停服务?趁现在教你一步一步实现即刻点赞效果
- 安卓Autojs逆向破解必备基础smail基础语法
- Labview编程模式
- Java金额大写转换
- Python官网安装包下载慢
- jQuery框架介绍
- LeetCode 831. Masking Personal Information【字符串,正则表达式】中等