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;
}
知识兔 1
2 half3 GetImageBasedReflectionLighting(FMaterialPixelParameters MaterialParameters, half Roughness)
3 {
4 #if HQ_REFLECTIONS
5 half3 SpecularIBL = BlendReflectionCaptures(MaterialParameters, Roughness);
6 #else
7
8 half3 ProjectedCaptureVector = MaterialParameters.ReflectionVector;
9
10 half UsingSkyReflection = MobileReflectionParams.w > 0;
11 half CubemapMaxMip = UsingSkyReflection ? MobileReflectionParams.w : ResolvedView.ReflectionCubemapMaxMip;
12
13 // Compute fractional mip from roughness
14 half AbsoluteSpecularMip = ComputeReflectionCaptureMipFromRoughness(Roughness, CubemapMaxMip);
15 // Fetch from cubemap and convert to linear HDR
16 half3 SpecularIBL;
17 half4 SpecularIBLSample = ReflectionCubemap.SampleLevel(ReflectionCubemapSampler, ProjectedCaptureVector, AbsoluteSpecularMip);
18 if (UsingSkyReflection)
19 {
20 SpecularIBL = SpecularIBLSample.rgb;
21 // Apply sky colour if the reflection map is the sky.
22 SpecularIBL *= ResolvedView.SkyLightColor.rgb;
23 }
24 else
25 {
26 SpecularIBL = RGBMDecode(SpecularIBLSample, 16.0);
27 SpecularIBL = SpecularIBL * SpecularIBL;
28 #if LQ_TEXTURE_LIGHTMAP || CACHED_POINT_INDIRECT_LIGHTING
29 // divide by average brightness for lightmap use cases only.
30 SpecularIBL *= MobileReflectionParams.x;
31 #endif
32 }
33
34 #endif
35
36 #if WEBGL
37 // need a rgb swizzle instead of the existing rgba swizzle, we should add it if another use case comes up.
38 return SpecularIBL.bgr;
39 #else
40 return SpecularIBL;
41 #endif
42 }
知识兔View Code