コード例 #1
0
void MapLinearIntensities(FourVectors const &intens,uint32 *p1, uint32 *p2, uint32 *p3, uint32 *p4)
{
	// convert four pixels worth of sse-style rgb into argb lwords
	// NOTE the _mm_empty macro is voodoo. do not mess with this routine casually - simply throwing
	// anything that ends up generating a fpu stack references in here would be bad news.
	static fltx4 pixscale={255.0,255.0,255.0,255.0};
	fltx4 r,g,b;
	r=MinSIMD(pixscale,MulSIMD(pixscale,PowSIMD(intens.x,IGAMMA)));
	g=MinSIMD(pixscale,MulSIMD(pixscale,PowSIMD(intens.y,IGAMMA)));
	b=MinSIMD(pixscale,MulSIMD(pixscale,PowSIMD(intens.z,IGAMMA)));
	// now, convert to integer
	r=AndSIMD( AddSIMD( r, Four_MagicNumbers ), PIXMASK );
	g=AndSIMD( AddSIMD( g, Four_MagicNumbers ), PIXMASK );
	b=AndSIMD( AddSIMD( b, Four_MagicNumbers ), PIXMASK );

	*(p1)=(SubInt(r, 0))|(SubInt(g, 0)<<8)|(SubInt(b, 0)<<16);
	*(p2)=(SubInt(r, 1))|(SubInt(g, 1)<<8)|(SubInt(b, 1)<<16);
	*(p3)=(SubInt(r, 2))|(SubInt(g, 2)<<8)|(SubInt(b, 2)<<16);
	*(p4)=(SubInt(r, 3))|(SubInt(g, 3)<<8)|(SubInt(b, 3)<<16);
}
コード例 #2
0
void LightDesc_t::ComputeLightAtPoints( const FourVectors &pos, const FourVectors &normal,
										FourVectors &color, bool DoHalfLambert ) const
{
	FourVectors delta;
	Assert((m_Type==MATERIAL_LIGHT_POINT) || (m_Type==MATERIAL_LIGHT_SPOT) || (m_Type==MATERIAL_LIGHT_DIRECTIONAL));
	switch (m_Type)
	{
		case MATERIAL_LIGHT_POINT:
		case MATERIAL_LIGHT_SPOT:
			delta.DuplicateVector(m_Position);
			delta-=pos;
			break;
				
		case MATERIAL_LIGHT_DIRECTIONAL:
			ComputeLightAtPointsForDirectional( pos, normal, color, DoHalfLambert );
			return;

		default:
			return;
	}

	fltx4 dist2 = delta*delta;

	dist2=MaxSIMD( Four_Ones, dist2 );

	fltx4 falloff;

	if( m_Flags & LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 )
	{
		falloff = ReplicateX4(m_Attenuation0);
	}
	else
		falloff= Four_Epsilons;

	if( m_Flags & LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 )
	{
		falloff=AddSIMD(falloff,MulSIMD(ReplicateX4(m_Attenuation1),SqrtEstSIMD(dist2)));
	}

	if( m_Flags & LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 )
	{
		falloff=AddSIMD(falloff,MulSIMD(ReplicateX4(m_Attenuation2),dist2));
	}

	falloff=ReciprocalEstSIMD(falloff);
	// Cull out light beyond this radius
	// now, zero out elements for which dist2 was > range^2. !!speed!! lights should store dist^2 in sse format
	if (m_Range != 0.f)
	{
		fltx4 RangeSquared=ReplicateX4(m_RangeSquared); // !!speed!!
		falloff=AndSIMD(falloff,CmpLtSIMD(dist2,RangeSquared));
	}

	delta.VectorNormalizeFast();
	fltx4 strength=delta*normal;
	if (DoHalfLambert)
	{
		strength=AddSIMD(MulSIMD(strength,Four_PointFives),Four_PointFives);
	}
	else
		strength=MaxSIMD(Four_Zeros,delta*normal);
		
	switch(m_Type)
	{
		case MATERIAL_LIGHT_POINT:
			// half-lambert
			break;
				
		case MATERIAL_LIGHT_SPOT:
		{
			fltx4 dot2=SubSIMD(Four_Zeros,delta*m_Direction); // dot position with spot light dir for cone falloff


			fltx4 cone_falloff_scale=MulSIMD(ReplicateX4(m_OneOverThetaDotMinusPhiDot),
												 SubSIMD(dot2,ReplicateX4(m_PhiDot)));
			cone_falloff_scale=MinSIMD(cone_falloff_scale,Four_Ones);
			
			if ((m_Falloff!=0.0) && (m_Falloff!=1.0))
			{
				// !!speed!! could compute integer exponent needed by powsimd and store in light
				cone_falloff_scale=PowSIMD(cone_falloff_scale,m_Falloff);
			}
			strength=MulSIMD(cone_falloff_scale,strength);

			// now, zero out lighting where dot2<phidot. This will mask out any invalid results
			// from pow function, etc
			fltx4 OutsideMask=CmpGtSIMD(dot2,ReplicateX4(m_PhiDot)); // outside light cone?
			strength=AndSIMD(OutsideMask,strength);
		}
		break;

		default:
			break;
	}
	strength=MulSIMD(strength,falloff);
	color.x=AddSIMD(color.x,MulSIMD(strength,ReplicateX4(m_Color.x)));
	color.y=AddSIMD(color.y,MulSIMD(strength,ReplicateX4(m_Color.y)));
	color.z=AddSIMD(color.z,MulSIMD(strength,ReplicateX4(m_Color.z)));
}