Пример #1
0
void AMurphysLawCharacter::ApplyMeshTeamColor()
{
	// Put color on meshes
	if (ValidTeamBodyMeshColor && ValidTeamMaskMeshColor)
	{
		/* Get references to mesh material to be able to color them. */
		UMaterialInstanceDynamic* ShaderMeshBody = GetMesh()->CreateDynamicMaterialInstance(0);
		UMaterialInstanceDynamic* ShaderMeshArms = GetMesh1P()->CreateDynamicMaterialInstance(0);
		checkf(ShaderMeshBody != nullptr && ShaderMeshArms != nullptr, TEXT("Unable to find first material on character"));

		ShaderMeshArms->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_CLOTHES, TeamBodyMeshColor);
		ShaderMeshArms->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_MASK, TeamMaskMeshColor);
		ShaderMeshBody->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_CLOTHES, TeamBodyMeshColor);
		ShaderMeshBody->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_MASK, TeamMaskMeshColor);
	}
}
Пример #2
0
void ABomb::ArmBomb()
{
	if (bIsArmed)
	{
		//Chance the base color of the static mesh to red
		UMaterialInstanceDynamic* DynamicMAT = SM->CreateAndSetMaterialInstanceDynamic(0);

		DynamicMAT->SetVectorParameterValue(FName("Color"), FLinearColor::Red);
	}
}
Пример #3
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 );
}
Пример #4
0
void AFlarePlanetarium::SetupCelestialBody(CelestialBodyPosition* BodyPosition, double DisplayDistance, double DisplayRadius)
{
	FVector PlayerShipLocation = FVector::ZeroVector;
	if (GetGame()->GetPC()->GetShipPawn())
	{
		PlayerShipLocation = GetGame()->GetPC()->GetShipPawn()->GetActorLocation();
	}

#ifdef PLANETARIUM_DEBUG
	DrawDebugSphere(GetWorld(), FVector::ZeroVector, DisplayDistance /1000 , 32, FColor::Blue, false);

	PlayerShipLocation = FVector::ZeroVector;
	DisplayRadius /= 1000;
	DisplayDistance /= 1000;
#endif

	BodyPosition->BodyComponent->SetRelativeLocation((DisplayDistance * BodyPosition->AlignedLocation.GetUnsafeNormal()).ToVector() + PlayerShipLocation);

	float Scale = DisplayRadius / 512; // Mesh size is 1024;
	BodyPosition->BodyComponent->SetRelativeScale3D(FPreciseVector(Scale).ToVector());

	FTransform BaseRotation = FTransform(FRotator(0, 0 ,90));
	FTransform TimeRotation = FTransform(FRotator(0, BodyPosition->TotalRotation, 0));

	FQuat Rotation = (TimeRotation * BaseRotation).GetRotation();

	// TODO Rotation float time interpolation
	BodyPosition->BodyComponent->SetRelativeRotation(FQuat::Identity);
	BodyPosition->BodyComponent->SetRelativeRotation(Rotation);

	// Apply sun direction to component
	UMaterialInstanceDynamic* ComponentMaterial = Cast<UMaterialInstanceDynamic>(BodyPosition->BodyComponent->GetMaterial(0));
	if (!ComponentMaterial)
	{
		ComponentMaterial = UMaterialInstanceDynamic::Create(BodyPosition->BodyComponent->GetMaterial(0) , GetWorld());
		BodyPosition->BodyComponent->SetMaterial(0, ComponentMaterial);
	}
	ComponentMaterial->SetVectorParameterValue("SunDirection", SunDirection.ToVector());

	// Look for rings and orient them
	TArray<USceneComponent*> RingCandidates;
	BodyPosition->BodyComponent->GetChildrenComponents(true, RingCandidates);
	for (int32 ComponentIndex = 0; ComponentIndex < RingCandidates.Num(); ComponentIndex++)
	{
		UStaticMeshComponent* RingComponent = Cast<UStaticMeshComponent>(RingCandidates[ComponentIndex]);

		if (RingComponent && RingComponent->GetName().Contains("ring"))
		{
			// Get or create the material
			UMaterialInstanceDynamic* RingMaterial = Cast<UMaterialInstanceDynamic>(RingComponent->GetMaterial(0));
			if (!RingMaterial)
			{
				RingMaterial = UMaterialInstanceDynamic::Create(RingComponent->GetMaterial(0), GetWorld());
				RingComponent->SetMaterial(0, RingMaterial);
			}

			// Get world-space rotation angles for the ring and the sun
			float SunRotationPitch = FMath::RadiansToDegrees(FMath::Atan2(SunDirection.Z,SunDirection.X)) + 180;
			float RingRotationPitch = -BodyPosition->TotalRotation;

			// Feed params to the shader
			RingMaterial->SetScalarParameterValue("RingPitch", RingRotationPitch / 360);
			RingMaterial->SetScalarParameterValue("SunPitch", SunRotationPitch / 360);
		}
	}

	// Sun also rotates to track direction
	if (BodyPosition->Body == &Sun)
	{
		BodyPosition->BodyComponent->SetRelativeRotation(SunDirection.ToVector().Rotation());
	}

	// Compute sun occlusion
	if (BodyPosition->Body != &Sun)
	{
		double OcclusionAngle = FPreciseMath::Asin(BodyPosition->Radius / BodyPosition->Distance);



		float BodyPhase =  FMath::UnwindRadians(FMath::Atan2(BodyPosition->AlignedLocation.Z, BodyPosition->AlignedLocation.X));
		float CenterAngularDistance = FMath::Abs(FMath::UnwindRadians(SunPhase - BodyPhase));
		float AngleSum = (SunOcclusionAngle + OcclusionAngle);
		float AngleDiff = FMath::Abs(SunOcclusionAngle - OcclusionAngle);

		/*FLOGV("SetupCelestialBody %s BodyPhase = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(BodyPhase));
		FLOGV("SetupCelestialBody %s SunPhase = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(SunPhase));
		FLOGV("SetupCelestialBody %s OcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(OcclusionAngle));
		FLOGV("SetupCelestialBody %s SunOcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(SunOcclusionAngle));
		FLOGV("SetupCelestialBody %s AngleDiff = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(AngleDiff));

		FLOGV("SetupCelestialBody %s CenterAngularDistance = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(CenterAngularDistance));
		FLOGV("SetupCelestialBody %s AngleSum = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(AngleSum));*/


		if (CenterAngularDistance < AngleSum)
		{
			// There is occlusion
			float OcclusionRatio;

			if (CenterAngularDistance < AngleDiff)
			{
				// Maximum occlusion
				OcclusionRatio = 1.0;
			}
			else
			{
				// Partial occlusion
				OcclusionRatio = (AngleSum - CenterAngularDistance) / (2* FMath::Min(SunOcclusionAngle, OcclusionAngle));

				// OcclusionRatio = ((SunOcclusionAngle + OcclusionAngle) + FMath::Max(SunOcclusionAngle, OcclusionAngle) - FMath::Min(SunOcclusionAngle, OcclusionAngle)) / (2 * CenterAngularDistance);
			}
			//FLOGV("MoveCelestialBody %s OcclusionRatio = %f", *Body->Name, OcclusionRatio);

			// Now, find the surface occlusion
			float SunAngularSurface = PI*FMath::Square(SunOcclusionAngle);
			float MaxOcclusionAngularSurface = PI*FMath::Square(FMath::Min(SunOcclusionAngle, OcclusionAngle));
			float MaxOcclusion = MaxOcclusionAngularSurface / SunAngularSurface;
			float Occlusion = OcclusionRatio * MaxOcclusion;

			/*FLOGV("SetupCelestialBody %s CenterAngularDistance = %f", *BodyPosition->Body->Name.ToString(), CenterAngularDistance);
			FLOGV("SetupCelestialBody %s SunOcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), SunOcclusionAngle);
			FLOGV("SetupCelestialBody %s OcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), OcclusionAngle);
			FLOGV("SetupCelestialBody %s SunAngularSurface = %f", *BodyPosition->Body->Name.ToString(), SunAngularSurface);
			FLOGV("SetupCelestialBody %s MaxOcclusionAngularSurface = %f", *BodyPosition->Body->Name.ToString(), MaxOcclusionAngularSurface);
			FLOGV("SetupCelestialBody %s MaxOcclusion = %f", *BodyPosition->Body->Name.ToString(), MaxOcclusion);
			FLOGV("SetupCelestialBody %s Occlusion = %f", *BodyPosition->Body->Name.ToString(), Occlusion);*/

			if (Occlusion > SunOcclusion)
			{
				// Keep only best occlusion
				SunOcclusion = Occlusion;
			}
		}
	}

}