treesummaryrefslogcommitdiff
diff options
context:
space:
mode:
authorPatrick2021-03-26 19:36:35 +0100
committerPatrick2021-03-26 19:36:35 +0100
commitc99ecda7bed596922125f6b1ef1ef2ae8f27703e (patch)
tree16b3a22483457d22fdd34c1e079fd25dabd84940
parent36fb27a899045de24d71d55b06648abda7547268 (diff)
downloadsubsurface_scattering-c99ecda7bed596922125f6b1ef1ef2ae8f27703e.tar.gz
subsurface_scattering-c99ecda7bed596922125f6b1ef1ef2ae8f27703e.zip
SSSSS comments
-rw-r--r--shaders/fbo_frag.glsl36
-rw-r--r--shaders/fbo_vert.glsl1
-rw-r--r--shaders/frag_irradiance.glsl30
-rw-r--r--shaders/frag_shadowmap.glsl2
-rw-r--r--shaders/vert_irradiance.glsl44
-rw-r--r--shaders/vert_shadowmap.glsl1
-rw-r--r--src/main.cpp50
-rw-r--r--src/main2.cpp13
8 files changed, 44 insertions, 133 deletions
diff --git a/shaders/fbo_frag.glsl b/shaders/fbo_frag.glsl
index 1102992..f92483e 100644
--- a/shaders/fbo_frag.glsl
+++ b/shaders/fbo_frag.glsl
@@ -11,45 +11,17 @@ uniform int renderState;
uniform vec2 samplePositions[13];
uniform vec3 sampleWeights[13];
-vec4 blur(sampler2D tex, vec2 uv, vec2 res) {
- float Pi = 6.28318530718; // Pi*2
-
- // GAUSSIAN BLUR SETTINGS {{{
- float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)
- float Quality = 4.0; // BLUR QUALITY (Default 4.0 - More is better but slower)
- float Size = 8.0; // BLUR SIZE (Radius)
- // GAUSSIAN BLUR SETTINGS }}}
-
- vec2 Radius = Size/res;
-
- // Pixel colour
- vec4 Color = texture(tex, uv);
-
- // Blur calculations
- for( float d=0.0; d<Pi; d+=Pi/Directions) {
- for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality) {
- Color += texture( tex, uv+vec2(cos(d),sin(d))*Radius*i);
- }
- }
-
- // Output to screen
- Color /= Quality * Directions - 15.0;
- return Color;
-}
-
void main()
{
if (renderState == 0) {
- FragColor = blur(shadowmapTexture, TexCoords, vec2(screenWidth, screenHeight));
- }
- else if (renderState == 1) {
FragColor = texture(shadowmapTexture, TexCoords);
}
- // stencil buffer
- else if (renderState == 2) {
+ else if (renderState == 1) {
FragColor = texture(irradianceTexture, TexCoords);
}
- else if (renderState == 3) {
+ else if (renderState == 2) {
+ // sample calculated irradiance
+ // using Gaussian kernel to approximate light spread
vec4 result = vec4(0, 0, 0, 1);
for (int i = 0; i < 13; i++) {
vec2 sampleCoords = TexCoords + samplePositions[i] * vec2(1.0/screenWidth, 1.0/screenHeight);
diff --git a/shaders/fbo_vert.glsl b/shaders/fbo_vert.glsl
index fb80df5..0cf6138 100644
--- a/shaders/fbo_vert.glsl
+++ b/shaders/fbo_vert.glsl
@@ -6,6 +6,7 @@ out vec2 TexCoords;
void main()
{
+ // this is just a plane that covers the screen
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
TexCoords = aTexCoords;
}
diff --git a/shaders/frag_irradiance.glsl b/shaders/frag_irradiance.glsl
index 1bcbc99..b985acf 100644
--- a/shaders/frag_irradiance.glsl
+++ b/shaders/frag_irradiance.glsl
@@ -17,11 +17,9 @@ uniform int renderState;
uniform float powBase;
uniform float powFactor;
-uniform float translucencySampleVariances[6];
-uniform vec3 translucencySampleWeights[6];
-
void main()
{
+ // phong lighting
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
@@ -37,30 +35,20 @@ void main()
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
- //float distanceToBackside = length(clamp(FragPos - Backside, vec3(0), vec3(1000)));
- float distanceToBackside = length(FragPos - Backside);
- //distanceToBackside = distance(Backside, LocalPos);
vec3 result = (ambient + diffuse + specular) * objectColor;
- if (renderState == 3) {
+ // thickness
+ float distanceToBackside = length(FragPos - Backside);
+
+ if (renderState == 2) {
if (distanceToBackside != 0) {
+ // add translucency by amplifying color inverse to the thickness
+ // (1 - diff) is part of the irradiance term,
+ // if the light hits the object straight at 90°
+ // most light is received
result += objectColor * pow(powBase, powFactor / pow(distanceToBackside, 0.6)) * transmittanceScale * (1 - diff);
- // vec3 translucency = vec3(0);
- // for (int i = 0; i < 6; i++) {
- // translucency += objectColor * translucencySampleWeights[i] * exp(-pow(distanceToBackside, 2.0) / translucencySampleVariances[i]);
- // }
-
- // result += translucency * transmittanceScale;
}
}
- //result += objectColor * pow(powBase, -pow(distanceToBackside, 2)) * transmittanceScale * (1 - diff);
- // if (renderState == 3) {
- // //result = Backside;
- // //result = LocalPos;
- // result = vec3(distanceToBackside);
- // }
-
FragColor = vec4(result, 1.0f);
- //FragColor = vec4(vec3(distanceToBackside), 1);
}
diff --git a/shaders/frag_shadowmap.glsl b/shaders/frag_shadowmap.glsl
index 2011f82..38a01b6 100644
--- a/shaders/frag_shadowmap.glsl
+++ b/shaders/frag_shadowmap.glsl
@@ -10,10 +10,10 @@ uniform vec3 lightPos;
void main()
{
+ // calculate distance in world coordinates
float lightDist = length(lightPos - FragPos);
float c1 = lightDist;
float c2 = lightDist;
float c3 = lightDist;
FragColor = vec4(c1, c2, c3, 1);
- //FragColor = vec4(LocalPos/10, 1);
}
diff --git a/shaders/vert_irradiance.glsl b/shaders/vert_irradiance.glsl
index 6b54180..89ba12e 100644
--- a/shaders/vert_irradiance.glsl
+++ b/shaders/vert_irradiance.glsl
@@ -23,55 +23,37 @@ uniform mat4 lightViewInv;
uniform mat4 projection;
uniform mat4 lightProjection;
-vec4 blur(sampler2D tex, vec2 uv, vec2 res) {
- float Pi = 6.28318530718; // Pi*2
-
- // GAUSSIAN BLUR SETTINGS {{{
- float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)
- float Quality = 4.0; // BLUR QUALITY (Default 4.0 - More is better but slower)
- float Size = 8.0; // BLUR SIZE (Radius)
- // GAUSSIAN BLUR SETTINGS }}}
-
- vec2 Radius = Size/res;
-
- // Pixel colour
- vec4 Color = texture(tex, uv);
-
- // Blur calculations
- for( float d=0.0; d<Pi; d+=Pi/Directions) {
- for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality) {
- Color += texture( tex, uv+vec2(cos(d),sin(d))*Radius*i);
- }
- }
-
- // Output to screen
- Color /= Quality * Directions - 15.0;
- return Color;
-}
-
void main()
{
gl_Position = projection * view * model * vec4(pos, 1.0);
+ // calculate fragment position in world coordinates
FragPos = vec3(model * vec4(pos, 1));
+ // and local coordinates
LocalPos = pos;
+
Normal = normal;
+ // get fragment position in the light's projection space
vec4 lightSpace = lightProjection * lightView * model * vec4(pos, 1.0);
+ // and transform them to 2D coordinates
+ // (this is usually done by OpenGL after applying the vertex shader,
+ // so to get them here, we have to divide by w manually)
lightSpace = lightSpace / lightSpace.w;
vec2 shadowmapCoords = lightSpace.xy;
+ // map coordinates from [0 1] to [-1 +1]
+ // multiply by 0.99 first to shift coordinates towards the center slightly
+ // to prevent artifacts at the edges
shadowmapCoords = vec2(
(shadowmapCoords.x * 0.99 + 1) / 2,
(shadowmapCoords.y * 0.99 + 1) / 2
);
-
- // blur
+ // sample shadowmap (brightness encodes distance of fragment to light)
vec4 t = texture(shadowmapTexture, shadowmapCoords);
- //vec4 t = blur(shadowmapTexture, shadowmapCoords, vec2(screenWidth, screenHeight));
- BacksideIrradiance = t.r; //*100 + t.g + t.b/100;
+ BacksideIrradiance = t.r;
+ // calculate backside with distance(BacksideIrradiance) and lightDir
vec3 lightDir = normalize(FragPos - lightPos);
Backside = (lightPos + (lightDir * BacksideIrradiance));
- //Backside = texture(shadowmapTexture, shadowmapCoords).xyz*10;
}
diff --git a/shaders/vert_shadowmap.glsl b/shaders/vert_shadowmap.glsl
index 50847bb..a6c9398 100644
--- a/shaders/vert_shadowmap.glsl
+++ b/shaders/vert_shadowmap.glsl
@@ -14,6 +14,7 @@ uniform mat4 projection;
void main()
{
gl_Position = projection * lightView * model * vec4(pos, 1.0);
+ // pass fragment position in world coordinates
FragPos = vec3(model * vec4(pos, 1));
LocalPos = pos;
Normal = normal;
diff --git a/src/main.cpp b/src/main.cpp
index b836ccb..8b48e70 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -65,24 +65,6 @@ float sampleWeights[] = {
0.073580f, 0.023239f, 0.009703f
};
-float translucencySampleVariances[] = {
- 0.0064,
- 0.0484,
- 0.187,
- 0.567,
- 1.99,
- 7.41,
-};
-
-float translucencySampleWeights[] = {
- 0.233, 0.455, 0.649,
- 0.100, 0.336, 0.344,
- 0.118, 0.198, 0,
- 0.113, 0.007, 0.007,
- 0.358, 0.004, 0,
- 0.078, 0, 0,
-};
-
struct model {
std::vector<float> vertices;
std::vector<GLuint> indices;
@@ -252,9 +234,9 @@ model loadModel(const std::string &filename) {
for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) {
aiVector3D v = scene->mMeshes[0]->mVertices[i];
aiVector3D n = scene->mMeshes[0]->mNormals[i];
- result.vertices.push_back(v.x*100);
- result.vertices.push_back(v.y*100);
- result.vertices.push_back(v.z*100);
+ result.vertices.push_back(v.x);
+ result.vertices.push_back(v.y);
+ result.vertices.push_back(v.z);
result.vertices.push_back(n.x);
result.vertices.push_back(n.y);
result.vertices.push_back(n.z);
@@ -412,9 +394,8 @@ int main() {
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");
- model m = loadModel("models/african_head/african_head.obj");
-
+ model m = loadModel("models/Isotrop-upperjaw.ply");
+
arccam arcCam;
freecam freeCam;
@@ -428,6 +409,7 @@ int main() {
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);
@@ -439,9 +421,9 @@ int main() {
int renderState = 2;
float color[3] = { 0.7f, 0.4f, 0.4f };
glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.03f);
- float transmittanceScale = 0.005f;
- float powBase = 2.718;
- float powFactor = 1;
+ float transmittanceScale = 0.025f;
+ float powBase = 2;
+ float powFactor = 1.5;
} DefaultOptions;
auto options = DefaultOptions;
@@ -476,7 +458,7 @@ int main() {
}
}
- // Update
+ // Update Camera
if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) {
window.setMouseCursorVisible(false);
@@ -499,7 +481,7 @@ 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);
@@ -540,7 +522,7 @@ int main() {
m.draw();
- // Render irradiance
+ // Render irradiance map to fbo
glBindFramebuffer(GL_FRAMEBUFFER, fb_irradiance.fbo);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
@@ -576,8 +558,6 @@ int main() {
glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "screenHeight"), window.getSize().y);
glUniform1fv(glGetUniformLocation(shaderProgramIrradiance, "samplePositions"), 13, samplePositions);
glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "sampleWeights"), 13, sampleWeights);
- glUniform2fv(glGetUniformLocation(shaderProgramIrradiance, "translucencySampleVariances"), 6, translucencySampleVariances);
- glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "translucencySampleWeights"), 6, translucencySampleWeights);
glUniform1f(
glGetUniformLocation(shaderProgramIrradiance, "transmittanceScale"),
@@ -612,7 +592,7 @@ int main() {
m.draw();
- // Render fbo to screen
+ // Render fbos to screen and calculate light spread/translucency in shader
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -638,6 +618,8 @@ int main() {
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
+ // menu
+
ImGui::SFML::Update(window, deltaClock.restart());
ImGui::Begin("Options");
@@ -646,8 +628,6 @@ int main() {
ImGui::InputInt("Render State", &options.renderState);
ImGui::DragFloat3("Color", options.color, 0.01, 0, 1);
ImGui::DragFloat("Transmittance Scale", &options.transmittanceScale, 0.0001f, 0, 0.3);
- ImGui::DragFloat("Pow Base", &options.powBase, 0.01f, 0, 4);
- ImGui::DragFloat("Pow Factor", &options.powFactor, 0.01f, 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);
diff --git a/src/main2.cpp b/src/main2.cpp
index 38ca5f2..206466d 100644
--- a/src/main2.cpp
+++ b/src/main2.cpp
@@ -20,19 +20,6 @@
#include <assimp/postprocess.h>
#include <assimp/scene.h>
-/*
-
-TODO:
-- Save Depth to fbo
-- Stencil Buffer
-- LightDist > 1
- - 1 - distanceToBackside in frag_irradiance
-- ShadowMap Perspective (no projection?)
-- (Implement Gaussian Blur)
-- LightDir nicht immer zu 0 0 0
-
-*/
-
float samplePositions[] = {
0.000000f, 0.000000f,
1.633992f, 0.036795f,