[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 mat3 normalMatrix;
uniform bool useNormalMap;
uniform bool useToon;
in vec3 fNormal;
in vec3 fPosition;
@ -22,17 +23,19 @@ in vec2 texCoords;
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
vec3 LightDirection = normalize(lDirection);
vec3 nviewDirection = normalize(fPos);
vec3 LightDirection = tbn * normalize(lDirection);
vec3 nviewDirection = tbn * normalize(fPos);
vec3 nfNormal;
if(useNormalMap) {
vec3 vNorm = texture(texNormal, texCoords).rgb;
nfNormal = normalMatrix * normalize(2 * vNorm - 1);
nfNormal = normalize(2 * vNorm - 1);
} else {
nfNormal = normalize(fNorm);
nfNormal = normalize(tbn * fNorm);
}
// Compute diffuse component
@ -40,30 +43,36 @@ vec4 calcDirLight(vec4 tex, vec3 fPos, vec3 fNorm) {
// Compute specular component
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
float amb = 0.2;
float mult = 1;//max(0.0, -LightDirection.y+1.5);
float mult = 2;
//return vec4(0);
return vec4(tex.xyz * (diff + amb + spec) * mult, tex.w);
float luminance = (diff + amb + spec);
if(useToon){
luminance = floor(luminance * lightLevels) / lightLevels;
}
vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) {
//return vec4(0);
return vec4(tex.xyz * luminance * mult, tex.w);
}
vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, mat3 tbn, int i) {
// Get lighting vectors
vec3 LightDirection = normalize(pointLight[i] + fPos);
vec3 LightDirection = tbn * normalize(pointLight[i] + fPos);
// vec3 nfNormal = normalize(fNorm);
vec3 nviewDirection = normalize(fPos);
vec3 nviewDirection = tbn * normalize(fPos);
vec3 nfNormal;
if(useNormalMap) {
vec3 vNorm = texture(texNormal, texCoords).rgb;
//nfNormal = normalize(normalMatrix * vNorm);
nfNormal = normalMatrix * normalize(2 * vNorm - 1);
nfNormal = normalize(2 * vNorm - 1);
} else {
nfNormal = normalize(fNorm);
nfNormal = normalize(tbn * fNorm);
}
// 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);
// 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
vec3 Rl = reflect(-LightDirection, /*normalMatrix */ nfNormal);
@ -80,14 +89,48 @@ vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) {
// Compute ambient component
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
main()
{
vec4 texColor;
mat3 tbn = cotangent_frame(fNormal, fPosition, texCoords);
if(isPickingMode){
fColor = ifColor;
@ -107,11 +150,12 @@ main()
vec3 LightDirection = normalize(lDirection);
vec3 nfNormal = normalize(fNormal);
vec3 nviewDirection = normalize(fPosition);
mat3 tbn = cotangent_frame(fNormal, fPosition, texCoords);
fColor = calcDirLight(texColor, fPosition, fNormal)
+ calcPointLight(texColor, fPosition, fNormal, 0)/4
+ calcPointLight(texColor, fPosition, fNormal, 1)/4
+ calcPointLight(texColor, fPosition, fNormal, 2)/4;
fColor = calcDirLight(texColor, fPosition, fNormal, tbn)
+ calcPointLight(texColor, fPosition, fNormal, tbn, 0)/4
+ calcPointLight(texColor, fPosition, fNormal, tbn, 1)/4
+ calcPointLight(texColor, fPosition, fNormal, tbn, 2)/4;
} else {
fColor = texColor + ifColor;
}

View File

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

View File

@ -700,8 +700,13 @@ void Viewer::initShaders()
if ((m_isPickingModeLoc = m_program->uniformLocation("isPickingMode")) < 0)
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_useToonShading, true);
m_program->setUniformValue(m_drawTextLoc, false);
m_program->setUniformValue(m_isPickingModeLoc, false);
m_program->setUniformValue(m_useNormalMap, true);

View File

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