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);
}
}