Dial software speculare color in to match the original as best possible (#302)

This commit is contained in:
Anders Jenbo 2025-06-14 16:52:08 +02:00 committed by GitHub
parent 2733ffcf69
commit d06caa99cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 9 deletions

View File

@ -231,16 +231,21 @@ SDL_Color Direct3DRMSoftwareRenderer::ApplyLighting(
}
lightVec = Normalize(lightVec);
float dotNL = normal.x * lightVec.x + normal.y * lightVec.y + normal.z * lightVec.z;
float dotNL = DotProduct(normal, lightVec);
if (dotNL > 0.0f) {
// Diffuse contribution
diffuse.r += dotNL * lightColor.r;
diffuse.g += dotNL * lightColor.g;
diffuse.b += dotNL * lightColor.b;
if (appearance.shininess != 0.0f) {
// Using dotNL ignores view angle, but this matches DirectX 5 behavior.
float spec = std::pow(dotNL, appearance.shininess * m_shininessFactor);
// Specular
if (appearance.shininess > 0.0f && light.directional == 1.0f) {
D3DVECTOR viewVec = Normalize({-position.x, -position.y, -position.z});
D3DVECTOR H = Normalize({lightVec.x + viewVec.x, lightVec.y + viewVec.y, lightVec.z + viewVec.z});
float dotNH = std::max(DotProduct(normal, H), 0.0f);
float spec = std::pow(dotNH, appearance.shininess);
specular.r += spec * lightColor.r;
specular.g += spec * lightColor.g;
specular.b += spec * lightColor.b;

View File

@ -595,11 +595,6 @@ bool RayIntersectsBox(const Ray& ray, const D3DRMBOX& box, float& outT)
return true;
}
inline float DotProduct(const D3DVECTOR& a, const D3DVECTOR& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
// Convert screen (x,y) in viewport to picking ray in world space
Ray BuildPickingRay(
float x,

View File

@ -25,6 +25,11 @@ inline D3DVECTOR Normalize(const D3DVECTOR& v)
return {0, 0, 0};
}
inline float DotProduct(const D3DVECTOR& a, const D3DVECTOR& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
inline D3DVECTOR CrossProduct(const D3DVECTOR& a, const D3DVECTOR& b)
{
return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};