uniform vec2 samplePositions[13];\r
uniform vec3 sampleWeights[13];\r
\r
-vec4 blur(sampler2D tex, vec2 uv, vec2 res) {\r
- float Pi = 6.28318530718; // Pi*2\r
- \r
- // GAUSSIAN BLUR SETTINGS {{{\r
- float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)\r
- float Quality = 4.0; // BLUR QUALITY (Default 4.0 - More is better but slower)\r
- float Size = 8.0; // BLUR SIZE (Radius)\r
- // GAUSSIAN BLUR SETTINGS }}}\r
- \r
- vec2 Radius = Size/res;\r
- \r
- // Pixel colour\r
- vec4 Color = texture(tex, uv);\r
- \r
- // Blur calculations\r
- for( float d=0.0; d<Pi; d+=Pi/Directions) {\r
- for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality) {\r
- Color += texture( tex, uv+vec2(cos(d),sin(d))*Radius*i); \r
- }\r
- }\r
- \r
- // Output to screen\r
- Color /= Quality * Directions - 15.0;\r
- return Color;\r
-}\r
-\r
void main()\r
{\r
if (renderState == 0) {\r
- FragColor = blur(shadowmapTexture, TexCoords, vec2(screenWidth, screenHeight));\r
- }\r
- else if (renderState == 1) {\r
FragColor = texture(shadowmapTexture, TexCoords);\r
}\r
- // stencil buffer\r
- else if (renderState == 2) {\r
+ else if (renderState == 1) {\r
FragColor = texture(irradianceTexture, TexCoords);\r
}\r
- else if (renderState == 3) {\r
+ else if (renderState == 2) {\r
+ // sample calculated irradiance\r
+ // using Gaussian kernel to approximate light spread\r
vec4 result = vec4(0, 0, 0, 1);\r
for (int i = 0; i < 13; i++) {\r
vec2 sampleCoords = TexCoords + samplePositions[i] * vec2(1.0/screenWidth, 1.0/screenHeight);\r
\r
void main()\r
{\r
+ // this is just a plane that covers the screen\r
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); \r
TexCoords = aTexCoords;\r
}\r
uniform float powBase;\r
uniform float powFactor;\r
\r
-uniform float translucencySampleVariances[6];\r
-uniform vec3 translucencySampleWeights[6];\r
-\r
void main()\r
{\r
+ // phong lighting\r
vec3 norm = normalize(Normal);\r
vec3 lightDir = normalize(lightPos - FragPos);\r
\r
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);\r
vec3 specular = specularStrength * spec * lightColor;\r
\r
- //float distanceToBackside = length(clamp(FragPos - Backside, vec3(0), vec3(1000)));\r
- float distanceToBackside = length(FragPos - Backside);\r
- //distanceToBackside = distance(Backside, LocalPos);\r
vec3 result = (ambient + diffuse + specular) * objectColor;\r
\r
- if (renderState == 3) {\r
+ // thickness\r
+ float distanceToBackside = length(FragPos - Backside);\r
+\r
+ if (renderState == 2) {\r
if (distanceToBackside != 0) {\r
+ // add translucency by amplifying color inverse to the thickness\r
+ // (1 - diff) is part of the irradiance term,\r
+ // if the light hits the object straight at 90°\r
+ // most light is received\r
result += objectColor * pow(powBase, powFactor / pow(distanceToBackside, 0.6)) * transmittanceScale * (1 - diff);\r
- // vec3 translucency = vec3(0);\r
- // for (int i = 0; i < 6; i++) {\r
- // translucency += objectColor * translucencySampleWeights[i] * exp(-pow(distanceToBackside, 2.0) / translucencySampleVariances[i]);\r
- // }\r
-\r
- // result += translucency * transmittanceScale;\r
}\r
}\r
- //result += objectColor * pow(powBase, -pow(distanceToBackside, 2)) * transmittanceScale * (1 - diff);\r
- // if (renderState == 3) {\r
- // //result = Backside;\r
- // //result = LocalPos;\r
- // result = vec3(distanceToBackside);\r
- // }\r
-\r
\r
FragColor = vec4(result, 1.0f);\r
- //FragColor = vec4(vec3(distanceToBackside), 1);\r
}\r
\r
void main()\r
{\r
+ // calculate distance in world coordinates\r
float lightDist = length(lightPos - FragPos);\r
float c1 = lightDist;\r
float c2 = lightDist;\r
float c3 = lightDist;\r
FragColor = vec4(c1, c2, c3, 1);\r
- //FragColor = vec4(LocalPos/10, 1);\r
}\r
uniform mat4 projection;\r
uniform mat4 lightProjection;\r
\r
-vec4 blur(sampler2D tex, vec2 uv, vec2 res) {\r
- float Pi = 6.28318530718; // Pi*2\r
- \r
- // GAUSSIAN BLUR SETTINGS {{{\r
- float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)\r
- float Quality = 4.0; // BLUR QUALITY (Default 4.0 - More is better but slower)\r
- float Size = 8.0; // BLUR SIZE (Radius)\r
- // GAUSSIAN BLUR SETTINGS }}}\r
- \r
- vec2 Radius = Size/res;\r
- \r
- // Pixel colour\r
- vec4 Color = texture(tex, uv);\r
- \r
- // Blur calculations\r
- for( float d=0.0; d<Pi; d+=Pi/Directions) {\r
- for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality) {\r
- Color += texture( tex, uv+vec2(cos(d),sin(d))*Radius*i); \r
- }\r
- }\r
- \r
- // Output to screen\r
- Color /= Quality * Directions - 15.0;\r
- return Color;\r
-}\r
-\r
void main()\r
{\r
gl_Position = projection * view * model * vec4(pos, 1.0);\r
+ // calculate fragment position in world coordinates\r
FragPos = vec3(model * vec4(pos, 1));\r
+ // and local coordinates\r
LocalPos = pos;\r
+\r
Normal = normal;\r
\r
+ // get fragment position in the light's projection space\r
vec4 lightSpace = lightProjection * lightView * model * vec4(pos, 1.0);\r
+ // and transform them to 2D coordinates\r
+ // (this is usually done by OpenGL after applying the vertex shader,\r
+ // so to get them here, we have to divide by w manually)\r
lightSpace = lightSpace / lightSpace.w;\r
vec2 shadowmapCoords = lightSpace.xy;\r
+ // map coordinates from [0 1] to [-1 +1]\r
+ // multiply by 0.99 first to shift coordinates towards the center slightly\r
+ // to prevent artifacts at the edges\r
shadowmapCoords = vec2(\r
(shadowmapCoords.x * 0.99 + 1) / 2,\r
(shadowmapCoords.y * 0.99 + 1) / 2\r
);\r
\r
-\r
- // blur\r
+ // sample shadowmap (brightness encodes distance of fragment to light)\r
vec4 t = texture(shadowmapTexture, shadowmapCoords);\r
- //vec4 t = blur(shadowmapTexture, shadowmapCoords, vec2(screenWidth, screenHeight));\r
\r
- BacksideIrradiance = t.r; //*100 + t.g + t.b/100;\r
+ BacksideIrradiance = t.r;\r
\r
+ // calculate backside with distance(BacksideIrradiance) and lightDir\r
vec3 lightDir = normalize(FragPos - lightPos);\r
Backside = (lightPos + (lightDir * BacksideIrradiance));\r
- //Backside = texture(shadowmapTexture, shadowmapCoords).xyz*10;\r
}\r
void main()\r
{\r
gl_Position = projection * lightView * model * vec4(pos, 1.0);\r
+ // pass fragment position in world coordinates\r
FragPos = vec3(model * vec4(pos, 1));\r
LocalPos = pos;\r
Normal = normal;\r
0.073580f, 0.023239f, 0.009703f\r
};\r
\r
-float translucencySampleVariances[] = {\r
- 0.0064,\r
- 0.0484,\r
- 0.187,\r
- 0.567,\r
- 1.99,\r
- 7.41,\r
-};\r
-\r
-float translucencySampleWeights[] = {\r
- 0.233, 0.455, 0.649,\r
- 0.100, 0.336, 0.344,\r
- 0.118, 0.198, 0,\r
- 0.113, 0.007, 0.007,\r
- 0.358, 0.004, 0,\r
- 0.078, 0, 0,\r
-};\r
-\r
struct model {\r
std::vector<float> vertices;\r
std::vector<GLuint> indices;\r
for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) {\r
aiVector3D v = scene->mMeshes[0]->mVertices[i];\r
aiVector3D n = scene->mMeshes[0]->mNormals[i];\r
- result.vertices.push_back(v.x*100);\r
- result.vertices.push_back(v.y*100);\r
- result.vertices.push_back(v.z*100);\r
+ result.vertices.push_back(v.x);\r
+ result.vertices.push_back(v.y);\r
+ result.vertices.push_back(v.z);\r
result.vertices.push_back(n.x);\r
result.vertices.push_back(n.y);\r
result.vertices.push_back(n.z);\r
GLuint shaderProgramShadowmap = compileShaders("shaders/vert_shadowmap.glsl", "shaders/frag_shadowmap.glsl");\r
GLuint shaderProgramIrradiance = compileShaders("shaders/vert_irradiance.glsl", "shaders/frag_irradiance.glsl");\r
\r
- //model m = loadModel("models/Isotrop-upperjaw.ply");\r
- model m = loadModel("models/african_head/african_head.obj");\r
-\r
+ model m = loadModel("models/Isotrop-upperjaw.ply");\r
+ \r
arccam arcCam;\r
freecam freeCam;\r
\r
glm::mat4 lightProj = glm::perspective(glm::radians(90.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);\r
\r
// Framebuffer\r
+\r
framebuffer fb_shadowmap("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);\r
framebuffer fb_irradiance("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);\r
\r
int renderState = 2;\r
float color[3] = { 0.7f, 0.4f, 0.4f };\r
glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.03f);\r
- float transmittanceScale = 0.005f;\r
- float powBase = 2.718;\r
- float powFactor = 1;\r
+ float transmittanceScale = 0.025f;\r
+ float powBase = 2;\r
+ float powFactor = 1.5;\r
} DefaultOptions;\r
\r
auto options = DefaultOptions;\r
}\r
}\r
\r
- // Update\r
+ // Update Camera\r
\r
if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) {\r
window.setMouseCursorVisible(false);\r
\r
prevMouse = sf::Mouse::isButtonPressed(sf::Mouse::Right);\r
\r
- // Render Shadowmap\r
+ // Render Shadowmap to fbo\r
\r
glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE);\r
glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);\r
\r
m.draw();\r
\r
- // Render irradiance\r
+ // Render irradiance map to fbo\r
\r
glBindFramebuffer(GL_FRAMEBUFFER, fb_irradiance.fbo);\r
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);\r
glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "screenHeight"), window.getSize().y);\r
glUniform1fv(glGetUniformLocation(shaderProgramIrradiance, "samplePositions"), 13, samplePositions);\r
glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "sampleWeights"), 13, sampleWeights);\r
- glUniform2fv(glGetUniformLocation(shaderProgramIrradiance, "translucencySampleVariances"), 6, translucencySampleVariances);\r
- glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "translucencySampleWeights"), 6, translucencySampleWeights);\r
\r
glUniform1f(\r
glGetUniformLocation(shaderProgramIrradiance, "transmittanceScale"),\r
\r
m.draw();\r
\r
- // Render fbo to screen\r
+ // Render fbos to screen and calculate light spread/translucency in shader\r
\r
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\r
\r
glDrawArrays(GL_TRIANGLES, 0, 6);\r
glBindVertexArray(0);\r
\r
+ // menu\r
+\r
ImGui::SFML::Update(window, deltaClock.restart());\r
\r
ImGui::Begin("Options");\r
ImGui::InputInt("Render State", &options.renderState);\r
ImGui::DragFloat3("Color", options.color, 0.01, 0, 1);\r
ImGui::DragFloat("Transmittance Scale", &options.transmittanceScale, 0.0001f, 0, 0.3);\r
- ImGui::DragFloat("Pow Base", &options.powBase, 0.01f, 0, 4);\r
- ImGui::DragFloat("Pow Factor", &options.powFactor, 0.01f, 0, 3);\r
ImGui::DragFloat3("Light Pos", glm::value_ptr(options.lightPos), 0.01, -5, 5);\r
if (options.freecam) {\r
ImGui::LabelText("Position", "%f %f %f", freeCam.pos.x, freeCam.pos.y, freeCam.pos.z);\r
#include <assimp/postprocess.h>\r
#include <assimp/scene.h>\r
\r
-/*\r
-\r
-TODO:\r
-- Save Depth to fbo\r
-- Stencil Buffer\r
-- LightDist > 1\r
- - 1 - distanceToBackside in frag_irradiance\r
-- ShadowMap Perspective (no projection?)\r
-- (Implement Gaussian Blur)\r
-- LightDir nicht immer zu 0 0 0\r
-\r
-*/\r
-\r
float samplePositions[] = {\r
0.000000f, 0.000000f,\r
1.633992f, 0.036795f,\r