Specular lighting works differently on flat-shaded polys

Also lower multIndex values for smooth-shaded specular, more accurate to real hardware
This commit is contained in:
gm-matthew 2024-07-26 17:22:35 +01:00
parent 5fa402f2f5
commit 6d5aeb1da5
6 changed files with 51 additions and 24 deletions

View file

@ -149,6 +149,7 @@ struct Mesh
// lighting
bool fixedShading = false;
bool smoothShading = false;
bool lighting = false;
bool specular = false;
float shininess = 0;

View file

@ -1246,6 +1246,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
currentMesh->fogIntensity = ph.LightModifier();
currentMesh->translatorMap = ph.TranslatorMap();
currentMesh->noLosReturn = ph.NoLosReturn();
currentMesh->smoothShading = ph.SmoothShading();
if (currentMesh->textured) {

View file

@ -31,6 +31,7 @@ void R3DShader::Start()
m_noLosReturn = false;
m_textureInverted = false;
m_fixedShading = false;
m_smoothShading = false;
m_translatorMap = false;
m_modelScale = 1.0f;
m_nodeAlpha = 1.0f;
@ -132,6 +133,7 @@ bool R3DShader::LoadShader(const char* vertexShader, const char* fragmentShader)
m_locSpecularValue = glGetUniformLocation(m_shaderProgram, "specularValue");
m_locSpecularEnabled = glGetUniformLocation(m_shaderProgram, "specularEnabled");
m_locFixedShading = glGetUniformLocation(m_shaderProgram, "fixedShading");
m_locSmoothShading = glGetUniformLocation(m_shaderProgram, "smoothShading");
m_locTranslatorMap = glGetUniformLocation(m_shaderProgram, "translatorMap");
m_locSpotEllipse = glGetUniformLocation(m_shaderProgram, "spotEllipse");
@ -294,6 +296,11 @@ void R3DShader::SetMeshUniforms(const Mesh* m)
m_fixedShading = m->fixedShading;
}
if (m_dirtyMesh || m->smoothShading != m_smoothShading) {
glUniform1i(m_locSmoothShading, m->smoothShading);
m_smoothShading = m->smoothShading;
}
if (m_dirtyMesh || m->translatorMap != m_translatorMap) {
glUniform1i(m_locTranslatorMap, m->translatorMap);
m_translatorMap = m->translatorMap;

View file

@ -67,6 +67,7 @@ private:
float m_specularValue;
bool m_specularEnabled;
bool m_fixedShading;
bool m_smoothShading;
bool m_translatorMap;
bool m_polyAlpha;
int m_texturePage;
@ -109,6 +110,7 @@ private:
GLint m_locSpecularValue;
GLint m_locSpecularEnabled;
GLint m_locFixedShading;
GLint m_locSmoothShading;
GLint m_locSpotEllipse;
GLint m_locSpotRange;

View file

@ -216,6 +216,7 @@ uniform float fogStart;
uniform float fogAttenuation;
uniform float fogAmbient;
uniform bool fixedShading;
uniform bool smoothShading;
uniform int hardwareStep;
uniform int colourLayer;
uniform bool polyAlpha;
@ -464,20 +465,27 @@ void main()
// for now assume fixed shading doesn't work with specular
if (specularEnabled) {
float exponent, NdotL, specularFactor;
vec4 biasIndex, expIndex, multIndex;
float specularFactor;
// Always clamp floor to zero, we don't want deep black areas
NdotL = max(0.0,sunFactor);
if (smoothShading)
{
// Always clamp floor to zero
float NdotL = max(0.0, sunFactor);
expIndex = vec4(8.0, 16.0, 32.0, 64.0);
multIndex = vec4(2.0, 2.0, 3.0, 4.0);
biasIndex = vec4(0.95, 0.95, 1.05, 1.0);
exponent = expIndex[int(shininess)] / biasIndex[int(shininess)];
vec4 expIndex = vec4(8.0, 16.0, 32.0, 64.0);
vec4 multIndex = vec4(1.6, 1.6, 2.4, 3.2);
float exponent = expIndex[int(shininess)];
specularFactor = pow(NdotL, exponent);
specularFactor *= multIndex[int(shininess)];
specularFactor *= biasIndex[int(shininess)];
specularFactor = pow(NdotL, exponent);
specularFactor *= multIndex[int(shininess)];
}
else
{
// flat shaded polys use Phong reflection model (R dot V) without any exponent or multiplier
// V = (0.0, 0.0, 1.0) is used by Model 3 as a fast approximation, so R dot V = R.z
vec3 R = reflect(-sunVector, fsViewNormal);
specularFactor = max(0.0, R.z);
}
specularFactor *= specularValue;
specularFactor *= lighting[1].x;

View file

@ -104,6 +104,7 @@ uniform float fogStart;
uniform float fogAttenuation;
uniform float fogAmbient;
uniform bool fixedShading;
uniform bool smoothShading;
uniform int hardwareStep;
uniform int colourLayer;
uniform bool polyAlpha;
@ -235,20 +236,27 @@ void main()
// for now assume fixed shading doesn't work with specular
if (specularEnabled) {
float exponent, NdotL, specularFactor;
vec4 biasIndex, expIndex, multIndex;
float specularFactor;
// Always clamp floor to zero, we don't want deep black areas
NdotL = max(0.0,sunFactor);
if (smoothShading)
{
// Always clamp floor to zero
float NdotL = max(0.0, sunFactor);
expIndex = vec4(8.0, 16.0, 32.0, 64.0);
multIndex = vec4(2.0, 2.0, 3.0, 4.0);
biasIndex = vec4(0.95, 0.95, 1.05, 1.0);
exponent = expIndex[int(shininess)] / biasIndex[int(shininess)];
vec4 expIndex = vec4(8.0, 16.0, 32.0, 64.0);
vec4 multIndex = vec4(1.6, 1.6, 2.4, 3.2);
float exponent = expIndex[int(shininess)];
specularFactor = pow(NdotL, exponent);
specularFactor *= multIndex[int(shininess)];
specularFactor *= biasIndex[int(shininess)];
specularFactor = pow(NdotL, exponent);
specularFactor *= multIndex[int(shininess)];
}
else
{
// flat shaded polys use Phong reflection model (R dot V) without any exponent or multiplier
// V = (0.0, 0.0, 1.0) is used by Model 3 as a fast approximation, so R dot V = R.z
vec3 R = reflect(-sunVector, fsViewNormal);
specularFactor = max(0.0, R.z);
}
specularFactor *= specularValue;
specularFactor *= lighting[1].x;