Depth adjustment for Clipping protection

I have characters with clothes that are a separate mesh and can clip through during bending. How to fix that? Render the clothes mesh as if it was a bit closer to the camera, thus being rendered slightly atop the body without any scaling (or below with negative offset). Feel free to use for any purpose.

Developed graciously by CattreesDev and reposted from reddit. There are two versions, you only need one. I would say it’s perfect, by Cattrees notes some flaws: 

“The adjustment being in world space means FOV distortion is ignored, if you make the model with shader a child of different object and then move very close to the camera, the offset shifts. This may also happen further away at a wide FoV.

The second issue is that the projection is from vertex/fragment to camera, so the scale is all wrong. If you use camera-node_world_position you get a more proper scale, but the math is still wrong and fixes nothing in fragment version.”

Basically it’s a bit flawed but you can more or less avoid the issues if you don’t change camera properties too much or don’t need much offset or percision.

Enjoy!

Shader code
shader_type spatial;


//positive depth moves toward the camera in world units
uniform float depth_offset = 0.0;


//offset object by world coordinates
//towards the camera. VERTEX version

void vertex() {
	//model(local,object) to world(global) vertex position set to world_position
	vec3 world_position = vec4(MODEL_MATRIX * vec4(VERTEX,1)).xyz;
	//set direction vector from vertex to camera in world space
	vec3 dir2cam  = normalize(CAMERA_POSITION_WORLD - world_position);
	//offset depth by world(global) units.
	world_position += dir2cam * depth_offset;
	//transform world_position back to model(local, object) space and set vertex position.
	VERTEX = vec4(inverse(MODEL_MATRIX) * vec4(world_position,1)).xyz;
}



=======================================================================


shader_type spatial;


//positive depth moves toward the camera in world units
uniform float depth_offset = 0.0;


//offset object by world coordinates
//towards the camera. FRAGMENT version

void fragment() {
	//view to world(global) fragment position set to world_position
	vec3 world_position = vec4(INV_VIEW_MATRIX * vec4(VERTEX,1)).xyz;
	//set direction fragment from vertex to camera in world space
	vec3 dir2cam  = normalize(CAMERA_POSITION_WORLD - world_position);
	//move fragment towards camera in world(global) space
	world_position += dir2cam * depth_offset;
	//transform world_position from world(global) to view space
	//then transform world_position from view to clip(ndc) space
	vec4 ndc_offset = PROJECTION_MATRIX * VIEW_MATRIX * vec4(world_position,1);
	//normalize ndc_offset.z and set depth
	DEPTH = ndc_offset.z/ndc_offset.w;
}



//NOTE:
//This shader does not correct for FoV or Scale.
//if the offset is too large, or the FoV is too wide
//these artifacts become more pronounced.
Tags
adjustment, camera, clip, Clipping, clothes, depth, move, on top, order, z-order
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Simple Clipping with Adjustable Softedge

Daruk’s Protection Shader!

HSV Adjustment

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments