]> git.localhorst.tv Git - blobs.git/commitdiff
varying material and schlick/fresnel
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 18 Dec 2017 22:33:03 +0000 (23:33 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 18 Dec 2017 22:33:03 +0000 (23:33 +0100)
looks a bit greyish weirdish in some cases, but overall not too shabby

assets
src/app/app.cpp
src/app/states.cpp
src/graphics/CreatureSkin.hpp
src/graphics/PlanetSurface.hpp
src/graphics/shader.cpp
src/world/Planet.hpp
src/world/TileType.hpp
src/world/world.cpp

diff --git a/assets b/assets
index ea14b7c01b5470c7f10eb349f355a6885ea184d4..c4158405ffc6c6198648b56f41fddecae9f0cb6a 160000 (submodule)
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit ea14b7c01b5470c7f10eb349f355a6885ea184d4
+Subproject commit c4158405ffc6c6198648b56f41fddecae9f0cb6a
index 8cd49f3e97b5488b7b59901ce94c51fe157ed2bf..582e62260475f161a583c6a28f85f81078214614 100644 (file)
@@ -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) {
index 8af5a8515815db212e2c646d5e57fa3ad1ab4f8c..f670f26e52ba33243ba614b559f7054898a494e2 100644 (file)
@@ -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()) {
index b61c108a9b973dc618483aabdfab79eb01357959..1dce8b532390ad0753262a42e2d0f1cb2a7edfff 100644 (file)
@@ -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];
 
index 27bd2bc616f703a3c6823a854f583a25bfdcdd07..94e201ece7e63760a890d4e50b39f2c30f1b49a3 100644 (file)
@@ -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];
index f68b5b523c450f1f373ad27ef4b7343d215d3b99..8078c9d0492c8fd5fdd973cafa63a735006164de 100644 (file)
@@ -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);
index f7efc585d6dbac8f58bf6ca0b3ae2cbddbcfedc2..3677ca4c92aeccd29e950920bc7461ca6c7c964f 100644 (file)
@@ -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<TileType> &);
+       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<graphics::SimpleVAO<Attributes, unsigned int>> vao;
 
index 7f18ee30261ac4ed0156956afa0787e6f197519e..47602691d190315110d37f26e2310f76ab220c22 100644 (file)
@@ -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;
index 596da072ed79ee211a88eef2188ea7adad2e6396..32ffeb954a965da4fd6bc344864ce93e52f16a57 100644 (file)
@@ -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<TileType> &ts) {
+void Planet::BuildVAO() {
        vao.reset(new graphics::SimpleVAO<Attributes, unsigned int>);
        vao->Bind();
        vao->BindAttributes();
        vao->EnableAttribute(0);
        vao->EnableAttribute(1);
        vao->EnableAttribute(2);
+       vao->EnableAttribute(3);
+       vao->EnableAttribute(4);
+       vao->EnableAttribute(5);
        vao->AttributePointer<glm::vec3>(0, false, offsetof(Attributes, position));
        vao->AttributePointer<glm::vec3>(1, false, offsetof(Attributes, normal));
        vao->AttributePointer<glm::vec3>(2, false, offsetof(Attributes, tex_coord));
+       vao->AttributePointer<float>(3, false, offsetof(Attributes, shiny));
+       vao->AttributePointer<float>(4, false, offsetof(Attributes, glossy));
+       vao->AttributePointer<float>(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<TileType> &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<TileType> &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<TileType> &tiles, Planet &p) noexcept {
                        }
                }
        }
-       p.BuildVAO(tiles);
+       p.BuildVAO();
 }
 
 void GenerateTest(const Set<TileType> &tiles, Planet &p) noexcept {
@@ -695,7 +714,7 @@ void GenerateTest(const Set<TileType> &tiles, Planet &p) noexcept {
                        }
                }
        }
-       p.BuildVAO(tiles);
+       p.BuildVAO();
 }