Commit 9bbb31e2 authored by Dario Seyb's avatar Dario Seyb

switched to proper PBS

parent 77a29210
# Blender MTL File: 'cockpit.blend'
# Blender MTL File: 'cockpit_applied.blend'
# Material Count: 1
newmtl Material
......
This diff is collapsed.
......@@ -2,40 +2,20 @@
uniform sampler2D uSamplerColor;
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;
in vec2 vTexCoord;
out vec4 oColor;
vec3 Uncharted2Tonemap(vec3 x)
{
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main()
{
vec3 texColor = texture(uSamplerColor, vTexCoord).rgb;
texColor *= 16; // Hardcoded Exposure Adjustment
float ExposureBias = 2.0f;
vec3 curr = Uncharted2Tonemap(ExposureBias*texColor);
vec3 whiteScale = vec3(1.0f)/Uncharted2Tonemap(vec3(W));
vec3 color = texture(uSamplerColor, vTexCoord).rgb; //curr*whiteScale;
vec3 color = texture(uSamplerColor, vTexCoord).rgb;
vec3 retColor = pow(color, vec3(1.0/2.2));
retColor += vec3(rand(gl_FragCoord.xy) * 1.0/255 - 0.5/255);
oColor = vec4( retColor, 1);
vec3 retColor = pow(color, vec3(1.0/2.2));
retColor += vec3(rand(gl_FragCoord.xy) * 1.0/255 - 0.5/255);
oColor = vec4( retColor, 1);
}
......@@ -9,6 +9,9 @@ uniform sampler2D uTexture;
uniform bool uHasNormalMap;
uniform sampler2D uNormalMap;
uniform bool uHasSpecularSmoothnessMap;
uniform sampler2D uSpecularSmoothnessMap;
uniform vec4 uEmissiveColor;
uniform vec4 uTintColor;
uniform float uTime;
......@@ -23,6 +26,7 @@ out vec4 oColor;
out vec4 oEmissive;
out vec3 oNormal;
out vec3 oMotion;
out vec4 oSpecularSmoothness;
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
......@@ -46,9 +50,15 @@ void main()
vec3 prevFragCoord = prevPosition.xyz/prevPosition.w;
vec3 thisFragCoord = thisPosition.xyz/thisPosition.w;
vec4 specularSmoothness = vec4(0.5);
if(uHasSpecularSmoothnessMap) {
specularSmoothness = texture(uSpecularSmoothnessMap, teTexCoord);
}
oMotion = (thisFragCoord-prevFragCoord)*0.5;
oMotion.z = thisPosition.z;
oColor = color;
oEmissive = emissive();
oSpecularSmoothness = specularSmoothness;
oNormal = normalize(normal());
}
......@@ -5,6 +5,7 @@ uniform sampler2D uSamplerEmissive;
uniform sampler2D uSamplerNormal;
uniform sampler2D uSamplerMotion;
uniform sampler2D uSamplerDepth;
uniform sampler2D uSamplerSpecularSmoothness;
uniform sampler2DShadow uSamplerShadowMap;
......@@ -26,6 +27,7 @@ in vec2 vTexCoord;
out vec4 oColor;
#pragma import "Utils.glsl"
#pragma import "Lighting.glsl"
float linearizeDepth(float depth) {
return (2.0 * uNear) / (uFar + uNear - depth * (uFar - uNear)); // convert to linear values
......@@ -69,7 +71,8 @@ float shadowFactor(vec3 worldPosition) {
void main()
{
vec4 color = texture(uSamplerColor, vTexCoord);
vec4 albedo = texture(uSamplerColor, vTexCoord);
vec4 specularSmoothness = texture(uSamplerSpecularSmoothness, vTexCoord);
vec4 emissive = texture(uSamplerEmissive, vTexCoord);
vec3 normal = texture(uSamplerNormal, vTexCoord).rgb;
......@@ -79,31 +82,23 @@ void main()
vec3 worldPosition = unpackWorldPosition(depth);
vec3 lightDir = vec3(0);
float lightDistance = 1;
vec3 lightDir = vec3(0);
float lightDistance = 1;
if(uLightIsDirectional) {
lightDir = uLightDir;
} else {
lightDir = uLightPosition - worldPosition;
lightDistance = length(lightDir);
lightDir /= lightDistance;
}
float diffuseFactor = dot(lightDir, normal);
if(diffuseFactor < 0) diffuseFactor = 0;
vec3 diffuseColor = diffuseFactor * uLightColor.rgb * color.rgb;
if(uLightIsDirectional) {
lightDir = uLightDir;
} else {
lightDir = uLightPosition - worldPosition;
lightDistance = length(lightDir);
lightDir /= lightDistance;
}
vec3 viewDir = normalize(cameraPosition - worldPosition);
float specularFactor = dot( reflect(lightDir, -normal), -viewDir);
if(specularFactor < 0) specularFactor = 0;
vec3 specularColor = pow(specularFactor, 210) * uLightColor.rgb;
float attenuation = 1.0/(lightDistance * lightDistance);
float oneMinusReflectivity;
albedo.rgb = EnergyConservationBetweenDiffuseAndSpecular (albedo.rgb, specularSmoothness.rgb, /*out*/ oneMinusReflectivity);
oColor = vec4((diffuseColor + specularColor) * color.rgb * uLightColor.a * shadowFactor(worldPosition) * attenuation + emissive.rgb, 1);
float lightNdotL = max(0, dot(lightDir, normal));
vec4 lighting = BRDF (albedo.rgb, specularSmoothness.rgb, oneMinusReflectivity, specularSmoothness.a, normal, viewDir, lightDir, lightNdotL, uLightColor.rgb * uLightColor.a);
oColor = vec4(lighting.rgb + emissive.rgb, 1);
}
float DotClamped (vec3 a, vec3 b)
{
return max(0.0, dot(a, b));
}
float BlinnTerm (vec3 normal, vec3 halfDir)
{
return DotClamped (normal, halfDir);
}
float Pow5(float v) {
return v * v * v * v * v;
}
vec3 FresnelTerm (vec3 F0, float cosA)
{
float t = Pow5(1.0 - cosA); // ala Schlick interpoliation
return F0 + (1-F0) * t;
}
vec3 FresnelLerp (vec3 F0, vec3 F90, float cosA)
{
float t = Pow5(1 - cosA); // ala Schlick interpoliation
return mix (F0, F90, t);
}
float SmithJointGGXVisibilityTerm (float NdotL, float NdotV, float roughness)
{
// This is an approximation
float a = roughness * roughness;
float gV = NdotL * (NdotV * (1 - a) + a);
float gL = NdotV * (NdotL * (1 - a) + a);
return (2.0 * NdotL) / (gV + gL + 1e-5); // This function is not intended to be running on Mobile,
// therefore epsilon is smaller than can be represented by float
}
float GGXTerm (float NdotH, float roughness)
{
float a = roughness * roughness;
float a2 = a * a;
float d = NdotH * NdotH * (a2 - 1) + 1;
return a2 / (3.141592 * d * d);
}
vec3 SafeNormalize(vec3 inVec)
{
float dp3 = max(0.001f, dot(inVec, inVec));
return inVec / sqrt(dp3);
}
vec4 BRDF(vec3 diffColor, vec3 specColor, float oneMinusReflectivity, float oneMinusRoughness,
vec3 normal, vec3 viewDir, vec3 lightDir, float lightNdotL, vec3 lightColor)
{
float roughness = 1.0-oneMinusRoughness;
vec3 halfDir = SafeNormalize(lightDir + viewDir);
float nl = lightNdotL;
float nh = BlinnTerm (normal, halfDir);
float nv = DotClamped (normal, viewDir);
float lv = DotClamped (lightDir, viewDir);
float lh = DotClamped (lightDir, halfDir);
float V = SmithJointGGXVisibilityTerm (nl, nv, roughness);
float D = GGXTerm (nh, roughness);
float nlPow5 = Pow5(1-nl);
float nvPow5 = Pow5(1-nv);
float Fd90 = 0.5 + 2 * lh * lh * roughness;
float disneyDiffuse = (1 + (Fd90-1) * nlPow5) * (1 + (Fd90-1) * nvPow5);
float specularTerm = (V * D) * (3.141592/4); // Torrance-Sparrow model, Fresnel is applied later (for optimization reasons)
specularTerm = max(0, specularTerm * nl);
float diffuseTerm = disneyDiffuse * nl;
float grazingTerm = clamp(oneMinusRoughness + (1-oneMinusReflectivity), 0, 1);
vec3 color = diffColor * (lightColor * diffuseTerm)
+ specularTerm * lightColor * FresnelTerm (specColor, lh) * FresnelLerp (specColor, vec3(grazingTerm), nv);
return vec4(color, 1);
}
float SpecularStrength(vec3 specular)
{
return max (max (specular.r, specular.g), specular.b);
}
// Diffuse/Spec Energy conservation
vec3 EnergyConservationBetweenDiffuseAndSpecular (vec3 albedo, vec3 specColor, out float oneMinusReflectivity)
{
oneMinusReflectivity = 1 - SpecularStrength(specColor);
return albedo * (vec3(1,1,1) - specColor);
}
\ No newline at end of file
......@@ -12,7 +12,20 @@ vec4 emissive() {
vec3 normal() {
if(uHasNormalMap) {
vec3 tangentNormal = unpackNormal(texture(uNormalMap, teTexCoord));
return tangentNormal;
vec3 Q1 = dFdx(tePosition);
vec3 Q2 = dFdy(tePosition);
vec2 st1 = dFdx(teTexCoord);
vec2 st2 = dFdy(teTexCoord);
vec3 T = normalize(Q1*st2.t - Q2*st1.t);
vec3 B = normalize(-Q1*st2.s + Q2*st1.s);
// the transpose of texture-to-eye space matrix
mat3 TBN = mat3(T, B, teNormal);
// transform the normal to eye space
return teNormal; //tangentNormal*TBN;
}
return teNormal;
}
......@@ -11,6 +11,7 @@ struct Material {
glm::vec4 emissiveColor;
SharedTexture2D mainTexture;
SharedTexture2D normalTexture;
SharedTexture2D SpecularSmoothnessTexture;
SharedShaderProgram prog;
bool castShadow;
RenderQueue queue;
......
......@@ -60,6 +60,7 @@ private:
SharedTexture2D m_normalBuffer;
SharedTexture2D m_motionBuffer;
SharedTexture2D m_depthBuffer;
SharedTexture2D m_specularBuffer;
ACGL::OpenGL::SharedFrameBufferObject m_gBufferObject;
......
......@@ -51,12 +51,14 @@ bool RendererSystem::startup() {
m_normalBuffer = createScreenspaceTexture(ScreenSpaceSize::FULL, GL_RGB32F);
m_motionBuffer = createScreenspaceTexture(ScreenSpaceSize::FULL, GL_RGB32F);
m_depthBuffer = createScreenspaceTexture(ScreenSpaceSize::FULL, GL_DEPTH24_STENCIL8);
m_specularBuffer = createScreenspaceTexture(ScreenSpaceSize::FULL, GL_RGBA32F);
m_gBufferObject = SharedFrameBufferObject(new FrameBufferObject());
m_gBufferObject->attachColorTexture("oColor", m_colorBuffer);
m_gBufferObject->attachColorTexture("oEmissive", m_emissiveBuffer);
m_gBufferObject->attachColorTexture("oNormal", m_normalBuffer);
m_gBufferObject->attachColorTexture("oMotion", m_motionBuffer);
m_gBufferObject->attachColorTexture("oSpecularSmoothness", m_specularBuffer);
m_gBufferObject->setDepthTexture(m_depthBuffer);
m_gBufferObject->validate(); // always a good idea
......@@ -177,6 +179,7 @@ bool RendererSystem::startup() {
ImGui::Image((void*)m_emissiveBuffer->getObjectName(), glm::vec2{ 1280, 720 } *0.2f, { 0, 1 }, { 1, 0 });
ImGui::Image((void*)m_normalBuffer->getObjectName(), glm::vec2{ 1280, 720 } *0.2f, { 0, 1 }, { 1, 0 });
ImGui::Image((void*)m_motionBuffer->getObjectName(), glm::vec2{ 1280, 720 } *0.2f, { 0, 1 }, { 1, 0 });
ImGui::Image((void*)m_specularBuffer->getObjectName(), glm::vec2{ 1280, 720 } *0.2f, { 0, 1 }, { 1, 0 });
ImGui::End();
/*ImGui::Begin("ShadowMap", 0, ImGuiWindowFlags_AlwaysAutoResize);
......@@ -332,6 +335,13 @@ void RendererSystem::render(RenderPass& pass, double interp, double totalTime) {
drawCall.material.prog->setUniform("uHasNormalMap", false);
}
if (drawCall.material.SpecularSmoothnessTexture) {
drawCall.material.prog->setTexture("uSpecularSmoothnessMap", drawCall.material.SpecularSmoothnessTexture, 2);
drawCall.material.prog->setUniform("uHasSpecularSmoothnessMap", true);
} else {
drawCall.material.prog->setUniform("uHasSpecularSmoothnessMap", false);
}
drawCall.material.prog->setUniform("uFar", cam->far);
drawCall.material.prog->setUniform("uTime", (float)totalTime);
drawCall.material.prog->setUniform("uTintColor", drawCall.material.tintColor);
......@@ -424,6 +434,7 @@ void RendererSystem::render(RenderPass& pass, double interp, double totalTime) {
m_deferredCombineProgram->setTexture("uSamplerNormal", m_normalBuffer, 2);
m_deferredCombineProgram->setTexture("uSamplerMotion", m_motionBuffer, 3);
m_deferredCombineProgram->setTexture("uSamplerDepth", m_depthBuffer, 4);
m_deferredCombineProgram->setTexture("uSamplerSpecularSmoothness", m_specularBuffer, 5);
m_deferredCombineProgram->setUniform("uNear", cam->near);
m_deferredCombineProgram->setUniform("uFar", cam->far);
......@@ -444,7 +455,7 @@ void RendererSystem::render(RenderPass& pass, double interp, double totalTime) {
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", m_dummyShadowMap, 5);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", m_dummyShadowMap, 6);
for (size_t i = 0; i < pass.submittedLights.size(); i++) {
auto light = pass.submittedLights[i];
......@@ -463,7 +474,7 @@ void RendererSystem::render(RenderPass& pass, double interp, double totalTime) {
m_deferredCombineProgram->setUniform("uLightProjMatrix",
biasMatrix * light.projMatrix);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", light.shadowMap,
5);
6);
auto size = light.shadowMap->getSize();
m_deferredCombineProgram->setUniform(
......
......@@ -59,16 +59,43 @@ bool OrbitalSimulationSystem::startup() {
.attributeLocations(m_renderer->m_transformFeedbackVAO->getAttributeLocations())
.fragmentDataLocations(m_renderer->getGBufferLocations()));
planetMat = { glm::vec4(1, 1, 1, 1), glm::vec4(0, 0, 0, 1), texture, nullptr, dispMappingShader, 1, RenderQueue::OPAQUE };
trajectoryMat = { glm::vec4(1, 1, 1, 1), glm::vec4(1, 0, 0, 1), texture, nullptr, testShader, 0, RenderQueue::OPAQUE };
atmosphereMat = { glm::vec4(0, 0, 1, 0.9f), glm::vec4(0, 0, .2, 1), texture, nullptr, atmosphereShader, 0, RenderQueue::TRANSPARENT };
waterMat = { glm::vec4(0, 0.2, 0.8, 1), glm::vec4(0, 0, .2, 1), texture, nullptr, waterShader, 0, RenderQueue::OPAQUE };
return true;
planetMat = {glm::vec4(1, 1, 1, 1),
glm::vec4(0, 0, 0, 1),
texture,
nullptr,
nullptr,
dispMappingShader,
1,
RenderQueue::OPAQUE};
trajectoryMat = {glm::vec4(1, 1, 1, 1),
glm::vec4(1, 0, 0, 1),
texture,
nullptr,
nullptr,
testShader,
0,
RenderQueue::OPAQUE};
atmosphereMat = {glm::vec4(0, 0, 1, 0.9f),
glm::vec4(0, 0, .2, 1),
texture,
nullptr,
nullptr,
atmosphereShader,
0,
RenderQueue::TRANSPARENT};
waterMat = {glm::vec4(0, 0.2, 0.8, 1),
glm::vec4(0, 0, .2, 1),
texture,
nullptr,
nullptr,
waterShader,
0,
RenderQueue::OPAQUE};
return true;
}
glm::dvec3 OrbitalSimulationSystem::applyKepler(Planet::Handle planet, float dt) {
......
......@@ -328,7 +328,6 @@ void PlayerSystem::update(float dt) {
cockpitCamTransform->rotation = glm::rotate(cockpitCamTransform->rotation, rotDir.y * 0.05, glm::dvec3(1, 0, 0));
// Rotate the camera based on the mouse movement
//up = rotate(camera->worldUp, glm::inverse(cameraTransform->rotation));
cameraTransform->rotation = glm::rotate(cameraTransform->rotation, rotDir.x * 0.05, up);
cameraTransform->rotation = glm::rotate(cameraTransform->rotation, rotDir.y * 0.05, glm::dvec3(1, 0, 0));
......
......@@ -52,7 +52,7 @@ bool AtmosphereTestScene::startup() {
geom1.vao->setMode(GL_PATCHES);
// Create a material that uses the loaded shader program
Material sunMaterial = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 2, 2, 1, 20 }, checkboardTexture, nullptr, sunShader, false, RenderQueue::OPAQUE };
Material sunMaterial = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 2, 2, 1, 20 }, checkboardTexture, nullptr, nullptr, sunShader, false, RenderQueue::OPAQUE };
// Let's create a placeholder sun
sun = m_sceneGraph->create();
......@@ -77,9 +77,10 @@ bool AtmosphereTestScene::startup() {
.fragmentDataLocations(m_renderer->getGBufferLocations()).create();
Material cockpitMaterial{ glm::vec4{0.4, 0.4, 0.4, 1}, glm::vec4{0, 0, 0, 1},
checkboardTexture,
Texture2DFileManager::the()->get(Texture2DCreator("cockpit/DefaultMaterial_Normal_OpenGL.png")),
cockpitShader,
Texture2DFileManager::the()->get(Texture2DCreator("cockpit/cockpit_DefaultMaterial_AlbedoTransparency.png")),
Texture2DFileManager::the()->get(Texture2DCreator("cockpit/cockpit_DefaultMaterial_Normal.png")),
Texture2DFileManager::the()->get(Texture2DCreator("cockpit/cockpit_DefaultMaterial_SpecularSmoothness.png")),
cockpitShader,
true,
RenderQueue::OPAQUE };
......@@ -94,13 +95,13 @@ bool AtmosphereTestScene::startup() {
auto cockpitLight = cockpit.assign<Light>(glm::vec4(1, 1, 1, 0.5), glm::vec3(1, 0, 0), false, LightType::POINT, 1);
auto blinkButton = m_sceneGraph->create();
blinkButton.assign<Light>(glm::vec4(1, 0.2, 0.2, 2), glm::vec3(1, 0, 0), false, LightType::POINT, 1);
blinkButton.assign<Light>(glm::vec4(1, 0.2, 0.2, 1), glm::vec3(1, 0, 0), false, LightType::POINT, 1);
auto transform = blinkButton.assign<Transform>();
transform->parent = cockpitTransform;
transform->position = { 0.7655, -0.4545 , -1.643 };
blinkButton = m_sceneGraph->create();
blinkButton.assign<Light>(glm::vec4(0, 0.2, 1.0, 2), glm::vec3(1, 0, 0), false, LightType::POINT, 1);
blinkButton.assign<Light>(glm::vec4(0, 0.2, 1.0, 1), glm::vec3(1, 0, 0), false, LightType::POINT, 1);
transform = blinkButton.assign<Transform>();
transform->parent = cockpitTransform;
transform->position = { -0.7655, -0.4545 , -1.643 };
......
......@@ -60,8 +60,8 @@ bool OrbitsScene::startup() {
Geometry geom2 = { vaoTeapot };
// Create a material that uses the loaded shader program
Material sunMaterial = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 2, 2, 1, 1 }, checkboardTexture, nullptr, pbrShader, false, RenderQueue::OPAQUE };
Material transparentMat = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 0, 0, 0, 1 }, testTransparencyTexture, nullptr, pbrShader, false, RenderQueue::TRANSPARENT };
Material sunMaterial = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 2, 2, 1, 1 }, checkboardTexture, nullptr, nullptr, pbrShader, false, RenderQueue::OPAQUE };
Material transparentMat = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 0, 0, 0, 1 }, testTransparencyTexture, nullptr, nullptr, pbrShader, false, RenderQueue::TRANSPARENT };
// Let's create a placeholder sun
auto scene = m_sceneGraph->create();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment