Browse Source

shader templating

master
alistair 12 months ago
parent
commit
00084967ba
  1. 6
      assets/shaders/deferred_lighting.frag
  2. 2
      assets/shaders/g_frag.gl
  3. 15
      assets/shaders/screen.frag
  4. 3
      assets/shaders/write/material_properties.gl
  5. 7
      assets/shaders/write/ubo_info.gl
  6. 2
      source/camera.hpp
  7. 135
      source/main.cpp
  8. 23
      source/shaders.cpp
  9. 6
      source/uniform-buffer.hpp
  10. 13
      source/window.cpp
  11. 10
      source/window.hpp

6
assets/shaders/deferred_lighting.frag

@ -44,7 +44,7 @@ vec3 apply_kernel(float kernel[9], sampler2D tex) { @@ -44,7 +44,7 @@ vec3 apply_kernel(float kernel[9], sampler2D tex) {
vec3 sampleTex[9];
for(int i = 0; i < 9; i++)
{
sampleTex[i] = vec3(texture(tex, TexCoords.st + offsets[i]).rgb);
sampleTex[i] = vec3(texture(tex, TexCoords.st + offsets[i]).a);
}
vec3 col = vec3(0.0);
for(int i = 0; i < 9; i++)
@ -142,14 +142,14 @@ if (enable_fog) { @@ -142,14 +142,14 @@ if (enable_fog) {
lighting = clamp(lighting, vec3(0), vec3(1));
}
if (length(edge) > 0.1) {
if (length(edge) > 0.2) {
edge = vec3(1);
} else {
edge = vec3(0);
}
FragColor = vec4(lighting, 1.0);
FragColor = vec4(lighting * (1-edge), 1.0);
}

2
assets/shaders/g_frag.gl

@ -69,7 +69,7 @@ main() { @@ -69,7 +69,7 @@ main() {
gAlbedoSpec.rgb = toLinear(tex.rgb); // store specular intensity in gAlbedoSpec's alpha component
// linear depth
float near = 0.1;
float far = 1000;
float far = 500;
float ndc = gl_FragCoord.z * 2.0 - 1.0;
float linearDepth = (2.0 * near * far) / (far + near - ndc * (far - near));
gAlbedoSpec.a = linearDepth / far; // texture(material.texture_specular1, theTexCoord).r;

15
assets/shaders/screen.frag

@ -3,15 +3,20 @@ out vec4 FragColor; @@ -3,15 +3,20 @@ out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
uniform float gamma = 2.2;
uniform float exposure = 1.0;
uniform bool use_hdr = false;
struct light_info {
vec4 colour;
vec4 position;
};
##material_properties##
##ubo_info##
##material_properties##
uniform sampler2D screenTexture;
void main()
{
vec3 hdrcol = texture(screenTexture, TexCoords).rgb;

3
assets/shaders/write/material_properties.gl

@ -9,4 +9,7 @@ layout (std140) uniform ubo_info @@ -9,4 +9,7 @@ layout (std140) uniform ubo_info
vec4 colour; // 16 224
int debug_shader; // 4 240
bool instancing_enabled; // 4 244
float gamma; // 4 248
float exposure; // 4 252
bool use_hdr; // 4 256
};

7
assets/shaders/write/ubo_info.gl

@ -9,6 +9,7 @@ layout (std140) uniform ubo_info @@ -9,6 +9,7 @@ layout (std140) uniform ubo_info
vec4 colour; // 16 224
int debug_shader; // 4 240
bool instancing_enabled; // 4 244
};4 244
};244
};
float gamma; // 4 248
float exposure; // 4 252
bool use_hdr; // 4 256
};

2
source/camera.hpp

@ -36,7 +36,7 @@ struct camera_third_person { @@ -36,7 +36,7 @@ struct camera_third_person {
// TODO: store in uniforms
float fov = 40.0;
float near_plane = 0.1;
float far_plane = 1000;
float far_plane = 10000;
glm::vec3 euler_angles;
void update_projection(float aspect_ratio) {

135
source/main.cpp

@ -251,6 +251,11 @@ struct g_buffer { @@ -251,6 +251,11 @@ struct g_buffer {
glCheckError();
}
void bind() {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glViewport(0,0,logical_width, logical_height);
}
};
@ -325,34 +330,18 @@ int main_loop(game_state& g) @@ -325,34 +330,18 @@ int main_loop(game_state& g)
glm::vec3 walking_state = glm::vec3(0);
ubo_info s = {};
//ubo_proxy model_ubo (s);
material_properties m {};
ubo_proxy mat_ubo_s (m);
auto mat_ubo = std::make_shared<ubo_proxy<material_properties>>(std::move(m));
auto model_ubo = std::make_shared<ubo_proxy<ubo_info>>(s);
std::unordered_map<std::string, std::string> templates {
{"##" + mat_ubo->block_name + "##", mat_ubo->fmt_uniform_block()},
{"##" + model_ubo->block_name + "##", model_ubo->fmt_uniform_block()}
};
for (auto item:templates) {
spdlog::info("Shader: {}", item.first);
}
auto forward_lighting = std::make_shared<shader_handle>(g.asset_dir / "shaders" / "uniformtest.vert",
g.asset_dir / "shaders" / "forward-frag.gl",
templates);
g.shader_templates);
auto deferred_lighting = std::make_shared<shader_handle>(g.asset_dir / "shaders" / "screen.vert",
g.asset_dir / "shaders" / "deferred_lighting.frag",
templates);
g.shader_templates);
auto g_shader =
std::make_shared<shader_handle>(g.asset_dir / "shaders" / "uniformtest.vert",
g.asset_dir / "shaders" / "g_frag.gl",
templates);
g.shader_templates);
auto forward_pass_shader = g_shader;
// set scaling
@ -363,20 +352,22 @@ int main_loop(game_state& g) @@ -363,20 +352,22 @@ int main_loop(game_state& g)
glCheckError();
auto output = fmt::output_file(std::string(g.asset_dir / "shaders" / "write" / fmt::format("{}.gl", model_ubo->block_name)));
output.print("{}", model_ubo->fmt_uniform_block());
fmt::output_file(std::string(g.asset_dir / "shaders" / "write" / fmt::format("{}.gl", mat_ubo->block_name))).print("{}", model_ubo->fmt_uniform_block());
auto output = fmt::output_file(std::string(g.asset_dir / "shaders" / "write" / fmt::format("{}.gl", g.model_ubo->block_name)));
output.print("{}", g.model_ubo->fmt_uniform_block());
fmt::output_file(std::string(g.asset_dir / "shaders" / "write" / fmt::format("{}.gl", g.material_ubo->block_name))).print("{}", g.model_ubo->fmt_uniform_block());
model_ubo->gen_ubo(2);
model_ubo->bind_to_shader(g_shader->program);
model_ubo->bind_to_shader(deferred_lighting->program);
model_ubo->bind_to_shader(forward_lighting->program);
model_ubo->update_all_fields_force();
g.model_ubo->gen_ubo(2);
g.model_ubo->bind_to_shader(g_shader->program);
g.model_ubo->bind_to_shader(deferred_lighting->program);
g.model_ubo->bind_to_shader(forward_lighting->program);
g.model_ubo->bind_to_shader(g.screen_shader->program);
g.model_ubo->update_all_fields_force();
mat_ubo->gen_ubo(3);
mat_ubo->bind_to_shader(g_shader->program);
mat_ubo->bind_to_shader(deferred_lighting->program);
mat_ubo->bind_to_shader(forward_lighting->program);
g.material_ubo->gen_ubo(3);
g.material_ubo->bind_to_shader(g_shader->program);
g.material_ubo->bind_to_shader(g.screen_shader->program);
g.material_ubo->bind_to_shader(deferred_lighting->program);
g.material_ubo->bind_to_shader(forward_lighting->program);
glCheckError();
camera_third_person cam {float(g.windowx)/g.windowy};
@ -461,12 +452,12 @@ int main_loop(game_state& g) @@ -461,12 +452,12 @@ int main_loop(game_state& g)
float z = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
// position component of transformation matrix
light_info l {glm::vec4(5 * x,5 * y, 5 * z,1), glm::vec4(pos[3][0], pos[3][1] + 2, pos[3][2], 0)};
mat_ubo->lights()[i] = l;
g.material_ubo->lights()[i] = l;
}
num_lights = lily_positions.size() + 1;
light_info camera_light {glm::vec4(2,2,2,0), glm::vec4(0,0,0,1)};
mat_ubo->lights()[0] = camera_light;
g.material_ubo->lights()[0] = camera_light;
for (int i = num_lights; i < max_lights; i++) {
float x = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
@ -477,11 +468,11 @@ int main_loop(game_state& g) @@ -477,11 +468,11 @@ int main_loop(game_state& g)
float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
// position component of transformation matrix
light_info l {glm::vec4(5 * x,5 * y, 5 * z,1), glm::vec4(p * extent, q * extent, r * extent, 0)};
mat_ubo->lights()[i] = l;
g.material_ubo->lights()[i] = l;
}
mat_ubo->update_all_fields_force();
mat_ubo->current_lights(3);
g.material_ubo->update_all_fields_force();
g.material_ubo->current_lights(3);
glDisable(GL_CULL_FACE);
double last_frame = SDL_GetTicks();
@ -495,9 +486,8 @@ int main_loop(game_state& g) @@ -495,9 +486,8 @@ int main_loop(game_state& g)
if (deferred) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, G.fbo);
glViewport(0,0,G.logical_width, G.logical_height);
G.bind_textures();
G.bind();
forward_pass_shader = g_shader;
} else {
forward_pass_shader = forward_lighting;
@ -513,7 +503,7 @@ int main_loop(game_state& g) @@ -513,7 +503,7 @@ int main_loop(game_state& g)
ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();
model_ubo->colour(glm::vec4(255,0,0,1));
g.model_ubo->colour(glm::vec4(255,0,0,1));
if (show_demo_window) {
ImGui::ShowMetricsWindow(&show_demo_window);
@ -525,8 +515,8 @@ int main_loop(game_state& g) @@ -525,8 +515,8 @@ int main_loop(game_state& g)
}
const char *debug_shaders[] = {"output", "normal", "position", "albedo", "specular"};
model_ubo->debug_shader(debug_shader);
model_ubo->update_all_fields();
g.model_ubo->debug_shader(debug_shader);
g.model_ubo->update_all_fields();
auto view = g.registry.view<static_model_transform>();
@ -542,9 +532,9 @@ int main_loop(game_state& g) @@ -542,9 +532,9 @@ int main_loop(game_state& g)
auto transform = g.registry.get<static_model_transform>(entity);
cam.update_view_transform_look_at(transform.position, parent_transform.position);
model_ubo->view(cam.view_transform);
model_ubo->view_pos(glm::vec4(transform.position, 0));
model_ubo->projection(cam.projection);
g.model_ubo->view(cam.view_transform);
g.model_ubo->view_pos(glm::vec4(transform.position, 0));
g.model_ubo->projection(cam.projection);
//tri_shader->set("view", cam.view_transform);
@ -552,53 +542,53 @@ int main_loop(game_state& g) @@ -552,53 +542,53 @@ int main_loop(game_state& g)
if (move_lights) {
for (int i = 10; i < max_lights/2; i++) {
light_info light = mat_ubo->lights()[i];
light_info light = g.material_ubo->lights()[i];
light.light_pos = glm::rotate(light.light_pos, (float)(0.0001 * frame_time), glm::vec3(0,1,0));
// position component of transformation matrix
mat_ubo->lights()[i] = light;
g.material_ubo->lights()[i] = light;
}
}
camera_light.light_pos = glm::vec4(parent_transform.position, 0);
mat_ubo->lights()[0] = camera_light;
mat_ubo->update_all_fields();
g.material_ubo->lights()[0] = camera_light;
g.material_ubo->update_all_fields();
//xenia.draw(mat_ubo, model_ubo, forward_pass_shader, glm::rotate(t1, (float)M_PI, glm::vec3(1,0,0)));
//xenia.draw(g.material_ubo, g.model_ubo, forward_pass_shader, glm::rotate(t1, (float)M_PI, glm::vec3(1,0,0)));
auto xenia_transform = glm::mat4(1);
xenia_transform = glm::translate(xenia_transform, parent_transform.position);
xenia_transform = glm::translate(xenia_transform, glm::vec3(0, -8, 0));
xenia_transform = glm::rotate(xenia_transform, (float)M_PI, glm::vec3(1,0,0));
xenia_transform = glm::rotate(xenia_transform, (float)M_PI/2 - (glm::radians(cam.euler_angles[0] * walking_state.z) - glm::radians((cam.euler_angles[0] + 90) * walking_state.x)), glm::vec3(0,1,0));
xenia_transform = glm::scale(xenia_transform, glm::vec3(0.5));
xenia.draw(mat_ubo, model_ubo, forward_pass_shader, xenia_transform);
xenia.draw(g.material_ubo, g.model_ubo, forward_pass_shader, xenia_transform);
for(auto entity: view) {
static_model_transform &model = view.get<static_model_transform>(entity);
//tri_shader->set("model", model.get_transform());
//model_ubo->model(model.get_transform());
//model_ubo->update_all_fields();
//g.model_ubo->model(model.get_transform());
//g.model_ubo->update_all_fields();
}
glClearColor(0.0F, 0.0F, 0, 1.0F);
mat_ubo->update_all_fields();
model_ubo->update_all_fields();
g.material_ubo->update_all_fields();
g.model_ubo->update_all_fields();
srand(920731031);
auto t1 = glm::mat4(1);
ground.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
model.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
ferns.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
grass.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
dead_tree.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
leaf_tree.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
ntrees.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
vegetation.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
dead2.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
lily.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
dry_grass.draw(mat_ubo, model_ubo, forward_pass_shader, t1);
ground.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
model.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
ferns.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
grass.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
dead_tree.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
leaf_tree.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
ntrees.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
vegetation.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
dead2.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
lily.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
dry_grass.draw(g.material_ubo, g.model_ubo, forward_pass_shader, t1);
break;
}
@ -629,19 +619,18 @@ int main_loop(game_state& g) @@ -629,19 +619,18 @@ int main_loop(game_state& g)
ImGui::Checkbox("Enable fog", (bool *)&fog_enabled);
ImGui::Checkbox("Move lights", (bool *)&move_lights);
ImGui::Checkbox("Deferred Shading", (bool *)&deferred);
ImGui::Checkbox("HDR", (bool *)&tone_mapping.use_hdr);
ImGui::SliderFloat("Exposure", &tone_mapping.exposure, 0, 3.0);
ImGui::SliderFloat("Gamma", &tone_mapping.gamma, 0, 4.0);
ImGui::Checkbox("HDR", (bool *)&g.model_ubo->use_hdr());
ImGui::SliderFloat("Exposure", &g.model_ubo->exposure(), 0, 3.0);
ImGui::SliderFloat("Gamma", &g.model_ubo->gamma(), 0, 4.0);
ImGui::Combo("Debug shader", &debug_shader, debug_shaders, IM_ARRAYSIZE(debug_shaders));
ImGui::End();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(g.window);
mat_ubo->current_lights(num_lights);
mat_ubo->enable_fog(fog_enabled);
g.screen_shader->set("gamma", tone_mapping.gamma);
g.screen_shader->set("exposure", tone_mapping.exposure);
g.screen_shader->set("use_hdr", tone_mapping.use_hdr);
g.material_ubo->current_lights(num_lights);
g.material_ubo->enable_fog(fog_enabled);
while (SDL_PollEvent(&e) != 0) {
ImGui_ImplSDL2_ProcessEvent(&e);

23
source/shaders.cpp

@ -1,11 +1,26 @@ @@ -1,11 +1,26 @@
#include <fstream>
#include <spdlog/spdlog.h>
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "shaders.h"
std::string format_with_line_numbers(const std::string &text) {
std::stringstream input{text};
std::stringstream out{};
int position;
int line_no = 1;
std::string line;
while (std::getline(input, line, '\n')) {
out << fmt::format("{} | {}\n", line_no++, line);
}
return out.str();
}
bool shader_handle::handle_error(const std::string &filename) {
GLint fShaderCompiled = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &fShaderCompiled);
@ -23,6 +38,7 @@ bool shader_handle::handle_error(const std::string &filename) { @@ -23,6 +38,7 @@ bool shader_handle::handle_error(const std::string &filename) {
glGetShaderInfoLog(shader, max_length, &max_length, &err_log[0]);
std::cerr << (char *)(&err_log[0]) << " (" << filename << ")" << std::endl;
spdlog::info("Shader errored:\n{}", format_with_line_numbers(source));
return true;
}
@ -48,11 +64,10 @@ void shader_handle::add_shader( @@ -48,11 +64,10 @@ void shader_handle::add_shader(
}
// apply templates
for (const auto &item : templates) {
for (const auto &[key, content] : templates) {
auto position = std::string::npos;
while ((position = source.rfind(item.first, position)) !=
std::string::npos) {
source.replace(position, item.first.size(), item.second);
while ((position = source.rfind(key, position)) != std::string::npos) {
source.replace(position, key.size(), content);
}
}
spdlog::info("New shader: {}\n{}", filename, source);

6
source/uniform-buffer.hpp

@ -35,11 +35,15 @@ struct ubo_info { @@ -35,11 +35,15 @@ struct ubo_info {
glm::vec4 offset;
glm::vec4 colour;
bool instancing_enabled;
float gamma = 2.2;
float exposure = 1.0;
bool use_hdr = false;
};
REFL_AUTO(type(ubo_info), field(view_pos), field(model), field(view),
field(projection), field(offset), field(colour), field(debug_shader),
field(instancing_enabled));
field(instancing_enabled), field(gamma), field(exposure),
field(use_hdr));
struct material_properties {
// not implemented: for material properties provided by assimp

13
source/window.cpp

@ -127,7 +127,8 @@ void game_state::init_renderbuffer() @@ -127,7 +127,8 @@ void game_state::init_renderbuffer()
windowx, windowy, platonic_shapes.quad_vao);
screen_shader =
std::make_shared<shader_handle>(asset_dir / "shaders" / "screen.vert",
asset_dir / "shaders" / "screen.frag");
asset_dir / "shaders" / "screen.frag",
shader_templates);
screen_shader->use();
screen_shader->set("screenTexture", 4);
@ -136,15 +137,18 @@ void game_state::init_renderbuffer() @@ -136,15 +137,18 @@ void game_state::init_renderbuffer()
void framebuffer_render_context::bind() const
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0,0, width, height);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, colour);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glViewport(0,0,width, height);
glCheckError();
}
void framebuffer_render_context::unbind() const
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0, width, height);
glCheckError();
}
@ -169,6 +173,7 @@ void framebuffer_render_context::clear() @@ -169,6 +173,7 @@ void framebuffer_render_context::clear()
void framebuffer_render_context::present(std::shared_ptr<shader_handle>& shader)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0,width, height);
glDisable(GL_DEPTH_TEST);
shader->use();

10
source/window.hpp

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
#include "glheader.hpp"
#include "shaders.h"
#include "uniform-buffer.hpp"
struct framebuffer_render_context {
int width;
@ -76,6 +77,15 @@ struct game_state { @@ -76,6 +77,15 @@ struct game_state {
const std::filesystem::path asset_dir;
std::string window_name;
entt::registry registry;
std::shared_ptr<ubo_proxy<material_properties>> material_ubo =
std::make_shared<ubo_proxy<material_properties>>();
std::shared_ptr<ubo_proxy<ubo_info>> model_ubo =
std::make_shared<ubo_proxy<ubo_info>>();
std::unordered_map<std::string, std::string> shader_templates{
{"##" + material_ubo->block_name + "##",
material_ubo->fmt_uniform_block()},
{"##" + model_ubo->block_name + "##", model_ubo->fmt_uniform_block()}};
struct {
GLuint quad_vao, quad_vbo;

Loading…
Cancel
Save