服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Unity3D旧电视滤镜shader的实现示例

Unity3D旧电视滤镜shader的实现示例

2022-11-15 14:24Marco&GalaxyDragon C#

这篇文章主要介绍了Unity3D旧电视滤镜shader的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

实现思路

既然是要实现旧电视的后处理效果,那么只要回忆一下那些古旧的电视的显示效果然后进行模拟就可以了。
1.首先那种大头电视一般屏幕有一些曲率,并不是完全的一个平面,而且一般是向外凸起,这种凸起会造成中间的显示区域会比原来更近一些,边缘的显示区域会比原来更远一些。这种效果我们直接用简单的二次函数来实现。
2.那种老旧电视会有不断运动的噪声,我们直接使用噪声函数加上时间变量来实现。
3.屏幕上会有一些条纹效果,这种周期性的条纹效果一般用三角函数来实现。
当然不可能模拟的完全准确。。也没有完全准确一说。毕竟每个人对老电视的印象也是不同的,我这里也只是把我印象里的效果来实现一下,看起来差不多就行了。

实现代码

首先实现第一点,实现屏幕的曲率。
我们采用的方法是先计算该uv坐标离(0.5,0.5)的距离,这个(0.5,0.5)的uv坐标其实可以看成屏幕的中心点。计算出距离之后根据这个距离的大小来对uv进行偏移,这其中用到了一个参数_Expand 为偏移的距离。
需要注意的是dot函数里填入两次同样的向量,算出的是向量模的平方而不是向量的模,不过这正是我们需要的,可以达到平方衰减的效果。

 float d2 = dot(i.uv - half2(0.5, 0.5), i.uv - half2(0.5, 0.5));
        half2 coord = (i.uv - half2(0.5, 0.5)) * (_Expand + d2 * (1 - _Expand)) + half2(0.5, 0.5);

接下来用这个偏移后的uv坐标来对纹理进行采样。

half4 color = tex2D(_MainTex, coord);

调整参数后就会出现一些屏幕凸出的效果,当然这里整个显示范围也变小了,这里是因为如果要显示原范围的话,需要的公式太复杂了,我们这里简单起见使用了简单的公式。

原图

Unity3D旧电视滤镜shader的实现示例

添加shader后

Unity3D旧电视滤镜shader的实现示例

接下来添加噪声,我们用一个变量控制噪声强度,同时传入时间变量来得到噪声一直变化的效果。

   float n = simpleNoise(coord.xy * _Time.x);
   half3 result = color.rgb * (1-_NoiseIntensity) + _NoiseIntensity * n;

而噪声函数具体的实现如下
至于为什么这个函数就可以得到噪声,其实也不好解释。大致就是sin函数倍增之后加上取小数的frac函数可以近似得到一种随机数的效果吧。

float simpleNoise(float2 uv)
    {
        return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
    }

效果如下

Unity3D旧电视滤镜shader的实现示例

最后添加上条纹效果

这个公式也不是什么经过精心推导的公式,只是因为我们需要一个周期出现的条纹效果,然后就想到用sin和cos函数,然后随便调整一下看起来有点样子就可以了

half2 sc = half2((sin(coord.y * _StripeIntensity) + 1) / 2, (cos(coord.y * _StripeIntensity) + 1) / 2);
result += color.rgb * sc.xyx;

添加条纹之后

Unity3D旧电视滤镜shader的实现示例

效果2

Unity3D旧电视滤镜shader的实现示例

完整代码

c#代码

namespace Colorful
{
    using UnityEngine;


    [ExecuteInEditMode]
    public class OldTV : MonoBehaviour
    {
        public               Shader shader;
        [Range(0, 1)] public float  Expand          = 0.7f;
        [Range(0, 1)] public float  NoiseIntensity  = 0.3f;
        public               int    StripeIntensity = 500;


        protected void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            Material material = new Material(shader);
            material.SetFloat("_Expand", Expand);
            material.SetFloat("_NoiseIntensity", NoiseIntensity);
            material.SetInt("_StripeIntensity", StripeIntensity);
            Graphics.Blit(source, destination, material, 0);
        }
    }
}

shader代码

Shader "LX/OldTV"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }

    CGINCLUDE
    #include "UnityCG.cginc"

    sampler2D _MainTex;

    float _Expand;
    float _NoiseIntensity;
    int _StripeIntensity;

    float simpleNoise(float2 uv)
    {
        return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
    }


    half4 frag(v2f_img i) : SV_Target
    {
        float d2 = dot(i.uv - half2(0.5, 0.5), i.uv - half2(0.5, 0.5));
        half2 coord = (i.uv - half2(0.5, 0.5)) * (_Expand + d2 * (1 - _Expand)) + half2(0.5, 0.5);
        half4 color = tex2D(_MainTex, coord);

        float n = simpleNoise(coord.xy * _Time.x);
        half3 result = color.rgb * (1-_NoiseIntensity) + _NoiseIntensity * n;

        half2 sc = half2((sin(coord.y * _StripeIntensity) + 1) / 2, (cos(coord.y * _StripeIntensity) + 1) / 2);
        result += color.rgb * sc.xyx;

        return half4(result, color.a);
    }
    ENDCG

    SubShader
    {
        ZTest Always Cull Off ZWrite Off
        Fog
        {
            Mode off
        }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            ENDCG
        }
    }

    FallBack off
}

另外代码也传到github仓库里了,大家也可以关注一下哦~
我的github

到此这篇关于Unity3D旧电视滤镜shader的实现示例的文章就介绍到这了,更多相关Unity3D旧电视滤镜shader内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/o83290102o5/article/details/115790763

延伸 · 阅读

精彩推荐
  • C#c# WinForm 窗体之间传值的几种方式(小结)

    c# WinForm 窗体之间传值的几种方式(小结)

    这篇文章主要介绍了WinForm 窗体之间传值的几种方式(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    大白快跑86372022-02-28
  • C#C#中析构函数、Dispose、Close方法的区别

    C#中析构函数、Dispose、Close方法的区别

    本文详细对比了C#中析构函数、Dispose和Close方法的区别,三者都是释放资源,本文介绍了他们各自的使用方法和使用场景,希望对大家有所帮助。...

    侧步投篮11122021-11-18
  • C#利用C#9.0新语法如何提升if语句美感

    利用C#9.0新语法如何提升if语句美感

    这篇文章主要给大家介绍了关于利用C# 9.0新语法如何提升if语句美感的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    精致码农 • 王亮3942022-10-14
  • C#C#判断一个字符串是否是数字或者含有某个数字的方法

    C#判断一个字符串是否是数字或者含有某个数字的方法

    这篇文章主要介绍了C#判断一个字符串是否是数字或者含有某个数字的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    次元宅的我3382022-02-24
  • C#unity实现翻页按钮功能

    unity实现翻页按钮功能

    这篇文章主要为大家详细介绍了unity实现翻页按钮功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    贪玩的孩纸时代11952022-09-02
  • C#C#生成Word文件(图片、文字)

    C#生成Word文件(图片、文字)

    这篇文章主要为大家详细介绍了C#生成Word文件,包括图片、文字等素材,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Daniel7995182022-07-24
  • C#C# 实现dataGridView选中一行右键出现菜单的示例代码

    C# 实现dataGridView选中一行右键出现菜单的示例代码

    这篇文章主要介绍了C# 实现dataGridView选中一行右键出现菜单,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要...

    孙正嗯大正5462022-10-09
  • C#C#实现在底图上动态生成文字和图片

    C#实现在底图上动态生成文字和图片

    这篇文章主要为大家详细介绍了C#实现在底图上动态生成文字和图片,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    寒冰屋10052022-07-24