Added gamma correction, Blinn-Phong shading, and normal map support
This commit is contained in:
parent
e7cd6d8132
commit
6daa9d8d25
@ -4,17 +4,17 @@ void MainState::onEnter() {
|
||||
Log("MainState onEnter!");
|
||||
camera->setType(nf::Camera::Type::FIRST_PERSON);
|
||||
ap.load("example.nfpack");
|
||||
test.create(ap["spec.obj"]);
|
||||
test.setPosition(0.0, 0.0, -5.0);
|
||||
plane.create(nf::BaseAssets::plane);
|
||||
plane.setPosition(0.0, -2.0, 0.0);
|
||||
plane.setScale(10.0);
|
||||
test.create(ap["normal.obj"]);
|
||||
test.setPosition(0.0, 0.05, -5.0);
|
||||
plane.create(nf::BaseAssets::cube);
|
||||
plane.setPosition(0.0, -1.0, 0.0);
|
||||
plane.setScale(50.0, 0.05, 50.0);
|
||||
text.create("This is a test text.", nf::Vec2(0.1, 0.025), nf::Vec3(0.8));
|
||||
text.centered(true);
|
||||
uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5);
|
||||
button.create(nf::Vec2(0.8, 0.025), "Reset");
|
||||
button2.create(nf::Vec2(0.6, 0.025), "Play Sound");
|
||||
light.create(nf::Vec3(-5.0, 10.0, 5.0), nf::Vec3(1.0, 1.0, 1.0), 1.0);
|
||||
light.create(nf::Vec3(-5.0, 10.0, 5.0), nf::Vec3(1.0, 1.0, 1.0));
|
||||
cm.create(nf::BaseAssets::cubemap);
|
||||
|
||||
sound.create(ap["sound.wav"]);
|
||||
@ -51,7 +51,7 @@ void MainState::update(double deltaTime) {
|
||||
xrot += offset;
|
||||
if (app->isKeyHeld(NFI_RIGHT))
|
||||
xrot -= offset;
|
||||
test.setPosition(-xrot / 10.0, 0.0, -yrot / 10.0 - 5.0);
|
||||
light.setPosition(nf::Vec3(-5.0, yrot / 10.0 + 10.0, 5.0));
|
||||
|
||||
text.setText("FPS: " + std::to_string(app->getFPS()));
|
||||
|
||||
|
@ -16,6 +16,8 @@ struct Material {
|
||||
bool hasSpecTex;
|
||||
sampler2D specularTexture;
|
||||
float specPower;
|
||||
bool hasNormTex;
|
||||
sampler2D normalTexture;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
@ -96,6 +98,15 @@ void main() {
|
||||
if (material.hasSpecTex)
|
||||
matSpec = texture(material.specularTexture, texCoord).rgb;
|
||||
|
||||
vec3 norm;
|
||||
if (material.hasNormTex) {
|
||||
norm = texture(material.normalTexture, texCoord).rgb;
|
||||
norm = normalize(norm * 2.0 - 1.0);
|
||||
}
|
||||
else {
|
||||
norm = normalize(normals);
|
||||
}
|
||||
|
||||
float ambientStrength = 0.2f;
|
||||
vec3 ambient = ambientStrength * matDiff;
|
||||
if (!isContinued)
|
||||
@ -104,7 +115,6 @@ void main() {
|
||||
|
||||
if (light[i].type == 1) {
|
||||
vec3 lightDir = normalize(light[i].pos - fragPos);
|
||||
vec3 norm = normalize(normals);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = light[i].color * diff * matDiff * (light[i].strength / 2.0f);
|
||||
|
||||
@ -119,13 +129,12 @@ void main() {
|
||||
}
|
||||
if (light[i].type == 2) {
|
||||
vec3 lightDir = normalize(light[i].pos - fragPos);
|
||||
vec3 norm = normalize(normals);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = light[i].color * diff * matDiff * light[i].strength;
|
||||
|
||||
vec3 viewDir = normalize(camera.pos - fragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
|
||||
vec3 halfway = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(norm, halfway), 0.0), material.specPower);
|
||||
vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.5f);
|
||||
|
||||
float length = length(light[i].pos - fragPos);
|
||||
@ -136,5 +145,8 @@ void main() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//TODO: Move this to a post-processing pass
|
||||
float gamma = 2.2;
|
||||
color.rgb = pow(color.rgb, vec3(1.0 / gamma));
|
||||
outColor = vec4(color, 1.0);
|
||||
}
|
||||
|
@ -5,10 +5,13 @@ in vec2 texCoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float opacity;
|
||||
|
||||
out vec4 color;
|
||||
out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture(tex, texCoord);
|
||||
|
||||
color = vec4(texColor.rgb, texColor.a * opacity);
|
||||
}
|
||||
vec4 color = texColor;
|
||||
//TODO: Move this to a post-processing pass too
|
||||
float gamma = 2.2;
|
||||
color.rgb = pow(color.rgb, vec3(1.0 / gamma));
|
||||
outColor = vec4(color.rgb, texColor.a * opacity);
|
||||
}
|
14
NFPackCreator/AssetBuild/example/models/normal.mtl
Normal file
14
NFPackCreator/AssetBuild/example/models/normal.mtl
Normal file
@ -0,0 +1,14 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl mat
|
||||
Ns 225.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.800000 0.800000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Bump brickwall_normal.jpg
|
||||
map_Kd brickwall.jpg
|
17
NFPackCreator/AssetBuild/example/models/normal.obj
Normal file
17
NFPackCreator/AssetBuild/example/models/normal.obj
Normal file
@ -0,0 +1,17 @@
|
||||
# Blender v2.93.3 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib normal.mtl
|
||||
o Plane_Plane.001
|
||||
v -1.000000 -1.000000 -0.000000
|
||||
v 1.000000 -1.000000 -0.000000
|
||||
v -1.000000 1.000000 0.000000
|
||||
v 1.000000 1.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
usemtl mat
|
||||
s off
|
||||
f 2/1/1 3/2/1 1/3/1
|
||||
f 2/1/1 4/4/1 3/2/1
|
BIN
NFPackCreator/AssetBuild/example/textures/brickwall.jpg
Normal file
BIN
NFPackCreator/AssetBuild/example/textures/brickwall.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
BIN
NFPackCreator/AssetBuild/example/textures/brickwall_normal.jpg
Normal file
BIN
NFPackCreator/AssetBuild/example/textures/brickwall_normal.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 559 KiB |
@ -69,7 +69,10 @@ void getNeededImages(std::string mtl, std::set<std::string>& set) {
|
||||
unsigned int pos = mtl.find("map_");
|
||||
if (pos == std::string::npos)
|
||||
break;
|
||||
mtl = mtl.substr(pos + 7);
|
||||
if (pos == mtl.find("map_Kd") || pos == mtl.find("map_Ks"))
|
||||
mtl = mtl.substr(pos + 7);
|
||||
else
|
||||
mtl = mtl.substr(pos + 9);
|
||||
std::stringstream ss(mtl);
|
||||
std::string temp;
|
||||
ss >> temp;
|
||||
@ -140,7 +143,7 @@ int main(int argc, char* argv[]) {
|
||||
getNeededImages(mtlContents, neededImages);
|
||||
if (!neededImages.empty()) {
|
||||
currFileContents.insert(0, "\n");
|
||||
for(std::string curr : neededImages) {
|
||||
for (std::string curr : neededImages) {
|
||||
currFileContents.insert(0, curr);
|
||||
currFileContents.insert(0, " ");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "Utility.h"
|
||||
|
||||
namespace nf {
|
||||
Material::Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess) {
|
||||
Material::Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess, ATexture* normalTex) {
|
||||
m_vao = new VertexArray();
|
||||
m_vao->addBuffer(vb, vbSize);
|
||||
m_vao->push<float>(3);
|
||||
@ -35,9 +35,16 @@ namespace nf {
|
||||
if (specTex->alreadyLoaded)
|
||||
m_specularTexture = specTex->loadedTexture;
|
||||
else
|
||||
m_specularTexture = new Texture(specTex);
|
||||
m_specularTexture = new Texture(specTex, true);
|
||||
}
|
||||
m_shininess = shininess;
|
||||
if (normalTex) {
|
||||
m_hasNormal = true;
|
||||
if (normalTex->alreadyLoaded)
|
||||
m_normalTexture = normalTex->loadedTexture;
|
||||
else
|
||||
m_normalTexture = new Texture(normalTex, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::render(Shader* shader, bool onlyDepth) {
|
||||
@ -60,6 +67,13 @@ namespace nf {
|
||||
}
|
||||
else
|
||||
shader->setUniform("material.hasSpecTex", false);
|
||||
if (m_hasNormal) {
|
||||
shader->setUniform("material.hasNormTex", true);
|
||||
m_normalTexture->bind(2);
|
||||
shader->setUniform("material.normalTexture", 2);
|
||||
}
|
||||
else
|
||||
shader->setUniform("material.hasNormTex", false);
|
||||
shader->setUniform("material.specPower", m_shininess);
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, m_ib->getCount(), GL_UNSIGNED_INT, nullptr);
|
||||
@ -94,6 +108,7 @@ namespace nf {
|
||||
std::string diffuseTextureName;
|
||||
Vec3 diffuseColor;
|
||||
std::string specularTextureName;
|
||||
std::string normalTextureName;
|
||||
float shininess = 1.0f;
|
||||
};
|
||||
std::unordered_map<std::string, TempMaterial*> mats;
|
||||
@ -124,6 +139,11 @@ namespace nf {
|
||||
sscanf_s(mtl.c_str(), "\nmap_Ks %s\n", texName, (unsigned)_countof(texName));
|
||||
mats[currMat]->specularTextureName = (std::string)texName;
|
||||
}
|
||||
else if (std::strcmp(line, "map_Bump") == 0) {
|
||||
char texName[100];
|
||||
sscanf_s(mtl.c_str(), "\nmap_Bump %s\n", texName, (unsigned)_countof(texName));
|
||||
mats[currMat]->normalTextureName = (std::string)texName;
|
||||
}
|
||||
else if (std::strcmp(line, "Ns") == 0) {
|
||||
float s = 0.0;
|
||||
sscanf_s(mtl.c_str(), "\nNs %f\n", &s);
|
||||
@ -277,7 +297,10 @@ namespace nf {
|
||||
ATexture* spec = nullptr;
|
||||
if (curr.specularTextureName.size())
|
||||
spec = model->neededTextures[curr.specularTextureName];
|
||||
m_materials.push_back(new Material(&curr.outVB[0], curr.outVB.size() * sizeof(float), &curr.outTC[0], curr.outTC.size() * sizeof(float), &curr.outVN[0], curr.outVN.size() * sizeof(float), &curr.outIB[0], curr.ibCount, diff, curr.diffuseColor, spec, curr.shininess));
|
||||
ATexture* norm = nullptr;
|
||||
if (curr.normalTextureName.size())
|
||||
norm = model->neededTextures[curr.normalTextureName];
|
||||
m_materials.push_back(new Material(&curr.outVB[0], curr.outVB.size() * sizeof(float), &curr.outTC[0], curr.outTC.size() * sizeof(float), &curr.outVN[0], curr.outVN.size() * sizeof(float), &curr.outIB[0], curr.ibCount, diff, curr.diffuseColor, spec, curr.shininess, norm));
|
||||
|
||||
delete m.second;
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ namespace nf {
|
||||
}
|
||||
|
||||
void Renderer::createShadowMap() {
|
||||
m_texSlots = 16;
|
||||
m_texSlots = 13;
|
||||
glGenFramebuffers(1, &m_shadowMapFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
||||
for (unsigned int i = 0; i < m_texSlots; i++) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "Utility.h"
|
||||
|
||||
namespace nf {
|
||||
Texture::Texture(ATexture* tex) :
|
||||
Texture::Texture(ATexture* tex, bool linear) :
|
||||
m_isBase(false),
|
||||
m_id(0),
|
||||
m_x(0),
|
||||
@ -23,10 +23,12 @@ namespace nf {
|
||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, linear ? GL_RGBA : GL_SRGB_ALPHA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
stbi_image_free(texture);
|
||||
m_isBase = tex->isBaseAsset;
|
||||
tex->alreadyLoaded = true;
|
||||
tex->loadedTexture = this;
|
||||
}
|
||||
|
||||
void Texture::bind(unsigned int slot) {
|
||||
|
@ -10,7 +10,7 @@ namespace nf {
|
||||
|
||||
class Material : public Drawable {
|
||||
public:
|
||||
Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess);
|
||||
Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess, ATexture* normalTex);
|
||||
|
||||
void render(Shader* shader, bool onlyDepth);
|
||||
|
||||
@ -22,6 +22,8 @@ namespace nf {
|
||||
bool m_hasSpecular = false;
|
||||
Texture* m_specularTexture = nullptr;
|
||||
float m_shininess;
|
||||
bool m_hasNormal = false;
|
||||
Texture* m_normalTexture = nullptr;
|
||||
};
|
||||
|
||||
class Model {
|
||||
|
@ -6,7 +6,7 @@ namespace nf {
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
Texture(ATexture* tex);
|
||||
Texture(ATexture* tex, bool linear = false);
|
||||
|
||||
void bind(unsigned int slot = 0);
|
||||
Vec2 getDimensions();
|
||||
|
Reference in New Issue
Block a user