Added light to span drawers

This commit is contained in:
Magnus Norddahl 2017-02-23 04:26:37 +01:00
parent e9efb64a0b
commit c6235fb674
2 changed files with 2936 additions and 1 deletions

File diff suppressed because it is too large Load diff

View file

@ -146,6 +146,13 @@ namespace swrenderer
int desaturate = shade_constants.desaturate;
<? } ?>
auto lights = args.dc_lights;
auto num_lights = args.dc_num_lights;
float vpx = args.dc_viewpos.X;
float stepvpx = args.dc_viewpos_step.X;
__m128 viewpos_x = _mm_setr_ps(vpx, vpx + stepvpx, 0.0f, 0.0f);
__m128 step_viewpos_x = _mm_set1_ps(stepvpx * 2.0f);
int count = args.DestX2() - args.DestX1() + 1;
int pitch = RenderViewport::Instance()->RenderTarget->GetPitch();
uint32_t *dest = (uint32_t*)RenderViewport::Instance()->GetDest(args.DestX1(), args.DestY());
@ -189,6 +196,7 @@ namespace swrenderer
<? Blend($blendVariant);?>
_mm_storel_epi64((__m128i*)(dest + offset), outcolor);
viewpos_x = _mm_add_ps(viewpos_x, step_viewpos_x);
}
if (ssecount * 2 != count)
@ -268,7 +276,9 @@ namespace swrenderer
}
function Shade($isSimpleShade)
{
{ ?>
__m128i material = fgcolor;
<?
if ($isSimpleShade == true)
{ ?>
fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, mlight), 8);
@ -292,6 +302,7 @@ namespace swrenderer
fgcolor = _mm_srli_epi16(_mm_add_epi16(shade_fade, fgcolor), 8);
fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, shade_light), 8);
<? }
AddLights();
}
function Blend($blendVariant)
@ -384,5 +395,49 @@ namespace swrenderer
outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000));
<? }
}
function AddLights()
{ ?>
__m128i lit = _mm_setzero_si128();
for (int i = 0; i != num_lights; i++)
{
__m128 light_x = _mm_set1_ps(lights[i].x);
__m128 light_y = _mm_set1_ps(lights[i].y);
__m128 light_z = _mm_set1_ps(lights[i].z);
__m128 light_radius = _mm_set1_ps(lights[i].radius);
__m128 m256 = _mm_set1_ps(256.0f);
// L = light-pos
// dist = sqrt(dot(L, L))
// distance_attenuation = 1 - MIN(dist * (1/radius), 1)
__m128 Lyz2 = light_y; // L.y*L.y + L.z*L.z
__m128 Lx = _mm_sub_ps(light_x, viewpos_x);
__m128 dist2 = _mm_add_ps(Lyz2, _mm_mul_ps(Lx, Lx));
__m128 rcp_dist = _mm_rsqrt_ps(dist2);
__m128 dist = _mm_mul_ps(dist2, rcp_dist);
__m128 distance_attenuation = _mm_sub_ps(m256, _mm_min_ps(_mm_mul_ps(dist, light_radius), m256));
// The simple light type
__m128 simple_attenuation = distance_attenuation;
// The point light type
// diffuse = dot(N,L) * attenuation
__m128 point_attenuation = _mm_mul_ps(_mm_mul_ps(light_z, rcp_dist), distance_attenuation);
__m128 is_attenuated = _mm_cmpeq_ps(light_z, _mm_setzero_ps());
__m128i attenuation = _mm_cvtps_epi32(_mm_or_ps(_mm_and_ps(is_attenuated, simple_attenuation), _mm_andnot_ps(is_attenuated, point_attenuation)));
attenuation = _mm_packs_epi32(_mm_shuffle_epi32(attenuation, _MM_SHUFFLE(0,0,0,0)), _mm_shuffle_epi32(attenuation, _MM_SHUFFLE(1,1,1,1)));
__m128i light_color = _mm_cvtsi32_si128(lights[i].color);
light_color = _mm_unpacklo_epi8(light_color, _mm_setzero_si128());
light_color = _mm_shuffle_epi32(light_color, _MM_SHUFFLE(1,0,1,0));
lit = _mm_add_epi16(lit, _mm_srli_epi16(_mm_mullo_epi16(light_color, attenuation), 8));
}
fgcolor = _mm_add_epi16(fgcolor, _mm_srli_epi16(_mm_mullo_epi16(material, lit), 8));
fgcolor = _mm_min_epi16(fgcolor, _mm_set1_epi16(255));
<? }
?>
}