Cheapest invisible shader

Hi,

I’m looking for the cheapest shader to make an object completely transparent. I’ve got a mesh that uses two materials, and I need the ability to hide the vertices linked to one of the materials. In vertex lit rendering you can just use a null shader, but in forward rendering a null shader will render the vertices with the default pink color rather than hiding them.

What do you think? Mobile particles additive? Mobile vertex colored simple with 0 alpha?

I use a nothingImage, a image, imported as a png of 64x64 from photoshop. It, in photo shop in an image of nothing. No pixels have been filled with any colour. Then use the 2D Art For the iPhone shader. I have no complaints.

“Completely transparent” isn’t a good way of thinking about it; that’s as about of expensive a thing as you can do. Instead, just don’t do any processing at all:

Shader "Unity's Multi-Material System is Borked" {

Subshader {Pass {	
	GLSLPROGRAM
	#ifdef VERTEX
	void main() {}
	#endif
	
	#ifdef FRAGMENT
	void main() {}
	#endif
	ENDGLSL
}}

Subshader {Pass {
	CGPROGRAM
	#pragma vertex vert
	#pragma fragment frag
	struct v2f {
		fixed4 position : SV_POSITION;
	};
	
	v2f vert() {
		v2f o;
		o.position = fixed4(0,0,0,0);
		return o;
	}
	
	fixed4 frag() : COLOR {
		return fixed4(0,0,0,0);
	}
	ENDCG
}}

}
3 Likes

Thanks renman and Jessy! That’s exactly what I was looking for. I wasn’t sure if you could have a shader that doesn’t process. I assume that’s what a null shader is doing in vertex lit, so I’m glad there’s an official way to do it too. Cheers!

If you set the vertex co-ords to a large number in the vertex shader so that they’lll be off screen, then they triangle won’t get drawn at all.

If you set them all to the same thing as above, then you’ve got a degenerate triangle. Not sure if these will be clipped or not.

Good point. I don’t know what the GLSL vertex shader does, but you could use something better than 0,0,0,0 for the Cg one. Large values aren’t necessary; just make sure they’re outside -1 to 1 (you’re rendering directly in clip space).

So, Jessy’s shader is working fine in the editor, but on my iOS device I’ve got the same purple default shading. Any thoughts?

Not really. Worked for me. You’re not using OpenGL ES 1.x, are you?

I must have had an issue with my shader applying code because it’s working now. Sorry for being ‘that guy.’ Thanks again for the help, Jessy!

Sorry to resurrect, but on my live game I did an update and used this shader. It worked great on my two android phones, however I started getting complete crashes and restarts from people.

With the help of a guy online that was having the issues, I narrowed it down to this invisible shader.

Why in the world does this just cause some devices to crash, and crash hard enough to restart the phone?!

Buggy GPU driver.

Really?!

Well, it was just insane… took me two days of trying to fix other stuff before I narrowed it down to this shader. All of my devices had no issues so it seemed impossible to find the issue.

Now that I think about it though, when I was porting this over to my Mac laptop, it was freezing up on import of this “invisible” material, and I had to keep killing Unity. Must have buggy GPU drivers on my Mac then as well, eh?!

Disclaimer : This is a very advanced shading technique, use with caution. It may or may not set the mobile device in fire. Use at your own risk.

renderer.enabled = false;

2 Likes

Ha ha ha

My meshes have multiple submeshes I want to selectively hide, which can only be done with invisible shader.

Shader "Hide" {
SubShader {
    Pass {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        struct v2f {
            fixed4 position : SV_POSITION;
        };
  
        v2f vert() {
            v2f o;
            o.position = fixed4(0,0,0,0);
            return o;
        }
  
        fixed4 frag() : COLOR {
            returnfixed4(0,0,0,0);
        }
        ENDCG
    }
}
fallback "Diffuse"
}

Anyway, gameObject.SetActive(false) is better I think.

3 Likes

But Unity wants the fragment shader, your example creates two warnings:

Shader warning in ‘Hide’: Shader is not supported on this GPU (none of subshaders/fallbacks are suitable)
Shader warning in ‘Hide’: Both vertex and fragment programs must be present in a CGPROGRAM. Excluding it from compilation. at line 4 (on )

You’re right, fixed.

There is

another solution

which may sometimes be useful in dealing with this problem. And it’s definitely more performant :slight_smile:

I had a case where I had to have a mesh, to get OnWillRenderObject. So I just made a tiny mesh. As in this QA, it was then annoying that you had to have “some sort of” material on it.

However.

I was surprised to learn it’s actually OK it have a “nothing mesh”:

    Mesh TrivialMesh() {

        Mesh mesh = new Mesh();
        return mesh;

        // it is, in fact, ok to have a "null mesh".  WTF right?
    }

You could just set the mesh to the “nothing mesh” when you want the thing invisible.

This would seem to be the most performant approach! :open_mouth:

Hope it helps someone in some unusual case!