mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +00:00
Merge pull request #168 from gm-matthew/specular
Specular lighting works differently on flat-shaded polys
This commit is contained in:
commit
32414ee1fd
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue