Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411276 Posts in 69323 Topics- by 58380 Members - Latest Member: bob1029

March 28, 2024, 11:47:08 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Implementing a wobble effect for speech bubbles in Unity?
Pages: [1]
Print
Author Topic: Implementing a wobble effect for speech bubbles in Unity?  (Read 4324 times)
Kyuugatsu
Level 1
*



View Profile
« on: July 05, 2018, 07:49:32 PM »

Hello,

I'm working on a little game in Unity 3D and I'd like to replicate the wobble effect seen on the speech bubbles in the game "Night in the woods", as seen here:

https://www.youtube.com/watch?v=wsjncjVfI_Y#t=0h14s

However, I have no idea how to do this -- I've tried writing some shader code to no avail (I get stuck with tessellation), and Unity's new shader graph doesn't seem to be able to do this.

Please let me know if you know of a way!
Logged

oahda
Level 10
*****



View Profile
« Reply #1 on: July 06, 2018, 12:35:31 AM »

Messing with vertices/tesselation seems rather overkill to me. I'd animate the UV's ever so slightly instead, perhaps by scrolling a monochrome displacement texture across the bubble and using the values to offset the UV values for the fragments.

Here's something I threw together quickly:



I assumed you wanted this to be a UI sprite, so my material/shader has been written with that assumption in mind. The inspector for the material looks like this:



It is then applied to the UI image like so:



Make sure the bubble sprite has an edge of transparent pixels or the edges will look weird. Here's the bubble and the displacement map (scaled down in the BBCode but at full size if you save them):



The first is set to a sprite and the latter is left as a regular texture and dragged to the material. The sprite's wrap mode is clamp and the displacement map's is repeat. My displacement map is just tiling difference clouds i generated in GIMP.

Finally, the shader:

Code:
Shader "Custom/UI/Bubble"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_DispTex ("Displacement", 2D) = "white" {}
_Speed ("Speed", Float) = 0.5
_Intensity ("Intensity", Float) = 0.025
}

SubShader
{
Tags
{
        "RenderType" = "Transparent"
        "Queue" = "Transparent"
}

Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
fixed4 vertexColor : COLOR;
};

struct v2f
{
float2 uv1 : TEXCOORD0;
float2 uv2 : TEXCOORD1;
float4 vertex : SV_POSITION;
fixed4 col : COLOR;
};

sampler2D _MainTex;
sampler2D _DispTex;
float4 _MainTex_ST;
float4 _DispTex_ST;
float _Speed;
float _Intensity;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv1 = TRANSFORM_TEX(v.uv, _DispTex);
o.uv2 = TRANSFORM_TEX(v.uv, _MainTex);
o.col = v.vertexColor;
return o;
}

fixed4 frag (v2f i) : SV_Target
{
float t = _Time.y * _Speed;
fixed disp = tex2D(_DispTex, i.uv1 + fixed2(t, t)).r;
fixed4 col = tex2D(_MainTex, i.uv2 + disp * _Intensity);
return col * i.col;
}

ENDCG
}
}
}

Just mess with the values exposed in the material and the look of the displacement texture to fine-tune the effect! c:

You can also modify the direction of the scrolling. Right now I'm just moving it diagonally with equal amounts on both axes.
« Last Edit: July 06, 2018, 08:02:44 AM by Prinsessa » Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #2 on: July 06, 2018, 07:21:55 AM »

Thank you! This is super helpful.

I especially appreciate the time taken to write the shader. I'm new to this so I wouldn't even have thought of using a scrolling noise texture! (I was trying to generate random values inside the shader...)
Logged

oahda
Level 10
*****



View Profile
« Reply #3 on: July 06, 2018, 07:53:14 AM »

Yeah, thinking with shaders is kinda different from "regular" programming logic in my experience. Tongue Using textures to sample values like noise or displacement can be really helpful!

BTW, I messed up a little: you don't use a _Color property to access the colour setting of a sprite renderer, but use the vertex colour. Updated the shader code! Of course, if you don't care about tinting your bubble sprite or changing its alpha (which I suppose you can do directly in the image anyway) you can just get rid of that part of the shader entirely instead. c:
« Last Edit: July 06, 2018, 08:03:37 AM by Prinsessa » Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #4 on: July 06, 2018, 10:26:29 AM »

Thanks! I've managed to get it looking almost the way I want, though I have a question:

I found this thread on Twitter: https://twitter.com/SmashyNick/status/1011319744031440896?s=19 and I think this is the same technique you're using -- but the effect is somewhat different (more of a wobble than a "shiver", hopefully you get what I mean). My question is -- why is this? Is it because the noise texture being used is different, or is there some other reason? (such as different settings / scrollspeed)
Logged

oahda
Level 10
*****



View Profile
« Reply #5 on: July 06, 2018, 11:28:29 AM »

Hah, I saw tweet, actually. c: Yeah, it should be fundamentally the same (I know OP was displacing the vertices at the start of the thread but they were quickly given the tip of using UV's instead and changed it) and just a matter of changing the details of the input (scroll speed, scroll direction, tiling/size of the displacement map and the look of the map itself). A lot of graphics programming tends to be just fiddling with numbers until it looks just right. I can't say which exact factor makes the difference here, but it's likely a combination.
Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #6 on: July 07, 2018, 02:02:50 PM »

I'm going to try and expand my understanding of shaders by doing an implementation of this shader in shader graph, even though I have the coded shader working.

Here is what the 'right hand side' looks like right now:

Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #7 on: July 07, 2018, 02:15:49 PM »

...and here is the left hand side:



I should convert the texture into a property, so it can be set independently of the shader.
Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #8 on: July 07, 2018, 02:54:09 PM »

As an additional note, I've found that a texture like this:



Works best, with an intensity of ~0.02 and a speed of 1.

I did indeed not care about the tint, so I didn't put it in the shader graph either, but it's easy enough to add (multiply with texture output before setting it to the color of the master node).

Now I know quite a bit about how to make shaders in shader graph, at least.  Beer!

Just don't know how to deal with lighting yet...  Shrug
Logged

oahda
Level 10
*****



View Profile
« Reply #9 on: July 08, 2018, 01:48:45 AM »

Yay!

Lighting is tricky. I've never used the shader graph so unfortunately I can only give you more info about regular old code shaders, but this is a great read for getting started shading 3D objects: https://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html

You can always settle with a much simple surface shader if it's enough to make the changes you want to as well.
Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #10 on: July 08, 2018, 06:54:59 PM »

I'd rather learn to code shaders anyway -- shader graph seems somewhat limited in what it can do (or at least, I don't understand it enough).

I do work at Unity though so maybe I can grab a hold of someone on the shader graph team and make them help me.  Cheesy

The latest thing I was trying to do was an outline shader, and here is the team's response:

Quote
multi-pass shaders are not supported by default in SRP, so neither LWRP or HDRP support this. The workaround here would be to render the object twice, once with the outline only and once to fill in the object or add the idea of a outline pass to the render pipeline itself(this would be the ideal solution if you were doing an toon styled game)
Logged

oahda
Level 10
*****



View Profile
« Reply #11 on: July 09, 2018, 12:45:16 AM »

Huh, I actually thought that was exactly what "multi-pass" shaders did in Unity, i.e. the "multi-pass" syntax just being a convenient way to write shaders, but that it would still result in two draw calls with different shaders getting queued in reality.
Logged

Kyuugatsu
Level 1
*



View Profile
« Reply #12 on: July 09, 2018, 07:06:01 AM »

Huh, I actually thought that was exactly what "multi-pass" shaders did in Unity, i.e. the "multi-pass" syntax just being a convenient way to write shaders, but that it would still result in two draw calls with different shaders getting queued in reality.

I think you're right about the draw calls, but there's a slight difference in this suggested workaround in that the two draw calls would actually be happening in the same pipeline 'pass' (unless you modify the render pipeline to add your outline pass). When you write a multi-pass shader, you can choose to some extent when the draw calls happen, since you're picking your 'pass' in the pipeline.

I still have no idea what I'm talking about though, so I might be completely wrong.
« Last Edit: July 09, 2018, 07:15:06 AM by Kyuugatsu » Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic