// This shader fills the mesh shape with a color that a user can change using the // Inspector window on a Material. Shader "Example/Disintegration" { // The _BaseColor variable is visible in the Material's Inspector, as a field // called Base Color. You can use it to select a custom color. This variable // has the default value (1, 1, 1, 1). Properties { _MainTex ("Texture", 2D) = "white" {} _Color("Color", Color) = (1, 1, 1, 1) [HDR]_AmbientColor("Ambient Color", Color) = (0.4,0.4,0.4,1) _BumpMap("Normal Map", 2D) = "bump" {} _BumpStr("Normal Map Strenght", float) = 1 _FlowMap("Flow (RG)", 2D) = "black" {} _DissolveTexture("Dissolve Texutre", 2D) = "white" {} _DissolveColor("Dissolve Color Border", Color) = (1, 1, 1, 1) _DissolveBorder("Dissolve Border", float) = 0.05 _Exapnd("Expand", float) = 1 _Weight("Weight", Range(0,1)) = 0 _Direction("Direction", Vector) = (0, 0, 0, 0) [HDR]_DisintegrationColor("Disintegration Color", Color) = (1, 1, 1, 1) _Glow("Glow", float) = 1 _Shape("Shape Texutre", 2D) = "white" {} _R("Radius", float) = .1 } SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalRenderPipeline" } Pass { HLSLPROGRAM #pragma vertex vert #pragma geometry geom #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // #include "UnityCG.cginc" struct Attributes { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; }; struct Varyings { float4 objPos : SV_POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; float3 worldPos : TEXCOORD1; }; struct g2f { float4 worldPos : SV_POSITION; float2 uv : TEXCOORD0; half4 color : COLOR; float3 normal : NORMAL; }; // This macro declares _BaseMap as a Texture2D object. TEXTURE2D(_MainTex); // This macro declares the sampler for the _BaseMap texture. SAMPLER(sampler_MainTex); // To make the Unity shader SRP Batcher compatible, declare all // properties related to a Material in a a single CBUFFER block with // the name UnityPerMaterial. CBUFFER_START(UnityPerMaterial) // sampler2D _MainTex; float4 _MainTex_ST; float4 _Color; float4 _AmbientColor; sampler2D _BumpMap; float _BumpStr; float _Metallic; sampler2D _FlowMap; float4 _FlowMap_ST; sampler2D _DissolveTexture; float4 _DissolveColor; float _DissolveBorder; float _Exapnd; float _Weight; float4 _Direction; float4 _DisintegrationColor; float _Glow; sampler2D _Shape; float _R; CBUFFER_END float remap(float value, float from1, float to1, float from2, float to2) { return (value - from1) / (to1 - from1) * (to2 - from2) + from2; } float4 remapFlowTexture(float4 tex) { return float4( remap(tex.x, 0, 1, -1, 1), remap(tex.y, 0, 1, -1, 1), 0, remap(tex.w, 0, 1, -1, 1) ); } Varyings vert(Attributes IN) { Varyings OUT; OUT.objPos = IN.vertex; OUT.uv = IN.uv; OUT.normal = TransformObjectToWorldNormal(IN.normal); OUT.worldPos = mul(unity_ObjectToWorld, IN.vertex).xyz; return OUT; } [maxvertexcount(7)] void geom(triangle Varyings IN[3], inout TriangleStream triStream) { float2 avgUV = (IN[0].uv + IN[1].uv + IN[2].uv) / 3; float3 avgPos = (IN[0].objPos + IN[1].objPos + IN[2].objPos) / 3; float3 avgNormal = (IN[0].normal + IN[1].normal + IN[2].normal) / 3; float dissolve_value = tex2Dlod(_DissolveTexture, float4(avgUV, 0, 0)).r; float t = clamp(_Weight * 2 - dissolve_value, 0, 1); float2 flowUV = TRANSFORM_TEX(mul(unity_ObjectToWorld, avgPos).xz, _FlowMap); float4 flowVector = remapFlowTexture(tex2Dlod(_FlowMap, float4(flowUV, 0, 0))); float3 pseudoRandomPos = (avgPos) + _Direction; pseudoRandomPos += (flowVector.xyz * _Exapnd); float3 p = lerp(avgPos, pseudoRandomPos, t); float radius = lerp(_R, 0, t); if (t > 0) { float3 look = _WorldSpaceCameraPos - p; look = normalize(look); float3 right = UNITY_MATRIX_IT_MV[0].xyz; float3 up = UNITY_MATRIX_IT_MV[1].xyz; float halfS = 0.5f * radius; float4 v[4]; v[0] = float4(p + halfS * right - halfS * up, 1.0f); v[1] = float4(p + halfS * right + halfS * up, 1.0f); v[2] = float4(p - halfS * right - halfS * up, 1.0f); v[3] = float4(p - halfS * right + halfS * up, 1.0f); g2f vert; vert.worldPos = TransformObjectToHClip(v[0]); vert.uv = mul(float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), float2(1.0f, 0.0f)); vert.color = float4(1, 1, 1, 1); vert.normal = avgNormal; triStream.Append(vert); vert.worldPos = TransformObjectToHClip(v[1]); vert.uv = mul(float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), float2(1.0f, 1.0f)); vert.color = float4(1, 1, 1, 1); vert.normal = avgNormal; triStream.Append(vert); vert.worldPos = TransformObjectToHClip(v[2]); vert.uv = mul(float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), float2(0.0f, 0.0f)); vert.color = float4(1, 1, 1, 1); vert.normal = avgNormal; triStream.Append(vert); vert.worldPos = TransformObjectToHClip(v[3]); vert.uv = mul(float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), float2(0.0f, 1.0f)); vert.color = float4(1, 1, 1, 1); vert.normal = avgNormal; triStream.Append(vert); triStream.RestartStrip(); } for (int j = 0; j < 3; j++) { g2f o; o.worldPos = TransformObjectToHClip(IN[j].objPos); o.uv = TRANSFORM_TEX(IN[j].uv, _MainTex); o.color = half4(0, 0, 0, 0); o.normal = IN[j].normal; triStream.Append(o); } triStream.RestartStrip(); } half4 frag(Varyings IN) : SV_Target { half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv); return color; } ENDHLSL } } }