Energy conserved specular blinn-phong implementation record

Elements of Implementations

  • Energy conserved diffuse with specular.
  • Physically based Fresnel.
  • Environments Reflectance.
  • Ambient lighting adjustment controller.

Energy conserved diffuse with specular.

about energy conserved specular.

Method of Simple energy calculations of shader.
Applied Energy Conservation of blinn-phong specular.
half3 LightingSpecularExtend(half3 lightColor, 
half3 lightDir, 
half3 normal, 
half3 viewDir, 
half4 specular, 
half smoothness)
{
     float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
     half NdotH = saturate(dot(normal, halfVec)) ; //specualrDot
     half VdotH = saturate(dot(viewDir,halfVec)); //FresnelDot
     half LdotH = saturate(dot(lightDir,halfVec));
              
     half modifier = 0;
     //http://www.farbrausch.de/~fg/articles/phong.pdf
     half norm = (smoothness + 2)*(smoothness + 4 ) / ((8 * PI )*(2-(smoothness/2) + smoothness)); 
#ifdef _ENERGY_CONSERVED_BLINNPHONG
     modifier = pow(NdotH, smoothness) * norm * F0Method(VdotH,LdotH,_f0,smoothness);
#else
     modifier = pow(NdotH, smoothness) * F0Method(VdotH,LdotH,_f0,smoothness);
#endif
     half3 specularReflection = specular.rgb * modifier;
     return lightColor * specularReflection;
}

Energy conserved experimental code block.


Simulate of Specular Reflectance

Applied Ambient Contrast
half3 GlossyEnvironmentReflectionExt(half3 reflectVector, half smoothness, half occlusion)
            {
            #if !defined(_ENVIRONMENTREFLECTIONS_OFF)
                half mip = smoothness;
                half4 encodedIrradiance = SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip);
            
            #if !defined(UNITY_USE_NATIVE_HDR)
                half3 irradiance = DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR);
            #else
                half3 irradiance = encodedIrradiance.rbg;
            #endif
            
                return irradiance * occlusion;
            #endif // GLOSSY_REFLECTIONS
                return _GlossyEnvironmentColor.rgb * occlusion;
            }

half4 UniversalFragmentBlinnPhongExtend(InputData inputData, half3 reflectVector,  half3 diffuse, half4 specularGloss, half smoothness, half reflectionRoughness,  half3 emission, half occlusion,half alpha)
            {
                
                Light mainLight = GetMainLight(inputData.shadowCoord);
                MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
            
                half3 attenuatedLightColor = mainLight.color * (mainLight.distanceAttenuation * mainLight.shadowAttenuation);
                half3 diffuseColor = 1;
            
                diffuseColor = inputData.bakedGI + LightingLambertExt(attenuatedLightColor, mainLight.direction, inputData.normalWS);
                diffuseColor *=occlusion;
                half3 specularColor = LightingSpecularExtend(attenuatedLightColor, mainLight.direction, inputData.normalWS, inputData.viewDirectionWS, specularGloss, smoothness);
                diffuseColor +=GlossyEnvironmentReflectionExt(reflectVector, reflectionRoughness, occlusion);
            #ifdef _ADDITIONAL_LIGHTS
                uint pixelLightCount = GetAdditionalLightsCount();
                for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
                {
                    Light light = GetAdditionalLight(lightIndex, inputData.positionWS);
                    half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
                    diffuseColor += LightingLambertExt(attenuatedLightColor, light.direction, inputData.normalWS);
                    specularColor += LightingSpecularExtend(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, specularGloss, smoothness);

                }
            #endif
            
            #ifdef _ADDITIONAL_LIGHTS_VERTEX
                diffuseColor += inputData.vertexLighting;
            #endif
                half3 finalColor = diffuseColor * diffuse + emission;
            
            #if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
                finalColor += specularColor;
            #endif
                
                return half4(finalColor, alpha);
            }

Specular Reflectance experimental code block.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s