Unreal Engine开发:Unreal Engine基础入门_(9).光照与阴影

光照与阴影

1. 光照的基本概念

在Unreal Engine中,光照是指模拟现实世界中光源对场景中物体的影响。光照可以为场景添加真实感,使物体看起来更加自然。Unreal Engine提供了多种类型的光源,包括定向光(Directional Light)、点光源(Point Light)、聚光灯(Spot Light)和天空光照(Sky Light)。

1.1 定向光(Directional Light)

定向光模拟的是来自无限远的光源,例如太阳。这种光源的特点是光线是平行的,因此对所有物体的影响是一致的。

示例:添加定向光
  1. 打开Unreal Engine编辑器,创建一个新的关卡。

  2. 在“模式”面板中选择“光源”类别。

  3. 从列表中拖动“定向光”到关卡中。

  4. 选中定向光,在“详细信息”面板中可以调整光源的方向、颜色和强度等属性。


// 示例代码:通过蓝图脚本添加定向光

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建定向光

    ADirectionalLight* DirectionalLight = GetWorld()->SpawnActor<ADirectionalLight>(ADirectionalLight::StaticClass(), FVector(0, 0, 1000), FRotator(-45, 0, 0));



    // 设置光源的颜色和强度

    DirectionalLight->SetLightColor(FLinearColor(1.0f, 1.0f, 1.0f));

    DirectionalLight->SetIntensity(1.0f);

}

2. 点光源(Point Light)

点光源是位于场景中的一个点,从该点向四周发射光线。这种光源适用于模拟电灯泡或烛光等近距离光源。

2.1 点光源的属性
  • 位置(Location):光源在场景中的坐标。

  • 颜色(Color):光源的颜色。

  • 强度(Intensity):光源的亮度。

  • 衰减半径(Attenuation Radius):光源影响的范围。

示例:添加点光源
  1. 打开Unreal Engine编辑器,创建一个新的关卡。

  2. 在“模式”面板中选择“光源”类别。

  3. 从列表中拖动“点光源”到关卡中。

  4. 选中点光源,在“详细信息”面板中可以调整光源的位置、颜色、强度和衰减半径等属性。


// 示例代码:通过蓝图脚本添加点光源

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建点光源

    APointLight* PointLight = GetWorld()->SpawnActor<APointLight>(APointLight::StaticClass(), FVector(500, 500, 500), FRotator(0, 0, 0));



    // 设置光源的颜色和强度

    PointLight->SetLightColor(FLinearColor(1.0f, 0.8f, 0.6f));

    PointLight->SetIntensity(5000.0f);



    // 设置衰减半径

    PointLight->SetAttenuationRadius(1000.0f);

}

3. 聚光灯(Spot Light)

聚光灯是一种具有特定方向和角度的光源,适用于模拟手电筒或舞台灯光等。聚光灯的光线形成一个锥形区域,只有在该区域内的物体才能受到光照的影响。

3.1 聚光灯的属性
  • 位置(Location):光源在场景中的坐标。

  • 方向(Direction):光源的朝向。

  • 颜色(Color):光源的颜色。

  • 强度(Intensity):光源的亮度。

  • 内锥角(Inner Cone Angle):内锥角度,光线最强的区域。

  • 外锥角(Outer Cone Angle):外锥角度,光线开始衰减的区域。

示例:添加聚光灯
  1. 打开Unreal Engine编辑器,创建一个新的关卡。

  2. 在“模式”面板中选择“光源”类别。

  3. 从列表中拖动“聚光灯”到关卡中。

  4. 选中聚光灯,在“详细信息”面板中可以调整光源的位置、方向、颜色、强度、内锥角和外锥角等属性。


// 示例代码:通过蓝图脚本添加聚光灯

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建聚光灯

    ASpotLight* SpotLight = GetWorld()->SpawnActor<ASpotLight>(ASpotLight::StaticClass(), FVector(500, 500, 500), FRotator(-45, 0, 0));



    // 设置光源的颜色和强度

    SpotLight->SetLightColor(FLinearColor(0.8f, 0.6f, 0.4f));

    SpotLight->SetIntensity(1000.0f);



    // 设置内锥角和外锥角

    SpotLight->SetInnerConeAngle(15.0f);

    SpotLight->SetOuterConeAngle(30.0f);

}

4. 天空光照(Sky Light)

天空光照模拟的是天空对场景的光照效果,通常用于室外场景。它可以通过环境立方体贴图或球体贴图来提供全局光照。

4.1 天空光照的属性
  • 光源类型(Light Source Type):可以选择环境立方体贴图(Captured Scene)或球体贴图(Spherical Environment Map)。

  • 强度(Intensity):光源的亮度。

  • 捕获设备(Capture Device):选择用于捕获环境的设备,例如静态捕获或动态捕获。

示例:添加天空光照
  1. 打开Unreal Engine编辑器,创建一个新的关卡。

  2. 在“模式”面板中选择“光源”类别。

  3. 从列表中拖动“天空光照”到关卡中。

  4. 选中天空光照,在“详细信息”面板中可以调整光源类型、强度和捕获设备等属性。


// 示例代码:通过蓝图脚本添加天空光照

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建天空光照

    ASkyLight* SkyLight = GetWorld()->SpawnActor<ASkyLight>(ASkyLight::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0));



    // 设置光源类型和强度

    SkyLight->SetLightSourceMode(ELightSourceMode::LSM_CapturedScene);

    SkyLight->SetIntensity(1.0f);



    // 设置捕获设备

    USkyLightComponent* SkyLightComponent = SkyLight->GetSkyLightComponent();

    if (SkyLightComponent)

    {

        SkyLightComponent->SetSourceCubemap(UTextureCube::StaticClass());

    }

}

5. 光照模式

Unreal Engine提供了多种光照模式,包括静态光照(Static Lighting)、固定光照(Stationary Lighting)和动态光照(Dynamic Lighting)。不同的光照模式会影响光照的计算方式和性能。

5.1 静态光照(Static Lighting)

静态光照是预计算的光照,适用于不经常变化的场景。这种模式下,光照效果会烘焙到光照贴图中,因此性能较高,但无法实时改变。

示例:设置静态光照
  1. 在场景中添加一个静态光源,例如定向光。

  2. 选中光源,在“详细信息”面板中将“光源移动性”设置为“静态(Static)”。

  3. 选择“构建”菜单中的“生成光照”选项,烘焙光照效果。


// 示例代码:通过蓝图脚本设置光源移动性为静态

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建定向光

    ADirectionalLight* DirectionalLight = GetWorld()->SpawnActor<ADirectionalLight>(ADirectionalLight::StaticClass(), FVector(0, 0, 1000), FRotator(-45, 0, 0));



    // 设置光源移动性为静态

    DirectionalLight->SetMobility(EComponentMobility::Static);

}

5.2 固定光照(Stationary Lighting)

固定光照是一种介于静态和动态之间的光照模式。它可以在编辑器中预计算,但可以在运行时进行部分修改。这种模式适用于需要在运行时进行少量变化的场景。

示例:设置固定光照
  1. 在场景中添加一个固定光源,例如点光源。

  2. 选中光源,在“详细信息”面板中将“光源移动性”设置为“固定(Stationary)”。

  3. 选择“构建”菜单中的“生成光照”选项,烘焙光照效果。


// 示例代码:通过蓝图脚本设置光源移动性为固定

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建点光源

    APointLight* PointLight = GetWorld()->SpawnActor<APointLight>(APointLight::StaticClass(), FVector(500, 500, 500), FRotator(0, 0, 0));



    // 设置光源移动性为固定

    PointLight->SetMobility(EComponentMobility::Stationary);

}

5.3 动态光照(Dynamic Lighting)

动态光照是完全在运行时计算的光照模式。它适用于需要频繁变化的场景,例如角色的灯光效果。这种模式下,光照效果可以实时改变,但性能较低。

示例:设置动态光照
  1. 在场景中添加一个动态光源,例如聚光灯。

  2. 选中光源,在“详细信息”面板中将“光源移动性”设置为“动态(Dynamic)”。


// 示例代码:通过蓝图脚本设置光源移动性为动态

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建聚光灯

    ASpotLight* SpotLight = GetWorld()->SpawnActor<ASpotLight>(ASpotLight::StaticClass(), FVector(500, 500, 500), FRotator(-45, 0, 0));



    // 设置光源移动性为动态

    SpotLight->SetMobility(EComponentMobility::Dynamic);

}

6. 阴影的基本概念

阴影是指物体挡住光线后形成的暗区。在Unreal Engine中,阴影可以通过多种方式生成,包括静态阴影、固定阴影和动态阴影。

6.1 静态阴影(Static Shadows)

静态阴影是预计算的阴影,适用于不经常变化的场景。这种模式下,阴影会烘焙到光照贴图中,因此性能较高,但无法实时改变。

示例:设置静态阴影
  1. 在场景中添加一个静态光源,例如定向光。

  2. 选中光源,在“详细信息”面板中将“光源移动性”设置为“静态(Static)”。

  3. 选中需要投射阴影的物体,在“详细信息”面板中将“投射阴影”设置为“启用(Enabled)”。

  4. 选择“构建”菜单中的“生成光照”选项,烘焙阴影效果。


// 示例代码:通过蓝图脚本设置物体投射静态阴影

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建静态光源

    ADirectionalLight* DirectionalLight = GetWorld()->SpawnActor<ADirectionalLight>(ADirectionalLight::StaticClass(), FVector(0, 0, 1000), FRotator(-45, 0, 0));

    DirectionalLight->SetMobility(EComponentMobility::Static);



    // 创建一个物体

    AStaticMeshActor* StaticMeshActor = GetWorld()->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0));

    UStaticMeshComponent* StaticMeshComponent = StaticMeshActor->GetStaticMeshComponent();



    // 启用投射阴影

    if (StaticMeshComponent)

    {

        StaticMeshComponent->SetCastShadow(true);

    }

}

6.2 固定阴影(Stationary Shadows)

固定阴影是一种介于静态和动态之间的阴影模式。它可以在编辑器中预计算,但可以在运行时进行部分修改。这种模式适用于需要在运行时进行少量变化的场景。

示例:设置固定阴影
  1. 在场景中添加一个固定光源,例如点光源。

  2. 选中光源,在“详细信息”面板中将“光源移动性”设置为“固定(Stationary)”。

  3. 选中需要投射阴影的物体,在“详细信息”面板中将“投射阴影”设置为“启用(Enabled)”。

  4. 选择“构建”菜单中的“生成光照”选项,烘焙阴影效果。


// 示例代码:通过蓝图脚本设置物体投射固定阴影

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建固定光源

    APointLight* PointLight = GetWorld()->SpawnActor<APointLight>(APointLight::StaticClass(), FVector(500, 500, 500), FRotator(0, 0, 0));

    PointLight->SetMobility(EComponentMobility::Stationary);



    // 创建一个物体

    AStaticMeshActor* StaticMeshActor = GetWorld()->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0));

    UStaticMeshComponent* StaticMeshComponent = StaticMeshActor->GetStaticMeshComponent();



    // 启用投射阴影

    if (StaticMeshComponent)

    {

        StaticMeshComponent->SetCastShadow(true);

    }

}

6.3 动态阴影(Dynamic Shadows)

动态阴影是完全在运行时计算的阴影,适用于需要频繁变化的场景,例如角色的阴影效果。这种模式下,阴影效果可以实时改变,但性能较低。

示例:设置动态阴影
  1. 在场景中添加一个动态光源,例如聚光灯。

  2. 选中光源,在“详细信息”面板中将“光源移动性”设置为“动态(Dynamic)”。

  3. 选中需要投射阴影的物体,在“详细信息”面板中将“投射阴影”设置为“启用(Enabled)”。


// 示例代码:通过蓝图脚本设置物体投射动态阴影

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建动态光源

    ASpotLight* SpotLight = GetWorld()->SpawnActor<ASpotLight>(ASpotLight::StaticClass(), FVector(500, 500, 500), FRotator(-45, 0, 0));

    SpotLight->SetMobility(EComponentMobility::Dynamic);



    // 创建一个物体

    AStaticMeshActor* StaticMeshActor = GetWorld()->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0));

    UStaticMeshComponent* StaticMeshComponent = StaticMeshActor->GetStaticMeshComponent();



    // 启用投射阴影

    if (StaticMeshComponent)

    {

        StaticMeshComponent->SetCastShadow(true);

    }

}

7. 光照和阴影的优化

在Unreal Engine中,光照和阴影的优化是提高游戏性能的关键。以下是一些常见的优化技巧:

7.1 减少光源数量

过多的光源会显著增加渲染时间,因此应尽量减少场景中的光源数量。对于不重要的光源,可以考虑使用更高效的灯光类型,例如环境光源。

示例:优化光源数量
  1. 评估场景中每个光源的重要性。

  2. 移除或合并不需要的光源。


// 示例代码:移除不必要的光源

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 获取所有光源

    TArray<AActor*> LightActors;

    UGameplayStatics::GetAllActorsOfClass(GetWorld(), ALight::StaticClass(), LightActors);



    // 遍历光源,移除不必要的光源

    for (AActor* LightActor : LightActors)

    {

        ALight* Light = Cast<ALight>(LightActor);

        if (Light && Light->GetMobility() == EComponentMobility::Dynamic && Light->GetIntensity() < 100.0f)

        {

            Light->Destroy();

        }

    }

}

7.2 使用光照贴图

光照贴图是一种将光照效果烘焙到纹理中的技术,可以显著提高性能。对于不经常变化的场景,应尽量使用光照贴图。

示例:使用光照贴图
  1. 选择需要烘焙的光源,将其移动性设置为“静态(Static)”或“固定(Stationary)”。

  2. 选择需要烘焙的物体,确保它们的光照属性设置正确。

  3. 选择“构建”菜单中的“生成光照”选项,烘焙光照效果。


// 示例代码:通过蓝图脚本烘焙光照

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 获取所有静态和固定的光源

    TArray<AActor*> LightActors;

    UGameplayStatics::GetAllActorsOfClass(GetWorld(), ALight::StaticClass(), LightActors);



    for (AActor* LightActor : LightActors)

    {

        ALight* Light = Cast<ALight>(LightActor);

        if (Light && (Light->GetMobility() == EComponentMobility::Static || Light->GetMobility() == EComponentMobility::Stationary))

        {

            // 确保物体的光照属性设置正确

            TArray<AActor*> MeshActors;

            UGameplayStatics::GetAllActorsOfClass(GetWorld(), AStaticMeshActor::StaticClass(), MeshActors);



            for (AActor* MeshActor : MeshActors)

            {

                AStaticMeshActor* StaticMeshActor = Cast<AStaticMeshActor>(MeshActor);

                if (StaticMeshActor)

                {

                    UStaticMeshComponent* StaticMeshComponent = StaticMeshActor->GetStaticMeshComponent();

                    if (StaticMeshComponent)

                    {

                        StaticMeshComponent->SetCastShadow(true);

                    }

                }

            }



            // 烘焙光照效果

            FLevelUtils::BuildLighting(GetWorld());

        }

    }

}

7.3 使用光照通道

光照通道(Lighting Channels)可以帮助优化光照计算。通过将不同的物体质感分配到不同的光照通道,可以减少光照计算的负担。

示例:使用光照通道
  1. 在“编辑”菜单中选择“项目设置”(Project Settings)。

  2. 在“渲染”(Rendering)类别中找到“光照通道”(Lighting Channels)。

  3. 创建并命名新的光照通道。

  4. 选择需要分配光照通道的物体,在“详细信息”面板中设置光照通道。


// 示例代码:通过蓝图脚本设置光照通道

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 获取所有静态网格物体

    TArray<AActor*> MeshActors;

    UGameplayStatics::GetAllActorsOfClass(GetWorld(), AStaticMeshActor::StaticClass(), MeshActors);



    for (AActor* MeshActor : MeshActors)

    {

        AStaticMeshActor* StaticMeshActor = Cast<AStaticMeshActor>(MeshActor);

        if (StaticMeshActor)

        {

            UStaticMeshComponent* StaticMeshComponent = StaticMeshActor->GetStaticMeshComponent();

            if (StaticMeshComponent)

            {

                // 设置光照通道

                StaticMeshComponent->SetLightingChannel(0, true);

                StaticMeshComponent->SetLightingChannel(1, false);

                StaticMeshComponent->SetLightingChannel(2, false);

            }

        }

    }

}

7.4 使用光照体积

光照体积(Light Volumes)用于优化动态光照的计算。它们可以减少动态光照在场景中的传播范围,从而提高性能。

示例:使用光照体积
  1. 在“模式”面板中选择“体积”(Volumes)类别。

  2. 从列表中拖动“光照体积”(Lightmass Importance Volume)到关卡中。

  3. 调整光照体积的大小,使其覆盖需要优化的区域。

  4. 选择“构建”菜单中的“生成光照”选项,烘焙光照效果。


// 示例代码:通过蓝图脚本添加光照体积

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建光照体积

    ALightmass ImportanceVolume* LightVolume = GetWorld()->SpawnActor<ALightmassImportanceVolume>(ALightmassImportanceVolume::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0));



    // 调整光照体积的大小

    if (LightVolume)

    {

        LightVolume->SetBounds(FVector(1000, 1000, 1000));

    }

}

8. 光照和阴影的高级技巧

除了基本的光照和阴影设置,Unreal Engine还提供了许多高级技巧,可以帮助你实现更复杂和逼真的光照效果。

8.1 使用IES纹理

IES(Industry Standard)纹理可以模拟真实世界中的光源分布。通过使用IES纹理,可以为场景中的光源添加更复杂的光照模式。

示例:使用IES纹理
  1. 在内容浏览器中创建一个新的IES纹理。

  2. 选择需要使用IES纹理的光源,在“详细信息”面板中找到“IES纹理”(IES Texture)属性。

  3. 将IES纹理分配给光源。


// 示例代码:通过蓝图脚本设置IES纹理

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建点光源

    APointLight* PointLight = GetWorld()->SpawnActor<APointLight>(APointLight::StaticClass(), FVector(500, 500, 500), FRotator(0, 0, 0));



    // 加载IES纹理

    UTexture2D* IESTexture = Cast<UTexture2D>(StaticLoadObject(UTexture2D::StaticClass(), nullptr, TEXT("/Game/Textures/IES_Profile")));



    // 设置IES纹理

    if (PointLight && IESTexture)

    {

        PointLight->SetLightSourceTexture(IESTexture);

    }

}

8.2 使用光源函数

光源函数(Light Functions)可以为光源添加更复杂的光照效果,例如颜色渐变或纹理映射。通过使用光源函数,可以创建更具创意的光照效果。

示例:使用光源函数
  1. 在内容浏览器中创建一个新的光源函数。

  2. 选择需要使用光源函数的光源,在“详细信息”面板中找到“光源函数”(Light Function)属性。

  3. 将光源函数分配给光源。


// 示例代码:通过蓝图脚本设置光源函数

void AMyGameMode::BeginPlay()

{

    Super::BeginPlay();



    // 创建点光源

    APointLight* PointLight = GetWorld()->SpawnActor<APointLight>(APointLight::StaticClass(), FVector(500, 500, 500), FRotator(0, 0, 0));



    // 加载光源函数

    ULightFunction* LightFunction = Cast<ULightFunction>(StaticLoadObject(ULightFunction::StaticClass(), nullptr, TEXT("/Game/Textures/LightFunction")));



    // 设置光源函数

    if (PointLight && LightFunction)

    {

        PointLight->SetLightFunction(LightFunction);

    }

}

9. 总结

通过合理设置和优化光照与阴影,可以显著提升Unreal Engine场景的真实感和性能。不同的光源类型和光照模式适用于不同的场景需求,而高级技巧如IES纹理和光源函数则可以帮助你实现更加复杂和创意的光照效果。希望本文档能帮助你在Unreal Engine中更好地理解和应用光照与阴影技术。

10. 常见问题解答

10.1 为什么我的场景中的阴影看起来不够真实?
  1. 光源设置:检查光源的属性,确保光源的颜色、强度和方向设置正确。

  2. 阴影质量:在“项目设置”(Project Settings)中调整阴影的质量设置,提高阴影分辨率和细节。

  3. 物体设置:确保需要投射阴影的物体的“投射阴影”属性已启用。

  4. 烘焙设置:对于静态和固定光源,重新烘焙光照效果,确保烘焙参数设置合理。

10.2 如何优化动态光照的性能?
  1. 减少动态光源数量:尽量减少场景中的动态光源数量,特别是那些对视觉效果影响不大的光源。

  2. 使用光照体积:为动态光源添加光照体积,限制其影响范围。

  3. 降低阴影分辨率:在“项目设置”中调整动态阴影的分辨率,降低其对性能的影响。

  4. 优化材质:使用更高效的材质和纹理,减少光照计算的复杂度。

10.3 如何实现环境光遮挡(Ambient Occlusion)?
  1. 启用全局光照:在“项目设置”中启用全局光照(Global Illumination)。

  2. 调整环境光遮挡参数:在“渲染”(Rendering)类别中找到“环境光遮挡”(Ambient Occlusion)设置,调整相关参数。

  3. 烘焙光照:对于静态和固定光源,重新烘焙光照效果,确保环境光遮挡效果正确。

11. 进一步阅读

希望本文档能帮助你更好地理解和应用Unreal Engine中的光照与阴影技术。如果有任何问题或需要进一步的帮助,请参考Unreal Engine的官方文档或社区资源。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值