# Unity - Adding a sphere volume to this shader

I'm trying to create a spherical effect around my player that when they walk into range of hidden object, it gradually renders the object.

I found a shader that would work pretty well for this. When applied to an object, that object doesn't render, but when the object is brought into range of a cube shaped volume (by default it's located at the world origin) it renders.

Shader "Custom/ClipVolume" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0

// Expose parameters for the minimum x, minimum z,
// maximum x, and maximum z of the rendered volume.
_Corners ("Min XZ / Max XZ", Vector) = (-1, -1, 1, 1)
}
Tags { "RenderType"="Opaque" }
LOD 200

// Allow back sides of the object to render.
Cull Off

CGPROGRAM

#pragma surface surf Standard fullforwardshadows
#pragma target 3.0

sampler2D _MainTex;

struct Input {
float2 uv_MainTex;
float3 worldPos;
};

half _Glossiness;
half _Metallic;
fixed4 _Color;

// Read the min xz/ max xz material properties.
float4 _Corners;

void surf (Input IN, inout SurfaceOutputStandard o) {

// Calculate a signed distance from the clipping volume.
float2 offset;
offset = IN.worldPos.xz - _Corners.zw;
float outOfBounds = max(offset.x, offset.y);
offset = _Corners.xy - IN.worldPos.xz;
outOfBounds = max(outOfBounds, max(offset.x, offset.y));
// Reject fragments that are outside the clipping volume.
clip(-outOfBounds);

// Default surface shading.
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
// Note that the non-clipped Diffuse material will be used for shadows.
// If you need correct shadowing with clipped material, add a shadow pass
// that includes the same clipping logic as above.
FallBack "Diffuse"
}


Issue 1: I want this effect to be spherical so that it looks like it radiates from the player. I followed some signed distance and volumetric rendering tutorials to create the sphere, but I can't seem to hook that in with my existing shader (most likely because I'm very new to creating shaders).

Issue 2: I can't seem to figure out how to move the volume with my player. I can get the volume to shift in the inspector using the vector4 coordinates, but I can't get my player's position to translate in a way that uniformly moves the volume.

Can someone give me some tips or examples on how I can shape and move this volume?

Any help would be greatly appreciated!

First, spheres have a center and a radius, not a min/max corner. We can pack those into one 4-vector, with the center in xyz and the radius in w:

 Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0

// Change the exposed property for positioning / sizing the volume.
_CenterRadius ("Center(xyz) + Radius(w)", Vector) = (0, 0, 0, 1)
}


And then use the variable like so:

float4 _CenterRadius;

void surf (Input IN, inout SurfaceOutputStandard o) {

// Calculate offset from the center of the sphere.
float3 offset = IN.worldPos.xyz - _CenterRadius.xyz;

// Reject fragments that are outside the clipping volume.
// (squared length of offset > squared radius)
- dot(offset, offset));

// Default surface shading.
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}


You can update the position in your C# script like...

Vector4 centerRadius = player.transform.position;

(Assuming you've populated suitably named variables for your player avatar object, your radius parameter, and your clippingMaterial. You can of course replace the string "_CenterRadius" with a cached integer ID for efficiency)