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(); }
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)); }
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)); }
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); } }
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 ) ) ); }
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)); }
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; }
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; }
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); }
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; }
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); } } }
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); } }
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 ) ); } }
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); } }
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(); } }