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 // lighting
bool fixedShading = false; bool fixedShading = false;
bool smoothShading = false;
bool lighting = false; bool lighting = false;
bool specular = false; bool specular = false;
float shininess = 0; float shininess = 0;

View file

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

View file

@ -31,6 +31,7 @@ void R3DShader::Start()
m_noLosReturn = false; m_noLosReturn = false;
m_textureInverted = false; m_textureInverted = false;
m_fixedShading = false; m_fixedShading = false;
m_smoothShading = false;
m_translatorMap = false; m_translatorMap = false;
m_modelScale = 1.0f; m_modelScale = 1.0f;
m_nodeAlpha = 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_locSpecularValue = glGetUniformLocation(m_shaderProgram, "specularValue");
m_locSpecularEnabled = glGetUniformLocation(m_shaderProgram, "specularEnabled"); m_locSpecularEnabled = glGetUniformLocation(m_shaderProgram, "specularEnabled");
m_locFixedShading = glGetUniformLocation(m_shaderProgram, "fixedShading"); m_locFixedShading = glGetUniformLocation(m_shaderProgram, "fixedShading");
m_locSmoothShading = glGetUniformLocation(m_shaderProgram, "smoothShading");
m_locTranslatorMap = glGetUniformLocation(m_shaderProgram, "translatorMap"); m_locTranslatorMap = glGetUniformLocation(m_shaderProgram, "translatorMap");
m_locSpotEllipse = glGetUniformLocation(m_shaderProgram, "spotEllipse"); m_locSpotEllipse = glGetUniformLocation(m_shaderProgram, "spotEllipse");
@ -294,6 +296,11 @@ void R3DShader::SetMeshUniforms(const Mesh* m)
m_fixedShading = m->fixedShading; 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) { if (m_dirtyMesh || m->translatorMap != m_translatorMap) {
glUniform1i(m_locTranslatorMap, m->translatorMap); glUniform1i(m_locTranslatorMap, m->translatorMap);
m_translatorMap = m->translatorMap; m_translatorMap = m->translatorMap;

View file

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

View file

@ -216,6 +216,7 @@ uniform float fogStart;
uniform float fogAttenuation; uniform float fogAttenuation;
uniform float fogAmbient; uniform float fogAmbient;
uniform bool fixedShading; uniform bool fixedShading;
uniform bool smoothShading;
uniform int hardwareStep; uniform int hardwareStep;
uniform int colourLayer; uniform int colourLayer;
uniform bool polyAlpha; uniform bool polyAlpha;
@ -464,20 +465,27 @@ void main()
// for now assume fixed shading doesn't work with specular // for now assume fixed shading doesn't work with specular
if (specularEnabled) { if (specularEnabled) {
float exponent, NdotL, specularFactor; float specularFactor;
vec4 biasIndex, expIndex, multIndex;
// Always clamp floor to zero, we don't want deep black areas if (smoothShading)
NdotL = max(0.0,sunFactor); {
// Always clamp floor to zero
float NdotL = max(0.0, sunFactor);
expIndex = vec4(8.0, 16.0, 32.0, 64.0); vec4 expIndex = vec4(8.0, 16.0, 32.0, 64.0);
multIndex = vec4(2.0, 2.0, 3.0, 4.0); vec4 multIndex = vec4(1.6, 1.6, 2.4, 3.2);
biasIndex = vec4(0.95, 0.95, 1.05, 1.0); float exponent = expIndex[int(shininess)];
exponent = expIndex[int(shininess)] / biasIndex[int(shininess)];
specularFactor = pow(NdotL, exponent); specularFactor = pow(NdotL, exponent);
specularFactor *= multIndex[int(shininess)]; specularFactor *= multIndex[int(shininess)];
specularFactor *= biasIndex[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 *= specularValue;
specularFactor *= lighting[1].x; specularFactor *= lighting[1].x;

View file

@ -104,6 +104,7 @@ uniform float fogStart;
uniform float fogAttenuation; uniform float fogAttenuation;
uniform float fogAmbient; uniform float fogAmbient;
uniform bool fixedShading; uniform bool fixedShading;
uniform bool smoothShading;
uniform int hardwareStep; uniform int hardwareStep;
uniform int colourLayer; uniform int colourLayer;
uniform bool polyAlpha; uniform bool polyAlpha;
@ -235,20 +236,27 @@ void main()
// for now assume fixed shading doesn't work with specular // for now assume fixed shading doesn't work with specular
if (specularEnabled) { if (specularEnabled) {
float exponent, NdotL, specularFactor; float specularFactor;
vec4 biasIndex, expIndex, multIndex;
// Always clamp floor to zero, we don't want deep black areas if (smoothShading)
NdotL = max(0.0,sunFactor); {
// Always clamp floor to zero
float NdotL = max(0.0, sunFactor);
expIndex = vec4(8.0, 16.0, 32.0, 64.0); vec4 expIndex = vec4(8.0, 16.0, 32.0, 64.0);
multIndex = vec4(2.0, 2.0, 3.0, 4.0); vec4 multIndex = vec4(1.6, 1.6, 2.4, 3.2);
biasIndex = vec4(0.95, 0.95, 1.05, 1.0); float exponent = expIndex[int(shininess)];
exponent = expIndex[int(shininess)] / biasIndex[int(shininess)];
specularFactor = pow(NdotL, exponent); specularFactor = pow(NdotL, exponent);
specularFactor *= multIndex[int(shininess)]; specularFactor *= multIndex[int(shininess)];
specularFactor *= biasIndex[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 *= specularValue;
specularFactor *= lighting[1].x; specularFactor *= lighting[1].x;