当前位置:网站首页>Ue5 Comment convertir les coordonnées de l'écran en coordonnées du monde et en direction du monde

Ue5 Comment convertir les coordonnées de l'écran en coordonnées du monde et en direction du monde

2022-06-10 13:59:00 Maison humaine

Bonjour.,Bonjour tout le monde,Partager un peu deUE5Comment convertir les coordonnées de l'écran en coordonnées du monde.

Les coordonnées de l'écran sont converties en coordonnées du monde

InPlayerControolerTrouvez cette fonction ci - dessous: DeprojectScreenPositionToWorld

bool APlayerController::DeprojectScreenPositionToWorld(float ScreenX, float ScreenY, FVector& WorldLocation, FVector& WorldDirection) const;

La position et l'orientation du monde en fonction de la position de l'écran peuvent être obtenues simplement en passant la position de l'écran.

Comment est - ce possible??

bool UGameplayStatics::DeprojectScreenToWorld(APlayerController const* Player, const FVector2D& ScreenPosition, FVector& WorldPosition, FVector& WorldDirection)
{
	ULocalPlayer* const LP = Player ? Player->GetLocalPlayer() : nullptr;
	if (LP && LP->ViewportClient)
	{
		// get the projection data
		FSceneViewProjectionData ProjectionData;
		if (LP->GetProjectionData(LP->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
		{
                        // Commencez à inverser  
			FMatrix const InvViewProjMatrix = ProjectionData.ComputeViewProjectionMatrix().InverseFast();
			FSceneView::DeprojectScreenToWorld(ScreenPosition, ProjectionData.GetConstrainedViewRect(), InvViewProjMatrix, /*out*/ WorldPosition, /*out*/ WorldDirection);
			return true;
		}
	}

	// something went wrong, zero things and return false
	WorldPosition = FVector::ZeroVector;
	WorldDirection = FVector::ZeroVector;
	return false;
}

Dont:FSceneViewProjectionData Est une description des données sur le viewport de la scène

// Projection data for a FSceneView
struct FSceneViewProjectionData
{
	/** The view origin. */
	FVector ViewOrigin;

	/** Rotation matrix transforming from world space to view space. */
	FMatrix ViewRotationMatrix;

	/** UE4 projection matrix projects such that clip space Z=1 is the near plane, and Z=0 is the infinite far plane. */
	FMatrix ProjectionMatrix;

protected:
	//The unconstrained (no aspect ratio bars applied) view rectangle (also unscaled)
	FIntRect ViewRect;

	// The constrained view rectangle (identical to UnconstrainedUnscaledViewRect if aspect ratio is not constrained)
	FIntRect ConstrainedViewRect;
};

ViewOrigin: C'est l'origine du viewport

ViewRotationMatrix:C'est une matrice de rotation Peut être compris commeViewMatrix Sauf qu'il n'y a pas de matrice de traduction

ProjectionMatrix:Matrice de projection

Ce qu'il faut distinguer ViewMatrix Est de transformer un objet du point du monde en coordonnées locales sous le viewport ,EtWorldMatrix Est de transformer les coordonnées locales en coordonnées du monde .

Dont: VP Inverse J'espère que les points sous le viewport seront convertis en coordonnées du monde par cette inversion

FMatrix ComputeViewProjectionMatrix() const
{
	return FTranslationMatrix(-ViewOrigin) * ViewRotationMatrix * ProjectionMatrix;
}

FMatrix const InvViewProjMatrix = ProjectionData.ComputeViewProjectionMatrix().InverseFast();

Quand j'ai obtenu FSceneViewProjectionData Données structurelles,Ensuite, regardons DeprojectScreenToWorld

Nous savons que la formule du rayon est

Voyons maintenant. DeprojectScreenToWorld Cette fonction Qu'est - ce qu'il y a dedans .

Nous savons que si vous déplacez un point de modèle local de l'espace local à l'espace d'écran , Il a subi ces changements

a.Adoptionworldmatrix Transformer le point local du modèle en point mondial
b.Adoptionviewmatrix La matrice déplace les points de la position du monde sous le viewport
c.Adoptionprojematrix La matrice de projection convertit les points de vue en points sur le plan de coupure proche
d. Mapping to NDCEspace[-1.1]
e. En utilisant la technique semi - Lambert [-1.1]Mapping to[0,1]
f. Multipliez ensuite la largeur et la hauteur de l'écran pour obtenir la position de l'écran

Si vous voulez réaliser la cueillette , Ce serait un processus inverse , L'emplacement de l'écran est déjà connu , Comment trouver la position de cet écran World locationEtOrientation

Voici un examen de la connaissance d'une matrice .

Si unworldmatrix Vous pouvez transformer des points de l'espace local en espace mondial , Alors, pour faire passer ce point de l'espace mondial à l'espace local ,C'est tout ce qu'il faut.worldmatrix L'inverse suffit , On peut comprendre que l'inversion est la Division d'une matrice .

Par exemple, Connu pour  ,J'espère que ça passera500S'il te plaît. 100,C'est tout.  Et vous obtenez100.Parmi eux  C'est5L'inverse de, La matrice est la même .

 

 

Voyons voir.UE5Comment faire:


1. Obtenez d'abord les coordonnées de l'écran

float PixelX = FMath::TruncToFloat(ScreenPos.X);
float PixelY = FMath::TruncToFloat(ScreenPos.Y);

2. Après avoir obtenu les coordonnées, cartographiez - les à 0-1Champ d'application

const float NormalizedX = (PixelX - ViewRect.Min.X) / ((float)ViewRect.Width());
const float NormalizedY = (PixelY - ViewRect.Min.Y) / ((float)ViewRect.Height());

3. Mapper les coordonnées à NDCEspace[-1,1]

const float ScreenSpaceX = (NormalizedX - 0.5f) * 2.0f;
const float ScreenSpaceY = ((1.0f - NormalizedY) - 0.5f) * 2.0f;

4. Le début et la fin du rayon dans l'espace projeté ,Parmi eux0.01 C'est près du plan de coupure ,1 C'est le plan de coupure

const FVector4 RayStartProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 1.0f, 1.0f);
const FVector4 RayEndProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 0.01f, 1.0f);

5.Par devantVPFonctionnement inverse de Convertir les points de l'espace de culture en espace mondial

const FVector4 HGRayStartWorldSpace = InvViewProjMatrix.TransformFVector4(RayStartProjectionSpace);
const FVector4 HGRayEndWorldSpace = InvViewProjMatrix.TransformFVector4(RayEndProjectionSpace);
FVector RayStartWorldSpace(HGRayStartWorldSpace.X, HGRayStartWorldSpace.Y, HGRayStartWorldSpace.Z);
FVector RayEndWorldSpace(HGRayEndWorldSpace.X, HGRayEndWorldSpace.Y, HGRayEndWorldSpace.Z);

6. Diviser le vecteur par W Pour annuler toute projection et obtenir 3-spaceCoordonnées( Vous pouvez comprendre le plan de coupure qui se rapproche du monde )

if (HGRayStartWorldSpace.W != 0.0f)
{
	RayStartWorldSpace /= HGRayStartWorldSpace.W;
}
if (HGRayEndWorldSpace.W != 0.0f)
{
	RayEndWorldSpace /= HGRayEndWorldSpace.W;
}

7. Prenez la direction

const FVector RayDirWorldSpace = (RayEndWorldSpace - RayStartWorldSpace).GetSafeNormal();

8. Et finalement obtenir la valeur requise

out_WorldOrigin = RayStartWorldSpace;
out_WorldDirection = RayDirWorldSpace;

On a l'occasion de parler des rayons

Nous allons maintenant appliquer cette idée à   Dans un petit moteur auto - développé :

 

 

原网站

版权声明
本文为[Maison humaine]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/161/202206101357342495.html