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*)¶ms->varyings[2]; Eye->Normalize(); // Get the normal vector MSR_SSEVec3 *Normal = (MSR_SSEVec3*)¶ms->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" ); }
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; }