You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown nick.penwarden #rb nobody ========================== MAJOR FEATURES + CHANGES ========================== Change2945508on 2016/04/15 by Nick.Whiting Integrating fix for module loading for SteamVR, prevents crashing in race conditions Change 2950385 on 2016/04/20 by Ryan.Vance We need to test if the hmd is enabled if it exists. Otherwise, this will return true even if we aren't rendering in stereo if there's an hmd plugin loaded. Change2955406on 2016/04/25 by Chad.Taylor Factor scale into the motion controller component late update Change 2956275 on 2016/04/26 by Nick.Whiting Initial integration of OSVR plugin support #pr 2097 Change 2964412 on 2016/05/03 by Chad.Taylor PSVR's GetControllerOrientationAndPosition now returns false if status is NOT_STARTED or CALIBRATING Change 2964612 on 2016/05/03 by Ryan.Vance Copying //UE4/Dev-VR-InstancedStereo to Dev-VR-Minimal (//UE4/Dev-VR-Minimal) Change 2985528 on 2016/05/20 by Ryan.Vance #jira UE-30715 Keep from spamming the output log for every single shader compile when instanced stereo is enabled for a shader platform that doesn't support it. Change 2986246 on 2016/05/22 by Chad.Taylor HMD late-update thread safety Change 2998629 on 2016/06/02 by Ryan.Vance Post 4.12 Oculus plugin integration Change 3000057 on 2016/06/03 by Ryan.Vance Updating serialize function for custom material nodes. The instanced stereo refactor moved Frame uniforms *back* to View (post 4.11). This should update only objects that went through the prior transformation from View *to* Frame. The serialize function was also being used to update Parameters.WorldPosition to Parameters.AbsoluteWorldPosition. This should still run as expected. Change 3002187 on 2016/06/06 by Ryan.Vance Switching from ._m syntax to array syntax. The cross compiler chokes on the former. Change 3004153 on 2016/06/07 by Chad.Taylor Enable PSVR on VS2015 #jira UE-31202 Change 3009958 on 2016/06/10 by Ryan.Vance #jira UE-31922 Velocity and depth pre-pass for dynamic instanced meshes with isr was only rendering in the left eye. Need to loop over the draw call the same way we do for the base pass. Change 3011054 on 2016/06/13 by Chad.Taylor Merging "SteamVR Positional Late-Update" back into Dev-VR Change 3013361 on 2016/06/14 by Ryan.Vance #jira UE-32022 Fixing dbuffer decal integration errors. [CL 3018810 by Ryan Vance in Main branch]
201 lines
8.9 KiB
Plaintext
201 lines
8.9 KiB
Plaintext
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
ReflectionEnvironmentShared
|
|
=============================================================================*/
|
|
|
|
#define REFLECTION_CAPTURE_ROUGHEST_MIP 1
|
|
#define REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE 1.2
|
|
|
|
/**
|
|
* Compute absolute mip for a reflection capture cubemap given a roughness.
|
|
*/
|
|
half ComputeReflectionCaptureMipFromRoughness(half Roughness, half CubemapMaxMip)
|
|
{
|
|
// Heuristic that maps roughness to mip level
|
|
// This is done in a way such that a certain mip level will always have the same roughness, regardless of how many mips are in the texture
|
|
// Using more mips in the cubemap just allows sharper reflections to be supported
|
|
half LevelFrom1x1 = REFLECTION_CAPTURE_ROUGHEST_MIP - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(Roughness);
|
|
return CubemapMaxMip - 1 - LevelFrom1x1;
|
|
}
|
|
|
|
float ComputeReflectionCaptureRoughnessFromMip(float Mip, half CubemapMaxMip)
|
|
{
|
|
float LevelFrom1x1 = CubemapMaxMip - 1 - Mip;
|
|
return exp2( ( REFLECTION_CAPTURE_ROUGHEST_MIP - LevelFrom1x1 ) / REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE );
|
|
}
|
|
|
|
TextureCube SkyLightCubemap;
|
|
SamplerState SkyLightCubemapSampler;
|
|
|
|
/** X = max mip, Y = 1 if sky light should be rendered, 0 otherwise, Z = 1 if sky light is dynamic, 0 otherwise, W = blend fraction. */
|
|
float4 SkyLightParameters;
|
|
|
|
float3 GetSkyLightReflection(float3 ReflectionVector, float Roughness, bool bNormalized)
|
|
{
|
|
float AbsoluteSpecularMip = ComputeReflectionCaptureMipFromRoughness(Roughness, SkyLightParameters.x);
|
|
float3 Reflection = TextureCubeSampleLevel(SkyLightCubemap, SkyLightCubemapSampler, ReflectionVector, AbsoluteSpecularMip).rgb;
|
|
|
|
BRANCH
|
|
if (bNormalized)
|
|
{
|
|
// Sample the lowest resolution mip to get the average color
|
|
//@todo - can't normalize sky lighting and reflection capture lighting separately
|
|
float3 LowFrequencyReflection = TextureCubeSampleLevel(SkyLightCubemap, SkyLightCubemapSampler, ReflectionVector, SkyLightParameters.x).rgb;
|
|
float LowFrequencyBrightness = Luminance(LowFrequencyReflection);
|
|
Reflection /= max(LowFrequencyBrightness, .00001f);
|
|
}
|
|
|
|
return Reflection * View.SkyLightColor.rgb;
|
|
}
|
|
|
|
TextureCube SkyLightBlendDestinationCubemap;
|
|
SamplerState SkyLightBlendDestinationCubemapSampler;
|
|
|
|
float3 GetSkyLightReflectionSupportingBlend(float3 ReflectionVector, float Roughness, bool bNormalized)
|
|
{
|
|
float3 Reflection = GetSkyLightReflection(ReflectionVector, Roughness, bNormalized);
|
|
|
|
BRANCH
|
|
if (SkyLightParameters.w > 0)
|
|
{
|
|
float AbsoluteSpecularMip = ComputeReflectionCaptureMipFromRoughness(Roughness, SkyLightParameters.x);
|
|
float3 BlendDestinationReflection = TextureCubeSampleLevel(SkyLightBlendDestinationCubemap, SkyLightBlendDestinationCubemapSampler, ReflectionVector, AbsoluteSpecularMip).rgb;
|
|
|
|
BRANCH
|
|
if (bNormalized)
|
|
{
|
|
// Sample the lowest resolution mip to get the average color
|
|
//@todo - can't normalize sky lighting and reflection capture lighting separately
|
|
float3 LowFrequencyReflection = TextureCubeSampleLevel(SkyLightBlendDestinationCubemap, SkyLightBlendDestinationCubemapSampler, ReflectionVector, SkyLightParameters.x).rgb;
|
|
float LowFrequencyBrightness = Luminance(LowFrequencyReflection);
|
|
BlendDestinationReflection /= max(LowFrequencyBrightness, .00001f);
|
|
}
|
|
|
|
Reflection = lerp(Reflection, BlendDestinationReflection * View.SkyLightColor.rgb, SkyLightParameters.w);
|
|
}
|
|
|
|
return Reflection;
|
|
}
|
|
|
|
/**
|
|
* Computes sky diffuse lighting from the SH irradiance map.
|
|
* This has the SH basis evaluation and diffuse convolusion weights combined for minimal ALU's - see "Stupid Spherical Harmonics (SH) Tricks"
|
|
*/
|
|
float3 GetSkySHDiffuse(float3 Normal)
|
|
{
|
|
float4 NormalVector = float4(Normal, 1);
|
|
|
|
float3 Intermediate0, Intermediate1, Intermediate2;
|
|
Intermediate0.x = dot(View.SkyIrradianceEnvironmentMap[0], NormalVector);
|
|
Intermediate0.y = dot(View.SkyIrradianceEnvironmentMap[1], NormalVector);
|
|
Intermediate0.z = dot(View.SkyIrradianceEnvironmentMap[2], NormalVector);
|
|
|
|
float4 vB = NormalVector.xyzz * NormalVector.yzzx;
|
|
Intermediate1.x = dot(View.SkyIrradianceEnvironmentMap[3], vB);
|
|
Intermediate1.y = dot(View.SkyIrradianceEnvironmentMap[4], vB);
|
|
Intermediate1.z = dot(View.SkyIrradianceEnvironmentMap[5], vB);
|
|
|
|
float vC = NormalVector.x * NormalVector.x - NormalVector.y * NormalVector.y;
|
|
Intermediate2 = View.SkyIrradianceEnvironmentMap[6].xyz * vC;
|
|
|
|
// max to not get negative colors
|
|
return max(0, Intermediate0 + Intermediate1 + Intermediate2);
|
|
}
|
|
|
|
/**
|
|
* Computes sky diffuse lighting from the SH irradiance map.
|
|
* This has the SH basis evaluation and diffuse convolusion weights combined for minimal ALU's - see "Stupid Spherical Harmonics (SH) Tricks"
|
|
* Only does the first 3 components for speed.
|
|
*/
|
|
float3 GetSkySHDiffuseSimple(float3 Normal)
|
|
{
|
|
float4 NormalVector = float4(Normal, 1);
|
|
|
|
float3 Intermediate0;
|
|
Intermediate0.x = dot(View.SkyIrradianceEnvironmentMap[0], NormalVector);
|
|
Intermediate0.y = dot(View.SkyIrradianceEnvironmentMap[1], NormalVector);
|
|
Intermediate0.z = dot(View.SkyIrradianceEnvironmentMap[2], NormalVector);
|
|
|
|
// max to not get negative colors
|
|
return max(0, Intermediate0);
|
|
}
|
|
|
|
|
|
// Point lobe in off-specular peak direction
|
|
float3 GetOffSpecularPeakReflectionDir(float3 Normal, float3 ReflectionVector, float Roughness)
|
|
{
|
|
float a = Square(Roughness);
|
|
return lerp( Normal, ReflectionVector, (1 - a) * ( sqrt(1 - a) + a ) );
|
|
}
|
|
|
|
float GetSpecularOcclusion(float NoV, float RoughnessSq, float AO)
|
|
{
|
|
return saturate( pow( NoV + AO, RoughnessSq ) - 1 + AO );
|
|
}
|
|
|
|
float3 GetLookupVectorForBoxCapture(float3 ReflectionVector, float3 WorldPosition, float4 BoxCapturePositionAndRadius, float4x4 BoxTransform, float4 BoxScales, float3 LocalCaptureOffset, out float DistanceAlpha)
|
|
{
|
|
// Transform the ray into the local space of the box, where it is an AABB with mins at -1 and maxs at 1
|
|
float3 LocalRayStart = mul(float4(WorldPosition, 1), BoxTransform).xyz;
|
|
float3 LocalRayDirection = mul(float4(ReflectionVector, 0), BoxTransform).xyz;
|
|
|
|
float3 InvRayDir = rcp(LocalRayDirection);
|
|
|
|
//find the ray intersection with each of the 3 planes defined by the minimum extrema.
|
|
float3 FirstPlaneIntersections = -InvRayDir - LocalRayStart * InvRayDir;
|
|
//find the ray intersection with each of the 3 planes defined by the maximum extrema.
|
|
float3 SecondPlaneIntersections = InvRayDir - LocalRayStart * InvRayDir;
|
|
//get the furthest of these intersections along the ray
|
|
float3 FurthestPlaneIntersections = max(FirstPlaneIntersections, SecondPlaneIntersections);
|
|
|
|
//clamp the intersections to be between RayOrigin and RayEnd on the ray
|
|
float Intersection = min(FurthestPlaneIntersections.x, min(FurthestPlaneIntersections.y, FurthestPlaneIntersections.z));
|
|
|
|
// Compute the reprojected vector
|
|
float3 IntersectPosition = WorldPosition + Intersection * ReflectionVector;
|
|
float3 ProjectedCaptureVector = IntersectPosition - (BoxCapturePositionAndRadius.xyz + LocalCaptureOffset);
|
|
|
|
// Compute the distance from the receiving pixel to the box for masking
|
|
// Apply local to world scale to take scale into account without transforming back to world space
|
|
// Shrink the box by the transition distance (BoxScales.w) so that the fade happens inside the box influence area
|
|
float BoxDistance = ComputeDistanceFromBoxToPoint(-(BoxScales.xyz - .5f * BoxScales.w), BoxScales.xyz - .5f * BoxScales.w, LocalRayStart * BoxScales.xyz);
|
|
|
|
// Setup a fade based on receiver distance to the box, hides the box influence shape
|
|
DistanceAlpha = 1.0 - smoothstep(0, .7f * BoxScales.w, BoxDistance);
|
|
|
|
return ProjectedCaptureVector;
|
|
}
|
|
|
|
float3 GetLookupVectorForSphereCapture(float3 ReflectionVector, float3 WorldPosition, float4 SphereCapturePositionAndRadius, float NormalizedDistanceToCapture, float3 LocalCaptureOffset, out float DistanceAlpha)
|
|
{
|
|
float3 ProjectedCaptureVector = ReflectionVector;
|
|
float ProjectionSphereRadius = SphereCapturePositionAndRadius.w;
|
|
float SphereRadiusSquared = ProjectionSphereRadius * ProjectionSphereRadius;
|
|
|
|
float3 LocalPosition = WorldPosition - SphereCapturePositionAndRadius.xyz;
|
|
float LocalPositionSqr = dot(LocalPosition, LocalPosition);
|
|
|
|
// Find the intersection between the ray along the reflection vector and the capture's sphere
|
|
float3 QuadraticCoef;
|
|
QuadraticCoef.x = 1;
|
|
QuadraticCoef.y = dot(ReflectionVector, LocalPosition);
|
|
QuadraticCoef.z = LocalPositionSqr - SphereRadiusSquared;
|
|
|
|
float Determinant = QuadraticCoef.y * QuadraticCoef.y - QuadraticCoef.z;
|
|
|
|
// Only continue if the ray intersects the sphere
|
|
//if (Determinant >= 0)
|
|
{
|
|
float FarIntersection = sqrt(Determinant) - QuadraticCoef.y;
|
|
|
|
float3 LocalIntersectionPosition = LocalPosition + FarIntersection * ReflectionVector;
|
|
ProjectedCaptureVector = LocalIntersectionPosition - LocalCaptureOffset;
|
|
// Note: some compilers don't handle smoothstep min > max (this was 1, .6)
|
|
//DistanceAlpha = 1.0 - smoothstep(.6, 1, NormalizedDistanceToCapture);
|
|
|
|
float x = saturate( 2.5 * NormalizedDistanceToCapture - 1.5 );
|
|
DistanceAlpha = 1 - x*x*(3 - 2*x);
|
|
}
|
|
return ProjectedCaptureVector;
|
|
} |