X-Git-Url: https://gitweb.ps.run/subsurface_scattering/blobdiff_plain/e03792c2d5620ca07ac50717062df846927027c0..0a5e8172a6ee0e79c81eec21a9966bea9385b249:/src/main.cpp diff --git a/src/main.cpp b/src/main.cpp index ddba48c..168d01d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,13 +20,9 @@ #include #include -/* -TODO: -- ShadowMap to fbo -- Save Depth to fbo - -*/ +// sample positions and weights for a Gaussian kernel from +// Hable, John ; Borshukov, George ; Hejl, Jim: Fast Skin Shading. In: ShaderX7, ShaderX : Charles River Media, 2009, S. 161–173 float samplePositions[] = { 0.000000f, 0.000000f, @@ -101,7 +97,6 @@ private: GLuint VAO = 0; }; - struct freecam { glm::vec3 pos = glm::vec3(0, 0, -1); glm::vec2 rot = glm::vec2(0, 0); @@ -155,7 +150,6 @@ private: float moveFactor = 20; }; - struct arccam { glm::vec2 rot = glm::vec2(0, 0); float radius = 1; @@ -207,7 +201,6 @@ private: const float angleFactor = 200; }; - std::string readFile(std::string filename) { std::ifstream ifs(filename, std::ios::binary); std::string result, line; @@ -222,10 +215,13 @@ model loadModel(const std::string &filename) { const aiScene *scene = importer.ReadFile( filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate | - aiProcess_SortByPType | aiProcess_GenSmoothNormals); + aiProcess_SortByPType | aiProcess_GenSmoothNormals | + aiProcess_GenUVCoords); model result; + printf("uv channels: %d\n", scene->mMeshes[0]->GetNumUVChannels()); + for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) { aiVector3D v = scene->mMeshes[0]->mVertices[i]; aiVector3D n = scene->mMeshes[0]->mNormals[i]; @@ -293,7 +289,6 @@ GLuint compileShaders(const char *vertFilename, const char *fragFilename) { return shaderProgram; } - struct framebuffer { framebuffer(const char *vertFilename, const char *fragFilename, int width, int height) { glGenFramebuffers(1, &fbo); @@ -387,36 +382,42 @@ int main() { if (glewInit() != GLEW_OK) { } - GLuint shaderProgramShadowmap = compileShaders("shaders/vert.glsl", "shaders/frag_shadowmap.glsl"); - GLuint shaderProgramIrradiance = compileShaders("shaders/vert.glsl", "shaders/frag_irradiance.glsl"); + GLuint shaderProgramShadowmap = compileShaders("shaders/vert_shadowmap.glsl", "shaders/frag_shadowmap.glsl"); + GLuint shaderProgramIrradiance = compileShaders("shaders/vert_irradiance.glsl", "shaders/frag_irradiance.glsl"); model m = loadModel("models/Isotrop-upperjaw.ply"); - + arccam arcCam; freecam freeCam; - - glm::vec3 lightPos(1.2f, 5.0f, 2.0f); // MVP glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f)); - glm::mat4 view; + glm::mat4 view, lightView; glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f); + glm::mat4 lightProj = glm::perspective(glm::radians(90.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f); // Framebuffer + framebuffer fb_shadowmap("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height); framebuffer fb_irradiance("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height); // Config - struct { + const struct { bool wireframe = false; bool freecam = false; - int renderState = 0; + int renderState = 2; float color[3] = { 0.7f, 0.4f, 0.4f }; - } options; + glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.03f); + float transmittanceScale = 0.025f; + float powBase = 2; + float powFactor = 1.5; + } DefaultOptions; + + auto options = DefaultOptions; sf::Clock deltaClock; @@ -448,7 +449,7 @@ int main() { } } - // Update + // Update Camera if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) { window.setMouseCursorVisible(false); @@ -471,7 +472,11 @@ int main() { prevMouse = sf::Mouse::isButtonPressed(sf::Mouse::Right); - // Render Shadowmap + // Render Shadowmap to fbo + + glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); + glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); + glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); glBindFramebuffer(GL_FRAMEBUFFER, fb_shadowmap.fbo); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -490,23 +495,25 @@ int main() { else view = arcCam.getViewMatrix(); + lightView = glm::lookAt(options.lightPos, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); + glUniformMatrix4fv( glGetUniformLocation(shaderProgramShadowmap, "model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv( - glGetUniformLocation(shaderProgramShadowmap, "view"), - 1, GL_FALSE, glm::value_ptr(view)); + glGetUniformLocation(shaderProgramShadowmap, "lightView"), + 1, GL_FALSE, glm::value_ptr(lightView)); glUniformMatrix4fv( glGetUniformLocation(shaderProgramShadowmap, "projection"), - 1, GL_FALSE, glm::value_ptr(proj)); + 1, GL_FALSE, glm::value_ptr(lightProj)); glUniform3fv( glGetUniformLocation(shaderProgramShadowmap, "lightPos"), - 1, glm::value_ptr(lightPos)); + 1, glm::value_ptr(options.lightPos)); m.draw(); - // Render irradiance + // Render irradiance map to fbo glBindFramebuffer(GL_FRAMEBUFFER, fb_irradiance.fbo); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -520,20 +527,41 @@ int main() { glUseProgram(shaderProgramIrradiance); - if (options.freecam) - view = freeCam.getViewMatrix(); - else - view = arcCam.getViewMatrix(); - glUniformMatrix4fv( glGetUniformLocation(shaderProgramIrradiance, "model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv( glGetUniformLocation(shaderProgramIrradiance, "view"), 1, GL_FALSE, glm::value_ptr(view)); + glUniformMatrix4fv( + glGetUniformLocation(shaderProgramIrradiance, "lightView"), + 1, GL_FALSE, glm::value_ptr(lightView)); + glUniformMatrix4fv( + glGetUniformLocation(shaderProgramIrradiance, "lightViewInv"), + 1, GL_FALSE, glm::value_ptr(glm::inverse(lightView))); glUniformMatrix4fv( glGetUniformLocation(shaderProgramIrradiance, "projection"), 1, GL_FALSE, glm::value_ptr(proj)); + glUniformMatrix4fv( + glGetUniformLocation(shaderProgramIrradiance, "lightProjection"), + 1, GL_FALSE, glm::value_ptr(lightProj)); + glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "screenWidth"), window.getSize().x); + glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "screenHeight"), window.getSize().y); + glUniform1fv(glGetUniformLocation(shaderProgramIrradiance, "samplePositions"), 13, samplePositions); + glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "sampleWeights"), 13, sampleWeights); + + glUniform1f( + glGetUniformLocation(shaderProgramIrradiance, "transmittanceScale"), + options.transmittanceScale); + glUniform1i( + glGetUniformLocation(shaderProgramIrradiance, "renderState"), + options.renderState); + glUniform1f( + glGetUniformLocation(shaderProgramIrradiance, "powBase"), + options.powBase); + glUniform1f( + glGetUniformLocation(shaderProgramIrradiance, "powFactor"), + options.powFactor); glUniform3fv( glGetUniformLocation(shaderProgramIrradiance, "objectColor"), @@ -543,18 +571,19 @@ int main() { 1.0f, 1.0f, 1.0f); glUniform3fv( glGetUniformLocation(shaderProgramIrradiance, "lightPos"), - 1, glm::value_ptr(lightPos)); + 1, glm::value_ptr(options.lightPos)); glUniform3fv( glGetUniformLocation(shaderProgramIrradiance, "viewPos"), 1, glm::value_ptr(options.freecam ? freeCam.pos : arcCam.getPos())); + glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "shadowmapTexture"), 0); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, fb_shadowmap.renderTexture); m.draw(); - // Render fbo to screen + // Render fbos to screen and calculate light spread/translucency in shader glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -580,19 +609,24 @@ int main() { glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); + // menu + ImGui::SFML::Update(window, deltaClock.restart()); ImGui::Begin("Options"); ImGui::Checkbox("Wireframe", &options.wireframe); ImGui::Checkbox("Free Cam", &options.freecam); ImGui::InputInt("Render State", &options.renderState); - ImGui::InputFloat3("Color", options.color, 2); + ImGui::DragFloat3("Color", options.color, 0.01, 0, 1); + ImGui::DragFloat("Transmittance Scale", &options.transmittanceScale, 0.0001f, 0, 0.3); + ImGui::DragFloat3("Light Pos", glm::value_ptr(options.lightPos), 0.01, -5, 5); if (options.freecam) { ImGui::LabelText("Position", "%f %f %f", freeCam.pos.x, freeCam.pos.y, freeCam.pos.z); ImGui::LabelText("Rotation", "%f %f", freeCam.rot.x, freeCam.rot.y); if (ImGui::Button("Reset")) { freeCam.pos = glm::vec3(0, 0, -1); freeCam.rot = glm::vec2(0); + options = DefaultOptions; } } else { ImGui::LabelText("Rotation", "%f %f", arcCam.rot.x, arcCam.rot.y); @@ -600,6 +634,7 @@ int main() { if (ImGui::Button("Reset")) { arcCam.rot = glm::vec2(0); arcCam.radius = 1; + options = DefaultOptions; } } ImGui::End(); @@ -610,4 +645,4 @@ int main() { } return 0; -} \ No newline at end of file +}