ue4 采样cubemap



float4 GetSphereCaptureVector(float3 ReflectionVector, float3 WorldPosition, float4 CapturePositionAndRadius) { float4 ProjectedCaptureVector; ProjectedCaptureVector.w
= 0; ProjectedCaptureVector.xyz = ReflectionVector; float3 RayDirection = ReflectionVector; float ProjectionSphereRadius = CapturePositionAndRadius.w * 1.2f; float SphereRadiusSquared = ProjectionSphereRadius * ProjectionSphereRadius; float3 ReceiverToSphereCenter = WorldPosition - CapturePositionAndRadius.xyz; float ReceiverToSphereCenterSq = dot(ReceiverToSphereCenter, ReceiverToSphereCenter); float3 CaptureVector = WorldPosition - CapturePositionAndRadius.xyz; float CaptureVectorLength = sqrt(dot(CaptureVector, CaptureVector)); float NormalizedDistanceToCapture = saturate(CaptureVectorLength / CapturePositionAndRadius.w); // Find the intersection between the ray along the reflection vector and the capture's sphere float3 QuadraticCoef; QuadraticCoef.x = 1; QuadraticCoef.y = 2 * dot(RayDirection, ReceiverToSphereCenter); QuadraticCoef.z = ReceiverToSphereCenterSq - SphereRadiusSquared; float Determinant = QuadraticCoef.y * QuadraticCoef.y - 4 * QuadraticCoef.z; BRANCH // Only continue if the ray intersects the sphere if (Determinant >= 0) { float FarIntersection = (sqrt(Determinant) - QuadraticCoef.y) * 0.5; float3 IntersectPosition = WorldPosition + FarIntersection * RayDirection; ProjectedCaptureVector.xyz = IntersectPosition - CapturePositionAndRadius.xyz; // Fade out based on distance to capture ProjectedCaptureVector.w = 1.0 - smoothstep(.6, 1, NormalizedDistanceToCapture); } return ProjectedCaptureVector; }

MobileBasePassPixelShader.usf文件里 SpecularIBL的计算:

// Environment map has been prenormalized, scale by lightmap luminance
            half3 SpecularIBL = GetImageBasedReflectionLighting(MaterialParameters, Roughness) * IndirectIrradiance;

 

 

 

    
half3 GetImageBasedReflectionLighting(FMaterialPixelParameters MaterialParameters, half Roughness)
{
#if HQ_REFLECTIONS
    half3 SpecularIBL = BlendReflectionCaptures(MaterialParameters, Roughness);
#else

    half3 ProjectedCaptureVector = MaterialParameters.ReflectionVector;    

    half UsingSkyReflection = MobileReflectionParams.w > 0;
    half CubemapMaxMip = UsingSkyReflection ? MobileReflectionParams.w : ResolvedView.ReflectionCubemapMaxMip;

    // Compute fractional mip from roughness
    half AbsoluteSpecularMip = ComputeReflectionCaptureMipFromRoughness(Roughness, CubemapMaxMip);
    // Fetch from cubemap and convert to linear HDR
    half3 SpecularIBL;
    half4 SpecularIBLSample = ReflectionCubemap.SampleLevel(ReflectionCubemapSampler, ProjectedCaptureVector, AbsoluteSpecularMip);
    if (UsingSkyReflection)
    {
        SpecularIBL = SpecularIBLSample.rgb;
        // Apply sky colour if the reflection map is the sky.
        SpecularIBL *= ResolvedView.SkyLightColor.rgb;
    }
    else
    {
        SpecularIBL = RGBMDecode(SpecularIBLSample, 16.0);
        SpecularIBL = SpecularIBL * SpecularIBL;
        #if LQ_TEXTURE_LIGHTMAP || CACHED_POINT_INDIRECT_LIGHTING
            // divide by average brightness for lightmap use cases only.
            SpecularIBL *= MobileReflectionParams.x;
        #endif
    }

#endif
    
#if WEBGL
    // need a rgb swizzle instead of the existing rgba swizzle, we should add it if another use case comes up. 
    return SpecularIBL.bgr;
#else
    return SpecularIBL;
#endif
}

 

 

half3 BlendReflectionCaptures(FMaterialPixelParameters MaterialParameters, half Roughness)
{
    // Compute fractional mip from roughness
    half AbsoluteSpecularMip = ComputeReflectionCaptureMipFromRoughness(Roughness, ResolvedView.ReflectionCubemapMaxMip);

    half3 SpecularIBL = half3(0, 0, 0);
    half BlendFactor = 1;

    SpecularIBL += BlendReflectionCapture(MaterialParameters, Roughness, ReflectionCubemap0, ReflectionCubemapSampler0, AbsoluteSpecularMip, 0, ReflectionInvAverageBrigtness.x, BlendFactor);
    SpecularIBL += BlendReflectionCapture(MaterialParameters, Roughness, ReflectionCubemap1, ReflectionCubemapSampler1, AbsoluteSpecularMip, 1, ReflectionInvAverageBrigtness.y, BlendFactor);
    SpecularIBL += BlendReflectionCapture(MaterialParameters, Roughness, ReflectionCubemap2, ReflectionCubemapSampler2, AbsoluteSpecularMip, 2, ReflectionInvAverageBrigtness.z, BlendFactor);

    return SpecularIBL;
}

 

 

half3 BlendReflectionCapture(FMaterialPixelParameters MaterialParameters, half Roughness, TextureCube ReflectionCube, SamplerState ReflectionSampler, half MipLevel, int ReflectionIndex, half InvReflectionCubemapAverageBrightness, inout half BlendFactor)
{
    half4 ProjectedCaptureVector;
#if ALLOW_CUBE_REFLECTIONS
    if (CaptureBoxScalesArray[ReflectionIndex].w > 0)
    {
        ProjectedCaptureVector = GetBoxCaptureVector(MaterialParameters.ReflectionVector, MaterialParameters.AbsoluteWorldPosition, ReflectionPositionsAndRadii[ReflectionIndex], CaptureBoxTransformArray[ReflectionIndex], CaptureBoxScalesArray[ReflectionIndex]);
    }
    else
#endif
    {
        ProjectedCaptureVector = GetSphereCaptureVector(MaterialParameters.ReflectionVector, MaterialParameters.AbsoluteWorldPosition, ReflectionPositionsAndRadii[ReflectionIndex]);
    }

    // Fetch from cubemap and convert to linear HDR
    float4 Reflection = ReflectionCube.SampleLevel(ReflectionSampler, ProjectedCaptureVector.xyz, MipLevel);
    half3 SpecularIBL = RGBMDecode(Reflection, 16.0f);

#if !LQ_TEXTURE_LIGHTMAP && !CACHED_POINT_INDIRECT_LIGHTING
    // ignore average brightness for non-lightmap use case.
    InvReflectionCubemapAverageBrightness = 1.0f;
#endif

    SpecularIBL = SpecularIBL * SpecularIBL * (InvReflectionCubemapAverageBrightness * ProjectedCaptureVector.w * BlendFactor);

    BlendFactor = BlendFactor * (1.0 - ProjectedCaptureVector.w);
    return SpecularIBL;
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM