Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by LunarPatrol · Dec 05, 2016 at 07:32 AM · 2dshadersimage effectsblurorthographic camera

How to blur objects based on distance from the camera using Unity's optimized blur effect?

Hello everybody,

I'm currently working on a 2D game for Android with Unity 5.4.3, in which the environment consists of several layers of sprites. Each layer is placed at a different Z-Position and I'm using an orthographic camera to render the scene. In order to make distant objects appear to be farther away, I want to blur the several background layers based on their distance from the camera (or their Z-Value). I found the Optimized Blur script and Fast Blur shader that come with Unity and want to adapt these to not blur the whole screen output to the same amount but to blur each layer at a different amount. I'm not much of a shader expert and despite some efforts and research I couldn't get anywhere near what I want to do. So, I would really appreciate any help you guys can offer me to make progress on this. I'm posting the script and shader code below.

This is the script I added to my main camera:

 using System;
 using UnityEngine;
 
 namespace UnityStandardAssets.ImageEffects
 {
     [ExecuteInEditMode]
     [RequireComponent (typeof(Camera))]
     [AddComponentMenu ("Image Effects/Blur/Blur (Optimized)")]
     public class CustomBlurOptimized : PostEffectsBase
     {
 
         [Range(0, 2)]
         public int downsample = 1;
 
         public enum BlurType {
             StandardGauss = 0,
             SgxGauss = 1,
         }
 
         [Range(0.0f, 10.0f)]
         public float blurSize = 3.0f;
 
         [Range(1, 4)]
         public int blurIterations = 2;
 
         public BlurType blurType= BlurType.StandardGauss;
 
         public Shader blurShader = null;
         private Material blurMaterial = null;
 
 
         public override bool CheckResources () {
             CheckSupport (false);
 
             blurMaterial = CheckShaderAndCreateMaterial (blurShader, blurMaterial);
 
             if (!isSupported)
                 ReportAutoDisable ();
             return isSupported;
         }
 
         // This is the only thing I added to the original Unity version
         public void OnEnable()
         {
             GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
         }
 
         public void OnDisable () {
             if (blurMaterial)
                 DestroyImmediate (blurMaterial);
         }
 
         public void OnRenderImage (RenderTexture source, RenderTexture destination) {
             if (CheckResources() == false) {
                 Graphics.Blit (source, destination);
                 return;
             }
 
             float widthMod = 1.0f / (1.0f * (1<<downsample));
             
             blurMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod, -blurSize * widthMod, 0.0f, 0.0f));
             source.filterMode = FilterMode.Bilinear;
 
             int rtW = source.width >> downsample;
             int rtH = source.height >> downsample;
 
             // downsample
             RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
 
             rt.filterMode = FilterMode.Bilinear;
             Graphics.Blit (source, rt, blurMaterial, 0);
 
             var passOffs= blurType == BlurType.StandardGauss ? 0 : 2;
 
             for(int i = 0; i < blurIterations; i++) {
                 float iterationOffs = (i*1.0f);
                 blurMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + iterationOffs, -blurSize * widthMod - iterationOffs, 0.0f, 0.0f));
 
                 // vertical blur
                 RenderTexture rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
                 rt2.filterMode = FilterMode.Bilinear;
                 Graphics.Blit (rt, rt2, blurMaterial, 1 + passOffs);
                 RenderTexture.ReleaseTemporary (rt);
                 rt = rt2;
 
                 // horizontal blur
                 rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
                 rt2.filterMode = FilterMode.Bilinear;
                 Graphics.Blit (rt, rt2, blurMaterial, 2 + passOffs);
                 RenderTexture.ReleaseTemporary (rt);
                 rt = rt2;
             }
 
             Graphics.Blit (rt, destination);
 
             RenderTexture.ReleaseTemporary (rt);
         }
     }
 }

And here's the shader code (I want to use the "normal" version, not the SGX stuff):

 Shader "Hidden/FastBlur" {
     Properties {
         _MainTex ("Base (RGB)", 2D) = "white" {}
         _Bloom ("Bloom (RGB)", 2D) = "black" {}
     }
     
     CGINCLUDE
 
         #include "UnityCG.cginc"
 
         sampler2D _MainTex;
         sampler2D _Bloom;
                 
         uniform half4 _MainTex_TexelSize;
         uniform half4 _Parameter;
 
         struct v2f_tap
         {
             float4 pos : SV_POSITION;
             half2 uv20 : TEXCOORD0;
             half2 uv21 : TEXCOORD1;
             half2 uv22 : TEXCOORD2;
             half2 uv23 : TEXCOORD3;
         };            
 
         v2f_tap vert4Tap ( appdata_img v )
         {
             v2f_tap o;
 
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             o.uv20 = v.texcoord + _MainTex_TexelSize.xy;                
             o.uv21 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,-0.5h);    
             o.uv22 = v.texcoord + _MainTex_TexelSize.xy * half2(0.5h,-0.5h);        
             o.uv23 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,0.5h);        
 
             return o; 
         }                    
         
         fixed4 fragDownsample ( v2f_tap i ) : SV_Target
         {                
             fixed4 color = tex2D (_MainTex, i.uv20);
             color += tex2D (_MainTex, i.uv21);
             color += tex2D (_MainTex, i.uv22);
             color += tex2D (_MainTex, i.uv23);
             return color / 4;
         }
     
         // weight curves
 
         static const half curve[7] = { 0.0205, 0.0855, 0.232, 0.324, 0.232, 0.0855, 0.0205 };  // gauss'ish blur weights
 
         static const half4 curve4[7] = { half4(0.0205,0.0205,0.0205,0), half4(0.0855,0.0855,0.0855,0), half4(0.232,0.232,0.232,0),
             half4(0.324,0.324,0.324,1), half4(0.232,0.232,0.232,0), half4(0.0855,0.0855,0.0855,0), half4(0.0205,0.0205,0.0205,0) };
 
         struct v2f_withBlurCoords8 
         {
             float4 pos : SV_POSITION;
             half4 uv : TEXCOORD0;
             half2 offs : TEXCOORD1;
         };    
         
         struct v2f_withBlurCoordsSGX 
         {
             float4 pos : SV_POSITION;
             half2 uv : TEXCOORD0;
             half4 offs[3] : TEXCOORD1;
         };
 
         v2f_withBlurCoords8 vertBlurHorizontal (appdata_img v)
         {
             v2f_withBlurCoords8 o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             
             o.uv = half4(v.texcoord.xy,1,1);
             o.offs = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
 
             return o; 
         }
         
         v2f_withBlurCoords8 vertBlurVertical (appdata_img v)
         {
             v2f_withBlurCoords8 o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             
             o.uv = half4(v.texcoord.xy,1,1);
             o.offs = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
              
             return o; 
         }    
 
         half4 fragBlur8 ( v2f_withBlurCoords8 i ) : SV_Target
         {
             half2 uv = i.uv.xy; 
             half2 netFilterWidth = i.offs;  
             half2 coords = uv - netFilterWidth * 3.0;  
             
             half4 color = 0;
               for( int l = 0; l < 7; l++ )  
               {   
                 half4 tap = tex2D(_MainTex, coords);
                 color += tap * curve4[l];
                 coords += netFilterWidth;
               }
             return color;
         }
 
 
         v2f_withBlurCoordsSGX vertBlurHorizontalSGX (appdata_img v)
         {
             v2f_withBlurCoordsSGX o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             
             o.uv = v.texcoord.xy;
             half2 netFilterWidth = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x; 
             half4 coords = -netFilterWidth.xyxy * 3.0;
             
             o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
             coords += netFilterWidth.xyxy;
             o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
             coords += netFilterWidth.xyxy;
             o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
 
             return o; 
         }        
         
         v2f_withBlurCoordsSGX vertBlurVerticalSGX (appdata_img v)
         {
             v2f_withBlurCoordsSGX o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             
             o.uv = half4(v.texcoord.xy,1,1);
             half2 netFilterWidth = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
             half4 coords = -netFilterWidth.xyxy * 3.0;
             
             o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
             coords += netFilterWidth.xyxy;
             o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
             coords += netFilterWidth.xyxy;
             o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
 
             return o; 
         }    
 
         half4 fragBlurSGX ( v2f_withBlurCoordsSGX i ) : SV_Target
         {
             half2 uv = i.uv.xy;
             
             half4 color = tex2D(_MainTex, i.uv) * curve4[3];
             
               for( int l = 0; l < 3; l++ )  
               {   
                 half4 tapA = tex2D(_MainTex, i.offs[l].xy);
                 half4 tapB = tex2D(_MainTex, i.offs[l].zw); 
                 color += (tapA + tapB) * curve4[l];
               }
 
             return color;
 
         }    
                     
     ENDCG
     
     SubShader {
       ZTest Off Cull Off ZWrite Off Blend Off
 
     // 0
     Pass { 
     
         CGPROGRAM
         
         #pragma vertex vert4Tap
         #pragma fragment fragDownsample
         
         ENDCG
          
         }
 
     // 1
     Pass {
         ZTest Always
         Cull Off
         
         CGPROGRAM 
         
         #pragma vertex vertBlurVertical
         #pragma fragment fragBlur8
         
         ENDCG 
         }    
         
     // 2
     Pass {        
         ZTest Always
         Cull Off
                 
         CGPROGRAM
         
         #pragma vertex vertBlurHorizontal
         #pragma fragment fragBlur8
         
         ENDCG
         }    
 
     // alternate blur
     // 3
     Pass {
         ZTest Always
         Cull Off
         
         CGPROGRAM 
         
         #pragma vertex vertBlurVerticalSGX
         #pragma fragment fragBlurSGX
         
         ENDCG
         }    
         
     // 4
     Pass {        
         ZTest Always
         Cull Off
                 
         CGPROGRAM
         
         #pragma vertex vertBlurHorizontalSGX
         #pragma fragment fragBlurSGX
         
         ENDCG
         }    
     }    
 
     FallBack Off
 }
 

My guess would be that I have to make the original Z-Value of the vertices available in the fragBlur8 function and then to tweak the calculations there depending on that value but I couldn't even make the first bit work. I tried some things but all I would ever get is a totally white/black/grey screen. I also tried rendering the depth to the screen as a starting point but couldn't manage that either although I sticked to code I found online. I'm quite lost at the moment and hope you guys can help me. If you need any further information concerning what I'm trying to achieve, just ask. Thank you very much in advance!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Custom sprite Shader works in 5.5, not 5.6 3 Answers

Disable angular shadow recieving in 2D? 0 Answers

Apply a shader to multiple 2D sprites 2 Answers

2D Lighting With Unity Free 2 Answers

2D displacement maps? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges