get normal maps working

This commit is contained in:
Bailey Harrison 2023-11-05 14:39:19 +00:00
parent b58d343c8d
commit 33ee5aa321
13 changed files with 1435 additions and 1576 deletions

View File

@ -47,6 +47,11 @@ struct GraphicsSettings {
MSAALevel msaa_level;
};
enum class ImageFormat {
kLinear,
kSRGB,
};
enum class ShaderType {
kVertex,
kFragment,

View File

@ -102,7 +102,7 @@ class GFXDevice {
void DestroyBuffer(const gfx::Buffer* buffer);
gfx::Image* CreateImage(uint32_t w, uint32_t h, const void* image_data);
gfx::Image* CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const void* image_data);
void DestroyImage(const gfx::Image* image);

View File

@ -17,7 +17,7 @@ class Texture {
kAnisotropic,
};
Texture(Renderer* renderer, const uint8_t* bitmap, int width, int height, Filtering filtering);
Texture(Renderer* renderer, const uint8_t* bitmap, int width, int height, Filtering filtering, bool srgb);
~Texture();
Texture(const Texture&) = delete;
@ -32,7 +32,7 @@ class Texture {
const gfx::Sampler* sampler_; // not owned by Texture, owned by Renderer
};
std::unique_ptr<Texture> LoadTextureFromFile(const std::string& path, Texture::Filtering filtering, Renderer* renderer);
std::unique_ptr<Texture> LoadTextureFromFile(const std::string& path, Texture::Filtering filtering, Renderer* renderer, bool srgb = true);
} // namespace engine

View File

@ -5,12 +5,10 @@ layout(set = 2, binding = 1) uniform sampler2D materialSetNormalSampler;
layout(set = 2, binding = 2) uniform sampler2D materialSetOcclusionSampler;
layout(set = 2, binding = 3) uniform sampler2D materialSetMetallicRoughnessSampler;
layout(location = 0) in vec3 fragPos;
layout(location = 1) in vec3 fragNorm;
layout(location = 2) in vec2 fragUV;
layout(location = 3) in vec3 fragViewPos;
layout(location = 4) in vec3 fragLightPos;
layout(location = 5) in mat3 fragTBN;
layout(location = 0) in vec2 fragUV;
layout(location = 1) in vec3 fragPosTangentSpace;
layout(location = 2) in vec3 fragViewPosTangentSpace;
layout(location = 3) in vec3 fragLightPosTangentSpace;
layout(location = 0) out vec4 outColor;
@ -25,10 +23,11 @@ void main() {
vec3 baseColor = vec3(texture(materialSetAlbedoSampler, fragUV));
vec3 norm = vec3(texture(materialSetNormalSampler, fragUV));
//norm.y = 1.0 - norm.y;
norm = normalize(norm * 2.0 - 1.0);
vec3 lightDir = fragTBN * normalize(fragLightPos - fragPos);
vec3 viewDir = fragTBN * normalize(fragViewPos - fragPos);
vec3 lightDir = normalize(fragLightPosTangentSpace - fragPosTangentSpace);
vec3 viewDir = normalize(fragViewPosTangentSpace - fragPosTangentSpace);
vec3 diffuse = max(dot(norm, lightDir), 0.0) * lightColor;
vec3 ambient = ambientColor * ambientStrength;
@ -36,7 +35,7 @@ void main() {
float spec = pow(max(dot(norm, halfwayDir), 0.0), 32.0);
vec3 specular = spec * lightColor;
vec3 lighting = min(diffuse + ambient + specular, 1.0);
outColor = min( ( vec4(baseColor, 1.0) ) * vec4(lighting + emission, 1.0), vec4(1.0));
vec3 lighting = diffuse + ambient + specular;
outColor = vec4(min(baseColor * (lighting + emission), 1.0), 1.0);
}

View File

@ -17,27 +17,24 @@ layout(location = 1) in vec3 inNorm;
layout(location = 2) in vec4 inTangent;
layout(location = 3) in vec2 inUV;
layout(location = 0) out vec3 fragPos;
layout(location = 1) out vec3 fragNorm;
layout(location = 2) out vec2 fragUV;
layout(location = 3) out vec3 fragViewPos;
layout(location = 4) out vec3 fragLightPos;
layout(location = 5) out mat3 fragTBN;
layout(location = 0) out vec2 fragUV;
layout(location = 1) out vec3 fragPosTangentSpace;
layout(location = 2) out vec3 fragViewPosTangentSpace;
layout(location = 3) out vec3 fragLightPosTangentSpace;
void main() {
gl_Position = globalSetUniformBuffer.proj * frameSetUniformBuffer.view * constants.model * vec4(inPosition, 1.0);
mat3 normalMatrix = mat3(transpose(inverse(constants.model)));
fragPos = vec3(constants.model * vec4(inPosition, 1.0));
fragNorm = normalize(normalMatrix * inNorm);
vec4 worldPosition = constants.model * vec4(inPosition, 1.0);
gl_Position = globalSetUniformBuffer.proj * frameSetUniformBuffer.view * worldPosition;
vec3 T = normalize(vec3(constants.model * vec4(inTangent.xyz, 0.0)));
vec3 N = normalize(vec3(constants.model * vec4(inNorm, 0.0)));
vec3 B = cross(T, N) * inTangent.w;
mat3 worldToTangentSpace = transpose(mat3(T, B, N));
fragUV = inUV;
fragViewPos = vec3(inverse(frameSetUniformBuffer.view) * vec4(0.0, 0.0, 0.0, 1.0));
fragLightPos = vec3(2000.0, -2000.0, 2000.0);
vec3 T = normalize(normalMatrix * inTangent.xyz);
vec3 B = cross(fragNorm, T) * inTangent.w; // from unity docs, w flips the binormal
fragTBN = transpose(mat3(T, B, fragNorm));
fragPosTangentSpace = worldToTangentSpace * vec3(worldPosition);
fragViewPosTangentSpace = worldToTangentSpace * vec3(inverse(frameSetUniformBuffer.view) * vec4(0.0, 0.0, 0.0, 1.0));
fragLightPosTangentSpace = worldToTangentSpace * vec3(59.0, -20.0, 10.0);
gl_Position.y *= -1.0;
}

View File

@ -29,7 +29,7 @@ void main() {
fragNorm = mat3(transpose(inverse(frameSetUniformBuffer.view * constants.model))) * inNorm;
fragUV = inUV;
vec3 lightPos = vec3(2000.0, -2000.0, 2000.0);
vec3 lightPos = vec3(59.0, -20.0, 10.0);
fragLightPos = vec3(frameSetUniformBuffer.view * vec4(lightPos, 1.0));
gl_Position.y *= -1.0;

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
namespace engine {
Texture::Texture(Renderer* renderer, const uint8_t* bitmap, int width, int height, Filtering filtering) : gfx_(renderer->GetDevice())
Texture::Texture(Renderer* renderer, const uint8_t* bitmap, int width, int height, Filtering filtering, bool srgb) : gfx_(renderer->GetDevice())
{
gfx::SamplerInfo samplerInfo{};
@ -40,7 +40,12 @@ Texture::Texture(Renderer* renderer, const uint8_t* bitmap, int width, int heigh
renderer->samplers.insert(std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
}
image_ = gfx_->CreateImage(width, height, bitmap);
gfx::ImageFormat format = gfx::ImageFormat::kLinear;
if (srgb) {
format = gfx::ImageFormat::kSRGB;
}
image_ = gfx_->CreateImage(width, height, format, bitmap);
sampler_ = renderer->samplers.at(samplerInfo);
LOG_DEBUG("Created texture: width: {}, height: {}", width, height);
@ -52,11 +57,11 @@ Texture::~Texture()
gfx_->DestroyImage(image_);
}
std::unique_ptr<Texture> LoadTextureFromFile(const std::string& path, Texture::Filtering filtering, Renderer* renderer)
std::unique_ptr<Texture> LoadTextureFromFile(const std::string& path, Texture::Filtering filtering, Renderer* renderer, bool srgb)
{
int width, height;
auto bitmap = util::ReadImageFile(path, width, height);
return std::make_unique<Texture>(renderer, bitmap->data(), width, height, filtering);
return std::make_unique<Texture>(renderer, bitmap->data(), width, height, filtering, srgb);
}
} // namespace engine

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 MiB

BIN
test/res/models/cube/cube.dae (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

View File

@ -164,33 +164,37 @@ void PlayGame(GameSettings settings)
scene2->AddComponent<CameraControllerComponent>(camera);
}
{ /* house */
engine::Entity floor = engine::util::LoadMeshFromFile(scene2, app.GetResourcePath("models/cobble_house/cobble_house.dae"), true);
}
{ /* axes */
engine::util::LoadMeshFromFile(scene2, app.GetResourcePath("models/MY_AXES.dae"), true);
}
{ /* a wall */
engine::Entity wall = scene2->CreateEntity("wall", 0, glm::vec3{50.0f, 0.0f, 0.0f});
auto wall_renderable = scene2->AddComponent<engine::MeshRenderableComponent>(wall);
{ /* a cube with a normal map */
engine::Entity wall2 = scene2->CreateEntity("wall2", 0, glm::vec3{ 60.0f, 0.0f, 0.0f });
auto wall_renderable = scene2->AddComponent<engine::MeshRenderableComponent>(wall2);
wall_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(), 8.0f, 8.0f, 8.0f);
wall_renderable->material = std::make_unique<engine::Material>(app.renderer(), app.GetResource<engine::Shader>("builtin.fancy"));
std::shared_ptr<engine::Texture> albedo_texture =
engine::LoadTextureFromFile(app.GetResourcePath("textures/brickwall_albedo.jpg"), engine::Texture::Filtering::kTrilinear, app.renderer());
engine::LoadTextureFromFile(app.GetResourcePath("textures/brickwall_albedo.jpg"), engine::Texture::Filtering::kBilinear, app.renderer());
std::shared_ptr<engine::Texture> normal_texture =
engine::LoadTextureFromFile(app.GetResourcePath("textures/testnormal.png"), engine::Texture::Filtering::kTrilinear, app.renderer());
engine::LoadTextureFromFile(app.GetResourcePath("textures/brickwall_normal.jpg"), engine::Texture::Filtering::kBilinear, app.renderer(), false);
wall_renderable->material->SetAlbedoTexture(app.GetResource<engine::Texture>("builtin.white"));
wall_renderable->material->SetAlbedoTexture(albedo_texture);
wall_renderable->material->SetNormalTexture(normal_texture);
auto custom = scene2->AddComponent<engine::CustomComponent>(wall);
auto custom = scene2->AddComponent<engine::CustomComponent>(wall2);
custom->onInit = []() {};
custom->onUpdate = [&](float dt) {
//scene2->GetComponent<engine::TransformComponent>(wall)->rotation *= glm::angleAxis(dt, glm::normalize(glm::vec3{2.0f, 1.0f, 1.0f}));
};
scene2->GetComponent<engine::TransformComponent>(wall2)->rotation *= glm::angleAxis(dt * 0.2f, glm::normalize(glm::vec3{ 0.3f, 2.1f, 1.0f }));
};
}
{ /* light */
engine::Entity light = scene2->CreateEntity("light", 0, glm::vec3{59.0f, -20.0f, 10.0f});
auto wall_renderable = scene2->AddComponent<engine::MeshRenderableComponent>(light);
wall_renderable->mesh = GenSphereMesh(app.renderer()->GetDevice(), 0.5f, 16, false, true);
wall_renderable->material = std::make_unique<engine::Material>(app.renderer(), app.GetResource<engine::Shader>("builtin.standard"));
wall_renderable->material->SetAlbedoTexture(app.GetResource<engine::Texture>("builtin.white"));
}
}

View File

@ -93,26 +93,26 @@ std::unique_ptr<engine::Mesh> GenCuboidMesh(engine::GFXDevice* gfx, float x, flo
v.push_back({{x, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
// back
v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {}, {0.0f, 0.0f}});
v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {}, {0.0f, tiling}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {}, {tiling, tiling}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {}, {tiling, tiling}});
v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {}, {tiling, 0.0f}});
v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {}, {0.0f, 0.0f}});
v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
// left
v.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {}, {0.0f, 0.0f}});
v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {}, {0.0f, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {}, {tiling, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {}, {tiling, tiling}});
v.push_back({{0.0f, 0.0f, z}, {-1.0f, 0.0f, 0.0f}, {}, {tiling, 0.0f}});
v.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {}, {0.0f, 0.0f}});
v.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{0.0f, 0.0f, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
// right
v.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {}, {0.0f, tiling}});
v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {}, {tiling, tiling}});
v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {}, {tiling, tiling}});
v.push_back({{x, y, z}, {1.0f, 0.0f, 0.0f}, {}, {tiling, 0.0f}});
v.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, tiling}});
v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{x, y, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
// top
v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
v.push_back({{0.0f, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}});
@ -121,12 +121,12 @@ std::unique_ptr<engine::Mesh> GenCuboidMesh(engine::GFXDevice* gfx, float x, flo
v.push_back({{x, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
// bottom
v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {}, {0.0f, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {}, {tiling, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {}, {tiling, tiling}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {}, {tiling, 0.0f}});
v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {}, {0.0f, 0.0f}});
v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
if (wind_inside) {
for (size_t i = 0; i < v.size(); i += 3) {