diff --git a/src/shaders/basicShader.frag b/src/shaders/basicShader.frag index ad0f0a0..92be03a 100644 --- a/src/shaders/basicShader.frag +++ b/src/shaders/basicShader.frag @@ -6,6 +6,7 @@ uniform sampler2D tex; uniform float skyMult; uniform bool drawTextures; uniform bool isLightSource; +uniform vec3 pointLight[3]; in vec3 fNormal; in vec3 fPosition; @@ -14,6 +15,50 @@ in vec2 texCoords; out vec4 fColor; + +vec4 calcDirLight(vec4 tex, vec3 fPos, vec3 fNorm) { + // Get lighting vectors + vec3 LightDirection = normalize(lDirection); + vec3 nfNormal = normalize(fNorm); + vec3 nviewDirection = normalize(fPos); + + // Compute diffuse component + float diff = 0.65 * max(0.0, dot(nfNormal, LightDirection)); + + // Compute specular component + vec3 Rl = normalize(-LightDirection+2.0*nfNormal*dot(nfNormal,LightDirection)); + float spec = 0.1*pow(max(0.0, dot(Rl, nviewDirection)), 16); + + // Compute ambient component + float amb = 0.1; + + //return vec4(0); + return vec4(tex.xyz * (amb + diff + spec), tex.w); +} + +vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) { + // Get lighting vectors + vec3 LightDirection = normalize(lDirection); + vec3 nfNormal = normalize(fNorm); + vec3 nviewDirection = normalize(fPos); + + // Attenuation + float distance = length(pointLight[i] - nviewDirection); + float attenuation = 1.0f;// / (distance * distance); + + // Compute diffuse component + float diff = 0.5 * max(0.0, dot(nfNormal, LightDirection)); + + // Compute specular component + vec3 Rl = normalize(-LightDirection+2.0*nfNormal*dot(nfNormal,LightDirection)); + float spec = 0.5*pow(max(0.0, dot(Rl, nviewDirection)), 32); + + // Compute ambient component + float amb = 0; + + return vec4(tex.xyz * attenuation * (amb + diff + spec), tex.w); +} + void main() { @@ -33,20 +78,10 @@ main() vec3 nfNormal = normalize(fNormal); vec3 nviewDirection = normalize(fPosition); - // Compute diffuse component - float diffuse = max(0.0, dot(nfNormal, LightDirection)); - - // Compute specular component - vec3 Rl = normalize(-LightDirection+2.0*nfNormal*dot(nfNormal,LightDirection)); - float specular = pow(max(0.0, dot(Rl, nviewDirection)), 16); - - // Fragment color : diffused + specular + ambient - vec4 color = texColor * diffuse * 0.6 + vec4(1) * specular * 0.6 + texColor * 0.1; - - // Compute final color - fColor = vec4(color.xyz, 1); - //fColor = vec4(color * (0.1 + diffuse + specular), 1); - //fColor = vec4(fNormal, 1); + fColor = calcDirLight(texColor, fPosition, fNormal) + + calcPointLight(texColor, fPosition, fNormal, 0) + + calcPointLight(texColor, fPosition, fNormal, 1) + + calcPointLight(texColor, fPosition, fNormal, 2); } else { fColor = texColor * ifColor; } diff --git a/src/shaders/basicShader.vert b/src/shaders/basicShader.vert index 8515ade..b2e45c6 100644 --- a/src/shaders/basicShader.vert +++ b/src/shaders/basicShader.vert @@ -9,6 +9,7 @@ uniform vec4 color; uniform bool isSky; uniform bool isPhong; +uniform vec3 pointLight[3]; in vec4 vPosition; in vec3 vNormal; @@ -19,6 +20,54 @@ out vec4 ifColor; out vec3 fPosition; out vec3 fNormal; +vec4 calcDirLight(vec4 eye, vec3 fPos, vec3 fNorm) { + // Get lighting vectors + vec3 LightDirection = normalize(lDirection); + vec3 nfNormal = normalize(fNorm); + vec3 nviewDirection = normalize(fPos); + + // Compute diffuse component + float diff = 0.65 * max(0.0, dot(nfNormal, LightDirection)); + + // Compute specular component + vec3 Rl = normalize(-LightDirection+2.0*nfNormal*dot(nfNormal,LightDirection)); + float spec = 0.1*pow(max(0.0, dot(Rl, nviewDirection)), 16); + + // Compute ambient component + vec3 amb = vec3(0.1); + + // Vertex color (currently static, to be replaced with texture) + vec4 color = ifColor; + + return color * vec4(amb + diff + spec, 1); +} + +vec4 calcPointLight(vec4 eye, vec3 fPos, vec3 fNorm, int i) { + // Get lighting vectors + vec3 LightDirection = normalize(lDirection); + vec3 nfNormal = normalize(fNorm); + vec3 nviewDirection = normalize(fPos); + + // Attenuation + float distance = length(pointLight[i] - nviewDirection); + float attenuation = 1.0f / (distance * distance); + + // Compute diffuse component + float diff = attenuation * 0.65 * max(0.0, dot(nfNormal, LightDirection)); + + // Compute specular component + vec3 Rl = normalize(-LightDirection+2.0*nfNormal*dot(nfNormal,LightDirection)); + float spec = attenuation * 0.1*pow(max(0.0, dot(Rl, nviewDirection)), 16); + + // Compute ambient component + vec3 amb = attenuation * vec3(0.1); + + // Vertex color (currently static, to be replaced with texture) + vec4 color = ifColor; + + return 0.3 * color * vec4(amb + diff + spec, 1); +} + void main() { @@ -32,24 +81,10 @@ main() ifColor = color; if(!isPhong && !isSky && !isLightSource) { - // Get lighting vectors - vec3 LightDirection = normalize(lDirection); - vec3 nfNormal = normalize(fNormal); - vec3 nviewDirection = normalize(fPosition); - - // Compute diffuse component - float diffuse = max(0.0, dot(nfNormal, LightDirection)); - - // Compute specular component - vec3 Rl = normalize(-LightDirection+2.0*nfNormal*dot(nfNormal,LightDirection)); - float specular = 0.0;//0.1*pow(max(0.0, dot(Rl, nviewDirection)), 16); - - // Vertex color (currently static, to be replaced with texture) - vec3 color = ifColor.xyz; - - // Compute final color - ifColor = vec4(color * (0.1 + diffuse + specular), 1); - //ifColor = vec4(fNormal, 1); + ifColor = calcDirLight(vEyeCoord, fPosition, fNormal) + + calcPointLight(vEyeCoord, fPosition, fNormal, 0) + + calcPointLight(vEyeCoord, fPosition, fNormal, 1) + + calcPointLight(vEyeCoord, fPosition, fNormal, 2); } } diff --git a/src/viewer/simpleViewer.cpp b/src/viewer/simpleViewer.cpp index 9b0f507..dada634 100644 --- a/src/viewer/simpleViewer.cpp +++ b/src/viewer/simpleViewer.cpp @@ -59,6 +59,8 @@ namespace QMatrix4x4 sunRotate; SceneGroup* selection; + + int currentPoint = 0; // VERY lazy way of tracking light balls } class SkyboxCamera : public qglviewer::Camera @@ -162,7 +164,7 @@ void Viewer::draw() float rotAngle = std::fmod(angle_mult * frame, 360); sunRotate.rotate(rotAngle, 1, 0, 0); - m_program->setUniformValue(m_lDirLoc, (sun * sunRotate)); + m_program->setUniformValue(m_lDirLoc, (sunRotate * sun)); selection->transform.setToIdentity(); selection->transform.rotate(rotAngle, 0, 1, 0); @@ -242,7 +244,7 @@ void Viewer::init() initGeometries(); sunRotate.rotate(-15,0,0,1); - sun = sun * sunRotate; + sun = sunRotate * sun; { Shape* cube = new Cube(); @@ -339,6 +341,15 @@ void Viewer::initShaders() if ((m_isLightLoc = m_program->uniformLocation("isLightSource")) < 0) qDebug() << "Unable to find m_shader location for" << "isLightSource"; + if ((m_point1Loc = m_program->uniformLocation("pointLight[0]")) < 0) + qDebug() << "Unable to find m_shader location for" << "pointLight[0]"; + + if ((m_point2Loc = m_program->uniformLocation("pointLight[1]")) < 0) + qDebug() << "Unable to find m_shader location for" << "pointLight[1]"; + + if ((m_point3Loc = m_program->uniformLocation("pointLight[2]")) < 0) + qDebug() << "Unable to find m_shader location for" << "pointLight[2]"; + m_program->setUniformValue(m_isPhongLoc, true); m_program->setUniformValue(m_drawTextLoc, true); @@ -645,6 +656,20 @@ void Viewer::visit(Sphere &s) m_program->setUniformValue(m_drawTextLoc, false); m_program->setUniformValue(m_isLightLoc, true); + // This will save the current position of this light ball as the next point + // This means point lights are technically 1 frame behind + + QVector3D point = QVector3D(1,0,0); + + point = modelViewMatrix * point; + int pointLocs[3] = {m_point1Loc, m_point2Loc, m_point3Loc}; + + std::cout << "Point " << currentPoint << " x:" << point.x() << " y:" << point.y() << " z:" << point.z() << "\n"; + + m_program->setUniformValue(pointLocs[currentPoint], point * modelViewMatrix); + + currentPoint = (currentPoint + 1) % 3; + glDrawElements(GL_TRIANGLES, numTriSphere * 3, GL_UNSIGNED_INT, 0); } diff --git a/src/viewer/simpleViewer.h b/src/viewer/simpleViewer.h index 5f8a2c6..fcc6e90 100644 --- a/src/viewer/simpleViewer.h +++ b/src/viewer/simpleViewer.h @@ -102,6 +102,10 @@ private: int m_drawTextLoc; int m_isLightLoc; + int m_point1Loc; + int m_point2Loc; + int m_point3Loc; + float angle_mult; QOpenGLTexture *s_texture;