콘텐츠로 건너뛰기

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 블로거가 이것을 좋아합니다: