Ejemplo n.º 1
0
void FSceneView::UpdateViewMatrix()
{
	FVector StereoViewLocation = ViewLocation;
	if (GEngine->IsStereoscopic3D() && StereoPass != eSSP_FULL)
	{
		GEngine->StereoRenderingDevice->CalculateStereoViewOffset(StereoPass, ViewRotation, WorldToMetersScale, StereoViewLocation);
		ViewLocation = StereoViewLocation;
	}

	ViewMatrices.ViewOrigin = StereoViewLocation;

	ViewMatrices.ViewMatrix = FTranslationMatrix(-StereoViewLocation);
	ViewMatrices.ViewMatrix = ViewMatrices.ViewMatrix * FInverseRotationMatrix(ViewRotation);
	ViewMatrices.ViewMatrix = ViewMatrices.ViewMatrix * FMatrix(
		FPlane(0,	0,	1,	0),
		FPlane(1,	0,	0,	0),
		FPlane(0,	1,	0,	0),
		FPlane(0,	0,	0,	1));
 
	ViewMatrices.PreViewTranslation = -ViewMatrices.ViewOrigin;
	FMatrix TranslatedViewMatrix = FTranslationMatrix(-ViewMatrices.PreViewTranslation) * ViewMatrices.ViewMatrix;
	
	// Compute a transform from view origin centered world-space to clip space.
	ViewMatrices.TranslatedViewProjectionMatrix = TranslatedViewMatrix * ViewMatrices.ProjMatrix;
	ViewMatrices.InvTranslatedViewProjectionMatrix = ViewMatrices.TranslatedViewProjectionMatrix.Inverse();

	ViewProjectionMatrix = ViewMatrices.GetViewProjMatrix();
	InvViewMatrix = ViewMatrices.GetInvViewMatrix();
	InvViewProjectionMatrix = ViewMatrices.GetInvViewProjMatrix();

}
Ejemplo n.º 2
0
void AGraph::initializeEdgeMesh(UStaticMeshComponent* edgeMesh,
								const AGVertex* v1,
								const AGVertex* v2)
{
	auto pos1 = v1->GetActorLocation();
	auto pos2 = v2->GetActorLocation();


	auto ray = pos2 - pos1;

	auto n_p1p2 = ray;
	n_p1p2.Z = 0;
	n_p1p2 = n_p1p2.GetSafeNormal();

	//tile is 40*40*1. The distance needs to substract half of the tile size
	auto totalOffsetDistance = 40.0f;
	//change start & end positions from the center of the vertex mesh
	//to the edges of the mesh to the right direction
	auto p1_offset = n_p1p2 * totalOffsetDistance;
	pos1 += p1_offset;
	pos2 += -p1_offset;
	auto newRay = pos2 - pos1;

	auto rotation = FRotationMatrix::MakeFromX(newRay);
	auto scaleX = FVector::Dist(pos1, pos2) * .5f ;
	auto scaleY = 40.0f;
	auto scaleZ = 1.0f;
	FMatrix transformMatrix = FScaleMatrix(FVector(scaleX, scaleY, scaleZ)) *
								rotation *
								FTranslationMatrix(pos1);

	edgeMesh->SetWorldTransform(FTransform(transformMatrix));
	edgeMesh->AddLocalOffset(FVector(scaleX, 0.0f, 0.0f));
}
Ejemplo n.º 3
0
FMatrix OSVRHMDDescription::GetProjectionMatrix(EEye Eye) const
{
	// @TODO: a proper stereo projection matrix should be calculated

	const float ProjectionCenterOffset = 0.151976421f;
	const float PassProjectionOffset = (Eye == LEFT_EYE) ? ProjectionCenterOffset : -ProjectionCenterOffset;

#if 1
	const float HalfFov = FMath::DegreesToRadians(GetFov(Eye).X) / 2.f;
	const float InWidth = GetDisplaySize(Eye).X;
	const float InHeight = GetDisplaySize(Eye).Y;
	const float XS = 1.0f / tan(HalfFov);
	const float YS = InWidth / tan(HalfFov) / InHeight;
#else
	const float HalfFov = 2.19686294f / 2.f;
	const float InWidth = 640.f;
	const float InHeight = 480.f;
	const float XS = 1.0f / tan(HalfFov);
	const float YS = InWidth / tan(HalfFov) / InHeight;
#endif

	const float InNearZ = GNearClippingPlane;
	return FMatrix(
			   FPlane(XS, 0.0f, 0.0f, 0.0f),
			   FPlane(0.0f, YS, 0.0f, 0.0f),
			   FPlane(0.0f, 0.0f, 0.0f, 1.0f),
			   FPlane(0.0f, 0.0f, InNearZ, 0.0f))

		   *
		   FTranslationMatrix(FVector(PassProjectionOffset, 0, 0));
}
Ejemplo n.º 4
0
void UNavCollision::DrawSimpleGeom(FPrimitiveDrawInterface* PDI, const FTransform& Transform, const FColor Color)
{
	const FMatrix ParentTM = Transform.ToMatrixWithScale();
	for (int32 i = 0; i < CylinderCollision.Num(); i++)
	{
		FMatrix ElemTM = FTranslationMatrix(CylinderCollision[i].Offset);
		ElemTM *= ParentTM;
		DrawCylinderHelper(PDI, ElemTM, CylinderCollision[i].Radius, CylinderCollision[i].Height, Color);
	}
	
	for (int32 i = 0; i < BoxCollision.Num(); i++)
	{
		FMatrix ElemTM = FTranslationMatrix(BoxCollision[i].Offset);
		ElemTM *= ParentTM;
		DrawBoxHelper(PDI, ElemTM, BoxCollision[i].Extent, Color);
	}
}
Ejemplo n.º 5
0
FMatrix FCanvas::CalcBaseTransform2D(uint32 ViewSizeX, uint32 ViewSizeY)
{
	return AdjustProjectionMatrixForRHI(
		FTranslationMatrix(FVector(-GPixelCenterOffset,-GPixelCenterOffset,0)) *
		FMatrix(
			FPlane(	1.0f / (ViewSizeX / 2.0f),	0.0,										0.0f,	0.0f	),
			FPlane(	0.0f,						-1.0f / (ViewSizeY / 2.0f),					0.0f,	0.0f	),
			FPlane(	0.0f,						0.0f,										1.0f,	0.0f	),
			FPlane(	-1.0f,						1.0f,										0.0f,	1.0f	)
			)
		);
}
Ejemplo n.º 6
0
FMatrix FSimpleHMD::GetStereoProjectionMatrix(const enum EStereoscopicPass StereoPassType, const float FOV) const
{
	const float ProjectionCenterOffset = 0.151976421f;
	const float PassProjectionOffset = (StereoPassType == eSSP_LEFT_EYE) ? ProjectionCenterOffset : -ProjectionCenterOffset;

	const float HalfFov = 2.19686294f / 2.f;
	const float InWidth = 640.f;
	const float InHeight = 480.f;
	const float XS = 1.0f / tan(HalfFov);
	const float YS = InWidth / tan(HalfFov) / InHeight;

	const float InNearZ = GNearClippingPlane;
	return FMatrix(
		FPlane(XS,                      0.0f,								    0.0f,							0.0f),
		FPlane(0.0f,					YS,	                                    0.0f,							0.0f),
		FPlane(0.0f,	                0.0f,								    0.0f,							1.0f),
		FPlane(0.0f,					0.0f,								    InNearZ,						0.0f))

		* FTranslationMatrix(FVector(PassProjectionOffset,0,0));
}
Ejemplo n.º 7
0
FMatrix FCanvas::CalcViewMatrix(uint32 ViewSizeX, uint32 ViewSizeY, float fFOV)
{
	// convert FOV to randians
	float FOVRad = fFOV * (float)PI / 360.0f;
	// move camera back enough so that the canvas items being rendered are at the same screen extents as regular canvas 2d rendering	
	FTranslationMatrix CamOffsetMat(-FVector(0,0,-FMath::Tan(FOVRad)*ViewSizeX/2));
	// adjust so that canvas items render as if they start at [0,0] upper left corner of screen 
	// and extend to the lower right corner [ViewSizeX,ViewSizeY]. 
	FMatrix OrientCanvasMat(
		FPlane(	1.0f,				0.0f,				0.0f,	0.0f	),
		FPlane(	0.0f,				-1.0f,				0.0f,	0.0f	),
		FPlane(	0.0f,				0.0f,				1.0f,	0.0f	),
		FPlane(	ViewSizeX * -0.5f,	ViewSizeY * 0.5f,	0.0f, 1.0f		)
		);
	return 
		// also apply screen offset to align to pixel centers
		FTranslationMatrix(FVector(-GPixelCenterOffset,-GPixelCenterOffset,0)) * 
		OrientCanvasMat * 
		CamOffsetMat;
}
Ejemplo n.º 8
0
bool FStrategyHelpers::DeprojectScreenToWorld(const FVector2D& ScreenPosition, ULocalPlayer* Player, FVector& RayOrigin, FVector& RayDirection)
{
	if (Player != NULL && Player->ViewportClient != NULL && Player->ViewportClient->Viewport != NULL && Player->PlayerController != NULL)
	{
		//get the projection data
		FSceneViewProjectionData ProjectionData;
		if (Player->GetProjectionData(Player->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
		{
			const FMatrix ViewMatrix = FTranslationMatrix(-ProjectionData.ViewOrigin) * ProjectionData.ViewRotationMatrix;
			const FMatrix InvViewMatrix = ViewMatrix.InverseFast();
			const FMatrix InvProjectionMatrix = ProjectionData.ProjectionMatrix.InverseFast();

			FSceneView::DeprojectScreenToWorld(ScreenPosition, ProjectionData.GetConstrainedViewRect(), InvViewMatrix, InvProjectionMatrix, /*out*/ RayOrigin, /*out*/ RayDirection);

			return true;
		}
	}

	return false;
}
Ejemplo n.º 9
0
void UMyGameViewportClient::UpdateSceneView(FSceneView* const View)
{
    if (View == nullptr)
        return;

    View->ProjectionMatrixUnadjustedForRHI.M[0][0] *= 1.04;

    View->ViewMatrices.PreViewTranslation = -View->ViewMatrices.ViewOrigin;
    View->ViewMatrices.ProjMatrix = _AdjustProjectionMatrixForRHI(View->ProjectionMatrixUnadjustedForRHI);
    View->ViewProjectionMatrix = View->ViewMatrices.GetViewProjMatrix();
    View->InvViewProjectionMatrix = View->ViewMatrices.GetInvProjMatrix() * View->InvViewMatrix;
    FMatrix TranslatedViewMatrix = FTranslationMatrix(-View->ViewMatrices.PreViewTranslation) * View->ViewMatrices.ViewMatrix;
    View->ViewMatrices.TranslatedViewProjectionMatrix = TranslatedViewMatrix * View->ViewMatrices.ProjMatrix;
    View->ViewMatrices.InvTranslatedViewProjectionMatrix = View->ViewMatrices.TranslatedViewProjectionMatrix.Inverse();
    View->ShadowViewMatrices = View->ViewMatrices;

    //View->InvDeviceZToWorldZTransform = CreateInvDeviceZToWorldZTransform(View->ProjectionMatrixUnadjustedForRHI);

    GetViewFrustumBounds(View->ViewFrustum, View->ViewProjectionMatrix, false);
}
Ejemplo n.º 10
0
bool FProjectionUtils::DeprojectScreenToWorld(const FVector2D& screenPosition, ULocalPlayer* player, FVector& rayOrigin, FVector& rayDirection)
{
	if (player != nullptr && player->ViewportClient != nullptr && player->ViewportClient->Viewport != nullptr && player->PlayerController != nullptr)
	{
		// get the projection data
		FSceneViewProjectionData projectionData;
		if (player->GetProjectionData(player->ViewportClient->Viewport, eSSP_FULL, /*out*/ projectionData))
		{
			const FMatrix viewMatrix = FTranslationMatrix(-projectionData.ViewOrigin) * projectionData.ViewRotationMatrix;
			const FMatrix inversedViewMatrix = viewMatrix.InverseFast();
			const FMatrix inversedProjectionMatrix = projectionData.ProjectionMatrix.InverseFast();

			FSceneView::DeprojectScreenToWorld(screenPosition, projectionData.GetConstrainedViewRect(), inversedViewMatrix, inversedProjectionMatrix, /*out*/ rayOrigin, /*out*/ rayDirection);

			return true;
		}
	}

	return false;
}
Ejemplo n.º 11
0
	void SetParameters(FRHICommandList& RHICmdList, const FScene* Scene, const FSceneView& View, const FProjectedShadowInfo* ProjectedShadowInfo)
	{
		FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
		FGlobalShader::SetParameters(RHICmdList, ShaderRHI, View);
		ObjectBufferParameters.Set(RHICmdList, ShaderRHI, *(Scene->DistanceFieldSceneData.ObjectBuffers), Scene->DistanceFieldSceneData.NumObjectsInBuffer);

		ObjectIndirectArguments.SetBuffer(RHICmdList, ShaderRHI, GShadowCulledObjectBuffers.Buffers.ObjectIndirectArguments);
		CulledObjectBounds.SetBuffer(RHICmdList, ShaderRHI, GShadowCulledObjectBuffers.Buffers.Bounds);
		CulledObjectData.SetBuffer(RHICmdList, ShaderRHI, GShadowCulledObjectBuffers.Buffers.Data);
		CulledObjectBoxBounds.SetBuffer(RHICmdList, ShaderRHI, GShadowCulledObjectBuffers.Buffers.BoxBounds);

		SetShaderValue(RHICmdList, ShaderRHI, ObjectBoundingGeometryIndexCount, StencilingGeometry::GLowPolyStencilSphereIndexBuffer.GetIndexCount());
		const FMatrix WorldToShadowValue = FTranslationMatrix(ProjectedShadowInfo->PreShadowTranslation) * ProjectedShadowInfo->SubjectAndReceiverMatrix;
		SetShaderValue(RHICmdList, ShaderRHI, WorldToShadow, WorldToShadowValue);

		int32 NumPlanes = 0;
		const FPlane* PlaneData = NULL;
		FVector4 ShadowBoundingSphereValue(0, 0, 0, 0);

		if (ProjectedShadowInfo->bDirectionalLight)
		{
			NumPlanes = ProjectedShadowInfo->CascadeSettings.ShadowBoundsAccurate.Planes.Num();
			PlaneData = ProjectedShadowInfo->CascadeSettings.ShadowBoundsAccurate.Planes.GetData();
		}
		else if (ProjectedShadowInfo->bOnePassPointLightShadow)
		{
			ShadowBoundingSphereValue = FVector4(ProjectedShadowInfo->ShadowBounds.Center.X, ProjectedShadowInfo->ShadowBounds.Center.Y, ProjectedShadowInfo->ShadowBounds.Center.Z, ProjectedShadowInfo->ShadowBounds.W);
		}
		else
		{
			NumPlanes = ProjectedShadowInfo->CasterFrustum.Planes.Num();
			PlaneData = ProjectedShadowInfo->CasterFrustum.Planes.GetData();
			ShadowBoundingSphereValue = FVector4(ProjectedShadowInfo->PreShadowTranslation, 0);
		}

		check(NumPlanes < 12);
		SetShaderValue(RHICmdList, ShaderRHI, NumShadowHullPlanes, NumPlanes);
		SetShaderValue(RHICmdList, ShaderRHI, ShadowBoundingSphere, ShadowBoundingSphereValue);
		SetShaderValueArray(RHICmdList, ShaderRHI, ShadowConvexHull, PlaneData, NumPlanes);
	}
static void UpdateProjectionMatrix(FSceneView* View, FMatrix OffAxisMatrix)
{
	View->ProjectionMatrixUnadjustedForRHI = OffAxisMatrix;

	FVector viewOrigin(0.0f, 0.0f, View->ProjectionMatrixUnadjustedForRHI.M[3][3]);

	View->ViewMatrices.ViewMatrix.SetOrigin(View->ViewMatrices.ViewMatrix.GetOrigin() - viewOrigin);

	View->InvViewMatrix = View->ViewMatrices.ViewMatrix.Inverse();
	View->ViewMatrices.ViewOrigin += View->InvViewMatrix.TransformPosition(-viewOrigin);
	View->ViewMatrices.PreViewTranslation = -View->ViewMatrices.ViewOrigin;
	View->ViewMatrices.ProjMatrix = _AdjustProjectionMatrixForRHI(View->ProjectionMatrixUnadjustedForRHI);
	View->ViewProjectionMatrix = View->ViewMatrices.GetViewProjMatrix();
	View->InvViewProjectionMatrix = View->ViewMatrices.GetInvProjMatrix() * View->InvViewMatrix;
	FMatrix TranslatedViewMatrix = FTranslationMatrix(-View->ViewMatrices.PreViewTranslation) * View->ViewMatrices.ViewMatrix;
	View->ViewMatrices.TranslatedViewProjectionMatrix = TranslatedViewMatrix * View->ViewMatrices.ProjMatrix;
	View->ViewMatrices.InvTranslatedViewProjectionMatrix = View->ViewMatrices.TranslatedViewProjectionMatrix.Inverse();
	View->ShadowViewMatrices = View->ViewMatrices;

	//View->InvDeviceZToWorldZTransform = CreateInvDeviceZToWorldZTransform(View->ProjectionMatrixUnadjustedForRHI);

	GetViewFrustumBounds(View->ViewFrustum, View->ViewProjectionMatrix, false);
}
void UWorldThumbnailRenderer::GetView(UWorld* World, FSceneViewFamily* ViewFamily, int32 X, int32 Y, uint32 SizeX, uint32 SizeY) const 
{
	check(ViewFamily);
	check(World);
	check(World->PersistentLevel);

	FIntRect ViewRect(
		FMath::Max<int32>(X, 0),
		FMath::Max<int32>(Y, 0),
		FMath::Max<int32>(X + SizeX, 0),
		FMath::Max<int32>(Y + SizeY, 0));

	if (ViewRect.Width() > 0 && ViewRect.Height() > 0)
	{
		FBox WorldBox(0);
		TArray<ULevel*> LevelsToRender = World->GetLevels();
		for ( auto* Level : LevelsToRender )
		{
			if (Level && Level->bIsVisible)
			{
				ALevelBounds* LevelBounds = Level->LevelBoundsActor.Get();
				if (!LevelBounds)
				{
					// Ensure a Level Bounds Actor exists for future renders
					FActorSpawnParameters SpawnParameters;
					SpawnParameters.OverrideLevel = Level;
					LevelBounds = World->SpawnActor<ALevelBounds>(SpawnParameters);
					LevelBounds->UpdateLevelBoundsImmediately();
					Level->LevelBoundsActor = LevelBounds;
				}

				if (!LevelBounds->IsUsingDefaultBounds())
				{
					WorldBox += LevelBounds->GetComponentsBoundingBox();
				}
			}
		}

		UWorldThumbnailInfo* ThumbnailInfo = Cast<UWorldThumbnailInfo>(World->ThumbnailInfo);
		if (!ThumbnailInfo)
		{
			ThumbnailInfo = UWorldThumbnailInfo::StaticClass()->GetDefaultObject<UWorldThumbnailInfo>();
		}

		const FVector Origin = WorldBox.GetCenter();
		FMatrix ViewMatrix = FTranslationMatrix(-Origin);
		FMatrix ProjectionMatrix;
		float FOVScreenSize = 0; // Screen size taking FOV into account
		if (ThumbnailInfo->CameraMode == ECameraProjectionMode::Perspective)
		{
			const float FOVDegrees = 30.f;
			const float HalfFOVRadians = FMath::DegreesToRadians<float>(FOVDegrees) * 0.5f;
			const float WorldRadius = WorldBox.GetSize().Size() / 2.f;
			float TargetDistance = WorldRadius / FMath::Tan(HalfFOVRadians);

			if (ensure(ThumbnailInfo))
			{
				if (TargetDistance + ThumbnailInfo->OrbitZoom < 0)
				{
					ThumbnailInfo->OrbitZoom = -TargetDistance;
				}
			}

			float OrbitPitch = GlobalOrbitPitchOffset + ThumbnailInfo->OrbitPitch;
			float OrbitYaw = GlobalOrbitYawOffset + ThumbnailInfo->OrbitYaw;
			float OrbitZoom = TargetDistance + ThumbnailInfo->OrbitZoom;

			// Ensure a minimum camera distance to prevent problems with really small objects
			const float MinCameraDistance = 48;
			OrbitZoom = FMath::Max<float>(MinCameraDistance, OrbitZoom);

			const FRotator RotationOffsetToViewCenter(0.f, 90.f, 0.f);
			ViewMatrix = ViewMatrix *
				FRotationMatrix(FRotator(0, OrbitYaw, 0)) *
				FRotationMatrix(FRotator(0, 0, OrbitPitch)) *
				FTranslationMatrix(FVector(0, OrbitZoom, 0)) *
				FInverseRotationMatrix(RotationOffsetToViewCenter);

			ViewMatrix = ViewMatrix * FMatrix(
				FPlane(0, 0, 1, 0),
				FPlane(1, 0, 0, 0),
				FPlane(0, 1, 0, 0),
				FPlane(0, 0, 0, 1));

			const float NearPlane = 1.0f;
			ProjectionMatrix = FReversedZPerspectiveMatrix(
				HalfFOVRadians,
				1.0f,
				1.0f,
				NearPlane
				);

			FOVScreenSize = SizeX / FMath::Tan(FOVDegrees);
		}
		else if (ThumbnailInfo->CameraMode == ECameraProjectionMode::Orthographic)
		{
			FVector2D WorldSizeMin2D;
			FVector2D WorldSizeMax2D;
			switch (ThumbnailInfo->OrthoDirection)
			{
				case EOrthoThumbnailDirection::Top:
					ViewMatrix = ViewMatrix * FMatrix(
						FPlane(1, 0, 0, 0),
						FPlane(0, -1, 0, 0),
						FPlane(0, 0, -1, 0),
						FPlane(0, 0, Origin.Z, 1));
					WorldSizeMin2D = FVector2D(WorldBox.Min.X,WorldBox.Min.Y);
					WorldSizeMax2D = FVector2D(WorldBox.Max.X,WorldBox.Max.Y);
					break;
				case EOrthoThumbnailDirection::Bottom:
					ViewMatrix = ViewMatrix * FMatrix(
						FPlane(1, 0, 0, 0),
						FPlane(0, -1, 0, 0),
						FPlane(0, 0, 1, 0),
						FPlane(0, 0, Origin.Z, 1));
					WorldSizeMin2D = FVector2D(WorldBox.Min.X, WorldBox.Min.Y);
					WorldSizeMax2D = FVector2D(WorldBox.Max.X, WorldBox.Max.Y);
					break;
				case EOrthoThumbnailDirection::Front:
					ViewMatrix = ViewMatrix * FMatrix(
						FPlane(1, 0, 0, 0),
						FPlane(0, 0, -1, 0),
						FPlane(0, 1, 0, 0),
						FPlane(0, 0, Origin.Y, 1));
					WorldSizeMin2D = FVector2D(WorldBox.Min.X, WorldBox.Min.Z);
					WorldSizeMax2D = FVector2D(WorldBox.Max.X, WorldBox.Max.Z);
					break;
				case EOrthoThumbnailDirection::Back:
					ViewMatrix = ViewMatrix * FMatrix(
						FPlane(-1, 0, 0, 0),
						FPlane(0, 0, 1, 0),
						FPlane(0, 1, 0, 0),
						FPlane(0, 0, Origin.Y, 1));
					WorldSizeMin2D = FVector2D(WorldBox.Min.X, WorldBox.Min.Z);
					WorldSizeMax2D = FVector2D(WorldBox.Max.X, WorldBox.Max.Z);
					break;
				case EOrthoThumbnailDirection::Left:
					ViewMatrix = ViewMatrix * FMatrix(
						FPlane(0, 0, -1, 0),
						FPlane(-1, 0, 0, 0),
						FPlane(0, 1, 0, 0),
						FPlane(0, 0, Origin.X, 1));
					WorldSizeMin2D = FVector2D(WorldBox.Min.Y, WorldBox.Min.Z);
					WorldSizeMax2D = FVector2D(WorldBox.Max.Y, WorldBox.Max.Z);
					break;
				case EOrthoThumbnailDirection::Right:
					ViewMatrix = ViewMatrix * FMatrix(
						FPlane(0, 0, 1, 0),
						FPlane(1, 0, 0, 0),
						FPlane(0, 1, 0, 0),
						FPlane(0, 0, Origin.X, 1));
					WorldSizeMin2D = FVector2D(WorldBox.Min.Y, WorldBox.Min.Z);
					WorldSizeMax2D = FVector2D(WorldBox.Max.Y, WorldBox.Max.Z);
					break;
				default:
					// Unknown OrthoDirection
					ensureMsgf(false, TEXT("Unknown thumbnail OrthoDirection"));
					break;
			}

			FVector2D WorldSize2D = (WorldSizeMax2D - WorldSizeMin2D);
			WorldSize2D.X = FMath::Abs(WorldSize2D.X);
			WorldSize2D.Y = FMath::Abs(WorldSize2D.Y);
			const bool bUseXAxis = (WorldSize2D.X / WorldSize2D.Y) > 1.f;
			const float WorldAxisSize = bUseXAxis ? WorldSize2D.X : WorldSize2D.Y;
			const uint32 ViewportAxisSize = bUseXAxis ? SizeX : SizeY;
			const float OrthoZoom = WorldAxisSize / ViewportAxisSize / 2.f;
			const float OrthoWidth = FMath::Max(1.f, SizeX * OrthoZoom);
			const float OrthoHeight = FMath::Max(1.f, SizeY * OrthoZoom);

			const float ZOffset = HALF_WORLD_MAX;
			ProjectionMatrix = FReversedZOrthoMatrix(
				OrthoWidth,
				OrthoHeight,
				0.5f / ZOffset,
				ZOffset
				);

			FOVScreenSize = SizeX;
		}
		else
		{
			// Unknown CameraMode
			ensureMsgf(false, TEXT("Unknown thumbnail CameraMode"));
		}

		FSceneViewInitOptions ViewInitOptions;
		ViewInitOptions.ViewFamily = ViewFamily;
		ViewInitOptions.SetViewRectangle(ViewRect);
		ViewInitOptions.BackgroundColor = FLinearColor::Black;
		ViewInitOptions.ViewMatrix = ViewMatrix;
		ViewInitOptions.ProjectionMatrix = ProjectionMatrix;

		FSceneView* NewView = new FSceneView(ViewInitOptions);

		ViewFamily->Views.Add(NewView);

		// Tell the texture streaming system about this thumbnail view, so the textures will stream in as needed
		// NOTE: Sizes may not actually be in screen space depending on how the thumbnail ends up stretched by the UI.  Not a big deal though.
		// NOTE: Textures still take a little time to stream if the view has not been re-rendered recently, so they may briefly appear blurry while mips are prepared
		// NOTE: Content Browser only renders thumbnails for loaded assets, and only when the mouse is over the panel. They'll be frozen in their last state while the mouse cursor is not over the panel.  This is for performance reasons
		IStreamingManager::Get().AddViewInformation(Origin, SizeX, FOVScreenSize);
	}
}
/** 
 * Render bones for debug display
 */
void USkeletalMeshComponent::DebugDrawBones(UCanvas* Canvas, bool bSimpleBones) const
{
	if (GetWorld()->IsGameWorld() && SkeletalMesh && Canvas)
	{
		// draw spacebases, we could cache parent bones, but this is mostly debug feature, I'm not caching it right now
		for ( int32 Index=0; Index<RequiredBones.Num(); ++Index )
		{
			int32 BoneIndex = RequiredBones[Index];
			int32 ParentIndex = SkeletalMesh->RefSkeleton.GetParentIndex(BoneIndex);
			FTransform BoneTM = (SpaceBases[BoneIndex] * ComponentToWorld);
			FVector Start, End;
			FLinearColor LineColor;

			End = BoneTM.GetLocation();

			if (ParentIndex >=0)
			{
				Start = (SpaceBases[ParentIndex] * ComponentToWorld).GetLocation();
				LineColor = FLinearColor::White;
			}
			else
			{
				Start = ComponentToWorld.GetLocation();
				LineColor = FLinearColor::Red;
			}

			if(bSimpleBones)
			{
				DrawDebugCanvasLine(Canvas, Start, End, LineColor);
			}
			else
			{
				static const float SphereRadius = 1.0f;

				//Calc cone size 
				FVector EndToStart = (Start-End);
				float ConeLength = EndToStart.Size();
				float Angle = FMath::RadiansToDegrees(FMath::Atan(SphereRadius / ConeLength));

				DrawDebugCanvasWireSphere(Canvas, End, LineColor, SphereRadius, 10);
				DrawDebugCanvasWireCone(Canvas, FTransform(FRotationMatrix::MakeFromX(EndToStart)*FTranslationMatrix(End)), ConeLength, Angle, 4, LineColor);
			}

			RenderAxisGizmo(BoneTM, Canvas);
		}
	}
}
Ejemplo n.º 15
0
void FCanvasBorderItem::Draw( class FCanvas* InCanvas )
{		
	// Rotate the canvas if the item has rotation
	if( Rotation.IsZero() == false )
	{
		FVector AnchorPos( Size.X * PivotPoint.X, Size.Y * PivotPoint.Y, 0.0f );
		FRotationMatrix RotMatrix( Rotation );
		FMatrix TransformMatrix;
		TransformMatrix = FTranslationMatrix(-AnchorPos) * RotMatrix * FTranslationMatrix(AnchorPos);

		FVector TestPos( Position.X, Position.Y, 0.0f );
		// translate the matrix back to origin, apply the rotation matrix, then transform back to the current position
		FMatrix FinalTransform = FTranslationMatrix(-TestPos) * TransformMatrix * FTranslationMatrix( TestPos );

		InCanvas->PushRelativeTransform(FinalTransform);
	}

	// Draw the item
	if( BorderTexture )
	{
		SCOPE_CYCLE_COUNTER(STAT_Canvas_BorderItemTime);

		FLinearColor ActualColor = Color;
		ActualColor.A *= InCanvas->AlphaModulate;
		const FTexture* CornersTexture = BorderTexture ? BorderTexture : GWhiteTexture;	
		const FTexture* BackTexture = BackgroundTexture ? BackgroundTexture : GWhiteTexture;	
		const FTexture* LeftTexture = BorderLeftTexture ? BorderLeftTexture : GWhiteTexture;	
		const FTexture* RightTexture = BorderRightTexture ? BorderRightTexture : GWhiteTexture;	
		const FTexture* TopTexture = BorderTopTexture ? BorderTopTexture : GWhiteTexture;	
		const FTexture* BottomTexture = BorderBottomTexture ? BorderBottomTexture : GWhiteTexture;	
		FBatchedElements* BatchedElements = InCanvas->GetBatchedElements(FCanvas::ET_Triangle, BatchedElementParameters, CornersTexture, BlendMode);
		FHitProxyId HitProxyId = InCanvas->GetHitProxyId();

		// Correct for Depth. This only works because we won't be applying a transform later--otherwise we'd have to adjust the transform instead.
		float Left, Top, Right, Bottom;
		Left =		Position.X * Z;
		Top =		Position.Y * Z;
		Right =		( Position.X + Size.X ) * Z;
		Bottom =	( Position.Y + Size.Y ) * Z;		

		const float BorderLeftDrawSizeX = BorderLeftTexture->GetSizeX()*BorderScale.X;
		const float BorderLeftDrawSizeY = BorderLeftTexture->GetSizeY()*BorderScale.Y;
		const float BorderTopDrawSizeX = BorderTopTexture->GetSizeX()*BorderScale.X;
		const float BorderTopDrawSizeY = BorderTopTexture->GetSizeY()*BorderScale.Y;
		const float BorderRightDrawSizeX = BorderRightTexture->GetSizeX()*BorderScale.X;
		const float BorderRightDrawSizeY = BorderRightTexture->GetSizeY()*BorderScale.Y;
		const float BorderBottomDrawSizeX = BorderBottomTexture->GetSizeX()*BorderScale.X;
		const float BorderBottomDrawSizeY = BorderBottomTexture->GetSizeY()*BorderScale.Y;

		const float BackgroundTilingX = (Right-Left)/(BackTexture->GetSizeX()*BackgroundScale.X);
		const float BackgroundTilingY = (Bottom-Top)/(BackTexture->GetSizeY()*BackgroundScale.Y);

		//Draw background
		int32 V00 = BatchedElements->AddVertex(
			FVector4( Left + BorderLeftDrawSizeX, Top + BorderTopDrawSizeY, 0.0f, Z ),
			FVector2D( 0, 0 ),
			ActualColor,
			HitProxyId );
		int32 V10 = BatchedElements->AddVertex(
			FVector4( Right - BorderRightDrawSizeX, Top + BorderTopDrawSizeY, 0.0f, Z ),
			FVector2D( BackgroundTilingX, 0 ),
			ActualColor,
			HitProxyId );
		int32 V01 = BatchedElements->AddVertex(
			FVector4( Left + BorderLeftDrawSizeX, Bottom - BorderBottomDrawSizeY, 0.0f, Z ),
			FVector2D( 0, BackgroundTilingY ),		
			ActualColor,
			HitProxyId );
		int32 V11 = BatchedElements->AddVertex(
			FVector4(Right - BorderRightDrawSizeX, Bottom - BorderBottomDrawSizeY, 0.0f, Z ),
			FVector2D( BackgroundTilingX, BackgroundTilingY ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, BackTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, BackTexture, BlendMode );


		const float BorderTextureWidth = BorderTexture->GetSizeX() * (BorderUV1.X - BorderUV0.X);
		const float BorderTextureHeight = BorderTexture->GetSizeY() * (BorderUV1.Y - BorderUV0.Y);
		const float CornerDrawWidth = BorderTextureWidth * CornerSize.X * BorderScale.X;
		const float CornerDrawHeight = BorderTextureHeight * CornerSize.Y * BorderScale.Y;

		//Top Left Corner
		V00 = BatchedElements->AddVertex(
			FVector4( Left, Top, 0.0f, Z ),
			FVector2D( BorderUV0.X, BorderUV0.Y ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( Left + CornerDrawWidth, Top, 0.0f, Z ),
			FVector2D( BorderUV1.X*CornerSize.X, BorderUV0.Y ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( Left, Top + CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV0.X, BorderUV1.Y*CornerSize.Y ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( Left + CornerDrawWidth, Top + CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV1.X*CornerSize.X, BorderUV1.Y*CornerSize.Y ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, CornersTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, CornersTexture, BlendMode );

		// Top Right Corner
		V00 = BatchedElements->AddVertex(
			FVector4( Right - CornerDrawWidth, Top, 0.0f, Z ),
			FVector2D( BorderUV1.X - (BorderUV1.X - BorderUV0.X)*CornerSize.X, BorderUV0.Y ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( Right, Top, 0.0f, Z ),
			FVector2D( BorderUV1.X, BorderUV0.Y ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( Right - CornerDrawWidth, Top + CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV1.X - (BorderUV1.X - BorderUV0.X)*CornerSize.X, BorderUV1.Y*CornerSize.Y ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( Right, Top + CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV1.X, BorderUV1.Y*CornerSize.Y ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, CornersTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, CornersTexture, BlendMode );

		//Left Bottom Corner
		V00 = BatchedElements->AddVertex(
			FVector4( Left, Bottom - CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV0.X, BorderUV1.Y - (BorderUV1.Y - BorderUV0.Y)*CornerSize.Y),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( Left + CornerDrawWidth, Bottom - CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV1.X*CornerSize.X, BorderUV1.Y - (BorderUV1.Y - BorderUV0.Y)*CornerSize.Y ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( Left, Bottom, 0.0f, Z ),
			FVector2D( BorderUV0.X, BorderUV1.Y ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( Left + CornerDrawWidth, Bottom, 0.0f, Z ),
			FVector2D( BorderUV1.X*CornerSize.X, BorderUV1.Y),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, CornersTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, CornersTexture, BlendMode );

		// Right Bottom Corner
		V00 = BatchedElements->AddVertex(
			FVector4( Right - CornerDrawWidth, Bottom - CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV1.X - (BorderUV1.X - BorderUV0.X)*CornerSize.X, BorderUV1.Y - (BorderUV1.Y - BorderUV0.Y)*CornerSize.Y ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( Right, Bottom - CornerDrawHeight, 0.0f, Z ),
			FVector2D( BorderUV1.X, BorderUV1.Y - (BorderUV1.Y - BorderUV0.Y)*CornerSize.Y ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( Right - CornerDrawWidth, Bottom, 0.0f, Z ),
			FVector2D( BorderUV1.X - (BorderUV1.X - BorderUV0.X)*CornerSize.X, BorderUV1.Y ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( Right, Bottom, 0.0f, Z ),
			FVector2D( BorderUV1.X, BorderUV1.Y ),
			ActualColor,
			HitProxyId);
			
		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, CornersTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, CornersTexture, BlendMode );

		const float BorderLeft = Left + CornerDrawWidth;
		const float BorderRight = Right - CornerDrawWidth;
		const float BorderTop = Top + CornerDrawHeight;
		const float BorderBottom = Bottom - CornerDrawHeight;

		//Top Frame Border
		const float TopFrameTilingX = (BorderRight-BorderLeft)/BorderTopDrawSizeX;

		V00 = BatchedElements->AddVertex(
			FVector4( BorderLeft, Top, 0.0f, Z ),
			FVector2D( 0, 0 ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( BorderRight, Top, 0.0f, Z ),
			FVector2D( TopFrameTilingX , 0 ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( BorderLeft, Top + BorderTopDrawSizeY, 0.0f, Z ),
			FVector2D( 0, 1.0f ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( BorderRight, Top + BorderTopDrawSizeY, 0.0f, Z ),
			FVector2D( TopFrameTilingX, 1.0f ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, BorderTopTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, BorderTopTexture, BlendMode );

		//Bottom Frame Border
		const float BottomFrameTilingX = (BorderRight-BorderLeft)/BorderBottomDrawSizeX;

		V00 = BatchedElements->AddVertex(
			FVector4( BorderLeft, Bottom - BorderBottomDrawSizeY, 0.0f, Z ),
			FVector2D( 0, 0 ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( BorderRight, Bottom - BorderBottomDrawSizeY, 0.0f, Z ),
			FVector2D( BottomFrameTilingX, 0 ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( BorderLeft, Bottom, 0.0f, Z ),
			FVector2D( 0, 1.0f ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( BorderRight, Bottom, 0.0f, Z ),
			FVector2D( BottomFrameTilingX, 1.0f ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, BorderBottomTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, BorderBottomTexture, BlendMode );


		//Left Frame Border
		const float LeftFrameTilingY = (BorderBottom-BorderTop) / BorderLeftDrawSizeY;

		V00 = BatchedElements->AddVertex(
			FVector4( Left, BorderTop, 0.0f, Z ),
			FVector2D( 0, 0 ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( Left +  BorderLeftDrawSizeX , BorderTop, 0.0f, Z ),
			FVector2D( 1.0f, 0 ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( Left, BorderBottom, 0.0f, Z ),
			FVector2D( 0, LeftFrameTilingY ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( Left + BorderLeftDrawSizeX, BorderBottom, 0.0f, Z ),
			FVector2D( 1.0f, LeftFrameTilingY ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, BorderLeftTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, BorderLeftTexture, BlendMode );


		//Right Frame Border
		const float RightFrameTilingY = (BorderBottom-BorderTop)/BorderRightDrawSizeY;

		V00 = BatchedElements->AddVertex(
			FVector4( Right - BorderRightDrawSizeX, BorderTop, 0.0f, Z ),
			FVector2D( 0, 0 ),
			ActualColor,
			HitProxyId );
		V10 = BatchedElements->AddVertex(
			FVector4( Right, BorderTop, 0.0f, Z ),
			FVector2D( 1.0f , 0 ),
			ActualColor,
			HitProxyId );
		V01 = BatchedElements->AddVertex(
			FVector4( Right - BorderRightDrawSizeX, BorderBottom, 0.0f, Z ),
			FVector2D( 0, RightFrameTilingY ),		
			ActualColor,
			HitProxyId );
		V11 = BatchedElements->AddVertex(
			FVector4( Right, BorderBottom, 0.0f, Z ),
			FVector2D( 1.0f, RightFrameTilingY ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, BorderRightTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, BorderRightTexture, BlendMode );

	}

	// Restore the canvas transform if we rotated it.
	if( Rotation.IsZero() == false )
	{
		InCanvas->PopTransform();
	}

}
void UOffAxisGameViewportClient::Draw(FViewport* InViewport, FCanvas* SceneCanvas)
{
	//Valid SceneCanvas is required.  Make this explicit.
	check(SceneCanvas);

	FCanvas* DebugCanvas = InViewport->GetDebugCanvas();

	// Create a temporary canvas if there isn't already one.
	static FName CanvasObjectName(TEXT("CanvasObject"));
	UCanvas* CanvasObject = GetCanvasByName(CanvasObjectName);
	CanvasObject->Canvas = SceneCanvas;

	// Create temp debug canvas object
	static FName DebugCanvasObjectName(TEXT("DebugCanvasObject"));
	UCanvas* DebugCanvasObject = GetCanvasByName(DebugCanvasObjectName);
	DebugCanvasObject->Canvas = DebugCanvas;
	DebugCanvasObject->Init(InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, NULL);

	const bool bScaledToRenderTarget = GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D(InViewport);
	if (bScaledToRenderTarget)
	{
		// Allow HMD to modify screen settings
		GEngine->HMDDevice->UpdateScreenSettings(Viewport);
	}
	if (DebugCanvas)
	{
		DebugCanvas->SetScaledToRenderTarget(bScaledToRenderTarget);
	}
	if (SceneCanvas)
	{
		SceneCanvas->SetScaledToRenderTarget(bScaledToRenderTarget);
	}

	bool bUIDisableWorldRendering = false;
	FViewElementDrawer GameViewDrawer;

	// create the view family for rendering the world scene to the viewport's render target
	FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
		InViewport,
		GetWorld()->Scene,
		EngineShowFlags)
		.SetRealtimeUpdate(true));

	// Allow HMD to modify the view later, just before rendering
	if (GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D(InViewport))
	{
		ISceneViewExtension* HmdViewExt = GEngine->HMDDevice->GetViewExtension();
		if (HmdViewExt)
		{
			ViewFamily.ViewExtensions.Add(HmdViewExt);
			HmdViewExt->ModifyShowFlags(ViewFamily.EngineShowFlags);
		}
	}


	ESplitScreenType::Type SplitScreenConfig = GetCurrentSplitscreenConfiguration();
	EngineShowFlagOverride(ESFIM_Game, (EViewModeIndex)ViewModeIndex, ViewFamily.EngineShowFlags, NAME_None, SplitScreenConfig != ESplitScreenType::None);

	TMap<ULocalPlayer*, FSceneView*> PlayerViewMap;

	FAudioDevice* AudioDevice = GEngine->GetAudioDevice();
	bool bReverbSettingsFound = false;
	FReverbSettings ReverbSettings;
	class AAudioVolume* AudioVolume = nullptr;

	for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
	{
		APlayerController* PlayerController = *Iterator;
		if (PlayerController)
		{
			ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player);
			if (LocalPlayer)
			{
				const bool bEnableStereo = GEngine->IsStereoscopic3D(InViewport);
				int32 NumViews = bEnableStereo ? 2 : 1;

				for (int i = 0; i < NumViews; ++i)
				{
					// Calculate the player's view information.
					FVector		ViewLocation;
					FRotator	ViewRotation;

					EStereoscopicPass PassType = !bEnableStereo ? eSSP_FULL : ((i == 0) ? eSSP_LEFT_EYE : eSSP_RIGHT_EYE);

					FSceneView* View = LocalPlayer->CalcSceneView(&ViewFamily, ViewLocation, ViewRotation, InViewport, &GameViewDrawer, PassType);

					if (mOffAxisMatrixSetted)
						UpdateProjectionMatrix(View, mOffAxisMatrix);

					if (View)
					{
						if (View->Family->EngineShowFlags.Wireframe)
						{
							// Wireframe color is emissive-only, and mesh-modifying materials do not use material substitution, hence...
							View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
							View->SpecularOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
						}
						else if (View->Family->EngineShowFlags.OverrideDiffuseAndSpecular)
						{
							View->DiffuseOverrideParameter = FVector4(GEngine->LightingOnlyBrightness.R, GEngine->LightingOnlyBrightness.G, GEngine->LightingOnlyBrightness.B, 0.0f);
							View->SpecularOverrideParameter = FVector4(.1f, .1f, .1f, 0.0f);
						}
						else if (View->Family->EngineShowFlags.ReflectionOverride)
						{
							View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
							View->SpecularOverrideParameter = FVector4(1, 1, 1, 0.0f);
							View->NormalOverrideParameter = FVector4(0, 0, 1, 0.0f);
							View->RoughnessOverrideParameter = FVector2D(0.0f, 0.0f);
						}


						if (!View->Family->EngineShowFlags.Diffuse)
						{
							View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
						}

						if (!View->Family->EngineShowFlags.Specular)
						{
							View->SpecularOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
						}

						View->CameraConstrainedViewRect = View->UnscaledViewRect;

						// If this is the primary drawing pass, update things that depend on the view location
						if (i == 0)
						{
							// Save the location of the view.
							LocalPlayer->LastViewLocation = ViewLocation;

							PlayerViewMap.Add(LocalPlayer, View);

							// Update the listener.
							if (AudioDevice != NULL)
							{
								FVector Location;
								FVector ProjFront;
								FVector ProjRight;
								PlayerController->GetAudioListenerPosition(/*out*/ Location, /*out*/ ProjFront, /*out*/ ProjRight);

								FTransform ListenerTransform(FRotationMatrix::MakeFromXY(ProjFront, ProjRight));
								ListenerTransform.SetTranslation(Location);
								ListenerTransform.NormalizeRotation();

								bReverbSettingsFound = true;

								FReverbSettings PlayerReverbSettings;
								FInteriorSettings PlayerInteriorSettings;
								class AAudioVolume* PlayerAudioVolume = GetWorld()->GetAudioSettings(Location, &PlayerReverbSettings, &PlayerInteriorSettings);

								if (AudioVolume == nullptr || (PlayerAudioVolume != nullptr && PlayerAudioVolume->Priority > AudioVolume->Priority))
								{
									AudioVolume = PlayerAudioVolume;
									ReverbSettings = PlayerReverbSettings;
								}

								uint32 ViewportIndex = PlayerViewMap.Num() - 1;
								AudioDevice->SetListener(ViewportIndex, ListenerTransform, (View->bCameraCut ? 0.f : GetWorld()->GetDeltaSeconds()), PlayerAudioVolume, PlayerInteriorSettings);
							}

						}

						// Add view information for resource streaming.
						IStreamingManager::Get().AddViewInformation(View->ViewMatrices.ViewOrigin, View->ViewRect.Width(), View->ViewRect.Width() * View->ViewMatrices.ProjMatrix.M[0][0]);
						GetWorld()->ViewLocationsRenderedLastFrame.Add(View->ViewMatrices.ViewOrigin);
					}
				}
			}
		}
	}

	if (bReverbSettingsFound)
	{
		AudioDevice->SetReverbSettings(AudioVolume, ReverbSettings);
	}

	// Update level streaming.
	GetWorld()->UpdateLevelStreaming();

	// Draw the player views.
	if (!bDisableWorldRendering && !bUIDisableWorldRendering && PlayerViewMap.Num() > 0)
	{
		GetRendererModule().BeginRenderingViewFamily(SceneCanvas, &ViewFamily);
	}

	// Clear areas of the rendertarget (backbuffer) that aren't drawn over by the views.
	{
		// Find largest rectangle bounded by all rendered views.
		uint32 MinX = InViewport->GetSizeXY().X, MinY = InViewport->GetSizeXY().Y, MaxX = 0, MaxY = 0;
		uint32 TotalArea = 0;
		for (int32 ViewIndex = 0; ViewIndex < ViewFamily.Views.Num(); ++ViewIndex)
		{
			const FSceneView* View = ViewFamily.Views[ViewIndex];

			FIntRect UpscaledViewRect = View->UnscaledViewRect;

			MinX = FMath::Min<uint32>(UpscaledViewRect.Min.X, MinX);
			MinY = FMath::Min<uint32>(UpscaledViewRect.Min.Y, MinY);
			MaxX = FMath::Max<uint32>(UpscaledViewRect.Max.X, MaxX);
			MaxY = FMath::Max<uint32>(UpscaledViewRect.Max.Y, MaxY);
			TotalArea += FMath::TruncToInt(UpscaledViewRect.Width()) * FMath::TruncToInt(UpscaledViewRect.Height());
		}

		// To draw black borders around the rendered image (prevents artifacts from post processing passes that read outside of the image e.g. PostProcessAA)
		{
			int32 BlackBorders = 0; // FMath::Clamp(CVarSetBlackBordersEnabled.GetValueOnGameThread(), 0, 10);

			if (ViewFamily.Views.Num() == 1 && BlackBorders)
			{
				MinX += BlackBorders;
				MinY += BlackBorders;
				MaxX -= BlackBorders;
				MaxY -= BlackBorders;
				TotalArea = (MaxX - MinX) * (MaxY - MinY);
			}
		}

		// If the views don't cover the entire bounding rectangle, clear the entire buffer.
		if (ViewFamily.Views.Num() == 0 || TotalArea != (MaxX - MinX)*(MaxY - MinY) || bDisableWorldRendering)
		{
			SceneCanvas->DrawTile(0, 0, InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
		}
		else
		{
			// clear left
			if (MinX > 0)
			{
				SceneCanvas->DrawTile(0, 0, MinX, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
			// clear right
			if (MaxX < (uint32)InViewport->GetSizeXY().X)
			{
				SceneCanvas->DrawTile(MaxX, 0, InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
			// clear top
			if (MinY > 0)
			{
				SceneCanvas->DrawTile(MinX, 0, MaxX, MinY, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
			// clear bottom
			if (MaxY < (uint32)InViewport->GetSizeXY().Y)
			{
				SceneCanvas->DrawTile(MinX, MaxY, MaxX, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
		}
	}

	// Remove temporary debug lines.
	if (GetWorld()->LineBatcher != NULL)
	{
		GetWorld()->LineBatcher->Flush();
	}

	if (GetWorld()->ForegroundLineBatcher != NULL)
	{
		GetWorld()->ForegroundLineBatcher->Flush();
	}

	// Draw FX debug information.
	if (GetWorld()->FXSystem)
	{
		GetWorld()->FXSystem->DrawDebug(SceneCanvas);
	}

	// Render the UI.
	{
		//SCOPE_CYCLE_COUNTER(STAT_UIDrawingTime);

		// render HUD
		bool bDisplayedSubtitles = false;
		for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
		{
			APlayerController* PlayerController = *Iterator;
			if (PlayerController)
			{
				ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player);
				if (LocalPlayer)
				{
					FSceneView* View = PlayerViewMap.FindRef(LocalPlayer);
					if (View != NULL)
					{
						// rendering to directly to viewport target
						FVector CanvasOrigin(FMath::TruncToFloat(View->UnscaledViewRect.Min.X), FMath::TruncToInt(View->UnscaledViewRect.Min.Y), 0.f);

						CanvasObject->Init(View->UnscaledViewRect.Width(), View->UnscaledViewRect.Height(), View);

						// Set the canvas transform for the player's view rectangle.
						SceneCanvas->PushAbsoluteTransform(FTranslationMatrix(CanvasOrigin));
						CanvasObject->ApplySafeZoneTransform();

						// Render the player's HUD.
						if (PlayerController->MyHUD)
						{
							//SCOPE_CYCLE_COUNTER(STAT_HudTime);

							DebugCanvasObject->SceneView = View;
							PlayerController->MyHUD->SetCanvas(CanvasObject, DebugCanvasObject);
							if (GEngine->IsStereoscopic3D(InViewport))
							{
								check(GEngine->StereoRenderingDevice.IsValid());
								GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, SceneCanvas, CanvasObject, Viewport);
								PlayerController->MyHUD->PostRender();
								SceneCanvas->PopTransform();

								GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, SceneCanvas, CanvasObject, Viewport);
								PlayerController->MyHUD->PostRender();
								SceneCanvas->PopTransform();

								// Reset the canvas for rendering to the full viewport.
								CanvasObject->Reset();
								CanvasObject->SizeX = View->UnscaledViewRect.Width();
								CanvasObject->SizeY = View->UnscaledViewRect.Height();
								CanvasObject->SetView(NULL);
								CanvasObject->Update();
							}
							else
							{
								PlayerController->MyHUD->PostRender();
							}

							// Put these pointers back as if a blueprint breakpoint hits during HUD PostRender they can
							// have been changed
							CanvasObject->Canvas = SceneCanvas;
							DebugCanvasObject->Canvas = DebugCanvas;

							// A side effect of PostRender is that the playercontroller could be destroyed
							if (!PlayerController->IsPendingKill())
							{
								PlayerController->MyHUD->SetCanvas(NULL, NULL);
							}
						}

						if (DebugCanvas != NULL)
						{
							DebugCanvas->PushAbsoluteTransform(FTranslationMatrix(CanvasOrigin));
							UDebugDrawService::Draw(ViewFamily.EngineShowFlags, InViewport, View, DebugCanvas);
							DebugCanvas->PopTransform();
						}

						CanvasObject->PopSafeZoneTransform();
						SceneCanvas->PopTransform();

						// draw subtitles
						if (!bDisplayedSubtitles)
						{
							FVector2D MinPos(0.f, 0.f);
							FVector2D MaxPos(1.f, 1.f);
							GetSubtitleRegion(MinPos, MaxPos);

							uint32 SizeX = SceneCanvas->GetRenderTarget()->GetSizeXY().X;
							uint32 SizeY = SceneCanvas->GetRenderTarget()->GetSizeXY().Y;
							FIntRect SubtitleRegion(FMath::TruncToInt(SizeX * MinPos.X), FMath::TruncToInt(SizeY * MinPos.Y), FMath::TruncToInt(SizeX * MaxPos.X), FMath::TruncToInt(SizeY * MaxPos.Y));
							// We need a world to do this
							FSubtitleManager::GetSubtitleManager()->DisplaySubtitles(SceneCanvas, SubtitleRegion, GetWorld()->GetAudioTimeSeconds());
						}
					}
				}
			}
		}

		//ensure canvas has been flushed before rendering UI
		SceneCanvas->Flush_GameThread();
		if (DebugCanvas != NULL)
		{
			DebugCanvas->Flush_GameThread();
		}
		// Allow the viewport to render additional stuff
		PostRender(DebugCanvasObject);

		// Render the console.
		if (ViewportConsole)
		{
			if (GEngine->IsStereoscopic3D(InViewport))
			{
				GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, DebugCanvas, DebugCanvasObject, Viewport);
				ViewportConsole->PostRender_Console(DebugCanvasObject);
#if !UE_BUILD_SHIPPING
				if (DebugCanvas != NULL && GEngine->HMDDevice.IsValid())
				{
					GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_LEFT_EYE);
				}
#endif
				DebugCanvas->PopTransform();

				GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, DebugCanvas, DebugCanvasObject, Viewport);
				ViewportConsole->PostRender_Console(DebugCanvasObject);
#if !UE_BUILD_SHIPPING
				if (DebugCanvas != NULL && GEngine->HMDDevice.IsValid())
				{
					GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_RIGHT_EYE);
				}
#endif
				DebugCanvas->PopTransform();

				// Reset the canvas for rendering to the full viewport.
				DebugCanvasObject->Reset();
				DebugCanvasObject->SizeX = Viewport->GetSizeXY().X;
				DebugCanvasObject->SizeY = Viewport->GetSizeXY().Y;
				DebugCanvasObject->SetView(NULL);
				DebugCanvasObject->Update();
			}
			else
			{
				ViewportConsole->PostRender_Console(DebugCanvasObject);
			}
		}
	}


	// Grab the player camera location and orientation so we can pass that along to the stats drawing code.
	FVector PlayerCameraLocation = FVector::ZeroVector;
	FRotator PlayerCameraRotation = FRotator::ZeroRotator;
	{
		for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
		{
			(*Iterator)->GetPlayerViewPoint(PlayerCameraLocation, PlayerCameraRotation);
		}
	}

	if (GEngine->IsStereoscopic3D(InViewport))
	{
		GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, DebugCanvas, DebugCanvasObject, InViewport);
		DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation);
		DebugCanvas->PopTransform();

		GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, DebugCanvas, DebugCanvasObject, InViewport);
		DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation);
		DebugCanvas->PopTransform();

		// Reset the canvas for rendering to the full viewport.
		DebugCanvasObject->Reset();
		DebugCanvasObject->SizeX = Viewport->GetSizeXY().X;
		DebugCanvasObject->SizeY = Viewport->GetSizeXY().Y;
		DebugCanvasObject->SetView(NULL);
		DebugCanvasObject->Update();

#if !UE_BUILD_SHIPPING
		if (GEngine->HMDDevice.IsValid())
		{
			GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_FULL);
		}
#endif
	}
	else
	{
		DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation);
	}
}
Ejemplo n.º 17
0
static FSceneView& CreateSceneView( FSceneViewFamilyContext& ViewFamilyContext, FSlateBackBuffer& BackBuffer, const FMatrix& ViewProjectionMatrix )
{
	FIntRect ViewRect(FIntPoint(0, 0), BackBuffer.GetSizeXY());

	// make a temporary view
	FSceneViewInitOptions ViewInitOptions;
	ViewInitOptions.ViewFamily = &ViewFamilyContext;
	ViewInitOptions.SetViewRectangle(ViewRect);
	ViewInitOptions.ViewOrigin = FVector::ZeroVector;
	ViewInitOptions.ViewRotationMatrix = FMatrix::Identity;
	ViewInitOptions.ProjectionMatrix = ViewProjectionMatrix;
	ViewInitOptions.BackgroundColor = FLinearColor::Black;
	ViewInitOptions.OverlayColor = FLinearColor::White;

	FSceneView* View = new FSceneView( ViewInitOptions );
	ViewFamilyContext.Views.Add( View );

	/** The view transform, starting from world-space points translated by -ViewOrigin. */
	FMatrix EffectiveTranslatedViewMatrix = FTranslationMatrix(-View->ViewMatrices.PreViewTranslation) * View->ViewMatrices.ViewMatrix;

	// Create the view's uniform buffer.
	FViewUniformShaderParameters ViewUniformShaderParameters;
	ViewUniformShaderParameters.TranslatedWorldToClip = View->ViewMatrices.TranslatedViewProjectionMatrix;
	ViewUniformShaderParameters.WorldToClip = ViewProjectionMatrix;
	ViewUniformShaderParameters.TranslatedWorldToView = EffectiveTranslatedViewMatrix;
	ViewUniformShaderParameters.ViewToTranslatedWorld = View->InvViewMatrix * FTranslationMatrix(View->ViewMatrices.PreViewTranslation);
	ViewUniformShaderParameters.ViewToClip = View->ViewMatrices.ProjMatrix;
	ViewUniformShaderParameters.ClipToTranslatedWorld = View->ViewMatrices.InvTranslatedViewProjectionMatrix;
	ViewUniformShaderParameters.ViewForward = EffectiveTranslatedViewMatrix.GetColumn(2);
	ViewUniformShaderParameters.ViewUp = EffectiveTranslatedViewMatrix.GetColumn(1);
	ViewUniformShaderParameters.ViewRight = EffectiveTranslatedViewMatrix.GetColumn(0);
	ViewUniformShaderParameters.InvDeviceZToWorldZTransform = View->InvDeviceZToWorldZTransform;
	ViewUniformShaderParameters.ScreenPositionScaleBias = FVector4(0,0,0,0);
	ViewUniformShaderParameters.ViewRectMin = FVector4(ViewRect.Min.X, ViewRect.Min.Y, 0.0f, 0.0f);
	ViewUniformShaderParameters.ViewSizeAndSceneTexelSize = FVector4(ViewRect.Width(), ViewRect.Height(), 1.0f/ViewRect.Width(), 1.0f/ViewRect.Height() );
	ViewUniformShaderParameters.ViewOrigin = View->ViewMatrices.ViewOrigin;
	ViewUniformShaderParameters.TranslatedViewOrigin = View->ViewMatrices.ViewOrigin + View->ViewMatrices.PreViewTranslation;
	ViewUniformShaderParameters.DiffuseOverrideParameter = View->DiffuseOverrideParameter;
	ViewUniformShaderParameters.SpecularOverrideParameter = View->SpecularOverrideParameter;
	ViewUniformShaderParameters.NormalOverrideParameter = View->NormalOverrideParameter;
	ViewUniformShaderParameters.RoughnessOverrideParameter = View->RoughnessOverrideParameter;
	ViewUniformShaderParameters.PrevFrameGameTime = View->Family->CurrentWorldTime - View->Family->DeltaWorldTime;
	ViewUniformShaderParameters.PrevFrameRealTime = View->Family->CurrentRealTime - View->Family->DeltaWorldTime;
	ViewUniformShaderParameters.PreViewTranslation = View->ViewMatrices.PreViewTranslation;
	ViewUniformShaderParameters.CullingSign = View->bReverseCulling ? -1.0f : 1.0f;
	ViewUniformShaderParameters.NearPlane = GNearClippingPlane;
	ViewUniformShaderParameters.GameTime = View->Family->CurrentWorldTime;
	ViewUniformShaderParameters.RealTime = View->Family->CurrentRealTime;
	ViewUniformShaderParameters.Random = FMath::Rand();
	ViewUniformShaderParameters.FrameNumber = View->Family->FrameNumber;

	ViewUniformShaderParameters.DirectionalLightShadowTexture = GWhiteTexture->TextureRHI;
	ViewUniformShaderParameters.DirectionalLightShadowSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();

	ViewUniformShaderParameters.ScreenToWorld = FMatrix(
		FPlane(1, 0, 0, 0),
		FPlane(0, 1, 0, 0),
		FPlane(0, 0, View->ProjectionMatrixUnadjustedForRHI.M[2][2], 1),
		FPlane(0, 0, View->ProjectionMatrixUnadjustedForRHI.M[3][2], 0))
		* View->InvViewProjectionMatrix;

	ViewUniformShaderParameters.ScreenToTranslatedWorld = FMatrix(
		FPlane(1, 0, 0, 0),
		FPlane(0, 1, 0, 0),
		FPlane(0, 0, View->ProjectionMatrixUnadjustedForRHI.M[2][2], 1),
		FPlane(0, 0, View->ProjectionMatrixUnadjustedForRHI.M[3][2], 0))
		* View->ViewMatrices.InvTranslatedViewProjectionMatrix;

	View->UniformBuffer = TUniformBufferRef<FViewUniformShaderParameters>::CreateUniformBufferImmediate(ViewUniformShaderParameters, UniformBuffer_SingleFrame);
	return *View;
}
void FThumbnailPreviewScene::GetView(FSceneViewFamily* ViewFamily, int32 X, int32 Y, uint32 SizeX, uint32 SizeY) const
{
    check(ViewFamily);

    FIntRect ViewRect(
        FMath::Max<int32>(X,0),
        FMath::Max<int32>(Y,0),
        FMath::Max<int32>(X+SizeX,0),
        FMath::Max<int32>(Y+SizeY,0));

    if (ViewRect.Width() > 0 && ViewRect.Height() > 0)
    {
        const float FOVDegrees = 30.f;
        const float HalfFOVRadians = FMath::DegreesToRadians<float>(FOVDegrees) * 0.5f;
        static_assert((int32)ERHIZBuffer::IsInverted != 0, "Check NearPlane and Projection Matrix");
        const float NearPlane = 1.0f;
        FMatrix ProjectionMatrix = FReversedZPerspectiveMatrix(
                                       HalfFOVRadians,
                                       1.0f,
                                       1.0f,
                                       NearPlane
                                   );

        FVector Origin(0);
        float OrbitPitch = 0;
        float OrbitYaw = 0;
        float OrbitZoom = 0;
        GetViewMatrixParameters(FOVDegrees, Origin, OrbitPitch, OrbitYaw, OrbitZoom);

        // Ensure a minimum camera distance to prevent problems with really small objects
        const float MinCameraDistance = 48;
        OrbitZoom = FMath::Max<float>(MinCameraDistance, OrbitZoom);

        const FRotator RotationOffsetToViewCenter(0.f, 90.f, 0.f);
        FMatrix ViewRotationMatrix = FRotationMatrix( FRotator(0, OrbitYaw, 0) ) *
                                     FRotationMatrix( FRotator(0, 0, OrbitPitch) ) *
                                     FTranslationMatrix( FVector(0, OrbitZoom, 0) ) *
                                     FInverseRotationMatrix( RotationOffsetToViewCenter );

        ViewRotationMatrix = ViewRotationMatrix * FMatrix(
                                 FPlane(0,	0,	1,	0),
                                 FPlane(1,	0,	0,	0),
                                 FPlane(0,	1,	0,	0),
                                 FPlane(0,	0,	0,	1));

        Origin -= ViewRotationMatrix.InverseTransformPosition( FVector::ZeroVector );
        ViewRotationMatrix = ViewRotationMatrix.RemoveTranslation();

        FSceneViewInitOptions ViewInitOptions;
        ViewInitOptions.ViewFamily = ViewFamily;
        ViewInitOptions.SetViewRectangle(ViewRect);
        ViewInitOptions.ViewOrigin = -Origin;
        ViewInitOptions.ViewRotationMatrix = ViewRotationMatrix;
        ViewInitOptions.ProjectionMatrix = ProjectionMatrix;
        ViewInitOptions.BackgroundColor = FLinearColor::Black;

        FSceneView* NewView = new FSceneView(ViewInitOptions);

        ViewFamily->Views.Add(NewView);

        NewView->StartFinalPostprocessSettings( ViewInitOptions.ViewOrigin );
        NewView->EndFinalPostprocessSettings(ViewInitOptions);

        FFinalPostProcessSettings::FCubemapEntry& CubemapEntry = *new(NewView->FinalPostProcessSettings.ContributingCubemaps) FFinalPostProcessSettings::FCubemapEntry;
        CubemapEntry.AmbientCubemap = GUnrealEd->GetThumbnailManager()->AmbientCubemap;
        const float AmbientCubemapIntensity = 1.69;
        CubemapEntry.AmbientCubemapTintMulScaleValue = FLinearColor::White * AmbientCubemapIntensity;

        // Tell the texture streaming system about this thumbnail view, so the textures will stream in as needed
        // NOTE: Sizes may not actually be in screen space depending on how the thumbnail ends up stretched by the UI.  Not a big deal though.
        // NOTE: Textures still take a little time to stream if the view has not been re-rendered recently, so they may briefly appear blurry while mips are prepared
        // NOTE: Content Browser only renders thumbnails for loaded assets, and only when the mouse is over the panel. They'll be frozen in their last state while the mouse cursor is not over the panel.  This is for performance reasons
        IStreamingManager::Get().AddViewInformation( Origin, SizeX, SizeX / FMath::Tan( FOVDegrees ) );
    }
}
Ejemplo n.º 19
0
FSceneView::FSceneView(const FSceneViewInitOptions& InitOptions)
	: Family(InitOptions.ViewFamily)
	, State(InitOptions.SceneViewStateInterface)
	, ViewActor(InitOptions.ViewActor)
	, Drawer(InitOptions.ViewElementDrawer)
	, ViewRect(InitOptions.GetConstrainedViewRect())
	, UnscaledViewRect(InitOptions.GetConstrainedViewRect())
	, UnconstrainedViewRect(InitOptions.GetViewRect())
	, MaxShadowCascades(10)
	, WorldToMetersScale(InitOptions.WorldToMetersScale)
	, ProjectionMatrixUnadjustedForRHI(InitOptions.ProjectionMatrix)
	, BackgroundColor(InitOptions.BackgroundColor)
	, OverlayColor(InitOptions.OverlayColor)
	, ColorScale(InitOptions.ColorScale)
	, StereoPass(InitOptions.StereoPass)
	, DiffuseOverrideParameter(FVector4(0,0,0,1))
	, SpecularOverrideParameter(FVector4(0,0,0,1))
	, NormalOverrideParameter(FVector4(0,0,0,1))
	, RoughnessOverrideParameter(FVector2D(0,1))
	, HiddenPrimitives(InitOptions.HiddenPrimitives)
	, LODDistanceFactor(InitOptions.LODDistanceFactor)
	, bCameraCut(InitOptions.bInCameraCut)
	, bOriginOffsetThisFrame(InitOptions.bOriginOffsetThisFrame)
	, CursorPos(InitOptions.CursorPos)
	, bIsGameView(false)
	, bForceShowMaterials(false)
	, bIsViewInfo(false)
	, bIsSceneCapture(false)
	, bIsReflectionCapture(false)
	, bIsLocked(false)
	, bStaticSceneOnly(false)
#if WITH_EDITOR
	, OverrideLODViewOrigin(InitOptions.OverrideLODViewOrigin)
	, bAllowTranslucentPrimitivesInHitProxy( true )
	, bHasSelectedComponents( false )
#endif
	, FeatureLevel(InitOptions.ViewFamily ? InitOptions.ViewFamily->GetFeatureLevel() : GMaxRHIFeatureLevel)
{
	check(UnscaledViewRect.Min.X >= 0);
	check(UnscaledViewRect.Min.Y >= 0);
	check(UnscaledViewRect.Width() > 0);
	check(UnscaledViewRect.Height() > 0);

	ViewMatrices.ViewMatrix = InitOptions.ViewMatrix;

	// Adjust the projection matrix for the current RHI.
	ViewMatrices.ProjMatrix = AdjustProjectionMatrixForRHI(ProjectionMatrixUnadjustedForRHI);

	// Compute the view projection matrix and its inverse.
	ViewProjectionMatrix = ViewMatrices.GetViewProjMatrix();

	// For precision reasons the view matrix inverse is calculated independently.
	InvViewMatrix = ViewMatrices.ViewMatrix.Inverse();
	InvViewProjectionMatrix = ViewMatrices.GetInvProjMatrix() * InvViewMatrix;

	bool ApplyPreViewTranslation = true;

	// Calculate the view origin from the view/projection matrices.
	if(IsPerspectiveProjection())
	{
		ViewMatrices.ViewOrigin = InvViewMatrix.GetOrigin();
	}
#if WITH_EDITOR
	else if (InitOptions.bUseFauxOrthoViewPos)
	{
		float DistanceToViewOrigin = WORLD_MAX;
		ViewMatrices.ViewOrigin = FVector4(InvViewMatrix.TransformVector(FVector(0,0,-1)).GetSafeNormal()*DistanceToViewOrigin,1) + InvViewMatrix.GetOrigin();
	}
#endif
	else
	{
		ViewMatrices.ViewOrigin = FVector4(InvViewMatrix.TransformVector(FVector(0,0,-1)).GetSafeNormal(),0);
		// to avoid issues with view dependent effect (e.g. Frensel)
		ApplyPreViewTranslation = false;
	}

	// Translate world-space so its origin is at ViewOrigin for improved precision.
	// Note that this isn't exactly right for orthogonal projections (See the above special case), but we still use ViewOrigin
	// in that case so the same value may be used in shaders for both the world-space translation and the camera's world position.
	if(ApplyPreViewTranslation)
	{
		ViewMatrices.PreViewTranslation = -FVector(ViewMatrices.ViewOrigin);

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
		{
			// console variable override
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.PreViewTranslation")); 
			int32 Value = CVar->GetValueOnGameThread();

			static FVector PreViewTranslationBackup;

			if(Value)
			{
				PreViewTranslationBackup = ViewMatrices.PreViewTranslation;
			}
			else
			{
				ViewMatrices.PreViewTranslation = PreViewTranslationBackup;
			}
		}
#endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	}

	/** The view transform, starting from world-space points translated by -ViewOrigin. */
	FMatrix TranslatedViewMatrix = FTranslationMatrix(-ViewMatrices.PreViewTranslation) * ViewMatrices.ViewMatrix;
	
	// Compute a transform from view origin centered world-space to clip space.
	ViewMatrices.TranslatedViewProjectionMatrix = TranslatedViewMatrix * ViewMatrices.ProjMatrix;
	ViewMatrices.InvTranslatedViewProjectionMatrix = ViewMatrices.TranslatedViewProjectionMatrix.Inverse();

	// Compute screen scale factors.
	// Stereo renders at half horizontal resolution, but compute shadow resolution based on full resolution.
	const bool bStereo = StereoPass != eSSP_FULL;
	const float ScreenXScale = bStereo ? 2.0f : 1.0f;
	ViewMatrices.ProjectionScale.X = ScreenXScale * FMath::Abs(ViewMatrices.ProjMatrix.M[0][0]);
	ViewMatrices.ProjectionScale.Y = FMath::Abs(ViewMatrices.ProjMatrix.M[1][1]);
	ViewMatrices.ScreenScale = FMath::Max(
		ViewRect.Size().X * 0.5f * ViewMatrices.ProjectionScale.X,
		ViewRect.Size().Y * 0.5f * ViewMatrices.ProjectionScale.Y
		);
	
	ShadowViewMatrices = ViewMatrices;

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	{
		// console variable override
		int32 Value = CVarShadowFreezeCamera.GetValueOnAnyThread();

		static FViewMatrices Backup = ShadowViewMatrices;

		if(Value)
		{
			ShadowViewMatrices = Backup;
		}
		else
		{
			Backup = ShadowViewMatrices;
		}
	}
#endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)

	if (InitOptions.OverrideFarClippingPlaneDistance > 0.0f)
	{
		const FPlane FarPlane(ViewMatrices.ViewOrigin + GetViewDirection() * InitOptions.OverrideFarClippingPlaneDistance, GetViewDirection());
		// Derive the view frustum from the view projection matrix, overriding the far plane
		GetViewFrustumBounds(ViewFrustum,ViewProjectionMatrix,FarPlane,true,false);
	}
	else
	{
		// Derive the view frustum from the view projection matrix.
		GetViewFrustumBounds(ViewFrustum,ViewProjectionMatrix,false);
	}

	// Derive the view's near clipping distance and plane.
	// The GetFrustumFarPlane() is the near plane because of reverse Z projection.
	bHasNearClippingPlane = ViewProjectionMatrix.GetFrustumFarPlane(NearClippingPlane);
	if(ViewMatrices.ProjMatrix.M[2][3] > DELTA)
	{
		// Infinite projection with reversed Z.
		NearClippingDistance = ViewMatrices.ProjMatrix.M[3][2];
	}
	else
	{
		// Ortho projection with reversed Z.
		NearClippingDistance = (1.0f - ViewMatrices.ProjMatrix.M[3][2]) / ViewMatrices.ProjMatrix.M[2][2];
	}

	// Determine whether the view should reverse the cull mode due to a negative determinant.  Only do this for a valid scene
	bReverseCulling = (Family && Family->Scene) ? FMath::IsNegativeFloat(ViewMatrices.ViewMatrix.Determinant()) : false;

	// OpenGL Gamma space output in GLSL flips Y when rendering directly to the back buffer (so not needed on PC, as we never render directly into the back buffer)
	auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel];
	static bool bPlatformRequiresReverseCulling = (IsOpenGLPlatform(ShaderPlatform) && !IsPCPlatform(ShaderPlatform));
	static auto* MobileHDRCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileHDR"));
	check(MobileHDRCvar);
	bReverseCulling = (bPlatformRequiresReverseCulling && MobileHDRCvar->GetValueOnAnyThread() == 0) ? !bReverseCulling : bReverseCulling;

	// Setup transformation constants to be used by the graphics hardware to transform device normalized depth samples
	// into world oriented z.
	InvDeviceZToWorldZTransform = CreateInvDeviceZToWorldZTransform(ProjectionMatrixUnadjustedForRHI);

	static TConsoleVariableData<int32>* SortPolicyCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.TranslucentSortPolicy"));
	TranslucentSortPolicy = static_cast<ETranslucentSortPolicy::Type>(SortPolicyCvar->GetValueOnAnyThread());

	TranslucentSortAxis = GetDefault<URendererSettings>()->TranslucentSortAxis;

	// As the world is only accessable from the game thread, bIsGameView should be explicitly
	// set on any other thread.
	if(IsInGameThread())
	{
		bIsGameView = (Family && Family->Scene && Family->Scene->GetWorld() ) ? Family->Scene->GetWorld()->IsGameWorld() : false;
	}

#if WITH_EDITOR
	EditorViewBitflag = InitOptions.EditorViewBitflag;

	SelectionOutlineColor = GEngine->GetSelectionOutlineColor();
#endif
}
	void SetParameters(const FRenderingCompositePassContext& Context)
	{
		const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();

		FGlobalShader::SetParameters(ShaderRHI, Context.View);

		DeferredParameters.Set(ShaderRHI, Context.View);

		{
			bool bFiltered = false;

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MotionBlurFiltering"));
			bFiltered = CVar->GetValueOnRenderThread() != 0;
#endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)

			if(bFiltered)
			{
				PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Bilinear,AM_Border,AM_Border,AM_Clamp>::GetRHI());
			}
			else
			{
				PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Point,AM_Border,AM_Border,AM_Clamp>::GetRHI());
			}
		}
		
		if( Context.View.Family->EngineShowFlags.CameraInterpolation )
		{
			// Instead of finding the world space position of the current pixel, calculate the world space position offset by the camera position, 
			// then translate by the difference between last frame's camera position and this frame's camera position,
			// then apply the rest of the transforms.  This effectively avoids precision issues near the extents of large levels whose world space position is very large.
			FVector ViewOriginDelta = Context.View.ViewMatrices.ViewOrigin - Context.View.PrevViewMatrices.ViewOrigin;
			SetShaderValue(ShaderRHI, PrevViewProjMatrix, FTranslationMatrix(ViewOriginDelta) * Context.View.PrevViewRotationProjMatrix);
		}
		else
		{
			SetShaderValue( ShaderRHI, PrevViewProjMatrix, Context.View.ViewMatrices.GetViewRotationProjMatrix() );
		}

		TRefCountPtr<IPooledRenderTarget> InputPooledElement = Context.Pass->GetInput(ePId_Input0)->GetOutput()->RequestInput();

		// to mask out samples from outside of the view
		{
			FIntPoint BufferSize = GSceneRenderTargets.GetBufferSizeXY();
			FVector2D InvBufferSize(1.0f / BufferSize.X, 1.0f / BufferSize.Y);

			FIntRect ClipRect = Context.View.ViewRect;

			// to avoid leaking in content from the outside because of bilinear filtering, shrink
			ClipRect.InflateRect(-1);

			FVector2D MinUV(ClipRect.Min.X * InvBufferSize.X, ClipRect.Min.Y * InvBufferSize.Y);
			FVector2D MaxUV(ClipRect.Max.X * InvBufferSize.X, ClipRect.Max.Y * InvBufferSize.Y);
			FVector2D SizeUV = MaxUV - MinUV;

			FVector2D Mul(1.0f / SizeUV.X, 1.0f / SizeUV.Y);
			FVector2D Add = - MinUV * Mul;
			FVector4 TextureViewMadValue(Mul.X, Mul.Y, Add.X, Add.Y);
			SetShaderValue(ShaderRHI, TextureViewMad, TextureViewMadValue);
		}

		{
			const float SizeX = Context.View.ViewRect.Width();
			const float SizeY = Context.View.ViewRect.Height();
			const float AspectRatio = SizeX / SizeY;
			const float InvAspectRatio = SizeY / SizeX;

			const FSceneViewState* ViewState = (FSceneViewState*) Context.View.State;
			float MotionBlurTimeScale = ViewState ? ViewState->MotionBlurTimeScale : 1.0f;

			float ViewMotionBlurScale = 0.5f * MotionBlurTimeScale * Context.View.FinalPostProcessSettings.MotionBlurAmount;

			// MotionBlurInstanceScale was needed to hack some cases where motion blur wasn't working well, this shouldn't be needed any more, can clean this up later
			float MotionBlurInstanceScale = 1;

			float ObjectMotionBlurScale	= MotionBlurInstanceScale * ViewMotionBlurScale;
			// 0:no 1:full screen width, percent conversion
			float MaxVelocity = Context.View.FinalPostProcessSettings.MotionBlurMax / 100.0f;
			float InvMaxVelocity = 1.0f / MaxVelocity;

			// *2 to convert to -1..1 -1..1 screen space
			// / MaxFraction to map screenpos to -1..1 normalized MaxFraction
			FVector4 MotionBlurParametersValue(
				ObjectMotionBlurScale * InvMaxVelocity,
				- ObjectMotionBlurScale * InvMaxVelocity * InvAspectRatio,
				MaxVelocity * 2,
				- MaxVelocity * 2 * AspectRatio);
			SetShaderValue(ShaderRHI, MotionBlurParameters, MotionBlurParametersValue);
		}
	}
Ejemplo n.º 21
0
void FCanvasTileItem::Draw( class FCanvas* InCanvas )
{		
	// Rotate the canvas if the item has rotation
	if( Rotation.IsZero() == false )
	{
		FVector AnchorPos( Size.X * PivotPoint.X, Size.Y * PivotPoint.Y, 0.0f );
		FRotationMatrix RotMatrix( Rotation );
		FMatrix TransformMatrix;
		TransformMatrix = FTranslationMatrix(-AnchorPos) * RotMatrix * FTranslationMatrix(AnchorPos);

		FVector TestPos( Position.X, Position.Y, 0.0f );
		// translate the matrix back to origin, apply the rotation matrix, then transform back to the current position
		FMatrix FinalTransform = FTranslationMatrix(-TestPos) * TransformMatrix * FTranslationMatrix( TestPos );

		InCanvas->PushRelativeTransform(FinalTransform);
	}

	// Draw the item
	if( Texture )
	{
		SCOPE_CYCLE_COUNTER(STAT_Canvas_TileTextureItemTime);

		FLinearColor ActualColor = Color;
		ActualColor.A *= InCanvas->AlphaModulate;
		const FTexture* FinalTexture = Texture ? Texture : GWhiteTexture;	
		FBatchedElements* BatchedElements = InCanvas->GetBatchedElements(FCanvas::ET_Triangle, BatchedElementParameters, FinalTexture, BlendMode);
		FHitProxyId HitProxyId = InCanvas->GetHitProxyId();

		// Correct for Depth. This only works because we won't be applying a transform later--otherwise we'd have to adjust the transform instead.
		float Left, Top, Right, Bottom;
		Left =		Position.X * Z;
		Top =		Position.Y * Z;
		Right =		( Position.X + Size.X ) * Z;
		Bottom =	( Position.Y + Size.Y ) * Z;		

		int32 V00 = BatchedElements->AddVertex(
			FVector4( Left, Top, 0.0f, Z ),
			FVector2D( UV0.X, UV0.Y ),
			ActualColor,
			HitProxyId );
		int32 V10 = BatchedElements->AddVertex(
			FVector4( Right, Top, 0.0f, Z ),
			FVector2D( UV1.X, UV0.Y ),
			ActualColor,
			HitProxyId );
		int32 V01 = BatchedElements->AddVertex(
			FVector4( Left, Bottom, 0.0f, Z ),
			FVector2D( UV0.X, UV1.Y ),		
			ActualColor,
			HitProxyId );
		int32 V11 = BatchedElements->AddVertex(
			FVector4(Right,	Bottom,	0.0f, Z ),
			FVector2D( UV1.X, UV1.Y ),
			ActualColor,
			HitProxyId);

		BatchedElements->AddTriangleExtensive( V00, V10, V11, BatchedElementParameters, FinalTexture, BlendMode );
		BatchedElements->AddTriangleExtensive( V00, V11, V01, BatchedElementParameters, FinalTexture, BlendMode );
	}
	else
	{
		SCOPE_CYCLE_COUNTER(STAT_Canvas_TileMaterialItemTime);
		RenderMaterialTile( InCanvas, Position );
	}

	// Restore the canvas transform if we rotated it.
	if( Rotation.IsZero() == false )
	{
		InCanvas->PopTransform();
	}
	

}