Unity3d Realize night vision effect

Source: Internet
Author: User

When it comes to night vision, you'll always think about the green game effect on the screen.
Night vision effects are often used in FPS (first person shooter) games,


Let's take a look at our implementation results:




It feels good.



There are three types of stickers needed for this shader:

1. Vignette map :
Gives a feeling of being with a night vision.



2. Noise map :
Produces snowflake-like noise



3. Scan Line Map :
Increase the realism of night vision goggles





First set up a shader
First look at the variables:

_scanlinetiletex; Map of the scan line effect


Noise Map
Create a random perturbation of a surface based on interaction between two colors or materials

Generates a noise effect by randomly mixing two colors

_noisetex; Noise map


_vignettetex; Vignette Map


_contrast; contrast ratio
How bright the color is


_brightness; brightness


_randomvalueRandom value, used in the noise map random UV perturbation


_distortionThe distortion degree of barrel distortion


_scale; Zoom in on the screen


_scanlinetileamountThe number of scanned lines (not the exact number, the degree of size)


_noisexspeed; Noise x-Direction speed
_noiseyspeed; Noise y-direction speed


_nightvisioncolor; Night vision goggles Color


Properties {_maintex ("Base (RGB)", 2D) = "White" {}_contrast ("contrast", Range (0, 4)) = 2 _brightness ("Brightness", Rang E (0, 2)) = 1_nightvisioncolor ("Night Vision Color", color) = (1, 1, 1, 1) _randomvalue ("Randomvalue", Float) = 0_distort Ion ("distortion", float) = 0.2_scale ("scale", float) = 0.8_vignettetex ("Vignette Texture", 2D) = "White" {}_scanlinetilet EX ("Scan line tile Texture", 2D) = ' White ' {}_scanlinetileamount ("Scan line tile Amount", Float) = 4.0_noisetex ("Noise Tex Ture ", 2D) =" White "{}_noisexspeed (' Noise X speed ', float) = 100.0_noiseyspeed (" Noise Y speed ", float) = 100.0}subsha


We would also like to state:

#pragma vertex vert_img The incoming pixel information is vert_img


#pragma fragment Frag
The element coloring function is Frag


#pragma fragmentoption arb_precision_hint_fastest

element coloring options. Arb_precision_hint_fastest uses this flag to fp16 pixels and speed up rendering


#pragma vertex vert_img#pragma fragment Frag #pragma fragmentoption arb_precision_hint_fastest




Lens barrel distortion correction algorithm to produce barrel distortion effect
Taking a rectangular object into a four-sided outward convex formation of a barrel-shaped image, it is said that the lens has a negative distortion, or barrel-shaped distortion

You'll need to transform the Uvs with this one.
Incoming UV value FLOAT2 coord
Outgoing distorted UV values
Creates a sense of lens, adds realism


Float2 barreldistortion (float2 coord) {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 * sqrt (R2)); return f * _scale * H + 0.5;}



Then we start coloring the slices in the Frag function.

The processed UV value is DISTORTEDUV from the barrel distortion function just now.
Gets the pixel information for the current incoming camera Rendertex

Get vignette map pixel information
Vignettetex = tex2d (_vignettetex, DISTORTEDUV);


Scan line UV controllable Scan line number

SCANLINESUV = HALF2 (i.uv.x * _scanlinetileamount, I.UV.Y * _scanlinetileamount);
Get Scan line map pixel information
Scanlinetex = tex2d (_scanlinetiletex, SCANLINESUV);



Noise map Uvs
To transform Uvs based on time and random values to produce disturbing effects
NOISEUV = Half2 (i.uv.x + (_randomvalue * _sintime.z * _noisexspeed), I.UV.Y + (_time.x * _noiseyspeed));
Get Noise map pixel information
Fixed4 Noisetex = tex2d (_noisetex, NOISEUV);


Lum is the luminosity luminance value
Lum = Dot (fixed3 (0.299, 0.587, 0.114), RENDERTEX.RGB);
Lum + = _brightness;//plus self-control brightness
Adjust saturation to zero, turn black and white, and mix with night-vision mirror Color
Fixed4 Finalcolor = (Lum) + _nightvisioncolor;


Mix with three different map colors to get the final color value
Finalcolor = Pow (finalcolor, _contrast);
Finalcolor *= Vignettetex;
Finalcolor *= Scanlinetex * NOISETEX;



Shader is OK.


Fixed4 Frag (v2f_img i/* Pixel Information */): color//element coloring function {Half2 Distorteduv = barreldistortion (I.UV);  Barrel-shaped distortion uvfixed4 Rendertex = tex2d (_maintex, DISTORTEDUV); Fixed4 Vignettetex = tex2d (_vignettetex, DISTORTEDUV); Vignette map//scan line UV controllable scan line number Half2 SCANLINESUV = HALF2 (i.uv.x * _scanlinetileamount, I.UV.Y * _scanlinetileamount);//_ Scanlinetileamount size Unrestricted Fixed4 Scanlinetex = tex2d (_scanlinetiletex, SCANLINESUV);//noise map Uvhalf2 NOISEUV = HALF2 (i.uv.x + (_randomvalue * _sintime.z * _noisexspeed), I.UV.Y + (_time.x * _noiseyspeed)); Fixed4 Noisetex = tex2d (_noisetex, NoiseUV );//lum = luminosity brightness fixed lum = dot (fixed3 (0.299, 0.587, 0.114), Rendertex.rgb), Lum + = _brightness;//plus automatic brightness//saturation adjustment to zero, Turns black and white, then mixes with night vision goggles fixed4 Finalcolor = (lum) + _nightvisioncolor;//finalcolor = Pow (finalcolor, _contrast);// Contrast Finalcolor *= vignettetex;//mixed with vignette map Finalcolor *= Scanlinetex * Noisetex;return finalcolor;}




Next look at the C # script placed in the camera



Build a C # script


The variables are given, similar to the shader variables above,
This is the value that will be passed to the shader


<span style= "FONT-SIZE:12PX;" > #region variablespublic Shader nightvisionshader;public float contrast = 2.0f;public float brightness = 1.0f;public Co Lor Nightvisioncolor = color.white;public texture2d vignettetexture;public texture2d scanlinetexture;public float Scanlinetileamount = 4.0f;public texture2d nightvisionnoise;public float noisexspeed = 100.0f;public float noiseYSpeed = 1 00.0f;public float distortion = 0.2f;public float scale = 0.8f;private float Randomvalue = 0.0f;private Material curmateri AL, #endregion </span>


Dynamically build a texture

<span style= "FONT-SIZE:12PX;" > #region propertiesmaterial material{get{if (curmaterial = = null) {curmaterial = new material (nightvisionshader); Curmaterial.hideflags = Hideflags.hideanddontsave;} return curmaterial;}} #endregion </span>

Still need onrenderimage () This function captures the image of the camera
Then we pass the various variables into the shader
by Graphics.blit () this function
Can undergo shader transformation processing in the output to our display



<span style= "FONT-SIZE:12PX;" >void onrenderimage (rendertexture sourcetexture, rendertexture desttexture) {if (Nightvisionshader! = null) { Material. SetFloat ("_contrast", contrast); material. SetFloat ("_brightness", brightness); material. SetColor ("_nightvisioncolor", nightvisioncolor); material. SetFloat ("_randomvalue", randomvalue); material. SetFloat ("_distortion", distortion); material. SetFloat ("_scale", scale), if (vignettetexture) {material. SetTexture ("_vignettetex", Vignettetexture);} if (scanlinetexture) {                material. SetTexture ("_scanlinetiletex", scanlinetexture);                Material. SetFloat ("_scanlinetileamount", Scanlinetileamount);} if (nightvisionnoise) {material. SetTexture ("_noisetex", nightvisionnoise); material. SetFloat ("_noisexspeed", noisexspeed); material. SetFloat ("_noiseyspeed", Noiseyspeed);} Graphics.blit (sourcetexture, desttexture, material);} Else{graphics.blit (Sourcetexture, desttexture);}} </span>

After all OK, after the script has adjusted the various values
Let's take a look at the effect



The feeling of fps immediately = =;




all of the following code :

C#:


<span style= "FONT-SIZE:12PX;" >using unityengine;using system.collections;public class night:monobehaviour{#region variablespublic Shader nightvisionshader;public float contrast = 2.0f;public float brightness = 1.0f;public Color nightvisioncolor = Color.white; Public texture2d vignettetexture;public texture2d scanlinetexture;public float scanlinetileamount = 4.0f;public Texture2d nightvisionnoise;public Float noisexspeed = 100.0f;public float noiseyspeed = 100.0f;public float distortion = 0 .2f;public float scale = 0.8f;private float Randomvalue = 0.0f;private Material curmaterial; #endregion #region Propertiesm Aterial material{get{if (curmaterial = = null) {curmaterial = new material (nightvisionshader); curmaterial.hideflags = Hideflags.hideanddontsave;} return curmaterial;}} #endregionvoid Start () {if (! systeminfo.supportsimageeffects) {enabled = False;return;} if (!nightvisionshader &&!nightvisionshader.issupported) {enabled = false;}} void Onrenderimage (Rendertexture sourcetexture,Rendertexture desttexture) {if (Nightvisionshader! = null) {material. SetFloat ("_contrast", contrast); material. SetFloat ("_brightness", brightness); material. SetColor ("_nightvisioncolor", nightvisioncolor); material. SetFloat ("_randomvalue", randomvalue); material. SetFloat ("_distortion", distortion); material. SetFloat ("_scale", scale), if (vignettetexture) {material. SetTexture ("_vignettetex", Vignettetexture);} if (scanlinetexture) {material.                SetTexture ("_scanlinetiletex", scanlinetexture); Material. SetFloat ("_scanlinetileamount", Scanlinetileamount);} if (nightvisionnoise) {material. SetTexture ("_noisetex", nightvisionnoise); material. SetFloat ("_noisexspeed", noisexspeed); material. SetFloat ("_noiseyspeed", Noiseyspeed);} Graphics.blit (sourcetexture, desttexture, material);} Else{graphics.blit (Sourcetexture, desttexture);}} void Update () {contrast = Mathf.clamp (contrast, 0f,4f); brightness = Mathf.clamp (brightness, 0f, 2f); Randomvalue = Random.range ( -1f,1f);d istortion = Mathf.clamp (dIstortion, -1f,1f); scale = Mathf.clamp (scale, 0f, 3f);} void Ondisable () {if (curmaterial) {destroyimmediate (curmaterial);}}} </span>
Shader

<span style= "FONT-SIZE:12PX;"  >shader "Custom/shadertest" {Properties {_maintex ("Base (RGB)", 2D) = "White" {}_contrast ("contrast", Range (0, 4)) = 2 _brightness ("Brightness", Range (0, 2)) = 1_nightvisioncolor ("Night Vision Color", color) = (1, 1, 1, 1) _randomvalue (" Randomvalue ", float) = 0_distortion (" distortion ", float) = 0.2_scale (" scale ", float) = 0.8_vignettetex (" Vignette Texture  ", 2D) =" White "{}_scanlinetiletex (" Scan line tile Texture ", 2D) = ' White ' {}_scanlinetileamount (" Scan line tile Amount ", float) = 4.0_noisetex ("Noise Texture", 2D) = "White" {}_noisexspeed ("Noise X speed", float) = 100.0_noiseyspeed ("Noise Y Speed ", Float) = 100.0}subshader {Pass {Tags {" rendertype "=" Opaque "}lod 200cgprogram#pragma vertex vert_img#pragma fra Gment frag #pragma fragmentoption arb_precision_hint_fastest//Use this flag to FP16 pixel operations # include "Unitycg.cginc" uniform sampler2d _maintex;uniform sampler2d _scanlinetiletex;//Scan Line effect map//noise map creates a random disturbance of the surface based on the interaction of two colors or materials//by randomly mixing the two colors, Generate noise effect uniform SamplER2D _noisetex;//Noise map Uniform sampler2d _vignettetex;//Decorative pattern, vignette, shadow map fixed _contrast;//contrast fixed _brightness;// Brightness fixed _randomvalue;//random value, fixed _distortion;//twisted fixed _scale;//screen proportional fixed _scanlinetileamount;//with random UV perturbation on noise map Number of scan lines fixed _noisexspeed;//noise x-direction speed fixed _noiseyspeed;//noise y-direction speed fixed4 _nightvisioncolor;//night vision Mirror color struct Input {float2 UV _maintex;}; Float2 barreldistortion (float2 coord) {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 * sqrt (R2)); return f * _scale * H + 0.5;}  Fixed4 Frag (v2f_img i/* Pixel Information */): color//element coloring function {Half2 Distorteduv = barreldistortion (I.UV); Barrel-shaped distortion uvfixed4 Rendertex = tex2d (_maintex, DISTORTEDUV); Fixed4 Vignettetex = tex2d (_vignettetex, DISTORTEDUV); Vignette map//scan line UV controllable scan line number Half2 SCANLINESUV = HALF2 (i.uv.x * _scanlinetileamount, I.UV.Y * _scanlinetileamount);//_ Scanlinetileamount size Unrestricted Fixed4 Scanlinetex = tex2d (_scanlinetiletex, SCANLINESUV);//noise map Uvhalf2 NOISEUV = HALF2 (i.uv.x + (_randomvalue * _sintime.z * _noiSexspeed), I.uv.y + (_time.x * _noiseyspeed)); Fixed4 Noisetex = tex2d (_noisetex, NOISEUV);//lum = luminosity brightness fixed lum = Dot (fixed3 (0.299, 0.587, 0.114), Rendertex.rgb); lum + = _brightness;//plus self-control brightness//saturation adjustment to zero, black and white effect, and night vision mirror color mixing fixed4 Finalcolor = (lum) + _nightvisioncolor;//finalcolor = Pow (finalcolor, _contrast);//contrast Finalcolor *= vignettetex;// Blend with vignette map Finalcolor *= Scanlinetex * Noisetex;return finalcolor;} ENDCG}}fallback "Diffuse"} </span>




-------------by wolf96






Unity3d Realize night vision effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.