Skip to content

Commit

Permalink
Corrected phong shading method to account for the camera position.
Browse files Browse the repository at this point in the history
  • Loading branch information
nitronoid committed Feb 9, 2018
1 parent 7b45666 commit 3a86dab
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 157 deletions.
6 changes: 3 additions & 3 deletions include/CameraStates.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef TRACKBALLCOMMANDS_H
#define TRACKBALLCOMMANDS_H
#ifndef CAMERASTATES_H
#define CAMERASTATES_H

#include "vec2.hpp"

Expand Down Expand Up @@ -88,4 +88,4 @@ class CameraPassive : public CameraState
};


#endif // TRACKBALLCOMMANDS_H
#endif // CAMERASTATES_H
2 changes: 1 addition & 1 deletion include/DemoScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public slots:
using matPtr = std::unique_ptr<Material>;
std::array<matPtr, 2> m_materials = {{
matPtr{new MaterialPBR(m_camera)},
matPtr{new MaterialPhong}
matPtr{new MaterialPhong(m_camera)}
}};
size_t m_currentMaterial = 0;
//----------------------------------------------------------------------------------------------------------------------
Expand Down
10 changes: 9 additions & 1 deletion include/MaterialPhong.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@

#include "Material.h"

class Camera;

class MaterialPhong : public Material
{
public:
MaterialPhong() = default;
MaterialPhong(Camera* _cam) :
Material(),
m_cam(_cam)
{}
MaterialPhong(const MaterialPhong&) = default;
MaterialPhong& operator=(const MaterialPhong&) = default;
MaterialPhong(MaterialPhong&&) = default;
Expand All @@ -20,6 +25,9 @@ class MaterialPhong : public Material
virtual const char* vertexName() const override;

virtual const char* fragName() const override;

private:
Camera* m_cam = nullptr;
};

#endif // MATERIALPHONG_H
6 changes: 3 additions & 3 deletions include/Mesh.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef AMESH_H
#define AMESH_H
#ifndef MESH_H
#define MESH_H

#include "OpenglPlatform.h"
#include <vector>
Expand Down Expand Up @@ -35,4 +35,4 @@ class Mesh
std::vector<GLfloat> m_uvs;
};

#endif // AMESH_H
#endif // MESH_H
6 changes: 3 additions & 3 deletions include/Scene.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef NGLSCENE_H_
#define NGLSCENE_H_
#ifndef SCENE_H_
#define SCENE_H_

#include "ShaderProgram.h"
#include "Mesh.h"
Expand Down Expand Up @@ -102,4 +102,4 @@ class Scene : public QOpenGLWidget

};

#endif
#endif //SCENE_H_
6 changes: 3 additions & 3 deletions include/ShaderProgram.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef Shader_h
#define Shader_h
#ifndef SHADERPROGRAM_H_
#define SHADERPROGRAM_H_

#include "OpenglPlatform.h"
#include <string>
Expand Down Expand Up @@ -53,4 +53,4 @@ class ShaderProgram

};

#endif /* Shader_h */
#endif //SHADERPROGRAM_H_
158 changes: 33 additions & 125 deletions shaders/phong_frag.glsl
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
#version 410
#version 420 // Keeping you on the bleeding edge!
#extension GL_EXT_gpu_shader4 : enable

// This is passed on from the vertex shader
in vec3 FragmentPosition;
in vec3 FragmentNormal;
in vec2 texCoord;
// Attributes passed on from the vertex shader
smooth in vec3 WSVertexPosition;
smooth in vec3 WSVertexNormal;
smooth in vec2 WSTexCoord;


uniform bool addingColor;
uniform sampler2D ColourTexture;
uniform sampler2D NormalTexture;
uniform vec4 LightPosition;

uniform vec3 baseColor;
uniform vec3 dotsColor;

layout ( location = 0 ) out vec4 FragColor;


/* light copied from vert */
struct LightInfo
{
// Structure for holding light parameters
struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
Expand All @@ -28,17 +16,14 @@ struct LightInfo

// We'll have a single light in the scene with some default values
uniform LightInfo Light = LightInfo(
vec4( 10, 25.0, 30.0, 1.0 ), // position
vec3( 2.5, 2.5, 2.5 ), // La
vec3( 1.0, 1.0, 1.0 ), // Ld
vec3( 1.0, 1.0, 1.0 ) // Ls
vec4(2.0, 2.0, 50.0, 1.0), // position
vec3(0.2, 0.2, 0.2), // La
vec3(1.0, 1.0, 1.0), // Ld
vec3(1.0, 1.0, 1.0) // Ls
);


/* material copied from vert */
// The material properties of our object
struct MaterialInfo
{
struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
Expand All @@ -49,112 +34,35 @@ struct MaterialInfo
uniform MaterialInfo Material = MaterialInfo(
vec3(0.1, 0.1, 0.1), // Ka
vec3(1.0, 1.0, 1.0), // Kd
vec3(1, 1, 1), // Ks
4.0 // Shininess
vec3(1.0, 1.0, 1.0), // Ks
10.0 // Shininess
);

/** From http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/ */
mat4 rotationMatrix( vec3 axis, float angle )
{
//axis = normalize(axis);
float s = sin( angle );
float c = cos( angle );
float oc = 1.0 - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
0.0, 0.0, 0.0, 1.0 );
}

vec3 rotateVector( vec3 src, vec3 tgt, vec3 vec )
{
float angle = acos( dot( src, tgt ) );

if ( angle == 0 )
{
return vec;
}
vec3 axis = normalize( cross( src, tgt ) );
mat4 R = rotationMatrix( axis, angle );
vec4 norm = R * vec4( vec, 1.0f );
return norm.xyz / norm.w;
}

/** https://www.shadertoy.com/view/XtV3z3 **/
float texture_lum(sampler2D _texture, vec2 _uv)
{
vec3 rgb = texture( _texture, _uv ).rgb;
return 0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b;
}

/** https://www.shadertoy.com/view/XtV3z3 **/
vec3 toNormal()
{
float r = 0.00078125f; // 1 / width of the texture
// This is no longer a built-in variable
out vec4 FragColor;

float x0 = texture_lum( ColourTexture, vec2( texCoord.x + r, texCoord.y ) );
float x1 = texture_lum( ColourTexture, vec2( texCoord.x - r, texCoord.y ) );
float y0 = texture_lum( ColourTexture, vec2( texCoord.x, texCoord.y + r ) );
float y1 = texture_lum( ColourTexture, vec2( texCoord.x, texCoord.y - r ) );
uniform vec3 camPos;

vec3 n = normalize( vec3( x1 - x0, y1 - y0, 1.0f ) );
void main() {
// Calculate the normal (this is the expensive bit in Phong)
vec3 n = normalize( WSVertexNormal );

return n * 0.5 + 0.5;
}

vec4 useColor(vec3 _LightIntensity)
{
if ( texture( ColourTexture, texCoord ).r < 0.4f )
return vec4( _LightIntensity * dotsColor, 1.0 );
else
return vec4( _LightIntensity * baseColor , 1.0 );
}
// Calculate the light vector
vec3 s = normalize( vec3(Light.Position) - WSVertexPosition );

// Calculate the view vector
vec3 v = normalize(camPos - vec3(WSVertexPosition));

vec3 PhongReflection(vec3 _s, vec3 _n, vec3 _v)
{
vec3 r = reflect( -_s, _n );
// Reflect the light about the surface normal
vec3 r = reflect( -s, n );

// Compute the light from the ambient, diffuse and specular components
return vec3(
Light.La * Material.Ka +
Light.Ld * Material.Kd * max( dot( _s, _n ), 0.0 ) +
Light.Ls * Material.Ks * pow( max( dot( r, _v ), 0.0 ), Material.Shininess ) );
}

vec3 FresnelReflection(vec3 _s, vec3 _n, vec3 _v)
{

float base = dot( _v, _s );
float exponential = pow( base, 5.0 );
float fresnel;
vec3 r = reflect( -_s, _n );
fresnel = exponential + .028f * ( 1.0 - exponential );

return vec3(
Light.La * Material.Ka +
Light.Ld * Material.Kd * max( dot( _s, _n ), 0.0 ) +
Light.Ls * Material.Ks * pow( max( dot( r, _v ), 0.0 ), Material.Shininess ) * fresnel );
}

void main()
{
vec3 n = normalize( FragmentNormal ); // normal

vec3 s = normalize( vec3( LightPosition.xyz ) - FragmentPosition ); // Calculate the light vector

vec3 v = normalize( -vec3( FragmentPosition ) ); // eye

vec3 tgt = normalize( toNormal() * 2.0 - 1.0 );

vec3 src = vec3( 0.0, 0.0, 1.0 );
n = rotateVector( src, tgt, n);
vec3 lightColor = (
Light.La * Material.Ka +
Light.Ld * Material.Kd * max( dot(s, n), 0.0 ) +
Light.Ls * Material.Ks * pow( max( dot(r,v), 0.0 ), Material.Shininess ));

// vec3 LightIntensity = FresnelReflection(s, n, v);
vec3 LightIntensity = PhongReflection(s, n, v);
// Set the output color of our current pixel
FragColor = vec4(lightColor, 1.0);

if ( addingColor )
FragColor = useColor(LightIntensity);
else
FragColor = vec4( texture( ColourTexture, texCoord ).rgb, 1);
}
39 changes: 23 additions & 16 deletions shaders/phong_vert.glsl
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
#version 410
#version 420 // Keeping you on the bleeding edge!
#extension GL_EXT_gpu_shader4 : enable
//#extension GL_ARB_shading_language_420pack: enable // Use for GLSL versions before 420.

// The modelview and projection matrices are no longer given in OpenGL 4.2
uniform mat4 M;
uniform mat4 MVP;
uniform mat4 N; // This is the inverse transpose of the MV matrix
uniform mat4 M;
uniform mat4 N; // This is the inverse transpose of the mv matrix

// The vertex position attribute
layout (location = 0) in vec3 inVert;
layout (location=0) in vec3 inVert;

// The texture coordinate attribute
layout (location = 1) in vec2 inUV;
layout (location=1) in vec2 inUV;

// The vertex normal attribute
layout (location = 2) in vec3 inNormal;
layout (location=2) in vec3 inNormal;

out vec3 FragmentPosition;
out vec3 FragmentNormal;
out vec2 texCoord;
// These attributes are passed onto the shader (should they all be smoothed?)
smooth out vec3 WSVertexPosition;
smooth out vec3 WSVertexNormal;
smooth out vec2 WSTexCoord;

/************************************************************************************/
void main()
{
// Set the position of the current vertex
gl_Position = MVP * vec4(inVert, 1.0);
FragmentPosition = vec3(M * vec4(inVert, 1.0));
FragmentNormal = vec3(N * vec4(inNormal, 1.0));
texCoord = inUV;
}
// Transform the vertex normal by the inverse transpose modelview matrix
WSVertexNormal = normalize(vec3(N * vec4(inNormal, 1.0f)));

// Compute the unprojected vertex position
WSVertexPosition = vec3(M * vec4(inVert, 1.0) );

// Copy across the texture coordinates
WSTexCoord = inUV;

// Compute the position of the vertex
gl_Position = MVP * vec4(inVert,1.0);
}
5 changes: 3 additions & 2 deletions src/MaterialPhong.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ void MaterialPhong::init(ShaderProgram* io_shader, std::array<glm::mat4, 3>* io_
{
Material::init(io_shader, io_matrices);

io_shader->setUniform("color", glm::vec3(1.0f, 1.0f, 1.0f));
//io_shader->setUniform("color", glm::vec3(1.0f, 1.0f, 1.0f));
// Update our matrices
update();
}

void MaterialPhong::update()
{
m_shader->setUniform("camPos", m_cam->getCameraEye());
// Scope the using declaration
{
using namespace SceneMatrices;
Expand All @@ -32,5 +33,5 @@ const char* MaterialPhong::vertexName() const

const char* MaterialPhong::fragName() const
{
return "shaders/phong_frag_toon.glsl";
return "shaders/phong_frag.glsl";
}

0 comments on commit 3a86dab

Please sign in to comment.