Skip to content

Commit

Permalink
feat: #86 Add auto exposure
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Aug 23, 2020
1 parent af0a8cb commit 21f423a
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 28 deletions.
16 changes: 16 additions & 0 deletions Assets/BuiltIn/Shader/PostProcessing/AdaptLuminance.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<shaderConfig name="AdaptLuminance" baseShader="SOLID">
<uniforms>
<vs>
<uniform name="uMvpMatrix" type="WORLD_VIEW_PROJECTION" value="0" float="16" matrix="true"/>
</vs>
<fs>
<uniform name="uTexLuminance" type="DEFAULT_VALUE" value="0" float="1" directX="false"/>
<uniform name="uTexLastLuminance" type="DEFAULT_VALUE" value="1" float="1" directX="false"/>
<uniform name="uTimeStep" type="TIME_STEP" value="0,0" float="2"/>
</fs>
</uniforms>
<customUI>
</customUI>
<shader type="GLSL" vs="GLSL/PostEffectVS.glsl" fs="GLSL/AdaptLuminanceFS.glsl"/>
<shader type="HLSL" vs="HLSL/PostEffectVS.hlsl" fs="HLSL/AdaptLuminanceFS.hlsl"/>
</shaderConfig>
20 changes: 20 additions & 0 deletions Assets/BuiltIn/Shader/PostProcessing/GLSL/AdaptLuminanceFS.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
precision mediump float;

uniform sampler2D uTexLuminance;
uniform sampler2D uTexLastLuminance;

uniform vec2 uTimeStep;

in vec2 varTexCoord0;
in vec4 varColor;
out vec4 FragColor;

void main(void)
{
float lum = texture(uTexLuminance, varTexCoord0).x;
float lastLum = texture(uTexLastLuminance, varTexCoord0).x;

float adaptLum = lastLum + (lum - lastLum) * uTimeStep.x * 0.001;

FragColor = vec4(adaptLum, 0, 0, 0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void main(void)
{
vec4 color = texture(uTexColor, varTexCoord0.xy);

float avgLuminance = textureLod(uTexLuminance, varTexCoord0.xy, 10.0).x;
float avgLuminance = textureLod(uTexLuminance, varTexCoord0.xy, 10.0).x;

float target = 0.2;
float threshold = 2.5;
Expand Down
27 changes: 27 additions & 0 deletions Assets/BuiltIn/Shader/PostProcessing/HLSL/AdaptLuminanceFS.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Texture2D uTexLuminance : register(t0);
SamplerState uTexLuminanceSampler : register(s0);

Texture2D uTexLastLuminance : register(t1);
SamplerState uTexLastLuminanceSampler : register(s1);

struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 color : COLOR0;
float2 tex0 : TEXCOORD0;
};

cbuffer cbPerFrame
{
float2 uTimeStep;
}

float4 main(PS_INPUT input) : SV_TARGET
{
float lum = uTexLuminance.Sample(uTexLuminanceSampler, input.tex0).x;
float lastLum = uTexLastLuminance.Sample(uTexLastLuminanceSampler, input.tex0).x;

float adaptLum = lastLum + (lum - lastLum) * uTimeStep.x * 0.001;

return float4(adaptLum, 0, 0, 0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ float4 main(PS_INPUT input) : SV_TARGET
{
float4 color = uTexColor.Sample(uTexColorSampler, input.tex0);

float avgLuminance = uTexLuminance.SampleLevel(uTexLuminanceSampler, input.tex0, 10.0).x;
float avgLuminance = uTexLuminance.SampleLevel(uTexLuminanceSampler, input.tex0, 10.0).x;

float target = 0.2;
float threshold = 2.5;
Expand Down
12 changes: 12 additions & 0 deletions Projects/Skylicht/Engine/Source/Material/Shader/CShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ namespace Skylicht
"SSAO_KERNEL",
"DEFERRED_VIEW",
"DEFERRED_PROJECTION",
"TIME_STEP",
"NULL"
};

Expand Down Expand Up @@ -914,6 +915,17 @@ namespace Skylicht
}
}
break;
case TIME_STEP:
{
float timestep[2] = { 0 };
timestep[0] = getTimeStep();

if (vertexShader == true)
matRender->setShaderVariable(uniform.UniformShaderID, timestep, uniform.SizeOfUniform, video::EST_VERTEX_SHADER);
else
matRender->setShaderVariable(uniform.UniformShaderID, timestep, uniform.SizeOfUniform, video::EST_PIXEL_SHADER);
}
break;
case DEFAULT_VALUE:
case CONFIG_VALUE:
{
Expand Down
1 change: 1 addition & 0 deletions Projects/Skylicht/Engine/Source/Material/Shader/CShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ namespace Skylicht
SSAO_KERNEL,
DEFERRED_VIEW,
DEFERRED_PROJECTION,
TIME_STEP,
NUM_SHADER_TYPE,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ namespace Skylicht
loadShader("BuiltIn/Shader/Lightmap/IndirectTest.xml");
loadShader("BuiltIn/Shader/Lightmap/LightmapVertex.xml");

loadShader("BuiltIn/Shader/PostProcessing/AdaptLuminance.xml");
loadShader("BuiltIn/Shader/PostProcessing/PostEffect.xml");
}

Expand All @@ -110,7 +111,7 @@ namespace Skylicht
loadShader("BuiltIn/Shader/SpecularGlossiness/Lighting/SGDirectionalLightBake.xml");
loadShader("BuiltIn/Shader/SpecularGlossiness/Lighting/SGPointLight.xml");
loadShader("BuiltIn/Shader/SpecularGlossiness/Lighting/SGPointLightShadow.xml");
loadShader("BuiltIn/Shader/SpecularGlossiness/Forward/SH.xml");
loadShader("BuiltIn/Shader/SpecularGlossiness/Forward/SH.xml");
}

void CShaderManager::initSkylichtEngineShader()
Expand Down
48 changes: 25 additions & 23 deletions Projects/Skylicht/Engine/Source/RenderPipeline/CPostProcessorRP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ This file is part of the "Skylicht Engine".
namespace Skylicht
{
CPostProcessorRP::CPostProcessorRP() :
m_currentLum(NULL),
m_lastLum(NULL)
m_adaptLum(NULL),
m_lumTarget(0)
{

m_luminance[0] = NULL;
m_luminance[1] = NULL;
}

CPostProcessorRP::~CPostProcessorRP()
{
IVideoDriver *driver = getVideoDriver();
driver->removeTexture(m_luminance[0]);
driver->removeTexture(m_luminance[1]);
driver->removeTexture(m_adaptLum);
}

void CPostProcessorRP::initRender(int w, int h)
Expand All @@ -53,12 +55,14 @@ namespace Skylicht

m_luminance[0] = driver->addRenderTargetTexture(m_lumSize, "lum_0", ECF_R16F);
m_luminance[1] = driver->addRenderTargetTexture(m_lumSize, "lum_1", ECF_R16F);
m_adaptLum = driver->addRenderTargetTexture(m_lumSize, "lum_adapt", ECF_R16F);

// init final pass shader
m_finalPass.MaterialType = shaderMgr->getShaderIDByName("PostEffect");

// init lum pass shader
m_lumPass.MaterialType = shaderMgr->getShaderIDByName("Luminance");
m_adaptLumPass.MaterialType = shaderMgr->getShaderIDByName("AdaptLuminance");
}

void CPostProcessorRP::render(ITexture *target, CCamera *camera, CEntityManager *entityManager, const core::recti& viewport)
Expand All @@ -71,27 +75,26 @@ namespace Skylicht

void CPostProcessorRP::luminanceMapGeneration(ITexture *color)
{
if (m_lastLum == m_luminance[0])
{
m_currentLum = m_luminance[1];
m_lastLum = m_luminance[0];
}
else
{
m_currentLum = m_luminance[0];
m_lastLum = m_luminance[1];
}
float w = (float)m_lumSize.Width;
float h = (float)m_lumSize.Height;

// Step 1: Generate target luminance from color to lum[0]
IVideoDriver * driver = getVideoDriver();
driver->setRenderTarget(m_currentLum, true, true);
driver->setRenderTarget(m_adaptLum, true, true);

m_lumPass.setTexture(0, color);

float w = (float)m_lumSize.Width;
float h = (float)m_lumSize.Height;

beginRender2D(w, h);
renderBufferToTarget(0.0f, 0.0f, w, h, m_lumPass);

// Step 2: Interpolate to target luminance
driver->setRenderTarget(m_luminance[m_lumTarget], true, true);

m_adaptLumPass.setTexture(0, m_adaptLum);
m_adaptLumPass.setTexture(1, m_luminance[!m_lumTarget]);

beginRender2D(w, h);
renderBufferToTarget(0.0f, 0.0f, w, h, m_adaptLumPass);
}

void CPostProcessorRP::postProcessing(ITexture *finalTarget, ITexture *color, ITexture *normal, ITexture *position, const core::recti& viewport)
Expand All @@ -100,8 +103,6 @@ namespace Skylicht

luminanceMapGeneration(color);

m_currentLum->regenerateMipMapLevels();

driver->setRenderTarget(finalTarget, false, false);

float renderW = (float)m_size.Width;
Expand All @@ -114,13 +115,14 @@ namespace Skylicht
renderH = (float)viewport.getHeight();
}

m_finalPass.setTexture(0, color);
m_finalPass.setTexture(1, m_currentLum);
m_finalPass.setTexture(2, m_lastLum);
m_luminance[m_lumTarget]->regenerateMipMapLevels();

m_finalPass.setTexture(0, color);
m_finalPass.setTexture(1, m_luminance[m_lumTarget]);

beginRender2D(renderW, renderH);
renderBufferToTarget(0.0f, 0.0f, renderW, renderH, m_finalPass);

m_lastLum = m_currentLum;
m_lumTarget = !m_lumTarget;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ namespace Skylicht
core::dimension2du m_lumSize;

ITexture *m_luminance[2];
ITexture *m_lastLum;
ITexture *m_currentLum;
ITexture *m_adaptLum;
int m_lumTarget;

SMaterial m_finalPass;
SMaterial m_lumPass;
SMaterial m_adaptLumPass;

public:
CPostProcessorRP();
Expand Down

0 comments on commit 21f423a

Please sign in to comment.