Skip to content

Commit

Permalink
Added environment mapping demo
Browse files Browse the repository at this point in the history
  • Loading branch information
nitronoid committed Feb 22, 2018
1 parent 1b797f5 commit c92c565
Show file tree
Hide file tree
Showing 14 changed files with 227 additions and 4 deletions.
6 changes: 4 additions & 2 deletions Project.pro
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ HEADERS += \
include/ShaderLib.h \
include/MeshVBO.h \
include/MaterialWireframe.h \
include/MaterialFractal.h
include/MaterialFractal.h \
include/MaterialEnvMap.h

SOURCES += \
src/main.cpp \
Expand All @@ -58,7 +59,8 @@ SOURCES += \
src/ShaderLib.cpp \
src/MeshVBO.cpp \
src/MaterialWireframe.cpp \
src/MaterialFractal.cpp
src/MaterialFractal.cpp \
src/MaterialEnvMap.cpp

OTHER_FILES += \
$$files(shaders/*, true) \
Expand Down
Binary file added images/gloss.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sky_xneg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sky_xpos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sky_yneg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sky_ypos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sky_zneg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sky_zpos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions include/MaterialEnvMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef MATERIALENVMAP_H
#define MATERIALENVMAP_H

#include "Material.h"
#include <QOpenGLTexture>
#include <QImage>

class Camera;

class MaterialEnvMap : public Material
{
public:
MaterialEnvMap(const std::shared_ptr<Camera> &io_camera, const std::shared_ptr<ShaderLib> &io_shaderLib, std::array<glm::mat4, 3>* io_matrices) :
Material(io_camera, io_shaderLib, io_matrices)
{}
MaterialEnvMap(const MaterialEnvMap&) = default;
MaterialEnvMap& operator=(const MaterialEnvMap&) = default;
MaterialEnvMap(MaterialEnvMap&&) = default;
MaterialEnvMap& operator=(MaterialEnvMap&&) = default;
~MaterialEnvMap() override = default;

virtual void init() override;

virtual void update() override;

virtual const char* shaderFileName() const override;

private:
void initEnvMap();
void initGlossMap();
std::unique_ptr<QOpenGLTexture> m_envMap;
std::unique_ptr<QOpenGLTexture> m_glossMap;

};

#endif // MATERIALENVMAP_H
5 changes: 5 additions & 0 deletions shaderPrograms/envMap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Name" : "EnvMap",
"Vertex" : "shaders/env_vert.glsl",
"Fragment" : "shaders/env_frag.glsl"
}
45 changes: 45 additions & 0 deletions shaders/env_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#version 420 core

// Attributes passed on from the vertex shader
smooth in vec3 FragmentPosition;
smooth in vec3 FragmentNormal;
smooth in vec2 FragmentTexCoord;

uniform mat4 N;

/// @brief our output fragment colour
layout (location=0) out vec4 FragColour;

// A texture unit for storing the 3D texture
uniform samplerCube envMap;

uniform sampler2D glossMap;

// Set the maximum environment level of detail (cannot be queried from GLSL apparently)
// The mipmap level is determined by log_2(resolution), so if the texture was 4x4,
// there would be 8 mipmap levels (128x128,64x64,32x32,16x16,8x8,4x4,2x2,1x1).
// The LOD parameter can be anything inbetween 0.0 and 8.0 for the purposes of
// trilinear interpolation.
uniform float envMaxLOD = 2.5;

uniform vec3 camPos;

// The inverse View matrix
uniform mat4 invV;

void main () {
// Calculate the normal (this is the expensive bit in Phong)
vec3 n = normalize( FragmentNormal );

// Calculate the eye vector
vec3 v = normalize(camPos-FragmentPosition);

vec3 r = reflect(v, n);

vec3 lookup = vec3(N * vec4(r, 0.0));

float gloss = (1.0 - texture(glossMap, FragmentTexCoord*2).r) * envMaxLOD;

FragColour = texture(envMap, r, gloss);
}

39 changes: 39 additions & 0 deletions shaders/env_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#version 420

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

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

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

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

uniform mat4 M; // model view matrix calculated in the App
uniform mat4 MVP; // model view projection calculated in the app
uniform mat4 N; // normal matrix calculated in the app

void main()
{
// Transform the vertex normal by the inverse transpose modelview matrix
FragmentNormal = normalize(vec3(N * vec4(inNormal, 1.0)));

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

// Copy across the texture coordinates
FragmentTexCoord = inUV;

// Compute the position of the vertex
gl_Position = MVP * vec4(inVert,1.0);
}





5 changes: 3 additions & 2 deletions src/DemoScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "MaterialPBR.h"
#include "MaterialPhong.h"
#include "MaterialFractal.h"
#include "MaterialEnvMap.h"
#include <QOpenGLContext>

//-----------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -70,8 +71,8 @@ void DemoScene::keyPress(QKeyEvent* io_event)
//-----------------------------------------------------------------------------------------------------
void DemoScene::initMaterials()
{
m_materials.reserve(5);

m_materials.reserve(6);
m_materials.emplace_back(new MaterialEnvMap(m_camera, m_shaderLib, &m_matrices));
m_materials.emplace_back(new MaterialPhong(m_camera, m_shaderLib, &m_matrices));
m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.5f, 0.0f, 0.0f}, 1.0f, 1.0f, 0.5f, 1.0f));
m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.1f, 0.2f, 0.5f}, 0.5f, 1.0f, 0.4f, 0.2f));
Expand Down
95 changes: 95 additions & 0 deletions src/MaterialEnvMap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "MaterialEnvMap.h"
#include "Scene.h"
#include "ShaderLib.h"

void MaterialEnvMap::init()
{
initEnvMap();
m_envMap->bind(0);

auto shaderPtr = m_shaderLib->getShader(m_shaderName);
shaderPtr->setUniformValue("envMap", 0);

initGlossMap();
m_glossMap->bind(1);
shaderPtr->setUniformValue("glossMap", 1);

update();
}

void MaterialEnvMap::initGlossMap()
{
m_glossMap.reset(new QOpenGLTexture(QImage("images/gloss.png")));
m_glossMap->create();
m_glossMap->bind(1);
using tex = QOpenGLTexture;
m_glossMap->setWrapMode(tex::Repeat);
m_glossMap->setMinMagFilters(tex::Linear, tex::Linear);
}

void MaterialEnvMap::initEnvMap()
{
m_envMap.reset(new QOpenGLTexture(QOpenGLTexture::TargetCubeMap));
static constexpr std::array<const char*, 6> paths = {{
"images/sky_xpos.png",
"images/sky_ypos.png",
"images/sky_zpos.png",
"images/sky_xneg.png",
"images/sky_yneg.png",
"images/sky_zneg.png"
}};

using tex = QOpenGLTexture;
static constexpr std::array<tex::CubeMapFace,6> dataTypes = {{
tex::CubeMapPositiveX,
tex::CubeMapPositiveY,
tex::CubeMapPositiveZ,
tex::CubeMapNegativeX,
tex::CubeMapNegativeY,
tex::CubeMapNegativeZ
}};
std::array<QImage, 6> maps;
for (size_t i = 0; i < maps.size(); ++i)
maps[i] = QImage(paths[i]).mirrored().convertToFormat(QImage::Format_RGBA8888);

m_envMap->create();
m_envMap->bind(0);
m_envMap->setSize(maps[0].width(), maps[0].height(), maps[0].depth());
m_envMap->setFormat(tex::RGBAFormat);
m_envMap->allocateStorage();

for (size_t i = 0; i < maps.size(); ++i)
m_envMap->setData(0, 0, dataTypes[i], tex::RGBA, tex::UInt8, maps[i].constBits());

m_envMap->setMinMagFilters(tex::LinearMipMapLinear, tex::Linear);

m_envMap->setWrapMode(tex::ClampToEdge);
m_envMap->generateMipMaps();
m_envMap->setAutoMipMapGenerationEnabled(true);
}

void MaterialEnvMap::update()
{
auto shaderPtr = m_shaderLib->getShader(m_shaderName);
auto eye = m_cam->getCameraEye();
shaderPtr->setUniformValue("camPos", QVector3D{eye.x, eye.y, eye.z});

// Scope the using declaration
{
using namespace SceneMatrices;
static constexpr std::array<const char*, 3> shaderUniforms = {{"M", "MVP", "N"}};
// Send all our matrices to the GPU
for (const auto matrixId : {MODEL_VIEW, PROJECTION, NORMAL})
{
// Convert from glm to Qt
QMatrix4x4 qmat(glm::value_ptr((*m_matrices)[matrixId]));
// Need to transpose the matrix as they both use different majors
shaderPtr->setUniformValue(shaderUniforms[matrixId], qmat.transposed());
}
}
}

const char* MaterialEnvMap::shaderFileName() const
{
return "shaderPrograms/envMap.json";
}

0 comments on commit c92c565

Please sign in to comment.