But most of our custom shaders are written in surface shader and tagging surface shader does not work. I wonder is there a way to tag all the fragment shader functions generated by surface shader.
Unity doesn’t use Cg, it’s all HLSL, regardless of what the CGPROGRAM blocks and and .cginc file extensions may make you think. Cg itself got removed from Unity many, many years ago. It’s only due to legacy naming conventions and shaders that they still use with “cg” in their name. The newer Post Processing stack and SRPs all use HLSLPROGRAM and .hlsl file extension names, but there’s no functional difference.
And no. There’s no way to do this for Surface Shaders while leaving them in their Surface Shader form. The only solution is to convert all of those shaders into vertex fragment shaders and modify them there. Luckily you can do that by selecting a Surface Shader and clicking on “Show Generated Code”, then copy and paste that over the original shader. The generated shaders are ugly, and a pain to work with, but that’s the actual shader code Unity is using.
This surprised me a lot, as a person who still go back to Nvidia Cg API website looking up how to call lerp or saturate. So the reason I did not run into any wall is that Cg mimics HLSL API which makes the transition is unnoticeable?
Yep, for the most part Cg and Direct3D 9 HLSL are the same. There are a handful of functions that are different, or which only exist in one or the other, but the most common ones are the same.