diff --git a/include/CameraStates.h b/include/CameraStates.h index 384e1df..8fd6bff 100644 --- a/include/CameraStates.h +++ b/include/CameraStates.h @@ -1,5 +1,5 @@ -#ifndef TRACKBALLCOMMANDS_H -#define TRACKBALLCOMMANDS_H +#ifndef CAMERASTATES_H +#define CAMERASTATES_H #include "vec2.hpp" @@ -88,4 +88,4 @@ class CameraPassive : public CameraState }; -#endif // TRACKBALLCOMMANDS_H +#endif // CAMERASTATES_H diff --git a/include/DemoScene.h b/include/DemoScene.h index b635899..25ac540 100644 --- a/include/DemoScene.h +++ b/include/DemoScene.h @@ -87,7 +87,7 @@ public slots: using matPtr = std::unique_ptr; std::array m_materials = {{ matPtr{new MaterialPBR(m_camera)}, - matPtr{new MaterialPhong} + matPtr{new MaterialPhong(m_camera)} }}; size_t m_currentMaterial = 0; //---------------------------------------------------------------------------------------------------------------------- diff --git a/include/MaterialPhong.h b/include/MaterialPhong.h index a91a517..250aa57 100644 --- a/include/MaterialPhong.h +++ b/include/MaterialPhong.h @@ -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; @@ -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 diff --git a/include/Mesh.h b/include/Mesh.h index 7d26a91..e1e51c3 100644 --- a/include/Mesh.h +++ b/include/Mesh.h @@ -1,5 +1,5 @@ -#ifndef AMESH_H -#define AMESH_H +#ifndef MESH_H +#define MESH_H #include "OpenglPlatform.h" #include @@ -35,4 +35,4 @@ class Mesh std::vector m_uvs; }; -#endif // AMESH_H +#endif // MESH_H diff --git a/include/Scene.h b/include/Scene.h index 27edf58..2ddd15c 100644 --- a/include/Scene.h +++ b/include/Scene.h @@ -1,5 +1,5 @@ -#ifndef NGLSCENE_H_ -#define NGLSCENE_H_ +#ifndef SCENE_H_ +#define SCENE_H_ #include "ShaderProgram.h" #include "Mesh.h" @@ -102,4 +102,4 @@ class Scene : public QOpenGLWidget }; -#endif +#endif //SCENE_H_ diff --git a/include/ShaderProgram.h b/include/ShaderProgram.h index d715d97..8c0fea5 100644 --- a/include/ShaderProgram.h +++ b/include/ShaderProgram.h @@ -1,5 +1,5 @@ -#ifndef Shader_h -#define Shader_h +#ifndef SHADERPROGRAM_H_ +#define SHADERPROGRAM_H_ #include "OpenglPlatform.h" #include @@ -53,4 +53,4 @@ class ShaderProgram }; -#endif /* Shader_h */ +#endif //SHADERPROGRAM_H_ diff --git a/shaders/phong_frag.glsl b/shaders/phong_frag.glsl index aae8c69..8ef18d0 100644 --- a/shaders/phong_frag.glsl +++ b/shaders/phong_frag.glsl @@ -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 @@ -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 @@ -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); } diff --git a/shaders/phong_vert.glsl b/shaders/phong_vert.glsl index 1937504..847c623 100644 --- a/shaders/phong_vert.glsl +++ b/shaders/phong_vert.glsl @@ -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); +} diff --git a/src/MaterialPhong.cpp b/src/MaterialPhong.cpp index 4196046..bed4139 100644 --- a/src/MaterialPhong.cpp +++ b/src/MaterialPhong.cpp @@ -6,13 +6,14 @@ void MaterialPhong::init(ShaderProgram* io_shader, std::array* 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; @@ -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"; }