I made a fairly simple shader based on the normal extrusion example. I’m using it to make objects glow. First of all, here’s what it looks like:
This is doing mostly what I want, with the shader growing the mesh. However, I don’t like that any overlapping portions of the mesh get drawn multiple times, resulting in the extra saturated overlap.
I looked into this, searching for “ghost” shader examples. They all recommend a two-pass approach, where the first pass just writes to the z-buffer. But so far none of the additional passes I’ve tries has worked.
Here’s my shader as it works in the GIF above. I tried a first pass vert function, which had the same logic as the vert function I’m showing here, but it doesn’t seem to work the same way in an initial pass as it does in the second pass. Curious if anyone knows how I can avoid the overlapping rendering.
Thanks.
Shader "Gravia/MeshGlow" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Speed ("Speed", Range(0,10)) = 1.5
_EmissionStrength ("Emission Strength", Range(0,10)) = 1
_MaxThickness ("Max Thickness", Range(0,2)) = .2
_MaxOpacity ("Max Opacity", Range(0,1)) = .5
}
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert alpha vertex:vert
#pragma target 3.0
#define M_PI 3.1415926535897932384626433832795
struct Input {
float2 uv_MainTex;
};
fixed4 _Color;
sampler2D _MainTex;
half _MaxThickness;
half _MaxOpacity;
half _EmissionStrength;
half _Speed;
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Emission = c.rgb * _EmissionStrength;
half opacity = (sin(_Time.y * _Speed * M_PI) * 0.5 + 0.5) * _MaxOpacity;
o.Alpha = opacity;
}
void vert (inout appdata_full v) {
half frequency = M_PI * _Speed;
// This looks a little silly, but the it's based on this calc:
// https://docs.google.com/spreadsheets/d/18_hKrlclQRlf9N_XlgSZ0R5TkeLchvE7RSyeGyl8E5o/edit?usp=drive_web&ouid=114159308504791951085
// I had to replace x % y with (x / y) % 1 because shader logic doesn't allow fractional mod.
half thicknessModifier = frac((((frequency) * _Time.y + (M_PI / 2)) * _Speed / 2) / (frequency)) / (frequency);
v.vertex.xyz += normalize(v.normal) * thicknessModifier * _MaxThickness;
}
ENDCG
}
FallBack "Diffuse"
}