[WIP] specular is being weird when normal maps are applied

This commit is contained in:
Dmitri K 2016-12-06 20:58:36 -05:00
parent 95aebfcc94
commit 63037d90c6
4 changed files with 158 additions and 106 deletions

View File

@ -13,6 +13,7 @@ uniform vec3 pointLight[3];
uniform vec4 pointLightCol[3]; uniform vec4 pointLightCol[3];
uniform mat3 normalMatrix; uniform mat3 normalMatrix;
uniform bool useNormalMap; uniform bool useNormalMap;
uniform bool useToon;
in vec3 fNormal; in vec3 fNormal;
in vec3 fPosition; in vec3 fPosition;
@ -22,17 +23,19 @@ in vec2 texCoords;
out vec4 fColor; out vec4 fColor;
vec4 calcDirLight(vec4 tex, vec3 fPos, vec3 fNorm) { const int lightLevels = 7;
vec4 calcDirLight(vec4 tex, vec3 fPos, vec3 fNorm, mat3 tbn) {
// Get lighting vectors // Get lighting vectors
vec3 LightDirection = normalize(lDirection); vec3 LightDirection = tbn * normalize(lDirection);
vec3 nviewDirection = normalize(fPos); vec3 nviewDirection = tbn * normalize(fPos);
vec3 nfNormal; vec3 nfNormal;
if(useNormalMap) { if(useNormalMap) {
vec3 vNorm = texture(texNormal, texCoords).rgb; vec3 vNorm = texture(texNormal, texCoords).rgb;
nfNormal = normalMatrix * normalize(2 * vNorm - 1); nfNormal = normalize(2 * vNorm - 1);
} else { } else {
nfNormal = normalize(fNorm); nfNormal = normalize(tbn * fNorm);
} }
// Compute diffuse component // Compute diffuse component
@ -40,30 +43,36 @@ vec4 calcDirLight(vec4 tex, vec3 fPos, vec3 fNorm) {
// Compute specular component // Compute specular component
vec3 Rl = reflect(-LightDirection, nfNormal); vec3 Rl = reflect(-LightDirection, nfNormal);
float spec = 0.2*pow(max(0.0, dot(/*normalMatrix */ Rl, nviewDirection)), 64); float spec = 0.2*pow(max(0.0, dot(Rl, -nviewDirection)), 64);
// Compute ambient component // Compute ambient component
float amb = 0.2; float amb = 0.2;
float mult = 1;//max(0.0, -LightDirection.y+1.5); float mult = 2;
float luminance = (diff + amb + spec);
if(useToon){
luminance = floor(luminance * lightLevels) / lightLevels;
}
//return vec4(0); //return vec4(0);
return vec4(tex.xyz * (diff + amb + spec) * mult, tex.w); return vec4(tex.xyz * luminance * mult, tex.w);
} }
vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) { vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, mat3 tbn, int i) {
// Get lighting vectors // Get lighting vectors
vec3 LightDirection = normalize(pointLight[i] + fPos); vec3 LightDirection = tbn * normalize(pointLight[i] + fPos);
// vec3 nfNormal = normalize(fNorm); // vec3 nfNormal = normalize(fNorm);
vec3 nviewDirection = normalize(fPos); vec3 nviewDirection = tbn * normalize(fPos);
vec3 nfNormal; vec3 nfNormal;
if(useNormalMap) { if(useNormalMap) {
vec3 vNorm = texture(texNormal, texCoords).rgb; vec3 vNorm = texture(texNormal, texCoords).rgb;
//nfNormal = normalize(normalMatrix * vNorm); //nfNormal = normalize(normalMatrix * vNorm);
nfNormal = normalMatrix * normalize(2 * vNorm - 1); nfNormal = normalize(2 * vNorm - 1);
} else { } else {
nfNormal = normalize(fNorm); nfNormal = normalize(tbn * fNorm);
} }
// Attenuation // Attenuation
@ -71,7 +80,7 @@ vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) {
float attenuation = 0.5 + 1 / max(0.25, distance * distance); float attenuation = 0.5 + 1 / max(0.25, distance * distance);
// Compute diffuse component // Compute diffuse component
float diff = 0.3 * max(0.0, dot(nfNormal, LightDirection)); float diff = 0.0 * max(0.0, dot(nfNormal, LightDirection));
// Compute specular component // Compute specular component
vec3 Rl = reflect(-LightDirection, /*normalMatrix */ nfNormal); vec3 Rl = reflect(-LightDirection, /*normalMatrix */ nfNormal);
@ -80,40 +89,75 @@ vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) {
// Compute ambient component // Compute ambient component
float amb = 0.2; float amb = 0.2;
return vec4(pointLightCol[i].xyz * attenuation * (amb + diff + spec) * tex.xyz, pointLightCol[i].w); float luminance = (diff + amb + spec);
if(useToon){
luminance = floor(luminance * lightLevels) / lightLevels;
}
return vec4(pointLightCol[i].xyz * attenuation * luminance * tex.xyz, pointLightCol[i].w);
} }
// ====================================================
// CODE RÉFÉRENCÉ
// https://gamedev.stackexchange.com/questions/86530/is-it-possible-to-calculate-the-tbn-matrix-in-the-fragment-shader
// ====================================================
mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
{
// get edge vectors of the pixel triangle
vec3 dp1 = dFdx( p );
vec3 dp2 = dFdy( p );
vec2 duv1 = dFdx( uv );
vec2 duv2 = dFdy( uv );
// solve the linear system
vec3 dp2perp = cross( dp2, N );
vec3 dp1perp = cross( N, dp1 );
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// construct a scale-invariant frame
float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
return mat3( T * invmax, B * invmax, N );
}
// ====================================================
// FIN DU CODE RÉFÉRENCÉ
// ====================================================
void void
main() main()
{ {
vec4 texColor; vec4 texColor;
mat3 tbn = cotangent_frame(fNormal, fPosition, texCoords);
if(isPickingMode){ if(isPickingMode){
fColor = ifColor; fColor = ifColor;
}else{ }else{
if(drawTextures) { if(drawTextures) {
texColor = texture(texCol, texCoords); texColor = texture(texCol, texCoords);
} else { } else {
texColor = ifColor; texColor = ifColor;
} }
if(isLightSource) { if(isLightSource) {
fColor = texColor; fColor = texColor;
} else if(isSky) { } else if(isSky) {
fColor = skyMult * normalize(texColor*texColor*texColor*2/1.41)*2; fColor = skyMult * normalize(texColor*texColor*texColor*2/1.41)*2;
} else if(isPhong) { } else if(isPhong) {
// Get lighting vectors // Get lighting vectors
vec3 LightDirection = normalize(lDirection); vec3 LightDirection = normalize(lDirection);
vec3 nfNormal = normalize(fNormal); vec3 nfNormal = normalize(fNormal);
vec3 nviewDirection = normalize(fPosition); vec3 nviewDirection = normalize(fPosition);
mat3 tbn = cotangent_frame(fNormal, fPosition, texCoords);
fColor = calcDirLight(texColor, fPosition, fNormal) fColor = calcDirLight(texColor, fPosition, fNormal, tbn)
+ calcPointLight(texColor, fPosition, fNormal, 0)/4 + calcPointLight(texColor, fPosition, fNormal, tbn, 0)/4
+ calcPointLight(texColor, fPosition, fNormal, 1)/4 + calcPointLight(texColor, fPosition, fNormal, tbn, 1)/4
+ calcPointLight(texColor, fPosition, fNormal, 2)/4; + calcPointLight(texColor, fPosition, fNormal, tbn, 2)/4;
} else { } else {
fColor = texColor + ifColor; fColor = texColor + ifColor;
} }
} }
} }

View File

@ -11,6 +11,7 @@ uniform bool isPhong;
uniform bool isLightSource; uniform bool isLightSource;
uniform bool isPickingMode; uniform bool isPickingMode;
uniform vec3 pointLight[3]; uniform vec3 pointLight[3];
uniform bool useToon;
in vec4 vPosition; in vec4 vPosition;
in vec3 vNormal; in vec3 vNormal;

View File

@ -700,8 +700,13 @@ void Viewer::initShaders()
if ((m_isPickingModeLoc = m_program->uniformLocation("isPickingMode")) < 0) if ((m_isPickingModeLoc = m_program->uniformLocation("isPickingMode")) < 0)
qDebug() << "Unable to find m_shader location for" << "isPickingMode" << m_program->log(); qDebug() << "Unable to find m_shader location for" << "isPickingMode" << m_program->log();
if ((m_useToonShading = m_program->uniformLocation("useToon")) < 0)
qDebug() << "Unable to find m_shader location for" << "useToon" << m_program->log();
} }
m_program->setUniformValue(m_isPhongLoc, true); m_program->setUniformValue(m_isPhongLoc, true);
m_program->setUniformValue(m_useToonShading, true);
m_program->setUniformValue(m_drawTextLoc, false); m_program->setUniformValue(m_drawTextLoc, false);
m_program->setUniformValue(m_isPickingModeLoc, false); m_program->setUniformValue(m_isPickingModeLoc, false);
m_program->setUniformValue(m_useNormalMap, true); m_program->setUniformValue(m_useNormalMap, true);

View File

@ -131,11 +131,13 @@ private:
QOpenGLShaderProgram *skyboxRenderShaderProgram; QOpenGLShaderProgram *skyboxRenderShaderProgram;
QOpenGLShaderProgram *m_program; QOpenGLShaderProgram *m_program;
QOpenGLShaderProgram *objShader; QOpenGLShaderProgram *objShader;
int m_vPositionLocation; int m_vPositionLocation;
int m_texColor; int m_texColor;
int m_texNormal; int m_texNormal;
int m_colorLocation; int m_colorLocation;
int m_useNormalMap; int m_useNormalMap;
int m_useToonShading;
int m_projMatrixLocation; int m_projMatrixLocation;
int m_mvMatrixLocation; int m_mvMatrixLocation;