Ok I posted the shader here, with a little video showing the effect, compared to the standard unity shader:
Enjoy…
Ok I posted the shader here, with a little video showing the effect, compared to the standard unity shader:
Enjoy…
Thanks!!!
You’re welcome. Hope you find a good use for it !
Hi guys,
This shader is amazing but I’ve a problem when I want to apply a Cut Plane to my object.
A picture to illustrate :
We can see when i cut the object, hte “Cut” pixel are always here and hides me the other part of the object that I have to see.
Any idea ?
Thanks
Can you share a unity project that shows the problem and maybe an image explaining exactly how you would want it to be ?
Hi,
I’ve an object. I’m applying a plane on it. This plane defines which pixels I want to be visible and the other have to be unvisible.
Here it’s the object with an other point of view. We see the object is cut on his left.
Here is the object see from the plane point of view. The plane has already cut some part of the object. But we see that these parts are always here because they hide the other part of the object.
The big problem is I can’t change dynamically the opcaity of an object at runtime without putting an alpha pragma to my shader code. But this alpha pragma break all my object with some artefacts because Unity is unable to manage Fade & ZDepth.
I just want an “opaque” object (and my CutPlane works well with it) but change the opacity dynamically too.
What shader are you using for the cutting ?
This one :
Shader "Custom/Clipping" {
Properties {
_Conversion ("Conversion (RGB)", 2D) = "white" {}
_MainTex ("Main Texture", 2D) = "white" {}
_NormalxValue("Normal X Value", Float) = 1
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_Color ("Color", Color) = (0.5,0.5,0.5,1)
}
SubShader {
Tags { "RenderType" = "TransparentCutout" "DisableBatching" = "True" }
LOD 200
Cull Off
Pass
{
ZWrite On
ColorMask 0
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float3 _PlaneNormal;
uniform float _xValue;
uniform float _yValue;
uniform float _zValue;
uniform float _NormalxValue;
uniform float _NormalyValue;
uniform float _NormalzValue;
uniform half _Radius;
float3 _Origin;
uniform float _xIValue;
uniform float _yIValue;
uniform float _zIValue;
uniform float _signe;
uniform float _InOut;
struct v2f {
float4 pos : SV_POSITION;
float4 worldPos : world ;
};
v2f vert (appdata_base v)
{
v2f o;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos (v.vertex); //o.pos = 0 ==> no Depth
return o;
}
half4 frag (v2f i) : COLOR
{
_PlaneNormal = float3(_NormalxValue,_NormalyValue,_NormalzValue);
_PlaneNormal = normalize(_PlaneNormal);
half dist = (i.worldPos.x * _PlaneNormal.x) + (i.worldPos.y * _PlaneNormal.y) + (i.worldPos.z * _PlaneNormal.z)
- (_xValue * _PlaneNormal.x) - (_yValue * _PlaneNormal.y) - (_zValue * _PlaneNormal.z)
/ sqrt( pow(_PlaneNormal.x, 2) + pow(_PlaneNormal.y, 2) + pow(_PlaneNormal.z,2));
if(any(dist < 0))
{
discard;
}
_Origin = float3( _xIValue,_yIValue, _zIValue);
half distIarea = distance( i.worldPos, _Origin);
if(_InOut == 1)
{
clip (_signe * (distIarea - _Radius));
}
return half4 (0,0,0,1);
}
ENDCG
}
CGPROGRAM
#pragma surface surf Standard alpha
#pragma target 3.0
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_Conversion;
float3 worldPos;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
float3 _PlaneNormal;
uniform float _xValue;
uniform float _yValue;
uniform float _zValue;
uniform float _NormalxValue;
uniform float _NormalyValue;
uniform float _NormalzValue;
uniform half _Radius;
uniform float3 _Origin;
uniform float _xIValue;
uniform float _yIValue;
uniform float _zIValue;
uniform float _signe; // 1 ou -1
uniform float _InOut; // 0 ou 1
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _Conversion;
void surf (Input IN, inout SurfaceOutputStandard o) {
_PlaneNormal = float3(_NormalxValue,_NormalyValue,_NormalzValue);
_PlaneNormal = normalize(_PlaneNormal);
half dist = (IN.worldPos.x * _PlaneNormal.x) + (IN.worldPos.y * _PlaneNormal.y) + (IN.worldPos.z * _PlaneNormal.z)
- (_xValue * _PlaneNormal.x) - (_yValue * _PlaneNormal.y) - (_zValue * _PlaneNormal.z)
/ sqrt( pow(_PlaneNormal.x, 2) + pow(_PlaneNormal.y, 2) + pow(_PlaneNormal.z,2));
if(any(dist < 0))
{
discard;
}
_Origin = float3( _xIValue,_yIValue, _zIValue);
half distIarea = distance( IN.worldPos, _Origin);
if(_InOut == 1)
{
clip (_signe * (distIarea - _Radius));
}
o.Albedo = _Color;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = _Color.a;
}
ENDCG
}
Fallback Off
}
I’m speaking with this shader with C#script at runtime to give it the plane position. And I calculate the distance to clip or not pixels.
EDIT : Solution found
Discard pixel in the first Pass managing the Depth like in the Pass managing the color.
Use
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
to know the world position of the object.
Thanks
Amazing stuff, @Tim-C .
I was really struggling to find a shader which handles transparency and z-depth.
Only 1 thing: when I use this version of the transparent surface shader, the outlines of my sprites are totally visible. How can I fix that? I tried removing ColorMask 0
but that turned the edges black.
Thanks!
is this possible with surface shaders at all ? i cant quite figure it out
Hi everyone,
is there any way to replicate this in URP? These solutions work flawlessly with the Builtin renderer but is it possible to convert them to the new Render Pipelines?
I’ve been reading about issues with OIT (Order Independent Transparency) and also found this thread:
which is basically similar to this one, but I can’t believe there’s not an easy way to do the same in URP.
Thanks in advance.
Yes, really keen to implement this in URP. Any advice?