Thanks for sharing! This is great for underwater distortion. Just drop it on a plane in front of the camera and bam! I changed the range to a float for more precision with the strength.
Yes, I am that person. The attached image shows what your sample package looks like on my mac with Unity 2.6.1f3 Pro. I have no clue what is wrong there, as I explained in the other thread, other GrabPass shaders seem to work fine.
Your shader already explicitly defines the queue as transparent+10. However, just to test, I tried a few other values. Interestingly, as soon as I drop into the geometry queue (Geometry,Geometry+1, ..., Geometry+999), the shader starts to partially work. That is, it correctly shows distorted grass in its entire area (with the fire particles rendered (undistorted) on top of it). Other solid geometry, like the walls and the logs are invisible within the spherical area. As soon as the queue hits Geometry+1000 (aka Transparent) it becomes the strange white egg from the picture. So I guess the render queue is indeed somehow involved, but I still don't know what is wrong exactly.
is thais shader work on unity pro only ? it can't work on my secene http://forum.unity3d.com/threads/83...can-t-work-in-my-scene-how-can-I-make-it-work
Yes, refraction / haze are always unity pro only You can easily identify this in the initial posting: GrabPass is Pro only
Old but very interesting water and Heat solutions from forestjohnson: http://forum.unity3d.com/threads/4285-quot-Sweet-arse-quot-water NB: it was a project for Unity 2.x so it needs some improvements with 3.4
Thanks for sharing meh11. I came across this becuase I am looking for some heat distortion for my project. For some reason everything is flipped in the distortion except during Deffered render mode. Would you know this could be fixed? Thanks for any help!
FYI, unity 3.3+ has now a proper builtin function for calculating GrabPass coordinates (handles flipping for windows et al): Code (csharp): float4 grabPassCoords = ComputeGrabScreenPos(o.pos) // o.pos is projected vertex
Hi ole! Could you show us please, how to use the grabbed texture in screen space on the original position? (like the "render nothing" example) I' ve tried the following in a Surface Shader: Code (csharp): float4 sPos = ComputeGrabScreenPos(IN.screenPos); // o.pos is projected vertex float2 uv = sPos.xy / sPos.w; o.Albedo = tex2D (_GrabTexture, uv).rgb; In forward rendering the texture is not flipped anymore, however it is not placed correctly either. In deferred rendering it is now flipped(and placed elsewhere) where it worked before: Code (csharp): float2 uv = IN.screenPos.xy / IN.screenPos.w; o.Albedo = tex2D (_GrabTexture, uv).rgb; Maybe I'm doing something wrong? Thanks!
hello, pasting a simplified code derived from our glass shader here that should work in all cases (if not it's a bug) ... Code (csharp): struct appdata_t { float4 vertex : POSITION; float2 texcoord: TEXCOORD0; }; struct v2f { float4 vertex : POSITION; float4 uvgrab : TEXCOORD0; float2 uvbump : TEXCOORD1; }; float4 _BumpMap_ST; v2f vert (appdata_t v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); #if UNITY_UV_STARTS_AT_TOP float scale = -1.0; #else float scale = 1.0; #endif o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5; o.uvgrab.zw = o.vertex.zw; o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap ); return o; } sampler2D _GrabTexture; float4 _GrabTexture_TexelSize; sampler2D _BumpMap; half4 frag( v2f i ) : COLOR { half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg; float2 offset = bump * 0.1 * _GrabTexture_TexelSize.xy; i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy; half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab)); return col; } remember to use GrabPass {} in a pass before this one and then all you'd need to do is add some animation to the bump lookup (and maybe fade out edges etc.) to get heat haze / distortion.
Code (csharp): // check if anti aliasing is used //if (_ProjectionParams.x < 0) screenPos.y = 1 - screenPos.y; Just comment out the checking anti-aliasing part, then it will render correctly, but I not sure what kind impact will this bring if we turn on the AA. --TwisterK
Hi All, This looks perfect for a project I am working on but does anyone have a package with the latest version of code? I don't mind piecing it all together from these posts but if someone has a current working version, I'd love to get my hands on it. Thanks.
The shader doesnt work for, its saying that i cant run subshaders on my graphics card. Im using Unity 3.5 without emulation mode and an nvidia GTX 570
Hey guys, I noticed a small problem when integrating this shader. It will render fog twice causing the distortion object to very obviously stand out. This can be fixed by adding: Code (csharp): Fog { Color (0,0,0,0) } Here's the full shader: Code (csharp): // Upgrade NOTE: replaced 'glstate.matrix.modelview[0]' with 'UNITY_MATRIX_MV' // Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP' Shader "HeatDistortion" { Properties { _NoiseTex ("Noise Texture (RG)", 2D) = "white" {} strength("strength", Range(0.1, 0.3)) = 0.2 transparency("transparency", Range(0.01, 0.1)) = 0.05 } Category { Tags { "Queue" = "Transparent+10" } SubShader { GrabPass { Name "BASE" Tags { "LightMode" = "Always" } } Pass { Name "BASE" Tags { "LightMode" = "Always" } Fog { Color (0,0,0,0) } Lighting Off Cull Off ZWrite On ZTest LEqual Blend SrcAlpha OneMinusSrcAlpha AlphaTest Greater 0 CGPROGRAM // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members distortion) #pragma exclude_renderers xbox360 #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #pragma fragmentoption ARB_fog_exp2 #include "UnityCG.cginc" sampler2D _GrabTexture : register(s0); float4 _NoiseTex_ST; sampler2D _NoiseTex; float strength; float transparency; struct data { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct v2f { float4 position : POSITION; float4 screenPos : TEXCOORD0; float2 uvmain : TEXCOORD2; float distortion; }; v2f vert(data i){ v2f o; o.position = mul(UNITY_MATRIX_MVP, i.vertex); // compute transformed vertex position o.uvmain = TRANSFORM_TEX(i.texcoord, _NoiseTex); // compute the texcoords of the noise float viewAngle = dot(normalize(ObjSpaceViewDir(i.vertex)), i.normal); o.distortion = viewAngle * viewAngle; // square viewAngle to make the effect fall off stronger float depth = -mul( UNITY_MATRIX_MV, i.vertex ).z; // compute vertex depth o.distortion /= 1+depth; // scale effect with vertex depth o.distortion *= strength; // multiply with user controlled strength o.screenPos = o.position; // pass the position to the pixel shader return o; } half4 frag( v2f i ) : COLOR { // compute the texture coordinates float2 screenPos = i.screenPos.xy / i.screenPos.w; // screenpos ranges from -1 to 1 screenPos.x = (screenPos.x + 1) * 0.5; // I need 0 to 1 screenPos.y = (screenPos.y + 1) * 0.5; // I need 0 to 1 // check if anti aliasing is used if (_ProjectionParams.x < 0) screenPos.y = 1 - screenPos.y; // get two offset values by looking up the noise texture shifted in different directions half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz); half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx); // use the r values from the noise texture lookups and combine them for x offset // use the g values from the noise texture lookups and combine them for y offset // use minus one to shift the texture back to the center // scale with distortion amount screenPos.x += ((offsetColor1.r + offsetColor2.r) - 1) * i.distortion; screenPos.y += ((offsetColor1.g + offsetColor2.g) - 1) * i.distortion; half4 col = tex2D( _GrabTexture, screenPos ); col.a = i.distortion/transparency; return col; } ENDCG } } } }
I know this kind off an old post, but is anyone capable of making this into a 4.0 shader? I have no experience with shaders and have no idea how to do this myself. I tried renaming and moving some stuff according to the logic in other 4.0 shaders, but without succes. The screenshots I saw in this post look promising. Any help would be appreciated.
I am trying to use this also on 4.0... looks fine on PC and mac, shader compiles ok for OGL2 emulation. but runs super slow on iPad3, just rendering 1/8 of screen area, goes from 30fps down to 7fps, shame, as it looks great.
Hi! Sorry for resurrecting this post but I need to ask: someone knows how to port this code to a compatible DX11 syntax? I'm getting the following errors when compiling in Directx11 rendering mode: Material doesn't have a texture property '_NoiseTex' Material doesn't have a texture property '_NoiseTex' Material doesn't have a float or range property 'strength' Material doesn't have a float or range property 'transparency' Thanks in advance for your time
Unity has an issue where the Material inspector complains about missing properties in shaders when the underlying issue is a shader compilation failure. I guess shaders that fail to compile are considered to have no properties, so you get a bunch of extra freaking out in the console. Save the shader again, and look for the actual compilation errors. If you can fix those, the Material ones should disappear.
Thanks for your help! The compilation errors are: No subshaders can run on this graphics card Program 'vert','vert': function return value missing semantics (compiling for d3d11_9x) at line 15 I'm running a 560GTX Ti so the first error its a little baffling. Additionally, the compiler its adding these lines to the shader code: // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members distortion) #pragma exclude_renderers d3d11 xbox360 Struct v2 its (its the same code posted on this thread): struct v2f { float4 position : POSITION; float4 screenPos : TEXCOORD0; float2 uvmain : TEXCOORD2; float distortion; }; Any idea of how to solve this?
Well, based on the error description, you could try giving distortion a semantic... how about TEXCOORD3?
Ok, got it. You need to keep the line but remove the if statement. Code (CSharp): // Upgrade NOTE: replaced 'glstate.matrix.modelview[0]' with 'UNITY_MATRIX_MV' // Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP' Shader "HeatDistortion" { Properties { _NoiseTex ("Noise Texture (RG)", 2D) = "white" {} strength("strength", Range(0.1, 0.3)) = 0.2 transparency("transparency", Range(0.01, 0.1)) = 0.05 } Category { Tags { "Queue" = "Transparent+10" } SubShader { // http://docs.unity3d.com/Manual/SL-GrabPass.html // http://docs.unity3d.com/Manual/SL-PassTags.html GrabPass { Name "BASE" Tags { "LightMode" = "Always" } // no lighting } Pass { Name "BASE" Tags { "LightMode" = "Always" } Fog { Color (0,0,0,0) } Lighting Off Cull Off ZWrite On ZTest LEqual Blend SrcAlpha OneMinusSrcAlpha AlphaTest Greater 0 CGPROGRAM // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members distortion) #pragma exclude_renderers d3d11 xbox360 // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members distortion) #pragma exclude_renderers xbox360 #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #pragma fragmentoption ARB_fog_exp2 #include "UnityCG.cginc" // http://forum.unity3d.com/threads/what-does-register-s0-do.26816/ sampler2D _GrabTexture : register(s0); float4 _NoiseTex_ST; sampler2D _NoiseTex; float strength; float transparency; struct data { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct v2f { float4 position : POSITION; float4 screenPos : TEXCOORD0; float2 uvmain : TEXCOORD2; float distortion; }; v2f vert(data i){ v2f o; o.position = mul(UNITY_MATRIX_MVP, i.vertex); // compute transformed vertex position o.uvmain = TRANSFORM_TEX(i.texcoord, _NoiseTex); // compute the texcoords of the noise float viewAngle = dot(normalize(ObjSpaceViewDir(i.vertex)), i.normal); o.distortion = viewAngle * viewAngle; // square viewAngle to make the effect fall off stronger float depth = -mul( UNITY_MATRIX_MV, i.vertex ).z; // compute vertex depth o.distortion /= 1+depth; // scale effect with vertex depth o.distortion *= strength; // multiply with user controlled strength o.screenPos = o.position; // pass the position to the pixel shader return o; } half4 frag( v2f i ) : COLOR { // compute the texture coordinates float2 screenPos = i.screenPos.xy / i.screenPos.w; // screenpos ranges from -1 to 1 screenPos.x = (screenPos.x + 1) * 0.5; // I need 0 to 1 screenPos.y = (screenPos.y + 1) * 0.5; // I need 0 to 1 // check if anti aliasing is used //if (_ProjectionParams.x < 0) screenPos.y = 1 - screenPos.y; screenPos.y = 1 - screenPos.y; // get two offset values by looking up the noise texture shifted in different directions half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz); half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx); // use the r values from the noise texture lookups and combine them for x offset // use the g values from the noise texture lookups and combine them for y offset // use minus one to shift the texture back to the center // scale with distortion amount screenPos.x += ((offsetColor1.r + offsetColor2.r) - 1) * i.distortion; screenPos.y += ((offsetColor1.g + offsetColor2.g) - 1) * i.distortion; half4 col = tex2D( _GrabTexture, screenPos ); col.a = i.distortion / transparency; return col; } ENDCG } } } }
Maybe the distortion shader in the following thread works for you? http://forum.unity3d.com/threads/horizontal-wave-distortion.295769/#post-1950999
Thanks for your post already found and used this shader. Very good for static objects. somewhat tricky to use for particles.