рдЖрдЬ рд╣рдо рдбрд╛рдпрд░реЗрдХреНрдЯрдПрдХреНрд╕ рдореЗрдВ рдкреЛрд╕реНрдЯ-рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдЗрдореЗрдЬ рдореЗрдВ рд▓рдЧреЗ рд░рд╣реЗрдВрдЧреЗред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЕрдВрдзреЗрд░реЗ рдореЗрдВ, рдорд╛рдирд╡ рджреГрд╖реНрдЯрд┐ рд░реЗрдЯрд┐рдирд▓ рд░реЙрдб рдХреЛрд╢рд┐рдХрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдЙрдЪреНрдЪ рдкреНрд░рдХрд╛рд╢ рд╕рдВрд╡реЗрджрдирд╢реАрд▓рддрд╛ рд░рдВрдЧ рд╕рдВрд╡реЗрджрдирд╢реАрд▓рддрд╛ рдФрд░ рджреГрд╢реНрдп рддреАрдХреНрд╖реНрдгрддрд╛ рдХреЗ рдиреБрдХрд╕рд╛рди рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреА рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рд░реЗрдЯрд┐рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЫрдбрд╝реЗрдВ рд╣реЛрддреА рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдПрдХ рдмрд╣реБрдд рдмрдбрд╝реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреБрд▓ "рд╕рдВрдХрд▓реНрдк" рдХрдо рд╣реИ)ред
рдЗрди рд╕рднреА рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХрдВрдкреНрдпреВрдЯрд░ рд╕реЗ рджреВрд░ рд╣реЛрдХрд░ рд░рд╛рдд рдореЗрдВ рдмрд╛рд╣рд░ рдЬрд╛рдирд╛ред
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдирд┐рдореНрди рдЬреИрд╕рд╛ рдХреБрдЫ рдорд┐рд▓рддрд╛ рд╣реИ (
рдкреВрд░реНрдг рд╕реНрдХреНрд░реАрди рдкрд░ рджреЗрдЦреЗрдВ! ):
рдкрд╣рд▓реЗ: рд╕реБрд╕реНрдд рдкреЛрд▓рд┐рд╢ рд╢реВрдЯрд░
рдХреЗ рдмрд╛рдж: IGF рдлрд╛рдЗрдирд▓рд┐рд╕реНрдЯ рдФрд░ рд╕рднреА E3 рдкреБрд░рд╕реНрдХрд╛рд░реЛрдВ рдХреЗ рд╡рд┐рдЬреЗрддрд╛
рдЯреНрд░реЗрдирд┐рдВрдЧ
рдкрд╣рд▓рд╛ рдХрджрдо рдпрд╣ рддрдп рдХрд░рдирд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдкреНрд░рднрд╛рд╡ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕рднреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рддреЛрдбрд╝ рджрд┐рдпрд╛:
- рдХрдо рдкреНрд░рдХрд╛рд╢ рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд░рдВрдЧ рдзрд╛рд░рдгрд╛ рдХрд╛ рдиреБрдХрд╕рд╛рди
- рд╡рд╣рд╛рдВ рдзреБрдВрдзрд▓реА рджреГрд╖реНрдЯрд┐
- рдереЛрдбрд╝рд╛ рд╢реЛрд░ (ibid)
- рдордзреНрдпрдо рдФрд░ рдХрдо рд░реЛрд╢рдиреА рдореЗрдВ рд▓рдВрдмреА рджреВрд░реА рдХреА рджреГрд╖реНрдЯрд┐ рд╣рд╛рдирд┐
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рд╣рдо Unity3D рдкреНрд░реЛ рдХреЗ рддрд╣рдд рд▓рд┐рдЦреЗрдВрдЧреЗ, рдкреЛрд╕реНрдЯрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ shader рдХреЗ рд░реВрдк рдореЗрдВред
рд╕реАрдзреЗ shader рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдПрдХ рдЫреЛрдЯреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдЗрд╕ рд╕рдорд╛рди shader рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реАрди рдмрдлрд░ рдЪрд▓рд╛рддрд╛ рд╣реИ:
using UnityEngine; [ExecuteInEditMode] public class HumanEye : MonoBehaviour { public Shader Shader; public float LuminanceThreshold; public Texture Noise; public float NoiseAmount = 0.5f, NoiseScale = 2; private Camera mainCam; private Material material; private const int PASS_MAIN = 0; void Start () { mainCam = camera; mainCam.depthTextureMode |= DepthTextureMode.DepthNormals; material = new Material (Shader); } void OnRenderImage (RenderTexture source, RenderTexture destination) { material.SetFloat("_LuminanceThreshold", LuminanceThreshold); material.SetFloat ("_BlurDistance", 0.01f); material.SetFloat ("_CamDepth", mainCam.far); material.SetTexture ("_NoiseTex", Noise); material.SetFloat ("_Noise", NoiseAmount); material.SetFloat ("_NoiseScale", NoiseScale); material.SetVector("_Randomness", Random.insideUnitSphere); Graphics.Blit (source, destination, material, PASS_MAIN); } }
рдпрд╣рд╛рдБ рд╣рдо рд╕рд┐рд░реНрдл shader рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдФрд░ рд╣рдорд╛рд░реЗ shader рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реАрди рдмрдлрд╝рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВред
рдЕрдм рдЪрд▓реЛ рд╡реНрдпрд╛рдкрд╛рд░ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рдЙрддрд░реЛред
рдЪрд░реЛрдВ рдФрд░ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреА рдШреЛрд╖рдгрд╛рдПрдБ:
sampler2D _CameraDepthNormalsTexture; float4 _CameraDepthNormalsTexture_ST; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _NoiseTex; float4 _NoiseTex_ST; float4 _Randomness; uniform float _BlurDistance, _LuminanceThreshold, _CamDepth, _Noise, _NoiseScale; #define DEPTH_BLUR_START 3 #define FAR_BLUR_START 40 #define FAR_BLUR_LENGTH 20
рд╡рд░реНрдЯреЗрдХреНрд╕ рд╢реЗрдбрд░ рдорд╛рдирдХ рд╣реИ рдФрд░ рдХреЛрдИ рдЕрд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣рд┐рд╕реНрд╕рд╛ рдкрд┐рдХреНрд╕реЗрд▓ shader рдореЗрдВ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред
рдкрд╣рд▓реЗ, рдЪрд▓реЛ рд╡рд░реНрддрдорд╛рди рдкрд┐рдХреНрд╕реЗрд▓ рдХрд╛ рдореВрд▓реНрдп рдЪреБрдиреЗрдВ, рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрд╕реА рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рд▓рд┐рдП "рдзреБрдВрдзрд▓реА" рдорд╛рди:
struct v2f { float4 pos : POSITION; float2 uv : TEXCOORD0; float2 uv_depth : TEXCOORD1; }; half4 main_frag (v2f i) : COLOR { half4 cColor = tex2D(_MainTex, i.uv); half4 cBlurred = blur(_MainTex, i.uv, _BlurDistance);
рдмреНрд▓рд░ () рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдПрдХ "рдзреБрдВрдзрд▓рд╛" рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рдЖрд╕-рдкрдбрд╝реЛрд╕ рдХреЗ рдХрдИ рдкрд┐рдХреНрд╕реЗрд▓ рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдФрд╕рдд рдХрд░рддрд╛ рд╣реИ:
inline half4 blur (sampler2D tex, float2 uv, float dist) { #define BLUR_SAMPLE_COUNT 16
рдкрд┐рдХреНрд╕реЗрд▓ рдбрд╛рд░реНрдХ рдлреИрдХреНрдЯрд░ рдХреЛ рддреАрди рдЪреИрдирд▓реЛрдВ рдкрд░ рдФрд╕рдд рдЪрдордХ рдореВрд▓реНрдп рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЧреБрдгрд╛рдВрдХ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рд╕реАрдорд╛ рдЪрдордХ рдорд╛рди (LuminanceThreshold), рдЕрд░реНрдерд╛рддреН рдкрд░ рдХрд╛рдЯ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рд╕рднреА рдкрд┐рдХреНрд╕реЗрд▓ рдЗрд╕рд╕реЗ рд╣рд▓реНрдХреЗ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ "рдЙрдЬреНрдЬреНрд╡рд▓ рдкрд░реНрдпрд╛рдкреНрдд" рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред
half kLum = (cColor.r + cColor.g + cColor.b) / 3; kLum = 1 - clamp(kLum / _LuminanceThreshold, 0, 1);
рдЪрдордХ рдкрд░ kLum рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

рд╣рдорд╛рд░реЗ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдХреНрд▓рдо рдорд╛рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ (рд╕рдлреЗрдж - 1, рдХрд╛рд▓рд╛ - 0):

рдпрд╣рд╛рдВ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЙрдЬреНрдЬреНрд╡рд▓ рдХреНрд╖реЗрддреНрд░реЛрдВ (рд▓рд╛рд▓рдЯреЗрди рдФрд░ рдкреНрд░рдмреБрджреНрдз рдШрд╛рд╕ рдХрд╛ рдкреНрд░рднрд╛рдордВрдбрд▓) рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ kum рд╣реИ рдФрд░ рд╣рдорд╛рд░реЗ рдкреНрд░рднрд╛рд╡ рдХреЛ рдЙрди рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдореАрдЯрд░ рдореЗрдВ рд╕реНрдХреНрд░реАрди рдХреА рд╕рддрд╣ рд╕реЗ рдкрд┐рдХреНрд╕реЗрд▓ рддрдХ рдХреА рджреВрд░реА рдЧрд╣рд░рд╛рдИ рдмрдирд╛рд╡рдЯ (рдЬреЗрдб-рдмрдлрд░) рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдЬреЛ рдХрд┐ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реИ рдЬрдм рдбрд┐рдлреЗрдВрдбрд░ рдкреНрд░рддрд┐рдкрд╛рджрдиред
float depth; float3 normal; DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, i.uv_depth), depth, normal); depth *= _CamDepth;
KDepth рдЧреБрдгрд╛рдВрдХ рдирд┐рдХрдЯ рдХреА рдХрд╛рд▓реА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдзреБрдВрдзрд▓рд╛ рдХрд░рдиреЗ рдХреА рдбрд┐рдЧреНрд░реА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛, рдФрд░ kFarBlur - рджреВрд░реА рдХреЗ рдЕрдиреНрдп рд╕рднреА:
#define DEPTH_BLUR_START 3 #define FAR_BLUR_START 40 #define FAR_BLUR_LENGTH 20 half kDepth = clamp(depth - DEPTH_BLUR_START, 0, 1); half kFarBlur = clamp((depth - FAR_BLUR_START) / FAR_BLUR_LENGTH, 0, 1);
рджреВрд░реА рд╕реЗ рджреЛрдиреЛрдВ рдЧреБрдгрд╛рдВрдХ рдХреЗ рд░реЗрдЦрд╛рдВрдХрди рд╕рдорд╛рди рджрд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рдХреЗрд╡рд▓ рдкреИрдорд╛рдиреЗ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВ:

KFarBlur рдорд╛рди:

рдФрд░ рдЕрдм - рдЬрд╛рджреВ! рд╣рдо рдкрд┐рдЫрд▓реЗ рддреАрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреБрд▓ рдкрд┐рдХреНрд╕реЗрд▓ рдХрд▓рдВрдХ рдЧреБрдгрд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
half kBlur = clamp(kLum * kDepth + kFarBlur, 0, 1);
рдбрд╛рд░реНрдХ рдкрд┐рдХреНрд╕рд▓реНрд╕ рдХреЛ рдХрдИ рдореАрдЯрд░ (DEPTH_BLUR_START) рдХреА рджреВрд░реА рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рджреВрд░ рдХреА рд╡рд╕реНрддреБрдПрдВ - рдкреНрд░рдХрд╛рд╢ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ред

рд╣рдо рдореЗрдВ рд░рдВрдЧ рдХреЗ рдиреБрдХрд╕рд╛рди рдХреА рдбрд┐рдЧреНрд░реА "рдкреНрд░рдХрд╛рд╢" (рдЖрдзрд╛ kDesaturate = kLum) рдХреА рдбрд┐рдЧреНрд░реА рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧреАред
рдЕрдм рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп, рдзреБрдВрдзрд▓реЗ рдФрд░ рдХрд╛рд▓реЗ рдФрд░ рд╕рдлреЗрдж рдкрд┐рдХреНрд╕рд▓реНрд╕ рдХреЛ рдорд┐рд▓рд╛рдиреЗ рдФрд░ рдЕрдВрддрд┐рдо рд░рдВрдЧ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ:
half kDesaturate = kLum; half4 result = cColor; result = (1 - kBlur) * result + kBlur * cBlurred; half resultValue = result; result = (1 - kDesaturate) * result + kDesaturate * resultValue; return result;

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдЖрдк рдбрд╛рдпрдирд╛рдорд┐рдХреНрд╕ рдореЗрдВ рдЪрд┐рддреНрд░ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреБрдЫ рдЧрд╛рдпрдм рд╣реИред рдХреНрдпрд╛? рд╢реЛрд░!
half noiseValue = tex2D(_NoiseTex, i.uv * _NoiseScale + _Randomness.xy); half kNoise = kLum * _Noise;
рдпрд╣рд╛рдВ рд╣рдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ _Randomness рд╡реЗрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ _NoiseTex рдмрдирд╛рд╡рдЯ (рдлрд╝реЛрдЯреЛрд╢реЙрдк рд╕реЗ тАЛтАЛрдЧреЙрд╕рд┐рдпрди рд╢реЛрд░ рд╕реЗ рднрд░рд╛) рд╕реЗ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЪрд░ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдлреНрд░реЗрдо рдкрд░ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред
рд╣рдо рдЕрдкрдиреЗ рдкрд┐рдХреНрд╕реЗрд▓ рдореЗрдВ рдкрд░рд┐рдгрд╛рдореА рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдореВрд▓реНрдп рдХреЛ рдорд┐рд▓рд╛рддреЗ рд╣реИрдВ:
result *= (1 - kNoise + noiseValue * kNoise);
рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ - рдПрдХ рд▓рдШреБ рд╡реАрдбрд┐рдпреЛ рдФрд░
рд╕реНрд╡рдпрдВ shader :
рдЕрджреНрдпрддрди : рд╕рд╣реА, рдорд╛рдирд╡ рд▓реЗрдВрд╕ flares:
