Box vertex shader

Hi.

I am a bit new to shaders in Unity and looking for some help.

I am looking for a realtime system to “clip” multiple meshes based on a 3D Box volume.
For any mesh outside the box volume I can cull them based on the bounding box, but for others I want to remove the parts of the mesh outside the box.

for all vertices outside I want to move them to the closest side of the box. if on top move it to the height of the box, if also on the left side, move it to the left etc.

this way the mesh will still have a outside. it will be trunked to the side of a box, but still have a texture when seen from the side.

any ideas?

Lennart

I imagine simply moving all vertices from meshes onto a single plane will lead to horrendous Z fighting, since you’ll have a mess of polygons all existing on the same depth. Personally I’d clip the meshes inside the cube so the protruding parts aren’t rendered, and have one orthographic camera for each side of the cube render only the protruding parts from the outside. The output of each camera is then applied to the cube sides (making sure that empty parts are transparent).

After some testing i have a sample shader up and running. I have not had much Z buffer problems, but I have not tested with very detailed geometry yet. It works good but I only made a box test working with and AABB axis aligned bounding box. Anyone have any idea on an approach where I can test for a rotated box?

Here is my shader code. I transform the vertex data to world space, do my vertex movement and then tranform back to object space before i finish the shader.

Shader"Custom/BoxShader" {
Properties {
_UL (“Upperleft”, vector) = (0., 0., 0., 1.0)
_LR (“Lowerright”, vector) = (0., 0., 0., 1.0)

_MainTex (“Base (RGB)”, 2D) = “white” {}
}
SubShader {
Pass {
CGPROGRAM

#pragmavertexvert
#pragmafragmentfrag

#include “UnityCG.cginc”

uniformsampler2D_MainTex;
uniformfloat_Cutoff;

float4_UL;
float4_LR;

structvertexInput {
float4vertex : POSITION;
float4texcoord : TEXCOORD0;
};

structvertexOutput {
float4pos : SV_POSITION;
float4tex : TEXCOORD0;
};

vertexOutputvert(vertexInputinput) {
//transformintoworlspace

float4v = input.vertex;
float4world_space_vertex = mul( _Object2World, v );

if ( world_space_vertex.x > _UL.x) { world_space_vertex.x = _UL.x; }
if ( world_space_vertex.x < _LR.x){ world_space_vertex.x = _LR.x; }

if ( world_space_vertex.y > _UL.y) { world_space_vertex.y = _UL.y; }
if ( world_space_vertex.y < _LR.y){ world_space_vertex.y = _LR.y; }

if ( world_space_vertex.z > _UL.z) { world_space_vertex.z = _UL.z; }
if ( world_space_vertex.z < _LR.z){ world_space_vertex.z = _LR.z; }

//transformbackintolocalspace
v = mul( _World2Object, world_space_vertex );

vertexOutputoutput;
output.pos = mul (UNITY_MATRIX_MVP, v);
output.tex = input.texcoord;
returnoutput;

}

fixed4_Color;

float4frag(vertexOutputinput) : COLOR
{
float4textureColor = tex2D(_MainTex, input.tex.xy);
if (textureColor.a < _Cutoff)
{
discard;
}
returntextureColor;
}

ENDCG
}
}
}