Пример #1
0
void FGridWidget::DrawNewGrid(const FSceneView* View, FPrimitiveDrawInterface* PDI)
{
	if (LevelGridMaterial->IsCompilingOrHadCompileError(View->GetFeatureLevel()) || LevelGridMaterial2->IsCompilingOrHadCompileError(View->GetFeatureLevel()))
	{
		// The material would appear to be black (because we don't use a MaterialDomain but a UsageFlag - we should change that).
		// Here we rather want to hide it.
		return;
	}

	bool bUseTextureSolution = CVarEditorNewLevelGrid.GetValueOnGameThread() > 1;

	UMaterialInstanceDynamic *MaterialInst = bUseTextureSolution ? LevelGridMaterialInst2 : LevelGridMaterialInst;

	if(!MaterialInst)
	{
		return;
	}

	bool bMSAA = IsEditorCompositingMSAAEnabled(View->GetFeatureLevel());
	bool bIsPerspective = ( View->ViewMatrices.ProjMatrix.M[3][3] < 1.0f );

	// in unreal units
	float SnapGridSize = GEditor->GetGridSize();

	// not used yet
	const bool bSnapEnabled = GetDefault<ULevelEditorViewportSettings>()->GridEnabled;

	float SnapAlphaMultiplier = 1.0f;

	// to get a light grid in a black level but use a high opacity value to be able to see it in a bright level
	static float Darken = 0.11f;

	static FName GridColorName("GridColor");
	static FName SnapColorName("SnapColor");
	static FName ExponentName("Exponent");
	static FName AlphaBiasName("AlphaBias");
	
	if(bIsPerspective)
	{
		MaterialInst->SetVectorParameterValue(GridColorName, FLinearColor(0.6f * Darken, 0.6f * Darken, 0.6f * Darken, CVarEditor3DGridFade.GetValueOnGameThread()));
		MaterialInst->SetVectorParameterValue(SnapColorName, FLinearColor(0.5f, 0.0f, 0.0f, SnapAlphaMultiplier * CVarEditor3DSnapFade.GetValueOnGameThread()));
	}
	else
	{
		MaterialInst->SetVectorParameterValue(GridColorName, FLinearColor(0.6f * Darken, 0.6f * Darken, 0.6f * Darken, CVarEditor2DGridFade.GetValueOnGameThread()));
		MaterialInst->SetVectorParameterValue(SnapColorName, FLinearColor(0.5f, 0.0f, 0.0f, SnapAlphaMultiplier * CVarEditor2DSnapFade.GetValueOnGameThread()));
	}

	// true:1m, false:1dm ios smallest grid size
	bool bLarger1mGrid = true;

	const int Exponent = 10;

	// 2 is the default so we need to set it
	MaterialInst->SetScalarParameterValue(ExponentName, (float)Exponent);

	// without MSAA we need the grid to be more see through so lines behind it can be recognized
	MaterialInst->SetScalarParameterValue(AlphaBiasName, bMSAA ? 0.0f : 0.05f);

	// grid for size
	float GridSplit = 0.5f;
	// red dots to visualize the snap
	float SnapSplit = 0.075f;

	float WorldToUVScale = 0.001f;

	if(bLarger1mGrid)
	{
		WorldToUVScale *= 0.1f;
		GridSplit *= 0.1f;
	}

	// in 2D all grid lines are same size in world space (they are at different scale so we need to adjust here)
	FLinearColor GridSplitTriple(GridSplit * 0.01f, GridSplit * 0.1f, GridSplit);

	if(bIsPerspective)
	{
		// largest grid lines
		GridSplitTriple.R *= 8.0f;
		// medium grid lines
		GridSplitTriple.G *= 3.0f;
		// fine grid lines
		GridSplitTriple.B *= 1.0f;
	}

	if(!bIsPerspective)
	{
		// screenspace size looks better in 2d

		float ScaleX = View->ViewMatrices.ProjMatrix.M[0][0] * View->ViewRect.Width();
		float ScaleY = View->ViewMatrices.ProjMatrix.M[1][1] * View->ViewRect.Height();

		float Scale = FMath::Min(ScaleX, ScaleY);

		float GridScale = CVarEditor2DSnapScale.GetValueOnGameThread();
		float GridMin = CVarEditor2DSnapMin.GetValueOnGameThread();

		// we need to account for a larger grids setting
		SnapSplit = 1.25f * FMath::Min(GridScale / SnapGridSize / Scale, GridMin);

		// hack test
		GridSplitTriple.R = 0.25f * FMath::Min(GridScale / 100 / Scale * 0.01f, GridMin);
		GridSplitTriple.G = 0.25f * FMath::Min(GridScale / 100 / Scale * 0.1f, GridMin);
		GridSplitTriple.B = 0.25f * FMath::Min(GridScale / 100 / Scale, GridMin);
	}

	float SnapTile = (1.0f / WorldToUVScale) / FMath::Max(1.0f, SnapGridSize);

	MaterialInst->SetVectorParameterValue("GridSplit", GridSplitTriple);
	MaterialInst->SetScalarParameterValue("SnapSplit", SnapSplit);
	MaterialInst->SetScalarParameterValue("SnapTile", SnapTile);

	FMatrix ObjectToWorld = FMatrix::Identity;

	FVector CameraPos = View->ViewMatrices.ViewOrigin;

	FVector2D UVCameraPos = FVector2D(CameraPos.X, CameraPos.Y);

	ObjectToWorld.SetOrigin(FVector(CameraPos.X, CameraPos.Y, 0));

	FLinearColor AxisColors[3];
	GetAxisColors(AxisColors, true);

	FLinearColor UAxisColor = AxisColors[1];
	FLinearColor VAxisColor = AxisColors[0];

	if(!bIsPerspective)
	{
		float FarZ = 100000.0f;

		if(View->ViewMatrices.ViewMatrix.M[1][1] == -1.f )		// Top
		{
			ObjectToWorld.SetOrigin(FVector(CameraPos.X, CameraPos.Y, -FarZ));
		}
		if(View->ViewMatrices.ViewMatrix.M[1][2] == -1.f )		// Front
		{
			UVCameraPos = FVector2D(CameraPos.Z, CameraPos.X);
			ObjectToWorld.SetAxis(0, FVector(0,0,1));
			ObjectToWorld.SetAxis(1, FVector(1,0,0));
			ObjectToWorld.SetAxis(2, FVector(0,1,0));
			ObjectToWorld.SetOrigin(FVector(CameraPos.X, -FarZ, CameraPos.Z));
			UAxisColor = AxisColors[0];
			VAxisColor = AxisColors[2];
		}
		else if(View->ViewMatrices.ViewMatrix.M[1][0] == 1.f )		// Side
		{
			UVCameraPos = FVector2D(CameraPos.Y, CameraPos.Z);
			ObjectToWorld.SetAxis(0, FVector(0,1,0));
			ObjectToWorld.SetAxis(1, FVector(0,0,1));
			ObjectToWorld.SetAxis(2, FVector(1,0,0));
			ObjectToWorld.SetOrigin(FVector(FarZ, CameraPos.Y, CameraPos.Z));
			UAxisColor = AxisColors[2];
			VAxisColor = AxisColors[1];
		}
	}
	
	MaterialInst->SetVectorParameterValue("UAxisColor", UAxisColor);
	MaterialInst->SetVectorParameterValue("VAxisColor", VAxisColor);

	// We don't want to affect the mouse interaction.
	PDI->SetHitProxy(0);

	// good enough to avoid the AMD artifacts, horizon still appears to be a line
	float Radii = 100000;

	if(bIsPerspective)
	{
		// the higher we get the larger we make the geometry to give the illusion of an infinite grid while maintains the precision nearby
		Radii *= FMath::Max( 1.0f, FMath::Abs(CameraPos.Z) / 1000.0f );
	}
	else
	{
		float ScaleX = View->ViewMatrices.ProjMatrix.M[0][0];
		float ScaleY = View->ViewMatrices.ProjMatrix.M[1][1];

		float Scale = FMath::Min(ScaleX, ScaleY);

		Scale *= View->ViewRect.Width();

		// We render a larger grid if we are zoomed out more (good precision at any scale)
		Radii *= 1.0f / Scale;
	}

	FVector2D UVMid = UVCameraPos * WorldToUVScale;
	float UVRadi = Radii * WorldToUVScale;

	FVector2D UVMin = UVMid + FVector2D(-UVRadi, -UVRadi);
	FVector2D UVMax = UVMid + FVector2D(UVRadi, UVRadi);

	// vertex pos is in -1..1 range
	DrawPlane10x10(PDI, ObjectToWorld, Radii, UVMin, UVMax, MaterialInst->GetRenderProxy(false), SDPG_World );
}