From: Daniel Karbach Date: Mon, 18 Dec 2017 22:33:03 +0000 (+0100) Subject: varying material and schlick/fresnel X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=0734615e546059679f1827c35fe1928ffea2fc56 varying material and schlick/fresnel looks a bit greyish weirdish in some cases, but overall not too shabby --- diff --git a/assets b/assets index ea14b7c..c415840 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ea14b7c01b5470c7f10eb349f355a6885ea184d4 +Subproject commit c4158405ffc6c6198648b56f41fddecae9f0cb6a diff --git a/src/app/app.cpp b/src/app/app.cpp index 8cd49f3..582e622 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -331,6 +331,12 @@ void Assets::ReadTileTypes(io::TokenStreamReader &in) { in.ReadString(data.tile_types[id].label); } else if (name == "texture") { data.tile_types[id].texture = in.GetInt(); + } else if (name == "shiny") { + data.tile_types[id].shiny = in.GetDouble(); + } else if (name == "glossy") { + data.tile_types[id].glossy = in.GetDouble(); + } else if (name == "metallic") { + data.tile_types[id].metallic = in.GetDouble(); } else if (name == "yield") { in.Skip(io::Token::BRACKET_OPEN); while (in.Peek().type != io::Token::BRACKET_CLOSE) { diff --git a/src/app/states.cpp b/src/app/states.cpp index 8af5a85..f670f26 100644 --- a/src/app/states.cpp +++ b/src/app/states.cpp @@ -246,12 +246,14 @@ void MasterState::OnRender(graphics::Viewport &viewport) { cam.LookAt(glm::vec3(cam_pos), glm::vec3(cam_focus), glm::vec3(cam_up)); assets.shaders.planet_surface.Activate(); assets.shaders.planet_surface.SetV(cam.View()); + assets.shaders.planet_surface.SetAmbient(glm::vec3(0.04, 0.05, 0.06)); assets.shaders.sky_box.Activate(); assets.shaders.sky_box.SetV(cam.View() * cam.Universe()); assets.shaders.sun_surface.Activate(); assets.shaders.sun_surface.SetV(cam.View()); assets.shaders.creature_skin.Activate(); assets.shaders.creature_skin.SetV(cam.View()); + assets.shaders.creature_skin.SetAmbient(glm::vec3(0.04, 0.05, 0.06)); int num_lights = 0; for (auto sun : sim.Suns()) { diff --git a/src/graphics/CreatureSkin.hpp b/src/graphics/CreatureSkin.hpp index b61c108..1dce8b5 100644 --- a/src/graphics/CreatureSkin.hpp +++ b/src/graphics/CreatureSkin.hpp @@ -34,6 +34,7 @@ public: void SetBaseColor(const glm::vec3 &) noexcept; void SetHighlightColor(const glm::vec4 &) noexcept; void SetTexture(ArrayTexture &) noexcept; + void SetAmbient(const glm::vec3 &) noexcept; void SetLight(int n, const glm::vec3 &pos, const glm::vec3 &color, float strength) noexcept; void SetNumLights(int n) noexcept; @@ -61,6 +62,7 @@ private: GLuint base_color_handle; GLuint highlight_color_handle; GLuint sampler_handle; + GLuint ambient_handle; GLuint num_lights_handle; GLuint light_handle[MAX_LIGHTS * 3]; diff --git a/src/graphics/PlanetSurface.hpp b/src/graphics/PlanetSurface.hpp index 27bd2bc..94e201e 100644 --- a/src/graphics/PlanetSurface.hpp +++ b/src/graphics/PlanetSurface.hpp @@ -32,6 +32,7 @@ public: void SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept; void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept; void SetTexture(ArrayTexture &) noexcept; + void SetAmbient(const glm::vec3 &) noexcept; void SetLight(int n, const glm::vec3 &pos, const glm::vec3 &color, float strength) noexcept; void SetNumLights(int n) noexcept; @@ -56,6 +57,7 @@ private: GLuint mv_handle; GLuint mvp_handle; GLuint sampler_handle; + GLuint ambient_handle; GLuint num_lights_handle; GLuint light_handle[MAX_LIGHTS * 3]; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index f68b5b5..8078c9d 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -194,6 +194,9 @@ PlanetSurface::PlanetSurface() "layout(location = 0) in vec3 vtx_position;\n" "layout(location = 1) in vec3 vtx_normal;\n" "layout(location = 2) in vec3 vtx_tex_uv;\n" + "layout(location = 3) in float vtx_shiny;\n" + "layout(location = 4) in float vtx_glossy;\n" + "layout(location = 5) in float vtx_metallic;\n" "uniform mat4 M;\n" "uniform mat4 MV;\n" @@ -202,12 +205,18 @@ PlanetSurface::PlanetSurface() "out vec3 vtx_viewspace;\n" "out vec3 nrm_viewspace;\n" "out vec3 frag_tex_uv;\n" + "out float frag_shiny;\n" + "out float frag_glossy;\n" + "out float frag_metallic;\n" "void main() {\n" "gl_Position = MVP * vec4(vtx_position, 1.0);\n" "vtx_viewspace = (MV * vec4(vtx_position, 1.0)).xyz;\n" "nrm_viewspace = (MV * vec4(vtx_position, 0.0)).xyz;\n" "frag_tex_uv = vtx_tex_uv;\n" + "frag_shiny = vtx_shiny;\n" + "frag_glossy = vtx_glossy;\n" + "frag_metallic = vtx_metallic;\n" "}\n" ); prog.LoadShader( @@ -223,8 +232,12 @@ PlanetSurface::PlanetSurface() "in vec3 vtx_viewspace;\n" "in vec3 nrm_viewspace;\n" "in vec3 frag_tex_uv;\n" + "in float frag_shiny;\n" + "in float frag_glossy;\n" + "in float frag_metallic;\n" "uniform sampler2DArray tex_sampler;\n" + "uniform vec3 ambient;\n" "uniform int num_lights;\n" "uniform LightSource light[8];\n" @@ -232,19 +245,19 @@ PlanetSurface::PlanetSurface() "void main() {\n" "vec3 normal = normalize(nrm_viewspace);\n" + "vec3 view_dir = vec3(0.0, 0.0, 1.0);\n" "vec3 tex_color = texture(tex_sampler, frag_tex_uv).rgb;\n" - "vec3 total_light = tex_color * vec3(0.1, 0.1, 0.1);\n" + "vec3 spec_color = mix(vec3(frag_glossy), tex_color, frag_metallic);\n" + "vec3 total_light = tex_color * ambient;\n" "for (int i = 0; i < num_lights; ++i) {\n" "vec3 to_light = light[i].position - vtx_viewspace;\n" "float distance = length(to_light) + length(vtx_viewspace);\n" "vec3 light_dir = normalize(to_light);\n" "float attenuation = light[i].strength / (distance * distance);\n" "vec3 diffuse = attenuation * max(0.0, dot(normal, light_dir)) * light[i].color * tex_color;\n" - "vec3 view_dir = vec3(0.0, 0.0, 1.0);\n" - "vec3 specular = vec3(0.0, 0.0, 0.0);\n" - "if (dot(normal, light_dir) >= 0.0) {\n" - "attenuation * light[i].color * pow(max(0.0, dot(reflect(-light_dir, normal), view_dir)), 25.0);\n" - "}\n" + "vec3 specular = attenuation * light[i].color" + " * mix(spec_color, vec3(1.0), pow(1.0 - max(0.0, dot(normalize(light_dir + view_dir), view_dir)), 5.0))" + " * pow(max(0.0, dot(reflect(-light_dir, normal), view_dir)), frag_shiny);\n" "total_light = total_light + diffuse + specular;\n" "}\n" "color = total_light;\n" @@ -259,6 +272,7 @@ PlanetSurface::PlanetSurface() mv_handle = prog.UniformLocation("MV"); mvp_handle = prog.UniformLocation("MVP"); sampler_handle = prog.UniformLocation("tex_sampler"); + ambient_handle = prog.UniformLocation("ambient"); num_lights_handle = prog.UniformLocation("num_lights"); for (int i = 0; i < MAX_LIGHTS; ++i) { light_handle[3 * i + 0] = prog.UniformLocation("light[" + std::to_string(i) + "].position"); @@ -321,6 +335,10 @@ void PlanetSurface::SetTexture(ArrayTexture &tex) noexcept { prog.Uniform(sampler_handle, GLint(0)); } +void PlanetSurface::SetAmbient(const glm::vec3 &a) noexcept { + prog.Uniform(ambient_handle, a); +} + void PlanetSurface::SetLight(int n, const glm::vec3 &pos, const glm::vec3 &color, float strength) noexcept { prog.Uniform(light_handle[3 * n + 0], pos); prog.Uniform(light_handle[3 * n + 1], color); @@ -703,26 +721,27 @@ CreatureSkin::CreatureSkin() "uniform vec3 base_color;\n" "uniform vec4 highlight_color;\n" "uniform sampler2DArray tex_sampler;\n" + "uniform vec3 ambient;\n" "uniform int num_lights;\n" "uniform LightSource light[8];\n" "out vec3 color;\n" "void main() {\n" + "vec3 view_dir = vec3(0.0, 0.0, 1.0);\n" "vec4 tex_color = texture(tex_sampler, frag_tex_uv);\n" "vec3 mat_color = mix(base_color, highlight_color.rgb, tex_color.r * tex_color.a * highlight_color.a);\n" - "vec3 total_light = mat_color * vec3(0.1, 0.1, 0.1);\n" + "vec3 spec_color = vec3(0.5);\n" + "vec3 total_light = mat_color * ambient;\n" "for (int i = 0; i < num_lights; ++i) {\n" "vec3 to_light = light[i].position - vtx_viewspace;\n" "float distance = length(to_light) + length(vtx_viewspace);\n" "vec3 light_dir = normalize(to_light);\n" "float attenuation = light[i].strength / (distance * distance);\n" "vec3 diffuse = attenuation * max(0.0, dot(normal, light_dir)) * light[i].color * mat_color;\n" - "vec3 view_dir = vec3(0.0, 0.0, 1.0);\n" - "vec3 specular = vec3(0.0, 0.0, 0.0);\n" - "if (dot(normal, light_dir) >= 0.0) {\n" - "attenuation * light[i].color * pow(max(0.0, dot(reflect(-light_dir, normal), view_dir)), 25.0);\n" - "}\n" + "vec3 specular = attenuation * light[i].color" + " * mix(spec_color, vec3(1.0), pow(1.0 - max(0.0, dot(normalize(light_dir + view_dir), view_dir)), 5.0))" + " * pow(max(0.0, dot(reflect(-light_dir, normal), view_dir)), 5.0);\n" "total_light = total_light + diffuse + specular;\n" "}\n" "color = total_light;\n" @@ -739,6 +758,7 @@ CreatureSkin::CreatureSkin() base_color_handle = prog.UniformLocation("base_color"); highlight_color_handle = prog.UniformLocation("highlight_color"); sampler_handle = prog.UniformLocation("tex_sampler"); + ambient_handle = prog.UniformLocation("ambient"); num_lights_handle = prog.UniformLocation("num_lights"); for (int i = 0; i < MAX_LIGHTS; ++i) { light_handle[3 * i + 0] = prog.UniformLocation("light[" + std::to_string(i) + "].position"); @@ -809,6 +829,10 @@ void CreatureSkin::SetTexture(ArrayTexture &tex) noexcept { prog.Uniform(sampler_handle, GLint(0)); } +void CreatureSkin::SetAmbient(const glm::vec3 &a) noexcept { + prog.Uniform(ambient_handle, a); +} + void CreatureSkin::SetLight(int n, const glm::vec3 &pos, const glm::vec3 &color, float strength) noexcept { prog.Uniform(light_handle[3 * n + 0], pos); prog.Uniform(light_handle[3 * n + 1], color); diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp index f7efc58..3677ca4 100644 --- a/src/world/Planet.hpp +++ b/src/world/Planet.hpp @@ -60,7 +60,7 @@ public: // center point of tile on surface at elevation glm::dvec3 TileCenter(int surface, int x, int y, double elevation = 0.0) const noexcept; - void BuildVAO(const Set &); + void BuildVAO(); void Draw(app::Assets &, graphics::Viewport &) override; private: @@ -88,6 +88,9 @@ private: glm::vec3 position; glm::vec3 normal; glm::vec3 tex_coord; + float shiny; + float glossy; + float metallic; }; std::unique_ptr> vao; diff --git a/src/world/TileType.hpp b/src/world/TileType.hpp index 7f18ee3..4760269 100644 --- a/src/world/TileType.hpp +++ b/src/world/TileType.hpp @@ -19,6 +19,10 @@ struct TileType { int id; int texture; + double shiny = 5.0; + double glossy = 0.5; + double metallic = 0.0; + struct Yield { int resource; double ubiquity; diff --git a/src/world/world.cpp b/src/world/world.cpp index 596da07..32ffeb9 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -469,16 +469,22 @@ glm::dvec3 Planet::TileCenter(int srf, int x, int y, double e) const noexcept { return glm::normalize(cubeunmap(srf, u, v)) * (Radius() + e); } -void Planet::BuildVAO(const Set &ts) { +void Planet::BuildVAO() { vao.reset(new graphics::SimpleVAO); vao->Bind(); vao->BindAttributes(); vao->EnableAttribute(0); vao->EnableAttribute(1); vao->EnableAttribute(2); + vao->EnableAttribute(3); + vao->EnableAttribute(4); + vao->EnableAttribute(5); vao->AttributePointer(0, false, offsetof(Attributes, position)); vao->AttributePointer(1, false, offsetof(Attributes, normal)); vao->AttributePointer(2, false, offsetof(Attributes, tex_coord)); + vao->AttributePointer(3, false, offsetof(Attributes, shiny)); + vao->AttributePointer(4, false, offsetof(Attributes, glossy)); + vao->AttributePointer(5, false, offsetof(Attributes, metallic)); vao->ReserveAttributes(TilesTotal() * 4, GL_STATIC_DRAW); { auto attrib = vao->MapAttributes(GL_WRITE_ONLY); @@ -504,7 +510,8 @@ void Planet::BuildVAO(const Set &ts) { pos[3][(surface + 1) % 3] = float(y + 1) - offset; pos[3][(surface + 2) % 3] = offset; - float tex = ts[TileAt(surface, x, y).type].texture; + const TileType &t = TypeAt(surface, x, y); + float tex = t.texture; const float tex_v_begin = surface < 3 ? 1.0f : 0.0f; const float tex_v_end = surface < 3 ? 0.0f : 1.0f; @@ -513,24 +520,36 @@ void Planet::BuildVAO(const Set &ts) { attrib[4 * index + 0].tex_coord[0] = 0.0f; attrib[4 * index + 0].tex_coord[1] = tex_v_begin; attrib[4 * index + 0].tex_coord[2] = tex; + attrib[4 * index + 0].shiny = t.shiny; + attrib[4 * index + 0].glossy = t.glossy; + attrib[4 * index + 0].metallic = t.metallic; attrib[4 * index + 1].position = glm::normalize(pos[1]) * (surface < 3 ? offset : -offset); attrib[4 * index + 1].normal = pos[1]; attrib[4 * index + 1].tex_coord[0] = 0.0f; attrib[4 * index + 1].tex_coord[1] = tex_v_end; attrib[4 * index + 1].tex_coord[2] = tex; + attrib[4 * index + 1].shiny = t.shiny; + attrib[4 * index + 1].glossy = t.glossy; + attrib[4 * index + 1].metallic = t.metallic; attrib[4 * index + 2].position = glm::normalize(pos[2]) * (surface < 3 ? offset : -offset); attrib[4 * index + 2].normal = pos[2]; attrib[4 * index + 2].tex_coord[0] = 1.0f; attrib[4 * index + 2].tex_coord[1] = tex_v_begin; attrib[4 * index + 2].tex_coord[2] = tex; + attrib[4 * index + 2].shiny = t.shiny; + attrib[4 * index + 2].glossy = t.glossy; + attrib[4 * index + 2].metallic = t.metallic; attrib[4 * index + 3].position = glm::normalize(pos[3]) * (surface < 3 ? offset : -offset); attrib[4 * index + 3].normal = pos[3]; attrib[4 * index + 3].tex_coord[0] = 1.0f; attrib[4 * index + 3].tex_coord[1] = tex_v_end; attrib[4 * index + 3].tex_coord[2] = tex; + attrib[4 * index + 3].shiny = t.shiny; + attrib[4 * index + 3].glossy = t.glossy; + attrib[4 * index + 3].metallic = t.metallic; } } } @@ -680,7 +699,7 @@ void GenerateEarthlike(const Set &tiles, Planet &p) noexcept { } } } - p.BuildVAO(tiles); + p.BuildVAO(); } void GenerateTest(const Set &tiles, Planet &p) noexcept { @@ -695,7 +714,7 @@ void GenerateTest(const Set &tiles, Planet &p) noexcept { } } } - p.BuildVAO(tiles); + p.BuildVAO(); }