Req: Specularity from Spherical Harmonics

Hi, really enjoy your shaders and they are certainly a fantastic improvement over the standard Unity Shaders (Especially since the Unity standard shader lacks any specular occlusion).

With that said I have a feature request, I noticed that when using your shader, probe-lit materials missed out on specular lobes from dominant light directions in the bake. You can bring it back by computing a specular term similar to how you are computing a specular term for light maps by adding the L1 bands of the spherical harmonic data and essentially using it to get the dominant direction of light from it. Here is a code snippet from an ubershader I'm writing.

Note: It's also worth mentioning this could be extended as well to work with Light Probe Proxy Volumes (LPPV) as you also have alot more data to work with in that instance.

//sample the given ambient probe for the material.
//this ambient probe depending on what it is, is either a lightprobe, or a regular ambient skybox probe.
float3 sphericalHarmonicsColor = ShadeSH9(float4(vector_normalDirection, 1.0));

//add the L1 bands from the spherical harmonics probe to get our direction.
float3 sphericalHarmonicsL1_direction = unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz;

//recalculate our own vector and dot products using the dominant direction from the spherical harmonics as the "light direction"
float sphericalHarmonics_NdotL = saturate(dot(vector_normalDirection, sphericalHarmonicsL1_direction));
float3 sphericalHarmonics_halfDirection = normalize(vector_viewDirection + sphericalHarmonicsL1_direction);
float sphericalHarmonics_NdotH = saturate(dot(vector_normalDirection, sphericalHarmonics_halfDirection));
float sphericalHarmonics_LdotH = saturate(dot(sphericalHarmonicsL1_direction, sphericalHarmonics_halfDirection));

//use our new vector and dot products to calculate new specular visibility, distribution, and fresnel terms using dominant spherical harmonic direction.
float sphericalHarmonics_specularVisibility = V_SmithGGXCorrelatedFast(NdotV, sphericalHarmonics_NdotL, roughness);
float sphericalHarmonics_specularDistribution = D_GGX(roughness, sphericalHarmonics_NdotH, vector_normalDirection, sphericalHarmonics_halfDirection);
float3 sphericalHarmonics_specularFresnel = F_Schlick(sphericalHarmonics_LdotH, f0);
float3 sphericalHarmonicsL1_specular = sphericalHarmonics_NdotL * (sphericalHarmonics_specularVisibility * sphericalHarmonics_specularDistribution) * sphericalHarmonics_specularFresnel * sphericalHarmonicsColor;

As a quick showcase here is an example from a custom uber shader I'm writing. The sphere on the left is lightmapped and computes a specular lobe from the lightmap direction, the sphere on the right is probe-lit only and computes a specular lobe from the dominant direction of the spherical harmonics. Both look very similar.

Unity_8FLLYOgiYc

Would certainly help add an extra zing to probe lit objects :P

Edited by David Matos