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 /
  • Help Room /
avatar image
0
Question by josessito · Mar 01, 2016 at 03:16 PM · shader2d-platformerwaterreflectionreflections

Help with grabpass shader for 2D water effect.

Hi, I been trying to write a shader for a water effect using grabpass to capture the screen the distorted with a scrollable bump map. But I have been having some isuess with the uv of the grabpass. Here is the current shader, wich at this moment just distorts the image behind it.

 Shader "Custom/WaterGrab" 
 {
     Properties 
     {        
         _Colour ("Colour", Color) = (1,1,1,1)
         _MainTex ("Noise text", 2D) = "bump" {}
         _Magnitude ("Magnitude", Range(0,1)) = 0.05
     }
     
     SubShader
     {
         Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Opaque"}
         ZWrite On Lighting Off Cull Off Fog { Mode Off } Blend One Zero
 
         GrabPass { "_GrabTexture" }
         
         Pass 
         {
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #include "UnityCG.cginc"
 
             sampler2D _GrabTexture;
             fixed4 _Colour;
             sampler2D _MainTex;
             float  _Magnitude;
 
             struct vin
             {
                 float4 vertex : POSITION;
                 float4 color : COLOR;
                 float2 texcoord : TEXCOORD0;
                 
             };
 
             struct v2f
             {
                 float4 vertex : POSITION;
                 fixed4 color : COLOR;
                 float2 texcoord : TEXCOORD0;
                 float4 uvgrab : TEXCOORD1;
                 float2 screenPos : TEXCOORD2;
                     
             };
 
             float4 _MainTex_ST;
 
             // Vertex function 
             v2f vert (vin v)
             {
                 v2f o;
                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 o.color = v.color;
                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                 o.screenPos = ComputeScreenPos(o.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;
 
                 return o;
             }
 
             // Fragment function
             half4 frag (v2f i) : COLOR
             {                
                 half4 bump = tex2D(_MainTex, i.texcoord);
                 half2 distortion = UnpackNormal(bump).rg;
                 
                 i.uvgrab.xy += distortion * _Magnitude;    
             
                 fixed4 col = tex2D( _GrabTexture, i.uvgrab);
                 return col * _Colour;
             }
         
             ENDCG
         } 
     }
 }
 

The desired effect is this one:

alt text

The setup is simple, I just put a quad with the shader, it gets the screen behind it with grabpass then find the right pixels (those that are on top of it in the y coordinate) and then flip it. I know how to apply the displacement and all the other effects in the fragment shader to make the captured image to look like water. But for the life of me I can't figure out how to map the right portion of the grabpass to the quad.

Please I've been trying for a week, learning everything I can about shaders, but I believe this one is over my head.

EDIT: I forgot to mention that my camera moves around in the y and x position and also changes its orthographic size. That is the reason why the following method didn't work:

 // Fragment function
             half4 frag (v2f i) : COLOR
             {                
                 half4 bump = tex2D(_MainTex, i.texcoord);
                 half2 distortion = UnpackNormal(bump).rg;
                 
                 i.uvgrab.xy += distortion * _Magnitude;    
                 i.uvgrab.y = 1 - i.uvgrab.y + _Offset;
             
                 fixed4 col = tex2D( _GrabTexture, i.uvgrab);
                 return col * _Colour;
             }

The issue here is that when the Camera moves up or down the reflection moves which should not happen. I also try to control the _Offset via a script based on the objects relative position with the camera like this:

 using UnityEngine;
 using System.Collections;
 
 public class WaterReflectionHeight : MonoBehaviour
 {
     public float factor;
     public float distance;
 
     float startingDist;
     float startingHeight;
     Renderer rend;
     Material mat;
     MeshRenderer meshRend;
 
     float ratio;
 
     void Awake()
     {
         rend = GetComponent<Renderer>();
         mat = rend.material;
         meshRend = GetComponent<MeshRenderer>();
         
     }
     void Start()
     {
         
         startingDist = CameraFollow.instance.transform.position.y -transform.position.y;
         startingHeight = mat.GetFloat("_Offset");
         ratio = startingHeight/ startingDist;
     }
 
     void LateUpdate()
     {
         distance = CameraFollow.instance.transform.position.y - transform.position.y;
         var height = distance*ratio;
         
 
         mat.SetFloat("_Offset", height);
     }
 }

But there are a few issues with this approach, the main one is that for some reason the reflection still moves a little (not sure why) and the second one is that the starting height (_Offset) will need to be set depending on the quad's position an the camera view (if, for instance, the screen size is not the same to the one the _Offset was adjusted for, the reflections would be too low or too high). So I think this hole _Offset - Script approach is not good.

I think someone with a better grasp on shaders could fix this. I been going nuts trying to understand matrix, transforms, clip space and all that to end up empty handed.

Thanks!!

kingdom.jpg (150.3 kB)
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

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by josessito · Mar 02, 2016 at 08:53 PM

Ok I did it.

 Shader "Custom/WaterGrab" 
 {
     Properties 
     {        
         _Colour ("Colour", Color) = (1,1,1,1)
         _MainTex ("Noise text", 2D) = "bump" {}
         _Magnitude ("Magnitude", Range(0,1)) = 0.05
     }
     
     SubShader
     {
         Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Opaque"}
         ZWrite On Lighting Off Cull Off Fog { Mode Off } Blend One Zero
 
         GrabPass { "_GrabTexture" }
         
         Pass 
         {
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #include "UnityCG.cginc"
 
             sampler2D _GrabTexture;
             fixed4 _Colour;
             sampler2D _MainTex;
             float  _Magnitude;
 
             struct vin
             {
                 float4 vertex : POSITION;
                 float4 color : COLOR;
                 float2 texcoord : TEXCOORD0;
                 
             };
 
             struct v2f
             {
                 float4 vertex : POSITION;
                 fixed4 color : COLOR;
                 float2 texcoord : TEXCOORD0;
                 float4 uvgrab : TEXCOORD1;
                     
             };
 
             float4 _MainTex_ST;
 
             // Vertex function 
             v2f vert (vin v)
             {
                 v2f o;
                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 o.color = v.color;
                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
 
 
             #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;
 
                 float4 top = mul(UNITY_MATRIX_MVP, float4(0, 0.5, 0, 1));
                 top.xy /= top.w;
 
                 o.uvgrab.y = 1 - (o.uvgrab.y + top.y);
 
                 return o;
             }
 
             // Fragment function
             half4 frag (v2f i) : COLOR
             {        
                 
                 half4 bump = tex2D(_MainTex, i.texcoord );
                 half2 distortion = UnpackNormal(bump).rg;
                 
                 
                 i.uvgrab.xy += distortion * _Magnitude;                    
                 fixed4 col = tex2D( _GrabTexture, i.uvgrab);                
                 return col * _Colour;
             }
         
             ENDCG
         } 
     }
 }
 
Comment
Add comment · Show 1 · Share
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
avatar image NerdRageStudios · Sep 17, 2017 at 11:57 AM 0
Share

Hi, any chance you could elaborate more on how you set this up in Unity itself? create a material, applying to a quad and placing in scene doesnt work. Is there an associated script needed for this?

avatar image
0

Answer by Kiupe · Apr 16, 2017 at 07:15 AM

Hi @ josessito,

I'm currently looking for a 2D water shader and when I saw your post I thought to test yours. So I did and unfortunately it seems to not work as expected. I created a material using this shader, put a texture on it and applied the material on a quad into a 2D scene, added a sprite character and hit play. The quad is displayed with a solid color but nothing else. Is there specific set-up to use this shader ?

Thanks

Comment
Add comment · Show 1 · Share
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
avatar image paatz04 · Aug 12, 2019 at 11:34 AM 0
Share

Hi did you manage to find a solution for this ?

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

68 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Keep water4 from reflecting certain objects 0 Answers

How to use reflection probes/cubemaps to make a reflection shader 0 Answers

Why does my mirror not reflect my water shader? 0 Answers

Removing the mirror effect in Reflection probes 0 Answers

How do you reflect a directional light Sun in Unity5 water? 2 Answers


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