2021-09-09 20:42:29 -04:00

122 lines
5.9 KiB
HLSL

#ifndef EYE_UTILS_HLSL
#define EYE_UTILS_HLSL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
void GetScleraUVLocation(float3 positionOS, out float2 scleraUV)
{
scleraUV = positionOS.xy + float2(0.5, 0.5);
}
void GetIrisUVLocation(float3 positionOS, float irisRadius, out float2 irisUV)
{
float2 irisUVCentered = positionOS.xy / irisRadius;
irisUV = (irisUVCentered * 0.5 + float2(0.5, 0.5));
}
void DebugSurfaceType(float3 positionOS, float3 eyeColor, float irisRadius, float pupilRadius, bool active, out float3 surfaceColor)
{
float pixelRadius = length(positionOS.xy);
bool isSclera = pixelRadius > irisRadius;
bool isPupil = !isSclera && length(positionOS.xy / irisRadius) < pupilRadius;
surfaceColor = active ? (isSclera ? 0.0 : (isPupil ? 1.0 : eyeColor)) : eyeColor;
}
void ScleraOrIris_float(float3 positionOS, float irisRadius, out float surfaceType)
{
float osRadius2 = (positionOS.x * positionOS.x + positionOS.y * positionOS.y);
surfaceType = osRadius2 > (irisRadius * irisRadius) ? 0.0 : 1.0;
}
void CirclePupilAnimation(float2 irusUV, float pupilRadius, float pupilAperture, float minimalPupilAperture, float maximalPupilAperture, out float2 animatedIrisUV)
{
// Compute the normalized iris position
float2 irisUVCentered = (irusUV - 0.5f) * 2.0f;
// Compute the radius of the point inside the eye
float localIrisRadius = length(irisUVCentered);
// First based on the pupil aperture, let's define the new position of the pupil
float newPupilRadius = pupilAperture > 0.5 ? lerp(pupilRadius, maximalPupilAperture, (pupilAperture - 0.5) * 2.0) : lerp(minimalPupilAperture, pupilRadius, pupilAperture * 2.0);
// If we are inside the pupil
float newIrisRadius = localIrisRadius < newPupilRadius ? ((pupilRadius / newPupilRadius) * localIrisRadius) : 1.0 - ((1.0 - pupilRadius) / (1.0 - newPupilRadius)) * (1.0 - localIrisRadius);
animatedIrisUV = irisUVCentered / localIrisRadius * newIrisRadius;
// Convert it back to UV space.
animatedIrisUV = (animatedIrisUV * 0.5 + float2(0.5, 0.5));
}
void CorneaRefraction(float3 positionOS, float3 viewDirectionOS, float3 corneaNormalOS, float corneaIOR, float irisPlaneOffset, out float3 refractedPositionOS)
{
// Compute the refracted
float eta = 1.0 / (corneaIOR);
corneaNormalOS = normalize(corneaNormalOS);
viewDirectionOS = -normalize(viewDirectionOS);
float3 refractedViewDirectionOS = refract(viewDirectionOS, corneaNormalOS, eta);
// Find the distance to intersection point
float t = -(positionOS.z + irisPlaneOffset) / refractedViewDirectionOS.z;
// Output the refracted point in OS
refractedPositionOS = float3(refractedViewDirectionOS.z < 0 ? positionOS.xy + refractedViewDirectionOS.xy * t: float2(1.5, 1.5), 0.0);
}
void IrisOutOfBoundColorClamp(float2 irisUV, float3 irisColor, float3 colorClamp, out float3 outputColor)
{
outputColor = (irisUV.x < 0.0 || irisUV.y < 0.0 || irisUV.x > 1.0 || irisUV.y > 1.0) ? colorClamp : irisColor;
}
void IrisOffset(float2 irisUV, float2 irisOffset, out float2 displacedIrisUV)
{
displacedIrisUV = (irisUV + irisOffset);
}
void IrisLimbalRing(float2 irisUV, float3 viewOS, float limbalRingSize, float limbalRingFade, float limbalRingItensity, out float limbalRingFactor)
{
float NdotV = dot(float3(0.0, 0.0, 1.0), viewOS);
// Compute the normalized iris position
float2 irisUVCentered = (irisUV - 0.5f) * 2.0f;
// Compute the radius of the point inside the eye
float localIrisRadius = length(irisUVCentered);
limbalRingFactor = localIrisRadius > (1.0 - limbalRingSize) ? lerp(0.1, 1.0, saturate(1.0 - localIrisRadius) / limbalRingSize) : 1.0;
limbalRingFactor = PositivePow(limbalRingFactor, limbalRingItensity);
limbalRingFactor = lerp(limbalRingFactor, PositivePow(limbalRingFactor, limbalRingFade), 1.0 - NdotV);
}
void ScleraLimbalRing(float3 positionOS, float3 viewOS, float irisRadius, float limbalRingSize, float limbalRingFade, float limbalRingItensity, out float limbalRingFactor)
{
float NdotV = dot(float3(0.0, 0.0, 1.0), viewOS);
// Compute the radius of the point inside the eye
float scleraRadius = length(positionOS.xy);
limbalRingFactor = scleraRadius > irisRadius ? (scleraRadius > (limbalRingSize + irisRadius) ? 1.0 : lerp(0.5, 1.0, (scleraRadius - irisRadius) / (limbalRingSize))) : 1.0;
limbalRingFactor = PositivePow(limbalRingFactor, limbalRingItensity);
limbalRingFactor = lerp(limbalRingFactor, PositivePow(limbalRingFactor, limbalRingFade), 1.0 - NdotV);
}
void ScleraIrisBlend(float3 scleraColor, float3 scleraNormal, float scleraSmoothness,
float3 irisColor, float3 irisNormal, float corneaSmoothness,
float irisRadius,
float3 positionOS,
float diffusionProfileSclera, float diffusionProfileIris,
out float3 eyeColor, out float surfaceMask,
out float3 diffuseNormal, out float3 specularNormal, out float eyeSmoothness, out float surfaceDiffusionProfile)
{
float osRadius = length(positionOS.xy);
float innerBlendRegionRadius = irisRadius - 0.02;
float outerBlendRegionRadius = irisRadius + 0.02;
float blendLerpFactor = 1.0 - (osRadius - irisRadius) / (0.04);
blendLerpFactor = pow(blendLerpFactor, 8.0);
blendLerpFactor = 1.0 - blendLerpFactor;
surfaceMask = (osRadius > outerBlendRegionRadius) ? 0.0 : ((osRadius < irisRadius) ? 1.0 : (lerp(1.0, 0.0, blendLerpFactor)));
eyeColor = lerp(scleraColor, irisColor, surfaceMask);
diffuseNormal = lerp(scleraNormal, irisNormal, surfaceMask);
specularNormal = lerp(scleraNormal, float3(0.0, 0.0, 1.0), surfaceMask);
eyeSmoothness = lerp(scleraSmoothness, corneaSmoothness, surfaceMask);
surfaceDiffusionProfile = lerp(diffusionProfileSclera, diffusionProfileIris, floor(surfaceMask));
}
#endif // EYE_UTILS_HLSL