콘텐츠로 건너뛰기

Horizon Occlusion ( Horizon Occlusion for Normal Mapped Reflections )

Horizon Occlusion for Normal Mapped Reflections

When rendering reflective surfaces with normal maps, something often goes wrong. With just about any normal map this happens quite a bit – the reflection vector ends up pointing behind the surface being rendered. If this vector is then used for shading, a surface can end up receiving light that should never have reached it. This is mitigated sometimes by shadow mapping or other occlusion terms, but in the case of image-based lighting it can be especially tricky to avoid this kind of “light leaking”. Here is a sphere lit with a single environment map that illustrates the problem well.

//Uber Inputs.hlsl //Adding this property _HorizonOcclusion ("Horizon Occlusion", Range(0,1)) = 0.5
Code language: JavaScript (javascript)
//Uber Lighting.hlsl // Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087 half HorizonOcclusion(half3 R, half3 normalWS, half3 vertexNormal, half horizonFade) { //half3 R = reflect(-V, normalWS); half specularOcclusion = saturate(1.0 + horizonFade * dot(R, vertexNormal)); // smooth it return specularOcclusion * specularOcclusion; } half3 GlobalIllumination(BRDFData brdfData, half3 bakedGI, half occlusion, float3 positionWS, half3 normalWS, half3 viewDirectionWS, half3 geoNormalWS, half horizonOcllusion) { ... // Horizon Occlusion #if defined (_SAMPLENORMAL) && defined(_UBER) reflOcclusion *= LuxGetHorizonOcclusion( reflectVector, normalWS, geoNormalWS, horizonOcllusion); #endif ... } half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, half3 geoNormalWS, half horizonOcllusion) { #if defined(_SPECULARHIGHLIGHTS_OFF) bool specularHighlightsOff = true; #else bool specularHighlightsOff = false; #endif BRDFData brdfData; InitializeBRDFData(surfaceData, brdfData); #if defined(DEBUG_DISPLAY) half4 debugColor; if (CanDebugOverrideOutputColor(inputData, surfaceData, brdfData, debugColor)) { return debugColor; } #endif BRDFData brdfDataClearCoat = (BRDFData)0; half4 shadowMask = CalculateShadowMask(inputData); AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData); uint meshRenderingLayers = GetMeshRenderingLightLayer(); Light mainLight = GetMainLight(inputData, shadowMask, aoFactor); // NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below... MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); LightingData lightingData = CreateLightingData(inputData, surfaceData); // lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask, // inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS, // inputData.normalWS, inputData.viewDirectionWS); lightingData.giColor = GlobalIllumination( brdfData, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS, geoNormalWS, horizonOcllusion );
Code language: PHP (php)
//UberShaderGUI.cs //Adding Find Shader Property inside shader GUI class HorizonOcclusionProp = FindProperty("_HorizonOcclusion", properties);
Code language: JavaScript (javascript)
태그:

댓글 남기기

%d 블로거가 이것을 좋아합니다: