Пример #1
0
	/**
	 * EvaluateSubBlock
	 * Iterates over all pixels in the specified rectangle, if the resulting pixel
	 * isn't black, mid grey or would result in X or Y being -1 or +1 then it is
	 * added to the average color and the number of samples count is incremented.
	 */
	void EvaluateSubBlock( int32 Left, int32 Top, int32 Width, int32 Height )
	{
		for ( int32 Y=Top; Y != (Top+Height); Y++ )
		{
			for ( int32 X=Left; X != (Left+Width); X++ )
			{
				FLinearColor ColorSample = Sampler.DoSampleColor( X, Y );

				// Nearly black or transparent pixels don't contribute to the calculation
				if (FMath::IsNearlyZero(ColorSample.A, AlphaComponentNearlyZeroThreshold) ||
					ColorSample.IsAlmostBlack())
				{
					continue;
				}

				// Scale and bias, if required, to get a signed vector
				float Vx = Sampler.ScaleAndBiasComponent( ColorSample.R );
				float Vy = Sampler.ScaleAndBiasComponent( ColorSample.G );
				float Vz = Sampler.ScaleAndBiasComponent( ColorSample.B );

				const float Length = FMath::Sqrt(Vx * Vx + Vy * Vy + Vz * Vz);
				if (Length < ColorComponentNearlyZeroThreshold)
				{
					// mid-grey pixels representing (0,0,0) are also not considered as they may be used to denote unused areas
					continue;
				}

				// If the vector is sufficiently different in length from a unit vector, consider it invalid.
				if (FMath::Abs(Length - 1.0f) > NormalVectorUnitLengthDeltaThreshold)
				{
					NumSamplesRejected++;
					continue;
				}

				// If the vector is pointing backwards then it is an invalid sample, so consider it invalid
				if (Vz < 0.0f)
				{
					NumSamplesRejected++;
					continue;
				}

				AverageColor += ColorSample;
				NumSamplesTaken++;
			}
		}
	}
	/**
	 * EvaluateSubBlock
	 * Iterates over all pixels in the specified rectangle, if the resulting pixel
	 * isn't black, mid grey or would result in X or Y being -1 or +1 then it is
	 * added to the average color and the number of samples count is incremented.
	 */
	void EvaluateSubBlock( int32 Left, int32 Top, int32 Width, int32 Height )
	{
		for ( int32 Y=Top; Y != (Top+Height); Y++ )
		{
			for ( int32 X=Left; X != (Left+Width); X++ )
			{
				FLinearColor ColorSample = Sampler.DoSampleColor( X, Y );
				if ( !ColorSample.IsAlmostBlack() )
				{
					if (FMath::IsNearlyZero(ColorSample.A, AlphaComponentNearlyZeroThreshold))
					{
						AverageColor += FLinearColor::Transparent;
						NumSamplesTaken++;
						continue;
					}

					// Scale and bias, if required, to get a signed vector
					float Vx = Sampler.ScaleAndBiasComponent( ColorSample.R );
					float Vy = Sampler.ScaleAndBiasComponent( ColorSample.G );
					float Vz = Sampler.ScaleAndBiasComponent( ColorSample.B );

					// If the vector is close to zero (mid-gray) then ignore it as invalid
					if ( FMath::IsNearlyZero(Vx, ColorComponentNearlyZeroThreshold) &&
						FMath::IsNearlyZero(Vy, ColorComponentNearlyZeroThreshold) &&
						FMath::IsNearlyZero(Vz, ColorComponentNearlyZeroThreshold) )
					{
						continue;
					}

					// Assume that if X or Y are very close to +1 or -1 then it is an invalid sample.
					// If this were to happen in a real normal map, it would imply an impossible gradient
					if ( !FMath::IsWithinInclusive( Vx, ColorComponentMinVectorThreshold, ColorComponentMaxVectorThreshold ) ||
						!FMath::IsWithinInclusive( Vy, ColorComponentMinVectorThreshold, ColorComponentMaxVectorThreshold ) )
					{
						continue;
					}

					AverageColor += ColorSample;
					NumSamplesTaken++;
				}
			}
		}
	}