World Space Ripple Effect

The world space ripple effect is an effect that spread an emissive circle over objects in a world space. This effect was made on Unity3D.

To achieve this effect I’ve created a surface shader on which I will make move an emissive channel. So, all the objects on which the emissive must appear, have to use this shader material. So i started to create my channels:

 _RippleTex("RippleTex",2D) = "white"{}
_RippleOrigin("Ripple Origin", Vector) = (0,0,0,0)
_RippleDistance("Ripple Distance", Float) = 0
_Emissive("Emissive", 2D) = "black" {}
_EmissiveColor("_EmissiveColor", Color) = (1,1,1,1)
_EmissiveIntensity("_EmissiveIntensity", Range(0,1000) ) = 0.5
_RippleWidth("Ripple Width", Float) = 0.1

The effect with a texture on the emissive

Then I’ve write a formula to make an emissive progress in function of the w float of the rippleOrigin.

float distance = length( IN.worldPos.xyz - _RippleOrigin.xyz) - _RippleDistance * _RippleOrigin.w ;
float halfWidth = _RippleWidth *0.5;
float lowerDistance = distance - halfWidth;
float upperDistance = distance + halfWidth;
fixed4 c = tex2D (_RippleTex, IN.uv_RippleTex) * _Color;
float ringStrength = pow(max(0, 1 - (abs(distance) / halfWidth)), 2.1) *(lowerDistance< 0 && upperDistance> 0);

Finally for make it move at runtime, I’ve write two C# scripts, RippleState and RippleSpawn.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RippleSpawn : MonoBehaviour
{
public RippleState state;

void Update()
{
if(Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
state.RippleOrigin = hit.point;
}
}
}
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RippleState : MonoBehaviour
{

public Material mymat;
public float speed;

private Vector4 rippleOrigin = Vector4.zero;

public Vector3 RippleOrigin { set { rippleOrigin = new Vector4(value.x, value.y, value.z, 0); } }

private void Update()
{
rippleOrigin.w = Mathf.Min(rippleOrigin.w + (Time.deltaTime * speed), 1);
mymat.SetVector(“_RippleOrigin”,rippleOrigin);
}
}