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.

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



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.
카테고리:shader