예제 #1
0
void ColorFragment(MSR_FShaderParameters *params)
{
    MSR_SSEColor3 &out = params->output;
    const MSR_ShaderGlobals *globals = params->globals;

    // Get the texture
    MSR_SSEColor3 tex = MSR_Tex2D_Wrap(params->globals->tex0, params->varyings[0], params->varyings[1]);

    // Depth
    params->varyings[10] = _mm_rcp_ps( *params->varyings[10] );
    params->varyings[8] *= params->varyings[10];
    params->varyings[9] = SSE_ONE - (params->varyings[9] * params->varyings[10]);
    MSR_SSEFloat shadow = MSR_Tex2D_F32(shadow_map_depth, params->varyings[8], params->varyings[9]);

    // Assemble the light direction
    const MSR_Vec4 &ld = params->globals->lights[0].direction;
    MSR_SSEVec3 LightDir( MSR_SSEFloat(ld.x), MSR_SSEFloat(ld.y), MSR_SSEFloat(ld.z) );

    params->varyings[10] += bias_amt;
    float4 cmp = _mm_cmplt_ps(*shadow, *params->varyings[10]);

    // Get the eye vector
    MSR_SSEVec3 *Eye = (MSR_SSEVec3*)&params->varyings[2];
    Eye->Normalize();

    // Get the normal vector
    MSR_SSEVec3 *Normal = (MSR_SSEVec3*)&params->varyings[5];
    Normal->Normalize();

    // Diffuse
    MSR_SSEFloat diff = MSR_Clamp(Normal->Dot(LightDir), *SSE_ZERO, *SSE_ONE);

    // Specular
    MSR_SSEVec3 Reflect = ((diff * MSR_SSEFloat(2.0f)) * *Normal) - LightDir;
    Reflect.Normalize();

    MSR_SSEFloat spec = MSR_Clamp(Reflect.Dot(*Eye), *SSE_ZERO, *SSE_ONE);
    spec = spec * spec * spec * spec * spec * spec * spec;

    float4 cmp2 = _mm_cmpgt_ps( *diff, *SSE_ZERO );
    cmp = _mm_and_ps( cmp2, cmp );

    MSR_SSEFloat clamped_ao = MSR_Clamp( params->varyings[11], *SSE_ZERO, *SSE_ONE );
    out.r = tex.r * clamped_ao;
    out.g = tex.g * clamped_ao;
    out.b = tex.b * clamped_ao;

    MSR_SSEColor3 opt1, opt2;
    opt1.r = globals->ml_ambient[0].r;
    opt1.g = globals->ml_ambient[0].g;
    opt1.b = globals->ml_ambient[0].b;

    opt2.r = (diff * globals->ml_diffuse[0].r) + (spec * globals->ml_specular[0].r) + opt1.r;
    opt2.g = (diff * globals->ml_diffuse[0].g) + (spec * globals->ml_specular[0].g) + opt1.g;
    opt2.b = (diff * globals->ml_diffuse[0].b) + (spec * globals->ml_specular[0].b) + opt1.b;

    out.r *= _mm_or_ps( _mm_and_ps(*opt2.r,cmp), _mm_andnot_ps(cmp, *opt1.r) );
    out.g *= _mm_or_ps( _mm_and_ps(*opt2.g,cmp), _mm_andnot_ps(cmp, *opt1.g) );
    out.b *= _mm_or_ps( _mm_and_ps(*opt2.b,cmp), _mm_andnot_ps(cmp, *opt1.b) );
}
void LightMapGenerator::CalculateSingleLight( ILightObject * l )
{
	int rayCasts = NUMPHOTONS;
	Vec3 RayOrigin;
	Vec3 LightDir(0,0,-1);
	//l->GetDirection( &LightDir.x );
	l->GetPosition( RayOrigin );
	Ray castRay;
	castRay.m_Origin = Vec3( (float)RayOrigin[0], (float)RayOrigin[1], (float)RayOrigin[2] );
	int bounces = NUMBOUNCES;
	char buf[1024];
	floatColor lightColor;
	float fcolor[4];
	l->GetColorIntensity(fcolor);
	lightColor.a = fcolor[3];
	lightColor.r = fcolor[0];
	lightColor.g = fcolor[1];
	lightColor.b = fcolor[2];
	for( int i = 0; i < rayCasts; )
	{
		//random raycast
		RandomRay( castRay.m_Direction );
		//Check for spotlight
		//Need to add angles to spotlights
		float attenuationMultiplier = 1.f;
		if( l->GetLightType() == SPOT_LIGHT )
		{
			float angledifference = castRay.m_Direction.Dot( LightDir );
			if( angledifference < SPOT_LIGHT_ANGLE_ATTEN2 )
			{
				//cull out
				continue;
			}else if( angledifference < SPOT_LIGHT_ANGLE_ATTEN1 )
			{
				//fade a bit
				float difference = SPOT_LIGHT_ANGLE_ATTEN1 - SPOT_LIGHT_ANGLE_ATTEN2;
				float realDifference = SPOT_LIGHT_ANGLE_ATTEN1 - angledifference;
				attenuationMultiplier = realDifference/difference;
				float random = (float)( rand()%100 ) / 100.f;
				if( random > attenuationMultiplier )//when it's fading has 100% chance of not going thruogh
				{
					continue;
				}
			}
		}
		if( ComputeRay( castRay, l, bounces, l->GetIntensity(), bounces, lightColor ) )
		{
			if( i%1000 == 0 )
			{
				sprintf( buf, "Calculating Photon %dx1000\n", i/1000 );
				OutputDebugString( buf );
			}
		}
		i++;
	}
	OutputDebugString( "DAMN IT\n" );
}
예제 #3
0
void
CWorld::vUpdateBeforeChildren( unsigned long in_Time )
{
 	CRenderProxy::getInstance().SetCamera(
		CRenderSection_SetCamera(	m_CamOrg, m_CamDir, m_CamRight,
 									m_FOVX, m_FOVY,
 									m_ZNear, m_ZFar
		)
	);
#define LIGHT_ROTATE_MILISECONDS 10000
#define LIGHT_ROTATE_RADIUS 10.0f
#define LIGHT_ROTATE_DISTANCE 10.0f
	unsigned long T = in_Time%LIGHT_ROTATE_MILISECONDS;
	float Angle = CONST_2PI*float(T)/float(LIGHT_ROTATE_MILISECONDS);
	CVector LightOrg( LIGHT_ROTATE_RADIUS*cos(Angle), LIGHT_ROTATE_RADIUS*sin(Angle), LIGHT_ROTATE_DISTANCE );
	CVector LightDir( -LightOrg ); LightDir.Normalize();
	CRenderProxy::getInstance().SetDirectionalLight(LightDir,1.0f,1.0f,1.0f);
 	CRenderProxy::getInstance().SetAmbient(0x808080);
}
bool LightMapGenerator::ComputeDirectLightAtPoint( Vec3 &tcoord, Vec3 &normal, floatColor &outDirect,
													ILightObject * light, floatColor &color)
{
	

	POTENTIAL_INTERSECTION_SORT sortedIntersections;
	Vec3 RayOrigin;
	Vec3 LightDir( 0,0, -1 );
	Vec3 Normals[ 3 ];
	float attenuationDistance = light->GetAttenuationDistance();
	light->GetPosition( RayOrigin );
	Ray castRay;
	double u, v, t;
	MeshParameterization * mesh = NULL;
	castRay.m_Origin = Vec3( (float)RayOrigin[0], (float)RayOrigin[1], (float)RayOrigin[2] );
	castRay.m_Direction = tcoord - castRay.m_Origin;
	float distanceFromLight = castRay.m_Direction.Length();
	castRay.m_Direction.Normalize();
	LightDir.Normalize();
	
	//Check for spotlight
	//Need to add angles to spotlights
	float attenuationMultiplier = 1.f;
	if( light->GetLightType() == SPOT_LIGHT )
	{
		float angledifference = castRay.m_Direction.Dot( LightDir );
		if( angledifference < SPOT_LIGHT_ANGLE_ATTEN2 )
		{
			//cull out
			return false;
		}else if( angledifference < SPOT_LIGHT_ANGLE_ATTEN1 )
		{
			//fade a bit
			float difference = SPOT_LIGHT_ANGLE_ATTEN1 - SPOT_LIGHT_ANGLE_ATTEN2;
			float realDifference = SPOT_LIGHT_ANGLE_ATTEN1 - angledifference;
			attenuationMultiplier = 1.f - realDifference/difference;
		}
	}
	if( distanceFromLight < attenuationDistance )
	{
		IntersectWithWorld( castRay, sortedIntersections);
	}
	if( sortedIntersections.size() > 0 )
	{
		
		POTENTIAL_INTERSECTION_SORT::iterator iter = sortedIntersections.begin();
		PotentialIntersection &firstIntersection = iter->second;
		if( firstIntersection.t < (distanceFromLight - SHADOW_EPSILON ) 
			|| firstIntersection.t > (distanceFromLight + SHADOW_EPSILON ) )//shadow
		{
			outDirect.a = 1;
			//outDirect.r = 0;
			//outDirect.g = 0;
			//outDirect.b = 1;	
#if 0
			//draw all mesh polygons
			static CHashString h(_T("none"));
			if( (rand()%40) == 0 )
			{
				ADDLINEPARAMS LineParam;
				LineParam.name = &h;
				//LineParam.start = last;
				//LineParam.end = transformed;
				//LineParam.start = tcoord;
				//LineParam.end = tcoord + normal*40;
				LineParam.start = castRay.m_Origin;
				LineParam.end = castRay.m_Origin + castRay.m_Direction*distanceFromLight;
				LineParam.blue = 0;
				LineParam.green = 0;
				static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID();
				EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
				LineParam.start = castRay.m_Origin;
				LineParam.end = castRay.m_Origin + castRay.m_Direction*(float)firstIntersection.t;
				LineParam.blue = 1;
				LineParam.green = 0;
				LineParam.red = 0;
				EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
				
			}
#endif
			return false;
		}
        u = firstIntersection.u;
		v = firstIntersection.v;
		t = firstIntersection.t;
		int face = firstIntersection.faceIndex;
		mesh =  firstIntersection.mesh;
		Ray rRay = castRay;
		TriangleFace &tri = (*mesh->m_Faces)[ face ];
		//we intersected, find point of intersection, find texel it maps to, color
		for( int a = 0; a < 3; a++ )
		{	
			Normals[ a ] = (*mesh->m_CollapsedMesh)[ tri.index [ a ] ].normal;
		}
		Normals[ 0 ] = normal;
		Normals[ 0 ].Normalize();
		//now take the dot with light ray
		float value = Normals[ 0 ].Dot( -rRay.m_Direction );

		//write to KD Tree
		//attenuate value based on distance
		float intensity = 1.f - ((float)t / attenuationDistance);
		if( intensity > 1.f )
		{
			intensity = 1.f;
		}
		else
			if( intensity < 0 )
		{
			intensity = 0;
		}
		value *= intensity;
		if( value <= 0.f )
		{
			outDirect.a = 1;
			//outDirect.r = 1;
			//outDirect.g = 0;
			//outDirect.b = 0;	
			return false;
		}
		else if( value > 1.f )
		{
			value = 1.f;
		}
		//linearly interpolate the color based on distance
		floatColor OutColor;
		float fogFactor = ( (float)t - m_FogStart ) / ( m_FogEnd - m_FogStart );
		if( fogFactor < 0 ) 
		{
			fogFactor = 0.f;
		}
		else
			if( fogFactor > 1.f )
		{
			fogFactor = 1.f;
		}
		OutColor.r = m_FogColor.r*fogFactor + color.r*(1.f - fogFactor );
		OutColor.g = m_FogColor.g*fogFactor + color.g*(1.f - fogFactor );
		OutColor.b = m_FogColor.b*fogFactor + color.b*(1.f - fogFactor );
			
		value *= color.a*attenuationMultiplier; //light intensity

		if( outDirect.a < 0 )
		{
			outDirect.a = 1;
			outDirect.r = value*OutColor.r;
			outDirect.g = value*OutColor.g;
			outDirect.b = value*OutColor.b;
		}else
		{
			outDirect.r += value*OutColor.r;
			outDirect.g += value*OutColor.g;
			outDirect.b += value*OutColor.b;
		}
		return true;
	}
	else
	{
		//DEBUG green for missed intersections
		//outDirect.a = 1.f;
		//outDirect.r = 0.f;
		//outDirect.g = 1.f;
		//outDirect.b = 0.f;
	}
	return false;
}