崩坏三 电子显示屏 信号干扰效果

崩坏三 电子显示屏信号干扰效果分析(Unity Shader)

    • 游戏内的截图
    • 效果分析
    • 例子1 老电视效果
    • 例子2 模拟崩坏3信号干扰效果
    • 例子3 电子广告屏信号干扰效果

游戏内的截图



西琳:我杀我自己

效果分析

实现信号干扰的效果主要是:通过噪声图来实现的,效果大致可以分为:扫描线、画面抖动、颜色偏移等。

例子1 老电视效果

崩坏三 电子显示屏 信号干扰效果_第1张图片
崩坏三 电子显示屏 信号干扰效果_第2张图片

Shader "Custom/Screen" {
	Properties{
		_MainTex("贴图", 2D) = "white" {}
		_TimeScale("花屏速度" , Range(0.0001, 2.0)) = 1.0
	}
		SubShader{
		Tags{ "RenderType" = "Opaque" }
		LOD 300

		pass {
		Cull Back
			
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag

		#include "UnityCG.cginc"
		#define R frac(43.*sin(p.x*73.+p.y*8.))


		float _TimeScale;
		float sat(float t) {
			return clamp(t, 0.0, 1.0);
		}

		float2 sat(float2 t) {
			return clamp(t, 0.0, 1.0);
		}

		float remap(float t, float a, float b) {
			return sat((t - a) / (b - a));
		}

		float linterp(float t) {
			return sat(1.0 - abs(2.0*t - 1.0));
		}

		float3 spectrum_offset(float t) {
			float3 ret;
			float lo = step(t,0.5);
			float hi = 1.0 - lo;
			float w = linterp(remap(t, 1.0 / 6.0, 5.0 / 6.0));
			float neg_w = 1.0 - w;
			ret = float3(lo,1.0,hi) * float3(neg_w, w, neg_w);
			return pow(ret, float3(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2));
		}

		float rand(float2 n) {
			return (sin(dot(float2(n.x *_TimeScale, n.y *_TimeScale), float2(12.9898, 78.233))));
		}

		float srand(float2 n) {
			return rand(n) * 2.0 - 1.0;
		}

		float mytrunc(float x, float num_levels)
		{
			return floor(x*num_levels) / num_levels;
		}
		float2 mytrunc(float2 x, float num_levels)
		{
			return floor(x*num_levels) / num_levels;
		}
			sampler2D _MainTex;
		float4 _MainTex_ST;
		float uvOffset;

		struct a2v {
			float4 vertex : POSITION;
			float3 normal : NORMAL;
			float4 texcoord : TEXCOORD0;
		};

		struct v2f {
			float4 pos : POSITION;
			float2 uv : TEXCOORD0;
			float3 color : TEXCOORD1;
		};

		v2f vert(a2v v) {
			v2f o; o.pos = UnityObjectToClipPos(v.vertex);
			o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
			o.color = ShadeVertexLights(v.vertex, v.normal);
			return o;
		}

		float4 frag(v2f i) : COLOR{
		float4 c;


		float aspect = _ScreenParams.x / _ScreenParams.y;
		aspect = 1;
		float2 uv = _ScreenParams.xy / _ScreenParams.xy;
		uv = float2(1,1);

		float time = fmod(_Time.y, 32.0); 
		float GLITCH = 10.1;

		float gnm = sat(GLITCH);
		float rnd0 = rand(mytrunc(float2(time, time), 6.0));
		float r0 = sat((1.0 - gnm)*0.7 + rnd0);
		float rnd1 = rand(float2(mytrunc(i.uv.x, 10.0*r0), time));
		float r1 = 0.5 - 0.5 * gnm + rnd1;
		r1 = 1.0 - max(0.0, ((r1<1.0) ? r1 : 0.9999999));
		float rnd2 = rand(float2(mytrunc(i.uv.y, 40.0*r1), time)); 
		float r2 = sat(rnd2);

		float rnd3 = rand(float2(mytrunc(i.uv.y, 10.0*r0), time));
		float r3 = (1.0 - sat(rnd3 + 0.8)) - 0.1;

		float pxrnd = rand(i.uv + time);

		float ofs = 0.05 * r2 * GLITCH * (rnd0 > 0.5 ? 1.0 : -1.0);
		ofs += 0.5 * pxrnd * ofs;

		i.uv.y += 0.1 * r3 * GLITCH;

		const int NUM_SAMPLES = 10;
		const float RCP_NUM_SAMPLES_F = 1.0 / float(NUM_SAMPLES);

		float4 sum = float4(0.0, 0.0, 0.0, 0.0);
		float3 wsum = float3(0.0, 0.0, 0.0);
		for (int j = 0; j<NUM_SAMPLES; ++j)
		{
			float t = float(j) * RCP_NUM_SAMPLES_F;
			i.uv.x = sat(i.uv.x + ofs * t);
			
			float4 samplecol = tex2D(_MainTex, i.uv); 
			float3 s = spectrum_offset(t);

			samplecol.rgb = samplecol.rgb * s;
			sum += samplecol;
			wsum += s;
		}
		sum.rgb /= wsum;
		sum.a *= RCP_NUM_SAMPLES_F;
		c.a = sum.a;
		c.rgb = sum.rgb;
		c.rgb = c.rgb;

		return c;
		}
			ENDCG
	}
	}FallBack "Diffuse"
}
  

例子2 模拟崩坏3信号干扰效果

崩坏三 电子显示屏 信号干扰效果_第3张图片

Shader "TV_Distortion" 
{
	Properties 
	{
		_MainTex("Sprite Texture", 2D) = "white" { }   //主纹理  
		_AdjustColor("Adjust Color (RGB)", Color) = (0,0,0,1)   //纹理颜色
		_BackgroundColor("Barckground Color (RGBA)", Color) = (0,0,0,1)   //背景颜色
		_DistortionTex("Distortion Tex (RG)", 2D) = "gray" { }   //扭曲噪点图
		_DistortionFrequency("Distortion Frequency", Float) = 1   //扭曲频率
		_DistortionAmplitude("Distortion Amplitude", Range(0, 1)) = 1   //扭曲强度
		_DistortionAnmSpeed("Distortion Animation Speed", Float) = 1  //扭曲动画速度
		_ColorScatterStrength("Color Scatter Strength", Range(-0.1, 0.1)) = 0.01  //偏移强度
		_NoiseTex("Noise Tex (RGB)", 2D) = "black" { }
		_NoiseAnmSpeed("Noise Animation Speed", Float) = 1
		_NoiseStrength("Noise Strength", Float) = 1
	}
 
	SubShader
	{
		Pass
		{
			Tags { "Queue"="Transparent" "IgnoreProjector"="True" "PreviewType"="Plane" "RenderType" = "Effect" }
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 3.0
			#pragma multi_compile_fog
			#include "UnityCG.cginc"
 
			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};
			struct v2f
			{
				float4 uv : TEXCOORD0;
				float4 Color : COLOR;
				float4 Distortion_UV : TEXCOORD1;
				float4 Noise_UV : TEXCOORD2;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};
 
			sampler2D _MainTex;
			float4 _MainTex_ST;
			float4 _BackgroundColor;
			float4 _AdjustColor;
			sampler2D _DistortionTex;
			float _DistortionFrequency;
			float _DistortionAmplitude;
			float _DistortionAnmSpeed;
			float _ColorScatterStrength;
			sampler2D _NoiseTex;
			float4 _NoiseTex_ST;
			float _NoiseAnmSpeed;
			float _NoiseStrength;
 
		v2f vert(appdata v)
		{
			v2f o;
			o.uv.xy = v.uv.xy;
			o.vertex = UnityObjectToClipPos(v.vertex);
 
			float4 distortUV;
			//扭曲图UV
			distortUV.x = (_Time.y * _DistortionAnmSpeed);
			distortUV.y = (v.uv.y * _DistortionFrequency);
			o.Distortion_UV = distortUV;
 
			//噪音图UV
			float2 noiseUV = TRANSFORM_TEX(v.uv, _NoiseTex);
			float3 noise1 = frac((sin((_SinTime.w * float3(13, 78, 46))) * 43960));
			float3 noise2 = frac((sin((_CosTime.x * float3(13, 78, 46))) * 43960));
			noiseUV.x = (noiseUV.x + ((noise1.x + noise2.x) * _NoiseAnmSpeed));
 
			float3 noise3 = frac((sin((_SinTime.x * float3(13, 78, 46))) * 43960));
			float3 noise4 = frac((sin((_CosTime.w * float3(13, 78, 46))) * 43960));
			noiseUV.y = (noiseUV.y + ((noise3.x + noise4.x) * _NoiseAnmSpeed));
 
 
			o.Noise_UV = float4(noiseUV, 0, 0);
			UNITY_TRANSFER_FOG(o, o.vertex);
			return o;
		}
 
		half4 frag(v2f i) : SV_Target
		{
			float4 color;
			color.yz = float2(0.0, 0.0);
			//获取扭曲图的偏移位置
			half offset = (tex2D(_DistortionTex, i.Distortion_UV.xy) - 0.5).x * _DistortionAmplitude;
			//颜色偏移强度(左右)
			float2 ColorStrength = float2(_ColorScatterStrength, 0.0);
			//红色偏移
			float4 redOffset = tex2D(_MainTex, ((i.uv.xy + offset) + ColorStrength));
			color.xw = redOffset.xw;
			//绿色位置不变
			float4 greenOffset = tex2D(_MainTex, i.uv.xy + offset);
			color.yw = (color.yw + greenOffset.yw);
			//蓝色偏移
			float4 blueOffset = tex2D(_MainTex,(i.uv.xy + offset) - ColorStrength);
			color.zw = (color.zw + blueOffset.zw);
 
			color.w = clamp(color.w, 0.0, 1.0);
			//如果是半透则使用背景颜色
			if ((color.w < 0.5)) 
			{
				color = _BackgroundColor;
			}
 
			//颜色调整
			color.xyz = (1.0 - ((1.0 - color.xyz) * (1.0 - _AdjustColor)));
 
			//噪音图叠加
			float4 noiseColor;
			noiseColor = tex2D(_NoiseTex, i.Noise_UV.xy);
			color.xyz = (1.0 - ((1.0 - color.xyz) * (1.0 -(noiseColor * _NoiseStrength).xyz)));
			return color;
		}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

例子3 电子广告屏信号干扰效果

崩坏三 电子显示屏 信号干扰效果_第4张图片
崩坏三 电子显示屏 信号干扰效果_第5张图片

Shader "MK4/Billboards"
{
	Properties
	{
		_Logo("Logo", 2D) = "black" {}
		_PannerX("Panner X", Range( 0 , 1)) = 0
		_PannerY("Panner Y", Range( 0 , 1)) = 0
		_DistortPower("Distort Power", Range( 0 , 1)) = 0
		_Distortions("Distortions", 2D) = "white" {}
		_AlbedoColor("Albedo Color", Color) = (0.490566,0.490566,0.490566,0)
		_Background("Background", 2D) = "gray" {}
		_BackgroundEm("Background Em", Range( 0 , 1)) = 0
		_LEDint("LED int", Range( 0 , 1)) = 0
		_LED("LED", 2D) = "white" {}
		_GlitchIntensity("Glitch Intensity", Range( 0 , 1)) = 0
		_LEDGlow("LED Glow", 2D) = "white" {}
		_Glitch1("Glitch1", Color) = (0.5197807,0.4306336,0.9926471,0)
		_Glitch2("Glitch2", Color) = (0.5588235,0.08093307,0,0)
		_Smoothness("Smoothness", Range( 0 , 1)) = 0
		[HideInInspector] _texcoord( "", 2D ) = "white" {}
		[HideInInspector] __dirty( "", Int ) = 1
	}

	SubShader
	{
		Tags{ "RenderType" = "TransparentCutout"  "Queue" = "AlphaTest+0" "IsEmissive" = "true"  }
		Cull Back
		CGPROGRAM
		#include "UnityShaderVariables.cginc"
		#pragma target 4.6
		#pragma surface surf Standard keepalpha addshadow fullforwardshadows 
		struct Input
		{
			float2 uv_texcoord;
		};

		uniform float4 _AlbedoColor;
		uniform sampler2D _Background;
		uniform sampler2D _Logo;
		uniform float4 _Logo_ST;
		uniform sampler2D _Distortions;
		uniform sampler2D _LED;
		uniform float4 _LED_ST;
		uniform float _DistortPower;
		uniform float _GlitchIntensity;
		uniform sampler2D _LEDGlow;
		uniform float4 _Glitch1;
		uniform float4 _Glitch2;
		uniform float _LEDint;
		uniform float _PannerX;
		uniform float _PannerY;
		uniform float _BackgroundEm;
		uniform float _Smoothness;

		void surf( Input i , inout SurfaceOutputStandard o )
		{
			float2 uv_Logo = i.uv_texcoord * _Logo_ST.xy + _Logo_ST.zw;
			float2 uv_LED = i.uv_texcoord * _LED_ST.xy + _LED_ST.zw;
			float4 tex2DNode249 = tex2D( _LED, uv_LED );
			float2 temp_output_272_0 = ( uv_Logo + ( tex2DNode249.a * 0.1 ) );
			float2 panner223 = ( 1.0 * _Time.y * float2( 1,2 ) + temp_output_272_0);
			float2 panner226 = ( 1.0 * _Time.y * float2( -1.8,0.3 ) + temp_output_272_0);
			float2 panner229 = ( 1.0 * _Time.y * float2( 0.8,-1.5 ) + temp_output_272_0);
			float2 panner231 = ( 1.0 * _Time.y * float2( -0.8,-1.5 ) + temp_output_272_0);
			float temp_output_216_0 = ( ( ( ( tex2D( _Distortions, panner223 ).r + tex2D( _Distortions, panner226 ).g ) + tex2D( _Distortions, panner229 ).b ) + tex2D( _Distortions, panner231 ).a ) * (0.0 + (_DistortPower - 0.0) * (0.5 - 0.0) / (1.0 - 0.0)) );
			float4 tex2DNode244 = tex2D( _Background, ( uv_Logo + temp_output_216_0 ) );
			o.Albedo = ( _AlbedoColor * tex2DNode244 ).rgb;
			float2 panner267 = ( 1.0 * _Time.y * float2( -6,5 ) + temp_output_272_0);
			float clampResult295 = clamp( ( _GlitchIntensity + tex2D( _LEDGlow, panner267 ).a ) , 0.0 , 1.0 );
			float2 panner257 = ( 1.0 * _Time.y * float2( 2,3 ) + temp_output_272_0);
			float2 panner255 = ( 1.0 * _Time.y * float2( 0,0.6 ) + temp_output_272_0);
			float clampResult280 = clamp( (0.7 + (( _SinTime.w * ( _SinTime.w * 2.5 ) * ( _SinTime.w * 1.3 ) ) - -2.0) * (1.0 - 0.7) / (1.0 - -2.0)) , 0.0 , 1.0 );
			float2 panner263 = ( 1.0 * _Time.y * float2( -5,-2.3 ) + temp_output_272_0);
			float2 appendResult286 = (float2(_PannerX , _PannerY));
			float2 panner219 = ( 1.0 * _Time.y * appendResult286 + uv_Logo);
			float4 clampResult284 = clamp( ( ( ( clampResult295 * ( ( ( _Glitch1 * tex2D( _LEDGlow, panner257 ).g ) + ( ( _Glitch2 * tex2D( _LEDGlow, panner255 ).r ) + ( tex2DNode249 * clampResult280 ) ) ) * _LEDint ) ) + ( tex2D( _LEDGlow, panner263 ).b * tex2D( _Logo, ( panner219 + temp_output_216_0 ) ) ) ) + ( tex2DNode244 * _BackgroundEm ) ) , float4( 0,0,0,0 ) , float4( 1,1,1,0 ) );
			o.Emission = clampResult284.rgb;
			o.Smoothness = _Smoothness;
			o.Alpha = 1;
		}

		ENDCG
	}
	Fallback "Diffuse"
	CustomEditor "ASEMaterialInspector"
}

你可能感兴趣的:(Unity,Shader,Shader)