编辑器界面:
代码流程:
FLinearColor ULightComponent::GetColoredLightBrightness() const
{// Brightness in Lumensfloat LightBrightness = ComputeLightBrightness();FLinearColor Energy = FLinearColor(LightColor) * LightBrightness;if (bUseTemperature){Energy *= FLinearColor::MakeFromColorTemperature(Temperature);}return Energy;
}/** * Filter color of the light.* Note that this can change the light's effective intensity.*/
UPROPERTY(BlueprintReadOnly, interp, Category=Light, meta=(HideAlphaChannel, ShouldShowInViewport = true))FColor LightColor;FORCEINLINE FLinearColor::FLinearColor(const FColor& Color)
{R = sRGBToLinearTable[Color.R];G = sRGBToLinearTable[Color.G];B = sRGBToLinearTable[Color.B];A = float(Color.A) * (1.0f / 255.0f);
}float ULightComponent::ComputeLightBrightness() const
{float LightBrightness = Intensity;if(IESTexture){if(bUseIESBrightness){LightBrightness = IESTexture->Brightness * IESBrightnessScale;}LightBrightness *= IESTexture->TextureMultiplier;}return LightBrightness;
}FLinearColor FLinearColor::MakeFromColorTemperature( float Temp )
{Temp = FMath::Clamp( Temp, 1000.0f, 15000.0f );// Approximate Planckian locus in CIE 1960 UCSfloat u = ( 0.860117757f + 1.54118254e-4f * Temp + 1.28641212e-7f * Temp*Temp ) / ( 1.0f + 8.42420235e-4f * Temp + 7.08145163e-7f * Temp*Temp );float v = ( 0.317398726f + 4.22806245e-5f * Temp + 4.20481691e-8f * Temp*Temp ) / ( 1.0f - 2.89741816e-5f * Temp + 1.61456053e-7f * Temp*Temp );float x = 3.0f * u / ( 2.0f * u - 8.0f * v + 4.0f );float y = 2.0f * v / ( 2.0f * u - 8.0f * v + 4.0f );float z = 1.0f - x - y;float Y = 1.0f;float X = Y/y * x;float Z = Y/y * z;// XYZ to RGB with BT.709 primariesfloat R = 3.2404542f * X + -1.5371385f * Y + -0.4985314f * Z;float G = -0.9692660f * X + 1.8760108f * Y + 0.0415560f * Z;float B = 0.0556434f * X + -0.2040259f * Y + 1.0572252f * Z;return FLinearColor(R,G,B);
}
void FLightRenderParameters::MakeShaderParameters(const FViewMatrices& ViewMatrices, float Exposure, FLightShaderParameters& OutShaderParameters) const
{OutShaderParameters.TranslatedWorldPosition = FVector3f(ViewMatrices.GetPreViewTranslation() + WorldPosition);OutShaderParameters.InvRadius = InvRadius;OutShaderParameters.Color = FVector3f(Color) * GetLightExposureScale(Exposure);OutShaderParameters.FalloffExponent = FalloffExponent;OutShaderParameters.Direction = Direction;OutShaderParameters.SpecularScale = SpecularScale;OutShaderParameters.Tangent = Tangent;OutShaderParameters.SourceRadius = SourceRadius;OutShaderParameters.SpotAngles = SpotAngles;OutShaderParameters.SoftSourceRadius = SoftSourceRadius;OutShaderParameters.SourceLength = SourceLength;OutShaderParameters.RectLightBarnCosAngle = RectLightBarnCosAngle;OutShaderParameters.RectLightBarnLength = RectLightBarnLength;OutShaderParameters.RectLightAtlasUVOffset = RectLightAtlasUVOffset;OutShaderParameters.RectLightAtlasUVScale = RectLightAtlasUVScale;OutShaderParameters.RectLightAtlasMaxLevel = RectLightAtlasMaxLevel;
}
FLightSceneProxy::FLightSceneProxy(const ULightComponent* InLightComponent): LightComponent(InLightComponent), SceneInterface(InLightComponent->GetScene()), IndirectLightingScale(InLightComponent->IndirectLightingIntensity), VolumetricScatteringIntensity(FMath::Max(InLightComponent->VolumetricScatteringIntensity, 0.0f)), ShadowResolutionScale(InLightComponent->ShadowResolutionScale), ShadowBias(InLightComponent->ShadowBias), ShadowSlopeBias(InLightComponent->ShadowSlopeBias), ShadowSharpen(InLightComponent->ShadowSharpen), ContactShadowLength(InLightComponent->ContactShadowLength), SpecularScale(InLightComponent->SpecularScale), LightGuid(InLightComponent->LightGuid), RayStartOffsetDepthScale(InLightComponent->RayStartOffsetDepthScale), IESTexture(0), bContactShadowLengthInWS(InLightComponent->ContactShadowLengthInWS ? true : false), bMovable(InLightComponent->IsMovable()), bStaticLighting(InLightComponent->HasStaticLighting()), bStaticShadowing(InLightComponent->HasStaticShadowing()), bCastDynamicShadow(InLightComponent->CastShadows && InLightComponent->CastDynamicShadows), bCastStaticShadow(InLightComponent->CastShadows && InLightComponent->CastStaticShadows), bCastTranslucentShadows(InLightComponent->CastTranslucentShadows), bTransmission(InLightComponent->bTransmission && bCastDynamicShadow && !bStaticShadowing), bCastVolumetricShadow(InLightComponent->bCastVolumetricShadow), bCastHairStrandsDeepShadow(InLightComponent->bCastDeepShadow), bCastShadowsFromCinematicObjectsOnly(InLightComponent->bCastShadowsFromCinematicObjectsOnly), bForceCachedShadowsForMovablePrimitives(InLightComponent->bForceCachedShadowsForMovablePrimitives), CastRaytracedShadow(InLightComponent->CastShadows == 0? (TEnumAsByte<ECastRayTracedShadow::Type>) ECastRayTracedShadow::Disabled : InLightComponent->CastRaytracedShadow), bAffectReflection(InLightComponent->bAffectReflection), bAffectGlobalIllumination(InLightComponent->bAffectGlobalIllumination), bAffectTranslucentLighting(InLightComponent->bAffectTranslucentLighting), bUsedAsAtmosphereSunLight(InLightComponent->IsUsedAsAtmosphereSunLight()), bAffectDynamicIndirectLighting(InLightComponent->bAffectDynamicIndirectLighting), bUseRayTracedDistanceFieldShadows(InLightComponent->bUseRayTracedDistanceFieldShadows), bUseVirtualShadowMaps(false) // See below, bCastModulatedShadows(false), bUseWholeSceneCSMForMovableObjects(false), AtmosphereSunLightIndex(InLightComponent->GetAtmosphereSunLightIndex()), AtmosphereSunDiskColorScale(InLightComponent->GetAtmosphereSunDiskColorScale()), LightType(InLightComponent->GetLightType()) , LightingChannelMask(GetLightingChannelMaskForStruct(InLightComponent->LightingChannels)), StatId(InLightComponent->GetStatID(true)), ComponentName(InLightComponent->GetFName()), LevelName(InLightComponent->GetOwner() ? InLightComponent->GetOwner()->GetLevel()->GetOutermost()->GetFName() : NAME_None), FarShadowDistance(0), FarShadowCascadeCount(0), ShadowAmount(1.0f), SamplesPerPixel(1), DeepShadowLayerDistribution(InLightComponent->DeepShadowLayerDistribution)
#if ACTOR_HAS_LABELS, OwnerNameOrLabel(InLightComponent->GetOwner() ? InLightComponent->GetOwner()->GetActorNameOrLabel() : InLightComponent->GetName())
#endif
{check(SceneInterface);// Currently we use virtual shadows maps for all lights when the global setting is enabledbUseVirtualShadowMaps = ::UseVirtualShadowMaps(SceneInterface->GetShaderPlatform(), SceneInterface->GetFeatureLevel());// Treat stationary lights as movable when non-nanite VSMs are enabledconst bool bNonNaniteVirtualShadowMaps = UseNonNaniteVirtualShadowMaps(SceneInterface->GetShaderPlatform(), SceneInterface->GetFeatureLevel());if (bNonNaniteVirtualShadowMaps){bStaticShadowing = bStaticLighting;}const FLightComponentMapBuildData* MapBuildData = InLightComponent->GetLightComponentMapBuildData();if (MapBuildData && bStaticShadowing && !bStaticLighting){ShadowMapChannel = MapBuildData->ShadowMapChannel;}else{ShadowMapChannel = INDEX_NONE;}// Use the preview channel if valid, otherwise fallback to the lighting build channelPreviewShadowMapChannel = InLightComponent->PreviewShadowMapChannel != INDEX_NONE ? InLightComponent->PreviewShadowMapChannel : ShadowMapChannel;StaticShadowDepthMap = &LightComponent->StaticShadowDepthMap;if(LightComponent->IESTexture){IESTexture = LightComponent->IESTexture;}Color = LightComponent->GetColoredLightBrightness();
}
FDeferredLightUniformStruct GetDeferredLightParameters(const FSceneView& View, const FLightSceneInfo& LightSceneInfo)
{FDeferredLightUniformStruct Out;FLightRenderParameters LightParameters;LightSceneInfo.Proxy->GetLightShaderParameters(LightParameters);LightParameters.MakeShaderParameters(View.ViewMatrices, View.GetLastEyeAdaptationExposure(), Out.LightParameters);
}
struct FLightRenderParameters
{ENGINE_API void MakeShaderParameters(const FViewMatrices& ViewMatrices, float Exposure, FLightShaderParameters& OutShaderParameters) const;ENGINE_API float GetLightExposureScale(float Exposure) const;static ENGINE_API float GetLightExposureScale(float Exposure, float InverseExposureBlend);// Position of the light in world space.FVector WorldPosition;// 1 / light's falloff radius from Position.float InvRadius;// Color of the light.FLinearColor Color;// The exponent for the falloff of the light intensity from the distance.float FalloffExponent;// Direction of the light if applies.FVector3f Direction;// Factor to applies on the specular.float SpecularScale;// One tangent of the light if applies.// Note: BiTangent is on purpose not stored for memory optimisation purposes.FVector3f Tangent;// Radius of the point light.float SourceRadius;// Dimensions of the light, for spot light, but alsoFVector2f SpotAngles;// Radius of the soft source.float SoftSourceRadius;// Other dimensions of the light source for rect light specifically.float SourceLength;// Barn door angle for rect lightfloat RectLightBarnCosAngle;// Barn door length for rect lightfloat RectLightBarnLength;// Rect. light atlas transformationFVector2f RectLightAtlasUVOffset;FVector2f RectLightAtlasUVScale;float RectLightAtlasMaxLevel;float InverseExposureBlend;// Return Invalid rect light atlas MIP levelstatic float GetRectLightAtlasInvalidMIPLevel() { return 32.f; }
};
Shader对应代码:
FDeferredLightData SetupLightDataForStandardDeferred()
{FDeferredLightData LightData;LightData.TranslatedWorldPosition = GetDeferredLightTranslatedWorldPosition();LightData.InvRadius = DeferredLightUniforms_InvRadius;LightData.Color = DeferredLightUniforms_Color;LightData.FalloffExponent = DeferredLightUniforms_FalloffExponent;LightData.Direction = DeferredLightUniforms_Direction;LightData.Tangent = DeferredLightUniforms_Tangent;LightData.SpotAngles = DeferredLightUniforms_SpotAngles;LightData.SourceRadius = DeferredLightUniforms_SourceRadius;LightData.SourceLength = 1 > 0 ? DeferredLightUniforms_SourceLength : 0;LightData.SoftSourceRadius = DeferredLightUniforms_SoftSourceRadius;LightData.SpecularScale = DeferredLightUniforms_SpecularScale;LightData.ContactShadowLength = abs(DeferredLightUniforms_ContactShadowLength);LightData.ContactShadowLengthInWS = DeferredLightUniforms_ContactShadowLength < 0.0f;LightData.ContactShadowNonShadowCastingIntensity = DeferredLightUniforms_ContactShadowNonShadowCastingIntensity;LightData.DistanceFadeMAD = DeferredLightUniforms_DistanceFadeMAD;LightData.ShadowMapChannelMask = DeferredLightUniforms_ShadowMapChannelMask;LightData.ShadowedBits = DeferredLightUniforms_ShadowedBits;LightData.bInverseSquared = 1 > 0 && DeferredLightUniforms_FalloffExponent == 0;LightData.bRadialLight = 1 > 0;LightData.bSpotLight = 1 > 0;LightData.bRectLight = 1 == 2;LightData.RectLightBarnCosAngle = DeferredLightUniforms_RectLightBarnCosAngle;LightData.RectLightBarnLength = DeferredLightUniforms_RectLightBarnLength;LightData.RectLightAtlasMaxLevel = DeferredLightUniforms_RectLightAtlasMaxLevel;LightData.RectLightAtlasUVOffset = DeferredLightUniforms_RectLightAtlasUVOffset;LightData.RectLightAtlasUVScale = DeferredLightUniforms_RectLightAtlasUVScale;LightData.HairTransmittance = InitHairTransmittanceData();return LightData;
}