Skip to content

Commit c01511d

Browse files
Created the material system and a separate SSBO for materials
1 parent 8c2e4c5 commit c01511d

File tree

6 files changed

+114
-50
lines changed

6 files changed

+114
-50
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ out
33
build
44
compile_commands.json
55
.cache
6+
bin

assets/shaders/main.glsl

+17-8
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,16 @@ struct HitPayload {
2929
vec3 worldNormal;
3030
};
3131

32+
struct Material
33+
{
34+
vec3 albedo;
35+
float roughness;
36+
};
37+
3238
struct Sphere {
33-
vec3 albedo;
34-
float radius;
3539
vec3 center;
36-
float roughness;
40+
int matIdx;
41+
float radius;
3742
};
3843

3944
struct Scene {
@@ -53,7 +58,6 @@ uniform vec3 u_camFront;
5358
uniform vec3 u_LightPos;
5459
uniform vec3 u_LightColor;
5560

56-
uniform int u_SphereCount;
5761
uniform int u_MaxBounces;
5862
uniform uint u_RndmSeed;
5963
uniform int u_FrameIdx;
@@ -66,6 +70,10 @@ layout(std430, binding = 0) buffer SphereData {
6670
Sphere spheres[];
6771
};
6872

73+
layout(std430, binding = 1) buffer MaterialData {
74+
Material materials[];
75+
};
76+
6977
uint pcg_hash(uint seed)
7078
{
7179
uint state = seed * 747796405u + 2891336453u;
@@ -153,7 +161,7 @@ HitPayload TraceRay(inout Scene scene, Ray ray) {
153161
float closestHitDist = 1e10;
154162
int sphereIdx;
155163

156-
for(int i = 0; i < u_SphereCount; i++) {
164+
for(int i = 0; i < spheres.length(); i++) {
157165
float hitDist = HitSphere(spheres[i], ray);
158166

159167
if(hitDist == INVALID)
@@ -188,13 +196,14 @@ vec3 GetColor(Scene scene, Ray ray) {
188196
}
189197

190198
Sphere sphere = spheres[scene.sphereIdx];
199+
Material mat = materials[sphere.matIdx];
191200

192201
float lightIntensity = max(dot(payload.worldNormal, normalize(scene.lightPos - payload.worldPos)), 0.0f);
193-
color += contrib * sphere.albedo * lightIntensity * scene.lightColor;
202+
color += contrib * mat.albedo * lightIntensity * scene.lightColor;
194203
contrib *= 0.5f;
195204

196205
ray.origin = payload.worldPos + payload.worldNormal * 0.0001f;
197-
ray.dir = reflect(ray.dir, payload.worldNormal + sphere.roughness * RandomVec3MinMax(scene.rndmSeed, -0.5f, 0.5f));
206+
ray.dir = reflect(ray.dir, payload.worldNormal + mat.roughness * RandomVec3MinMax(scene.rndmSeed, -0.5f, 0.5f));
198207
// ray.dir = payload.worldNormal + RandomInUnitSphere(scene.rndmSeed);
199208
}
200209

@@ -233,4 +242,4 @@ void main() {
233242
uv = gl_FragCoord.xy / u_resolution;
234243
FragColor = (texture(t_PrevFrame, uv) * (u_FrameIdx - 1.0) + FragColor) / u_FrameIdx;
235244
}
236-
}
245+
}

src/Scene.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@
66

77
#include <cstdalign>
88

9-
struct alignas(16) Sphere
9+
struct alignas(16) Material
1010
{
1111
glm::vec3 albedo = glm::vec3(1.0f);
12-
float radius = 0.5f;
12+
float roughness = 0.01f;
13+
};
14+
15+
struct alignas(16) Sphere
16+
{
1317
glm::vec3 center = glm::vec3(0.0f);
14-
float roughness = 0.0f;
18+
int materialIdx = 0.0f;
19+
float radius = 0.5f;
1520
};
1621

1722
struct Scene
1823
{
1924
std::vector<Sphere> spheres;
20-
};
25+
std::vector<Material> materials;
26+
};

src/Tracer.cpp

+83-35
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
#include <nfd.h>
1616

17+
#include <string>
1718
#include <thread>
18-
#include <ctime>
1919
#include <cstdlib>
2020

2121
void Tracer::Run()
@@ -163,7 +163,7 @@ void Tracer::Run()
163163
if(ImGui::TreeNodeEx("Scene", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth))
164164
{
165165
ImGui::Text("Light Pos");
166-
if(ImGui::DragFloat3("##lightPos", &m_LightPos[0], 0.01f, -1.0f, 1.0f))
166+
if(ImGui::DragFloat3("##lightPos", &m_LightPos[0], 0.01f, -100.0f, 100.0f))
167167
resetFrameIdx = true;
168168

169169
ImGui::Spacing();
@@ -186,26 +186,63 @@ void Tracer::Run()
186186
ImGui::Spacing();
187187
ImGui::Spacing();
188188

189-
if(ImGui::Button("Add a sphere"))
189+
if(ImGui::Button("Add sphere"))
190190
{
191-
resetFrameIdx = true;
192-
193191
m_Scene.spheres.push_back(Sphere());
194192

195-
glDeleteBuffers(1, &ssbo);
193+
glDeleteBuffers(1, &m_SceneSSBO);
196194

197-
glGenBuffers(1, &ssbo);
198-
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
195+
glGenBuffers(1, &m_SceneSSBO);
196+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_SceneSSBO);
199197
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Sphere) * m_Scene.spheres.size(), m_Scene.spheres.data(), GL_DYNAMIC_DRAW);
200-
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
198+
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_SceneSSBO);
201199

202200
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
203201
}
204202

205203
ImGui::Spacing();
206-
ImGui::Spacing();
207-
ImGui::Spacing();
204+
205+
if(ImGui::Button("Add material"))
206+
{
207+
m_Scene.materials.push_back(Material{});
208+
209+
glDeleteBuffers(1, &m_MatSSBO);
210+
211+
glGenBuffers(1, &m_MatSSBO);
212+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_MatSSBO);
213+
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Material) * m_Scene.materials.size(), m_Scene.materials.data(), GL_DYNAMIC_DRAW);
214+
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_MatSSBO);
215+
216+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
217+
}
208218

219+
ImGui::Separator();
220+
221+
if(ImGui::TreeNodeEx("Materials", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth))
222+
{
223+
for(int i = 0; i < m_Scene.materials.size(); i++)
224+
{
225+
if(ImGui::TreeNodeEx(("Material #" + std::to_string(i)).c_str(), ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth))
226+
{
227+
ImGui::Text("Albedo");
228+
if(ImGui::ColorEdit3(("##albedo" + std::to_string(i)).c_str(), &m_Scene.materials[i].albedo[0]))
229+
resetFrameIdx = true;
230+
231+
ImGui::Spacing();
232+
ImGui::Spacing();
233+
ImGui::Spacing();
234+
235+
ImGui::Text("Roughness");
236+
if(ImGui::DragFloat(("##rougness" + std::to_string(i)).c_str(), &m_Scene.materials[i].roughness, 0.1f, 0.0f, 1.0f))
237+
resetFrameIdx = true;
238+
239+
ImGui::TreePop();
240+
}
241+
}
242+
243+
ImGui::TreePop();
244+
}
245+
209246
for(int i = 0; i < m_Scene.spheres.size(); i++)
210247
{
211248
if(ImGui::TreeNodeEx(("Sphere " + std::to_string(i + 1)).c_str(), ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth))
@@ -217,27 +254,24 @@ void Tracer::Run()
217254
ImGui::Spacing();
218255
ImGui::Spacing();
219256
ImGui::Spacing();
220-
221-
ImGui::Text("Sphere Albedo");
222-
if(ImGui::ColorEdit3(("##sphereAlbedo" + std::to_string(i)).c_str(), &m_Scene.spheres[i].albedo[0]))
223-
resetFrameIdx = true;
224-
225-
ImGui::Spacing();
226-
ImGui::Spacing();
227-
ImGui::Spacing();
228257

229258
ImGui::Text("Sphere Radius");
230-
if(ImGui::DragFloat(("##sphereRadius" + std::to_string(i)).c_str(), &m_Scene.spheres[i].radius, 0.1f, 0.2f, 100.0f))
259+
if(ImGui::DragFloat(("##sphereRadius" + std::to_string(i)).c_str(), &m_Scene.spheres[i].radius, 0.1f, 0.2f, 1000.0f))
231260
resetFrameIdx = true;
232-
233-
ImGui::Spacing();
234-
ImGui::Spacing();
235-
ImGui::Spacing();
236-
237-
ImGui::Text("Sphere Roughness");
238-
if(ImGui::DragFloat(("##sphereRoughness" + std::to_string(i)).c_str(), &m_Scene.spheres[i].roughness, 0.1f, 0.0f, 1.0f))
261+
262+
ImGui::Spacing();
263+
ImGui::Spacing();
264+
ImGui::Spacing();
265+
266+
ImGui::Text("Material Index");
267+
if(ImGui::DragInt(("##matIdx" + std::to_string(i)).c_str(), &m_Scene.spheres[i].materialIdx, 1.0f))
239268
resetFrameIdx = true;
240269

270+
if(m_Scene.spheres[i].materialIdx >= m_Scene.materials.size())
271+
{
272+
m_Scene.spheres[i].materialIdx = 0;
273+
}
274+
241275
ImGui::TreePop();
242276
}
243277
}
@@ -339,13 +373,21 @@ void Tracer::Init()
339373
// Scene
340374
{
341375
m_Scene.spheres.push_back(Sphere{});
376+
m_Scene.materials.push_back(Material{});
342377
}
343-
// SSBO
378+
// SSBOs
344379
{
345-
glGenBuffers(1, &ssbo);
346-
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
380+
glGenBuffers(1, &m_SceneSSBO);
381+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_SceneSSBO);
347382
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Sphere) * m_Scene.spheres.size(), m_Scene.spheres.data(), GL_DYNAMIC_DRAW);
348-
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
383+
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_SceneSSBO);
384+
385+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
386+
387+
glGenBuffers(1, &m_MatSSBO);
388+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_MatSSBO);
389+
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Material) * m_Scene.materials.size(), m_Scene.materials.data(), GL_DYNAMIC_DRAW);
390+
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_MatSSBO);
349391

350392
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
351393
}
@@ -360,16 +402,23 @@ void Tracer::Cleanup()
360402

361403
m_Shader.Destroy();
362404

405+
glDeleteBuffers(1, &m_MatSSBO);
406+
glDeleteBuffers(1, &m_SceneSSBO);
407+
363408
glDeleteBuffers(1, &vbo);
364409
glDeleteVertexArrays(1, &vao);
365410
m_Window.Destroy();
366411
}
367412

368413
void Tracer::Render(int width, int height)
369414
{
370-
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
415+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_SceneSSBO);
371416
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Sphere) * m_Scene.spheres.size(), m_Scene.spheres.data());
372-
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
417+
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_SceneSSBO);
418+
419+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_MatSSBO);
420+
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Material) * m_Scene.materials.size(), m_Scene.materials.data());
421+
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_MatSSBO);
373422

374423
m_Shader.Bind();
375424

@@ -380,7 +429,6 @@ void Tracer::Render(int width, int height)
380429
m_Shader.PutTex("t_Skybox", 0);
381430
m_Shader.PutTex("t_PrevFrame", 1);
382431

383-
m_Shader.PutInt("u_SphereCount", m_Scene.spheres.size());
384432
m_Shader.PutInt("u_MaxBounces", m_MaxBounces);
385433
m_Shader.PutInt("u_FrameIdx", m_FrameIdx);
386434
m_Shader.PutInt("u_Accumulate", (int)m_Accumulate);
@@ -415,4 +463,4 @@ void Tracer::WriteToPngFile(std::string fileName, unsigned char* pixels, int wid
415463
stbi_write_png(fileName.c_str(), width, height, channels, flippedPixels, width * channels);
416464

417465
delete[] flippedPixels;
418-
}
466+
}

src/Tracer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class Tracer
3131

3232
bool m_Render = false, m_IsSceneHovered = false, m_Accumulate = false;
3333
float lastTime, deltaTime, currentTime;
34-
uint32_t vao, vbo, ssbo;
34+
uint32_t vao, vbo, m_SceneSSBO, m_MatSSBO;
3535
int m_MaxBounces = 2, m_FrameIdx = 1;
3636

3737
private:
3838
void WriteToPngFile(std::string fileName, unsigned char* pixels, int width, int height);
39-
};
39+
};

src/Utils/Utils.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace Utils
2323
const char *message,
2424
const void *userParam)
2525
{
26-
return; // For now!
26+
// return; // For now!
2727

2828
// ignore non-significant error/warning codes
2929
if(id == 131169 || id == 131185 || id == 131218 || id == 131204) return;

0 commit comments

Comments
 (0)