为啥我的太阳(定向光)卡在 -90/90 旋转?

Posted

技术标签:

【中文标题】为啥我的太阳(定向光)卡在 -90/90 旋转?【英文标题】:Why is my sun (directional light) getting stuck at -90/90 rotation?为什么我的太阳(定向光)卡在 -90/90 旋转? 【发布时间】:2019-09-16 14:40:19 【问题描述】:

我不明白为什么我的太阳在地球上被万向节锁定在 90*。

在.h文件中

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="World Environment")
ADirectionalLight *SunLight;

在我移动太阳的 .cpp 中

float p = totalRealTimeSecondsPerGameDay / DeltaTime;
float r = 360 / p;

FRotator newRot;
newRot.Pitch = r;
newRot.Roll = 0.0f;
newRot.Yaw = 0.0f;

SunLight->AddActorLocalRotation(newRot);

效果非常好......直到达到 90* 或 -90*。

我很迷茫。

编辑:为了澄清这是一个奇怪的错误,或者我只是遗漏了一些东西,我尝试在蓝图中复制我的 C++ 以准确复制该过程,但它也停滞在 90 和 -90。

我什至尝试使用 Quats,因为通过我的搜索,我看到了很多建议。

FQuat quatRot = FQuat(newRot);
SunLight->AddActorLocalRotation(quatRot, false, 0, ETeleportType::None);

【问题讨论】:

【参考方案1】:

这是仅在使用相对旋转时才会出现的问题。

退一步,我可以建议您使用绝对旋转而不是相对旋转吗?在您当前的实现中,您将遭受累积浮点舍入错误;你的太阳会“漂移”游戏时间。如果您改为使用绝对轮换,则可以保证您忠实于游戏时间,同时纠正您的问题:

float gameDaysElapsed = GetWorld()->TimeSeconds / totalRealTimeSecondsPerGameDay;
float alpha;
FMath::Modf(gameDaysElapsed, alpha);

check(FMath::IsWithin(alpha, -SMALL_NUMBER, 1.f + SMALL_NUMBER));    
FRotator rot(alpha * 360.f, 0.f, 0.f);
SunLight->SetActorRotation(rot);

作为脚注,这还允许您应用时间函数来改变太阳在未来的行为方式,而不是线性的。因此,让它做一些诸如“弹出”之类的事情会更容易,例如在快速弹出之前缓慢地穿过天空中心。

【讨论】:

【参考方案2】:

这应该发生在Gimbal Lock

遗憾的是,引擎仍然没有为此提供解决方法。

【讨论】:

以上是关于为啥我的太阳(定向光)卡在 -90/90 旋转?的主要内容,如果未能解决你的问题,请参考以下文章

unity3d中四种光源有啥区别

SceneKit:向相机节点添加定向光没有效果

OpenGL定向照明+定位

将方向向量转换为四元数旋转

如何仅将定向光应用于 Three.js 中的有限区域?

如何在 SceneKit 的场景视图中为阴影正确添加定向光?