Hello all,
I am trying to create a geometry based dissolve effect I am doing it with a script and a shader.
This is what I have done so far…
Shader "Effects/DissolveWorldSpaceSurface"
{
Properties
{
_MainTex("Diffuse Map",2D)="white"{}
_Specular("Specular",2D)="white"{}
_Normal("Normal Map",2D)="white"{}
_Color("Diffuse Color",COLOR)=(1,1,1,1)
_Rim("Rim Color",Color)=(0,0,1,1)
_Noise("Dissolve Map",2D)="white"{}
_Start("Start Point",Vector)=(0.0,0.0,0.0,0.0)
_End("End Point",Vector)=(0.0,0.0,0.0,0.0)
_DissolveAmount("Dissolve Amount",Float)=1.0
_rimscale("Rim Scale",Range(0.01,5))=1.3
[Toggle(X_AXIS)]
_xAxis("X AXIS",Float)=0.0
[Toggle(Y_AXIS)]
_yAxis("Y AXIS",Float)=0.0
[Toggle(Z_AXIS)]
_zAxis("Z AXIS",Float)=0.0
}
SubShader
{
Tags{"RenderType"="Opaque" "DisableBatching"="true"}
Cull Off
CGPROGRAM
#pragma surface surf StandardSpecular fullforwardshadows vertex:vert
#pragma shaderfeature X_AXIS
#pragma shaderfeature Y_AXIS
#pragma shaderfeature Z_AXIS
#pragma target 3.0
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Specular;
sampler2D _Normal;
sampler2D _Noise;
float3 _Start;
float3 _End;
float3 _disvector;
half _DissolveAmount;
float4 _Color;
float4 _Rim;
half _rimscale;
struct Input
{
float2 uv_MainTex;
float3 Position;
};
void vert(inout appdata_full v,out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input,o);
o.Position=v.vertex.xyz;//mul(unity_ObjectToWorld,v.vertex.xyz);
}
void surf(Input IN,inout SurfaceOutputStandardSpecular o)
{
float4 c = tex2D(_MainTex,IN.uv_MainTex)*_Color;
float4 spec = tex2D(_Specular,IN.uv_MainTex);
float3 dir=normalize(_End-_Start);
half cut = dot(IN.Position,dir);
// #ifdef X_AXIS
// cut=dir.x;
// #endif
// #ifdef Y_AXIS
// cut=dir.y;
// #endif
// #ifdef Z_AXIS
// cut=dir.z;
// #endif
half noise=tex2D(_Noise,IN.uv_MainTex).a;
clip(cut-_DissolveAmount);
o.Albedo = c.rgb;
o.Emission=step(cut - (noise*_rimscale),_DissolveAmount)*_Rim;
o.Specular= spec.rgb;
o.Smoothness=spec.a;
o.Normal=UnpackNormal(tex2D(_Normal,IN.uv_MainTex));
}
ENDCG
}
}
And here is the script I am using to do an Axis based dissolve effect:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DissolveVector : MonoBehaviour
{
public Renderer rend;
[Range(0.0f, 1.0f)]
public float dissolve = 0.0f;
public Transform p0, p1;
public bool xAxis;
public bool yAxis;
public bool zAxis;
public bool invert;
private Vector3 start;
private Vector3 end;
private Bounds bounds;
private Vector3 interpolVec;
private void OnEnable()
{
rend = GetComponent<Renderer>();
bounds = rend.bounds;
}
private void Update()
{
if (xAxis)
{
rend.material.SetFloat("_xAxis", 1.0f);
rend.material.SetFloat("_yAxis", 0.0f);
rend.material.SetFloat("_zAxis", 0.0f);
start = transform.InverseTransformPoint(bounds.center + new Vector3(-bounds.extents.x, 0, 0));
end = transform.InverseTransformPoint(bounds.center + new Vector3(bounds.extents.x, 0, 0));
if (invert)
{
Vector3 temp = end;
end = start;
start = temp;
}
rend.material.SetVector("_Start", new Vector4(start.x, start.y, start.z, 1.0f));
rend.material.SetVector("_End", new Vector4(end.x, end.y, end.z, 1.0f));
interpolVec = Vector3.Lerp(start, end, dissolve);
p0.localPosition = start;
p1.localPosition = end;
float xlerp = interpolVec.x;
rend.material.SetFloat("_DissolveAmount", xlerp);
}
else if (yAxis)
{
rend.material.SetFloat("_yAxis", 1.0f);
rend.material.SetFloat("_xAxis", 0.0f);
rend.material.SetFloat("_zAxis", 0.0f);
start = transform.InverseTransformPoint(bounds.center + new Vector3(0, -bounds.extents.y, 0));
end = transform.InverseTransformPoint(bounds.center + new Vector3(0, bounds.extents.y, 0));
if (invert)
{
Vector3 temp = end;
end = start;
start = temp;
}
rend.material.SetVector("_Start", new Vector4(start.x, start.y, start.z, 1.0f));
rend.material.SetVector("_End", new Vector4(end.x, end.y, end.z, 1.0f));
interpolVec = Vector3.Lerp(start, end, dissolve);
p0.localPosition = start;
p1.localPosition = end;
float ylerp = interpolVec.y;
rend.material.SetFloat("_DissolveAmount", ylerp);
}
else if (zAxis)
{
rend.material.SetFloat("_zAxis", 1.0f);
rend.material.SetFloat("_xAxis", 0.0f);
rend.material.SetFloat("_zAxis", 0.0f);
start = transform.InverseTransformPoint(bounds.center + new Vector3(0, 0, -bounds.extents.z));
end = transform.InverseTransformPoint(bounds.center + new Vector3(0, 0, bounds.extents.z));
if (invert)
{
Vector3 temp = end;
end = start;
start = temp;
}
rend.material.SetVector("_Start", new Vector4(start.x, start.y, start.z, 1.0f));
rend.material.SetVector("_End", new Vector4(end.x, end.y, end.z, 1.0f));
interpolVec = Vector3.Lerp(start, end, dissolve);
p0.localPosition = start;
p1.localPosition = end;
float zlerp = interpolVec.z;
rend.material.SetFloat("_DissolveAmount", zlerp);
}
}
}
This work fine when I check Invert it doesn’t work properly. Also when I am moving my object in checked axis it’s also changes dissolve value.
Can anyone please tell me what I am doing wrong, I am pretty new to shader writing.