Skip to content

Commit 964c1f0

Browse files
committed
feat: normal and roughness mapping
1 parent f2b6ab8 commit 964c1f0

File tree

14 files changed

+190
-138
lines changed

14 files changed

+190
-138
lines changed

Examples/Sofa/Main.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class MainApp final : public fra::AbstractApplication
2525
"./Resources/Textures/OfficeSofa_BaseColor.png");
2626
mTextureB = mTexturePool->CreateTextureFromFile(
2727
"./Resources/Textures/OfficeSofa_Normal.png");
28+
mTextureC = mTexturePool->CreateTextureFromFile(
29+
"./Resources/Textures/OfficeSofa_Roughness.png");
2830
mModelA =
2931
mMeshPool->CreateMeshFromFile("./Resources/Models/OfficeSofa.fbx");
3032
}
@@ -57,9 +59,11 @@ class MainApp final : public fra::AbstractApplication
5759

5860
for (const auto& mesh : mModelA)
5961
{
60-
mTexturePool->Bind(mTextureA);
62+
mTexturePool->Bind(mTextureA, 0);
63+
mTexturePool->Bind(mTextureB, 1);
64+
mTexturePool->Bind(mTextureC, 2);
65+
6166
mMeshPool->DrawInstanced(mesh, 1);
62-
mTexturePool->Bind(mTextureB);
6367
mMeshPool->DrawInstanced(mesh, 1, 1);
6468
}
6569

@@ -72,6 +76,7 @@ class MainApp final : public fra::AbstractApplication
7276

7377
std::vector<unsigned> mModelB;
7478
std::uint32_t mTextureB {};
79+
std::uint32_t mTextureC {};
7580

7681
Ref<fra::TexturePool> mTexturePool;
7782
Ref<fra::MeshPool> mMeshPool;

Shaders/Forward/Frag.spv

2 KB
Binary file not shown.

Shaders/Forward/Shader.frag

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,40 @@ layout (binding = 0) uniform ProjectionUniformBuffer {
66
vec4 ambientLight;
77
} pub;
88

9-
layout (set = 1, binding = 0) uniform sampler2D texSampler;
9+
layout (set = 1, binding = 0) uniform sampler2D albedoSampler;
10+
layout (set = 1, binding = 1) uniform sampler2D normalSampler;
11+
layout (set = 1, binding = 2) uniform sampler2D roughnessSampler;
1012

1113
layout (location = 0) in vec3 fragColor;
1214
layout (location = 1) in vec3 fragPosition;
13-
layout (location = 2) in vec3 fragNormal;
14-
layout (location = 3) in vec2 fragTexCoord;
15+
layout (location = 2) in vec2 fragTexCoord;
16+
layout (location = 3) in mat3 TBN;
1517

1618
layout (location = 0) out vec4 outColor;
1719

20+
vec3 getNormalFromMap() {
21+
vec3 normal = texture(normalSampler, fragTexCoord).rgb * 2.0 - 1.0;
22+
return normalize(TBN * normal);
23+
}
24+
25+
vec3 getCameraPosition(mat4 viewMatrix) {
26+
return -viewMatrix[3].xyz * mat3(viewMatrix);
27+
}
28+
1829
void main()
1930
{
20-
float lightIntensity = pub.ambientLight.w + max(dot(normalize(fragNormal), pub.ambientLight.xyz), 0);
31+
vec3 albedo = texture(albedoSampler, fragTexCoord).rgb;
32+
vec3 normal = getNormalFromMap();
33+
float roughness = texture(roughnessSampler, fragTexCoord).r;
34+
35+
vec3 lightDirNorm = normalize(-pub.ambientLight.xyz);
36+
vec3 viewDir = normalize(getCameraPosition(pub.view) - fragPosition);
37+
38+
float diff = max(dot(normal, lightDirNorm), pub.ambientLight.w);
2139

22-
outColor = texture(texSampler, fragTexCoord) * vec4(lightIntensity * fragColor, 1.0);
40+
vec3 halfwayDir = normalize(lightDirNorm + viewDir);
41+
float spec = pow(max(dot(normal, halfwayDir), 0.0), mix(16.0, 2.0, roughness));
42+
43+
vec3 lighting = (diff + spec) * vec3(1.0, 1.0, 1.0);
44+
outColor = vec4(albedo * lighting, 1.0);
2345
}

Shaders/Forward/Shader.vert

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@ layout(binding = 0) uniform ProjectionUniformBuffer {
99
layout(location = 0) in vec3 inPosition;
1010
layout(location = 1) in vec3 inColor;
1111
layout(location = 2) in vec3 inNormal;
12-
layout(location = 3) in vec2 inTexCoord;
13-
layout(location = 4) in mat4 inModel;
12+
layout(location = 3) in vec3 inTangent;
13+
layout(location = 4) in vec2 inTexCoord;
14+
layout(location = 5) in mat4 inModel;
1415

1516
layout(location = 0) out vec3 fragColor;
1617
layout(location = 1) out vec3 fragPosition;
17-
layout(location = 2) out vec3 fragNormal;
18-
layout(location = 3) out vec2 fragTexCoord;
18+
layout(location = 2) out vec2 fragTexCoord;
19+
layout(location = 3) out mat3 TBN;
1920

2021
void main() {
2122
vec4 vertexPosition = inModel * vec4(inPosition, 1.0);
2223
gl_Position = pub.proj * pub.view * vertexPosition;
2324

2425
fragColor = inColor;
2526
fragPosition = vertexPosition.xyz;
26-
fragNormal = normalize(mat3(inModel)*inNormal);
2727
fragTexCoord = inTexCoord;
28+
29+
vec3 T = normalize(vec3(inModel * vec4(inTangent, 0.0)));
30+
vec3 N = normalize(vec3(inModel * vec4(inNormal, 0.0)));
31+
vec3 B = cross(N, T);
32+
33+
TBN = mat3(T, B, N);
2834
}

Shaders/Forward/Vert.spv

912 Bytes
Binary file not shown.

src/Freya/Asset/MeshPool.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,18 +261,21 @@ namespace FREYA_NAMESPACE
261261
{
262262
const auto& aVertex = mesh->mVertices[i];
263263
const auto& aNormal = mesh->mNormals[i];
264+
const auto& aTangent = mesh->mTangents[i];
264265
const auto& aTextCoord = mesh->mTextureCoords[0][i];
265266

266267
const auto material = scene->mMaterials[mesh->mMaterialIndex];
267268

268269
aiColor3D aColor(1.0, 1.0, 1.0);
269270
material->Get(AI_MATKEY_COLOR_DIFFUSE, aColor);
270271

271-
auto vertex =
272-
Vertex { .position = glm::vec3(aVertex.x, aVertex.y, aVertex.z),
273-
.color = glm::vec3(aColor.r, aColor.g, aColor.b),
274-
.normal = glm::vec3(aNormal.x, aNormal.y, aNormal.z),
275-
.texCoord = glm::vec2(aTextCoord.x, aTextCoord.y) };
272+
auto vertex = Vertex {
273+
.position = glm::vec3(aVertex.x, aVertex.y, aVertex.z),
274+
.color = glm::vec3(aColor.r, aColor.g, aColor.b),
275+
.normal = glm::vec3(aNormal.x, aNormal.y, aNormal.z),
276+
.tangent = glm::vec3(aTangent.x, aTangent.y, aTangent.z),
277+
.texCoord = glm::vec2(aTextCoord.x, aTextCoord.y)
278+
};
276279

277280
// process vertex positions, normals and texture coordinates
278281
vertices.push_back(vertex);

src/Freya/Asset/Texture.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace FREYA_NAMESPACE
88
{
99
operator std::uint32_t() const { return id; }
1010

11-
Ref<Image> image;
12-
vk::DescriptorSet descriptorSet;
11+
Ref<Image> image;
12+
vk::Sampler sampler;
1313

1414
std::uint32_t width;
1515
std::uint32_t height;

src/Freya/Asset/TexturePool.cpp

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,27 @@ namespace FREYA_NAMESPACE
2626
{
2727
mLogger = mServiceProvider->GetService<skr::Logger<TexturePool>>();
2828
stbi_set_flip_vertically_on_load(true);
29+
30+
const auto samplerDescriptorSetAllocInfo =
31+
vk::DescriptorSetAllocateInfo()
32+
.setSetLayouts(mRenderPass->GetSamplerLayout())
33+
.setDescriptorPool(mRenderPass->GetSamplerDescriptorPool());
34+
35+
mTextureDescriptorSet = mDevice->Get().allocateDescriptorSets(
36+
samplerDescriptorSetAllocInfo)[0];
2937
}
3038

3139
TexturePool::~TexturePool()
3240
{
3341
for (auto texture : mTextures)
3442
{
3543
texture.image.reset();
44+
45+
mDevice->Get().destroySampler(texture.sampler);
3646
}
3747
}
3848

39-
std::uint32_t TexturePool::CreateTextureFromFile(std::string path,
40-
int binding)
49+
std::uint32_t TexturePool::CreateTextureFromFile(std::string path)
4150
{
4251
mLogger->LogTrace("TexturePool::CreateTextureFromFile:");
4352
mLogger->LogTrace("\tPath: {}", path);
@@ -63,23 +72,53 @@ namespace FREYA_NAMESPACE
6372

6473
stbi_image_free(imageData);
6574

66-
const auto samplerDescriptorSetAllocInfo =
67-
vk::DescriptorSetAllocateInfo()
68-
.setSetLayouts(mRenderPass->GetSamplerLayout())
69-
.setDescriptorPool(mRenderPass->GetSamplerDescriptorPool());
75+
constexpr auto samplerCreateInfo =
76+
vk::SamplerCreateInfo()
77+
.setMagFilter(vk::Filter::eLinear)
78+
.setMinFilter(vk::Filter::eLinear)
79+
.setAddressModeU(vk::SamplerAddressMode::eRepeat)
80+
.setAddressModeV(vk::SamplerAddressMode::eRepeat)
81+
.setAddressModeW(vk::SamplerAddressMode::eRepeat)
82+
.setBorderColor(vk::BorderColor::eIntOpaqueBlack)
83+
.setUnnormalizedCoordinates(false)
84+
.setMipmapMode(vk::SamplerMipmapMode::eLinear)
85+
.setMipLodBias(0.0f)
86+
.setMinLod(0.0f)
87+
.setMaxLod(0.0f)
88+
.setAnisotropyEnable(true)
89+
.setMaxAnisotropy(16);
90+
91+
const auto sampler = mDevice->Get().createSampler(samplerCreateInfo);
92+
93+
const auto texture = Texture {
94+
.image = image,
95+
.sampler = sampler,
96+
.width = static_cast<std::uint32_t>(width),
97+
.height = static_cast<std::uint32_t>(height),
98+
.id = static_cast<std::uint32_t>(mTextures.size()),
99+
};
100+
101+
mTextures.insert(texture);
102+
103+
return texture.id;
104+
}
70105

71-
const auto samplerDescriptorSet = mDevice->Get().allocateDescriptorSets(
72-
samplerDescriptorSetAllocInfo);
106+
void TexturePool::Bind(const std::uint32_t uint32, int binding)
107+
{
108+
if (!mTextures.contains(uint32))
109+
return;
110+
111+
const auto& texture = mTextures[uint32];
73112

74113
auto descriptorImageInfo =
75114
vk::DescriptorImageInfo()
76115
.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
77-
.setSampler(mRenderPass->GetSampler())
78-
.setImageView(image->GetImageView());
116+
.setSampler(texture.sampler)
117+
.setImageView(texture.image->GetImageView());
79118

80119
auto samplerDescriptorWriter =
81120
vk::WriteDescriptorSet()
82-
.setDstSet(samplerDescriptorSet[0])
121+
.setDstSet(mTextureDescriptorSet)
83122
.setDstBinding(binding)
84123
.setDstArrayElement(0)
85124
.setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
@@ -89,27 +128,7 @@ namespace FREYA_NAMESPACE
89128
mDevice->Get()
90129
.updateDescriptorSets(1, &samplerDescriptorWriter, 0, nullptr);
91130

92-
const auto texture = Texture {
93-
.image = image,
94-
.descriptorSet = samplerDescriptorSet[0],
95-
.width = static_cast<std::uint32_t>(width),
96-
.height = static_cast<std::uint32_t>(height),
97-
.id = static_cast<std::uint32_t>(mTextures.size()),
98-
};
99-
100-
mTextures.insert(texture);
101-
102-
return texture.id;
103-
}
104-
105-
void TexturePool::Bind(const std::uint32_t uint32)
106-
{
107-
if (!mTextures.contains(uint32))
108-
return;
109-
110-
const auto& texture = mTextures[uint32];
111-
112-
const auto descriptorSets = std::array { texture.descriptorSet };
131+
const auto descriptorSets = std::array { mTextureDescriptorSet };
113132

114133
mCommandPool->GetCommandBuffer().bindDescriptorSets(
115134
vk::PipelineBindPoint::eGraphics,

src/Freya/Asset/TexturePool.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ namespace FREYA_NAMESPACE
2020

2121
~TexturePool();
2222

23-
std::uint32_t CreateTextureFromFile(std::string path, int binding = 0);
24-
void Bind(uint32_t uint32);
23+
std::uint32_t CreateTextureFromFile(std::string path);
24+
void Bind(uint32_t texture, int binding = 0);
2525

2626
Ref<Buffer> queryStagingBuffer(std::uint32_t size);
2727
Ref<Buffer> createStagingBuffer(std::uint32_t size);
@@ -33,6 +33,7 @@ namespace FREYA_NAMESPACE
3333
Ref<CommandPool> mCommandPool;
3434
Ref<ForwardPass> mRenderPass;
3535
std::vector<Ref<Buffer>> mStagingBuffers;
36+
vk::DescriptorSet mTextureDescriptorSet;
3637

3738
TextureSet mTextures;
3839
};

0 commit comments

Comments
 (0)