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.htm

				float2 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 struct
				half2 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 Texture
				fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);

				//Process the Scratches UV and pixels
				half2 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 pixels
				half2 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 values
				fixed4 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 effects
				fixed3 constantWhite = fixed3(1,1,1);

				//Composite together the different layers to create finsl Screen Effect
				finalColor = 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 Variables
    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;
    #endregion

    #region Properties
    public Material material
    {
        get
        {
            if (curMaterial == null)
            {
                curMaterial = new Material(oldFilmShader);
                curMaterial.hideFlags = HideFlags.HideAndDontSave;
            }
            return curMaterial;
        }
    }
    #endregion
    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);
        }
    }

    // Use this for initialization
    void Start()
    {
        if (SystemInfo.supportsImageEffects == false)
        {
            enabled = false;
            return;
        }

        if (oldFilmShader != null && oldFilmShader.isSupported == false)
        {
            enabled = false;
        }
    }

    // Update is called once per frame
    void 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.htm

				float2 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 struct
				half2 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 Texture
				fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);

				//Process the Scratches UV and pixels
				half2 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 pixels
				half2 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 values
				fixed4 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 effects
				fixed3 constantWhite = fixed3(1,1,1);

				//Composite together the different layers to create finsl Screen Effect
				finalColor = 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

时间: 2024-09-30 21:30:14

unity3d 老电影式的屏幕特效的相关文章

【Unity Shaders】游戏性和画面特效——创建一个老电影式的画面特效

本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ========================================== 写在前面 终于到了本书的最后一章了,好激动有木有!作为压轴章,虽然只有两篇,但每篇的内容是比之前的任

Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果

全屏特效 黑白(对于<着色器和屏幕特效开发秘籍>的学习) 可实现死亡效果或需要黑白特效的效果 原理是通过OnRenderImage()函数在摄像机渲染的时候,改变颜色(饱和度) 新建一个c#脚本,将要放在摄像机中 [ExecuteInEditMode] 就是让这个脚本不开始也直接运行,方便观察效果 using UnityEngine; using System.Collections; [ExecuteInEditMode] public class ShaderTest : MonoBeha

自适应屏幕的jQuery响应式布局网站特效代码

jQuery响应式图片九宫格布局点击图片查看大图效果代码 jquery响应式布局_宽屏响应式焦点图片动画轮播代码 css3绘图制作css3响应式组织架构图形代码 jQuery css3图片翻转响应式布局翻转图片筛选器代码 jquery html5响应式幻灯片插件网站响应式全屏幻灯片轮播代码 jQuery响应式焦点图插件制作响应式全屏焦点图切换代码 jQuery html5全屏响应式幻灯片制作触屏手机幻灯片代码 jQuery图片响应式布局点击弹出图片响应式幻灯片代码 jquery 3d响应式幻灯片

八十年代老电影

八十年代老电影目录,分为上下两部分.上半部80-84年,下半部85-89年.大部分电影为大陆拍摄,其余为台湾和香港拍摄. 八十年代老电影目录(上)80-84年 电影名 上映时间 导演 主演 拍摄单位 405谋杀案 1980 沈耀庭 仲星火 徐敏 严翔 上海电影制片厂 爱情啊,你姓什么? 1980 颜碧丽 王伟平 颜正安 程之 叶琳琅 上海电影制片厂 爱情与遗产 1980 颜学恕 张玉玉 袁宗福 周锦堂 韩月乔 西安电影制片厂 巴山夜雨 1980 吴贻弓 吴永刚 李志舆 张瑜 上海电影制片厂 白莲

基于HTML5 SVG和CSS3炫酷蹦床式图片切换特效

今天给大家分享一款效果非常炫酷的HTML5 SVG和CSS3蹦床式图片切换特效插件.该图片切换插件在进行图片切换时,整个屏幕就像一张大蹦床一样,将图片弹射出去,切换到另一张图片,效果非常有创意.效果图如下: 在线预览   源码下载 HTML结构 该图片切换特效的HTML结构中,第一个元素是SVG图形,当切换图片时,它将从一个规则的矩形变为一个被压缩的矩形. <div class="stack"> <ul id="elasticstack" clas

效果不错的冒泡式提示信息框特效

纯css打造 预览demo:纯css3冒泡式提示信息框特效 css代码: <style type="text/css"> body{ background:#D6D3C9; color:#383835; font-family:Arial, Arial, Helvetica, sans-serif; } #bubblemenu li { display: inline; margin-left: 15px; cursor:pointer; } #bubblemenu li

UnityShader实例15:屏幕特效之Bloom

http://blog.csdn.net/u011047171/article/details/48522073 Bloom特效 概述 Bloom,又称"全屏泛光",是游戏中常用的一种镜头效果,是一种比较廉价的"伪HDR"效果(如下右图):使用了Bloom效果后,画面的对比会得到增强,亮的地方曝光也会得到加强,画面也会呈现一种朦胧,梦幻的效果,婚纱摄影中照片处理经常用到这种类似处理效果.Bloom效果一般用来近似模拟HDR效果,效果也比较相向,但实现原理却完全不同.

UnityShader实例11:屏幕特效之马赛克(Mosaic)材质

马赛克(Mosaic)材质 概述 马赛克(Mosaic),估计是大伙平时很常见最讨厌的图片处理手段,嘿嘿,没错我说的就是"打码".好了,正经点,马赛克指现行广为使用的一种图像(视频)处理手段,此手段将影像特定区域的色阶细节劣化并造成色块打乱的效果,因为这种模糊看上去有一个个的小格子组成,便形象的称这种画面为马赛克.其目的通常是让图像大规模的降低图像()视频分辨率,而让图像(视频)的一些细节隐藏起来,使之无法辨认,一般用来保护隐私,或者隐藏某些不健康的画面. 原理 要实现马赛克的效果,需

jQuery 间歇式无缝滚动特效分享(三张图片平行滚动)

最近项目中门户首页需要做出图片间歇式无缝滚动特效,但是在网上找资料都是不太理想,不过可以指导.最后自己写了一个demo实现了这个特效,分享出来. 1.jquery.cxscroll.js /*! * jQuery cxScroll 1.2.1 * http://code.ciaoca.com/ * https://github.com/ciaoca/cxScroll * E-mail: [email protected] * Released under the MIT license * Da