Making Surface Shader without needing normal component

I want to make a surface shader that doesn’t need normal input from mesh.

Basically I want to use mesh without normal information (because I don’t need it) and use surface shader to make shader for it.

But no matter what I try to do , surface shader always seems to require normal component as input. If I don’t supply normal , then it Unity complains that shader needs normal but mesh doesn’t have it.

I can use vertex and fragment cg shader to archive this, but I really wish to know if this is possible using surface shader.

Thanks!

There is no reason to use a surface shader if you don’t want to create a surface (something that depends on the surface and structure of the mesh and the surounding environment like light interaction which requires normals and which is the ‘minimum’ surface shaders will offer).
Surface shaders add a pretty major overhead at no gain in such a case.

mind if I ask what you are trying to achieve that will not interact with lights and not care about the mesh they are on? Perhaps there is something not taken into account yet that will require the normal anyway or something that points towards them being unsuitable independent of the case.

You don’t need to use surface shaders for cross platform targeting btw, cg will have this benefit as well

I am creating series of shader that is going to be used for effects.

Our platform is truly diverse and in my experience, surface shader does the best job of cross platform compatibility.

CG is ok… but not as good as surface shader especially when it comes down to the console implementation.

CG will work fine for consoles, you just have to ensure you give the full semantics for your vertex info otherwise 360 will complain.

In my experience, some CG shaders work for Xbox 360 but not on PS3 and vice versa. But then again even default shaders in Unity doesn’t always work on consoles so maybe this can’t be helped…

But I think if surface shader can have flexible custom input then it will be more useful.

I also would like this

My use case is for a shader that uses a lightmap for lighting (the normal has already been considered in making the color of the lightmap, so it isn’t needed anymore). I still need the DecodeLightmap function, which I think implies that a surfaceshader is needed (but I might be wrong here).

DecodeLightmap is a function that’s included in UnityCG.cginc - you don’t need to use a surface shader to use it.

Add a vertex modifier to your surface shader and overwrite the vertex normal. This way the shader compiler throws out the normal input register and the shader no longer requests it.

eg:

#pragma surface surf Lambert vertex:vert

void vert (inout appdata_full v)
{
  v.normal = 0;
}

This actually is useful for surface shaders as surface shaders have some useful features even when not calculating lighting. eg decal:blend working in deferred and forward without much work and does not really require normals as it simply reuses the lighting of the underlying geometry. I bake pretty big meshes each frame and baking normals would take a lot of additional resources I do not use in the shader.

Instead of setting the normal to zero you could eg use an object space normal map in the fragment shaderm have a fixed normal direction or sample the normals from a displacement map.