Skip to content

Commit

Permalink
gpu: Fix ambient light intensity and implement shiny table
Browse files Browse the repository at this point in the history
  • Loading branch information
fleroviux committed Dec 10, 2023
1 parent 607207e commit d30a78d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ namespace dual::nds::gpu {
void cmdSetSpecularAndEmissiveMaterialColors();
void cmdSetLightVector();
void cmdSetLightColor();
void cmdSetShininessTable();
void cmdBeginVertices();
void cmdEndVertices();
void cmdSwapBuffers();
Expand Down
10 changes: 10 additions & 0 deletions src/dual/include/dual/nds/video_unit/gpu/geometry_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ namespace dual::nds::gpu {
m_light_color[light_index] = color;
}

void SetShininessTableEnable(bool enabled) {
m_enable_shininess_table = enabled;
}

std::array<u8, 128>& GetShininessTable() {
return m_shininess_table;
}

void SubmitVertex(Vector3<Fixed20x12> position, const Matrix4<Fixed20x12>& clip_matrix);

[[nodiscard]] std::span<const Polygon> GetPolygonsToRender() const {
Expand Down Expand Up @@ -186,6 +194,8 @@ namespace dual::nds::gpu {
Color4 m_material_ambient_color{};
Color4 m_material_specular_color{};
Color4 m_material_emissive_color{};
std::array<u8, 128> m_shininess_table{};
bool m_enable_shininess_table{};
};

} // namespace dual::nds::gpu
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ namespace dual::nds::gpu {
case 0x31: cmdSetSpecularAndEmissiveMaterialColors(); break;
case 0x32: cmdSetLightVector(); break;
case 0x33: cmdSetLightColor(); break;
case 0x34: cmdSetShininessTable(); break;
case 0x40: cmdBeginVertices(); break;
case 0x41: cmdEndVertices(); break;
case 0x50: cmdSwapBuffers(); break;
Expand Down
17 changes: 15 additions & 2 deletions src/dual/src/nds/video_unit/gpu/command_processor/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ namespace dual::nds::gpu {
const Color4 specular = Color4::FromRGB555((u16)(param >> 0));
const Color4 emissive = Color4::FromRGB555((u16)(param >> 16));

// @todo: handle shininess table enable
m_geometry_engine.SetMaterialSpecularColor(specular);
m_geometry_engine.SetMaterialEmissiveColor(emissive);
m_geometry_engine.SetShininessTableEnable(param & 0x8000u);
}

void CommandProcessor::cmdSetLightVector() {
Expand All @@ -120,7 +120,20 @@ namespace dual::nds::gpu {
void CommandProcessor::cmdSetLightColor() {
const u32 i_rgb555 = DequeueFIFO();

m_geometry_engine.SetLightColor(i_rgb555 >> 30, Color4::FromRGB555((u16)i_rgb555));
m_geometry_engine.SetLightColor((int)(i_rgb555 >> 30), Color4::FromRGB555((u16)i_rgb555));
}

void CommandProcessor::cmdSetShininessTable() {
std::array<u8, 128> shininess_table = m_geometry_engine.GetShininessTable();

for(int a = 0; a < 128; a += 4) {
u32 word = (u32)DequeueFIFO();

for(int b = 0; b < 4; b++) {
shininess_table[a | b] = (u8)word;
word >>= 8;
}
}
}

} // namespace dual::nds::gpu
31 changes: 18 additions & 13 deletions src/dual/src/nds/video_unit/gpu/geometry_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ namespace dual::nds::gpu {
m_material_ambient_color = {};
m_material_specular_color = {};
m_material_emissive_color = {};
m_shininess_table.fill(0u);
m_enable_shininess_table = false;
}

void GeometryEngine::SwapBuffers() {
Expand Down Expand Up @@ -427,9 +429,9 @@ namespace dual::nds::gpu {
void GeometryEngine::SetNormal(Vector3<Fixed20x12> normal) {
// @todo: texture mapping

i32 r = m_material_emissive_color.R().Raw() << 18;
i32 g = m_material_emissive_color.G().Raw() << 18;
i32 b = m_material_emissive_color.B().Raw() << 18;
i32 r = m_material_emissive_color.R().Raw() << 14;
i32 g = m_material_emissive_color.G().Raw() << 14;
i32 b = m_material_emissive_color.B().Raw() << 14;

const Color4 diffuse = m_material_diffuse_color;
const Color4 ambient = m_material_ambient_color;
Expand All @@ -446,21 +448,24 @@ namespace dual::nds::gpu {
(m_light_direction[i].Z().Raw() - (1 << 12)) >> 1
};

const i32 n_dot_l = std::max<i32>(0, -normal.Dot(m_light_direction[i]).Raw());
const i32 n_dot_h = std::max<i32>(0, -normal.Dot(halfway).Raw());
const i32 n_dot_h_2 = (n_dot_h * n_dot_h) >> 12;
const u8 n_dot_l = (u8)std::clamp<i32>(-normal.Dot(m_light_direction[i]).Raw() >> 4, 0, 255);
const u8 n_dot_h = (u8)std::clamp<i32>(-normal.Dot(halfway).Raw() >> 4, 0, 255);

// @todo: implement shininess table
i32 n_dot_h_2 = (n_dot_h * n_dot_h) >> 8;

r += m_light_color[i].R().Raw() * (n_dot_l * diffuse.R().Raw() + n_dot_h_2 * specular.R().Raw() + ambient.R().Raw());
g += m_light_color[i].G().Raw() * (n_dot_l * diffuse.G().Raw() + n_dot_h_2 * specular.G().Raw() + ambient.G().Raw());
b += m_light_color[i].B().Raw() * (n_dot_l * diffuse.B().Raw() + n_dot_h_2 * specular.B().Raw() + ambient.B().Raw());
if(m_enable_shininess_table) {
n_dot_h_2 = m_shininess_table[n_dot_h_2 >> 1];
}

r += m_light_color[i].R().Raw() * (n_dot_l * diffuse.R().Raw() + n_dot_h_2 * specular.R().Raw() + (ambient.R().Raw() << 8));
g += m_light_color[i].G().Raw() * (n_dot_l * diffuse.G().Raw() + n_dot_h_2 * specular.G().Raw() + (ambient.G().Raw() << 8));
b += m_light_color[i].B().Raw() * (n_dot_l * diffuse.B().Raw() + n_dot_h_2 * specular.B().Raw() + (ambient.B().Raw() << 8));
}

// @todo: getting some random colors which are off. figure out why this happens.
m_vertex_color.R() = std::min(r >> 18, 63);
m_vertex_color.G() = std::min(g >> 18, 63);
m_vertex_color.B() = std::min(b >> 18, 63);
m_vertex_color.R() = std::min(r >> 14, 63);
m_vertex_color.G() = std::min(g >> 14, 63);
m_vertex_color.B() = std::min(b >> 14, 63);
}

} // namespace dual::nds::gpu
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace dual::nds::gpu {
if(w == 0) {
return;
}

const i32 x = (i32)(((( (i64)position.X().Raw() + w) * viewport.width + 0x800) / two_w) + viewport.x0);
const i32 y = (i32)((((-(i64)position.Y().Raw() + w) * viewport.height + 0x800) / two_w) + viewport.y0);
const u32 depth = (u32)((((i64)position.Z().Raw() << 14) / w + 0x3FFF) << 9);
Expand Down

0 comments on commit d30a78d

Please sign in to comment.