diff --git a/build/engine/shaders/const.h b/build/engine/shaders/const.h index 3a6ddad89181b51ef070c129f86ec9b0e594dc7c..c679b050cd6e681db084f13afdbeb253a0c9c75f 100644 --- a/build/engine/shaders/const.h +++ b/build/engine/shaders/const.h @@ -12,6 +12,10 @@ const.h float4 vWinSize; float4 vNearFarLayers; }; */ +cbuffer CDataFrame: register(b4) +{ + float g_fFrameTime; +}; cbuffer CDataScene: register(b3) { float4 g_vNearFarInvWinSize; diff --git a/build/engine/shaders/default/sky.ps b/build/engine/shaders/default/sky.ps index 698718b0a77f35e66e9d95b868885f70f1949080..9d72f0bba4d51f8720bce48adcd53d0e4b10e45e 100644 --- a/build/engine/shaders/default/sky.ps +++ b/build/engine/shaders/default/sky.ps @@ -3,13 +3,15 @@ XMaterial MainGBuffer(PSI_XMaterial IN) { XMaterial OUT = XMATERIAL_LOAD_DEFAULTS(); - float4 vColor = g_txBase.Sample(g_sScene, IN.vTexUV); + // float4 vColor = g_txBase.Sample(g_sScene, IN.vTexUV); // float4 vColor = g_txCurrent.Sample(g_sScene, IN.vTexUV); - vColor.xyz *= vColor.w * 25.0f; - vColor.w = 1.0f; + // vColor.xyz *= vColor.w * 25.0f; + // vColor.xyz = 0.0f; + // vColor.w = 1.0f; - OUT.vBaseColor = vColor.xyz; + // OUT.vBaseColor = vColor.xyz; + OUT.vBaseColor = (float3)0.0f; OUT.fLightCoeff = 0.0f; OUT.vNormal = -IN.vTexUV; OUT.fDepth = g_vNearFarInvWinSize.y - g_vNearFarInvWinSize.x; @@ -24,7 +26,7 @@ XMaterial MainIllimination(PSI_XMaterial IN) float4 fColor = g_txBase.Sample(g_sScene, IN.vTexUV); - OUT.vEmissiveColor = fColor.xyz; + OUT.vEmissiveColor = fColor.xyz * fColor.w * 16.0f; return(OUT); } diff --git a/build/engine/shaders/default/terrain.ps b/build/engine/shaders/default/terrain.ps index 9a3f5775552128272a6c72f1ee5f990ab5a7bb70..dbf581973ecf8ebb00c05d588a0683bbd935c9be 100644 --- a/build/engine/shaders/default/terrain.ps +++ b/build/engine/shaders/default/terrain.ps @@ -62,7 +62,7 @@ XMaterial MainGBuffer(PSI_XMaterial IN) #endif // float fMixFactor = min(1.0f, length(vMask)); - float fMixFactor = min(1.0f, vMask.x + vMask.y + vMask.z + vMask.w); + float fMixFactor = min(1.0f, dot(vMask, 1.0f)); OUT.vBaseColor = lerp(vBaseColor.xyz, vColor.xyz, fMixFactor); diff --git a/build/engine/shaders/gi/gi_propagation.cs b/build/engine/shaders/gi/gi_propagation.cs index 8c6b328e5c3e7cfc8ead720f6818080877247487..ef7ce9cf530adc072b9671d93d9d722b9baf4aae 100644 --- a/build/engine/shaders/gi/gi_propagation.cs +++ b/build/engine/shaders/gi/gi_propagation.cs @@ -62,7 +62,7 @@ float3x3 neighbourOrientations[6] = { 0, 1, 0) }; -[numthreads(16, 2, 1)] +[numthreads(8, 8, 1)] void main(uint3 dispatchThreadID: SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID) { uint3 cellIndex = dispatchThreadID.xyz; diff --git a/build/engine/shaders/hdr/hdr_adapt.ps b/build/engine/shaders/hdr/hdr_adapt.ps new file mode 100644 index 0000000000000000000000000000000000000000..f74bfeef7169e22abf66e73d522477b7cb9c59b9 --- /dev/null +++ b/build/engine/shaders/hdr/hdr_adapt.ps @@ -0,0 +1,35 @@ + +/* +hdr_adapt +адаптация яркости +*/ + +#include <struct.h> +#include <const.h> + +//########################################################################## + +SamplerState g_sPointClamp: register(s0); +Texture2D g_txPrevLuminance: register(t0); +Texture2D g_txNewLuminance: register(t1); + +//########################################################################## + +cbuffer b8: register(b8) +{ + float g_fAdaptationSpeed; + float g_fBaseValue; +}; + +//########################################################################## + +float4 main(VSO_PP IN):SV_TARGET +{ + float fPrevLuminance = g_txPrevLuminance.Load(uint3(0, 0, 0)).x; + float fNewLuminance = max(exp(g_txNewLuminance.Load(uint3(0, 0, 0)).x), 0.005f); // 0.03f + + // Pattanaik's technique + float fAdapted = fPrevLuminance + (fNewLuminance - fPrevLuminance) * (1 - exp(-g_fFrameTime * g_fAdaptationSpeed)); + + return(float4(fAdapted, 1.0f, 1.0f, 1.0f)); +} diff --git a/build/engine/shaders/hdr/hdr_luminance.ps b/build/engine/shaders/hdr/hdr_luminance.ps new file mode 100644 index 0000000000000000000000000000000000000000..789fc92d3aa7376e1fb4e7163d7c27e0230390f7 --- /dev/null +++ b/build/engine/shaders/hdr/hdr_luminance.ps @@ -0,0 +1,29 @@ + +/* +hdr_luminance +расчет логарифмической яркости +*/ + +#include <struct.h> + +//########################################################################## + +SamplerState g_sLinearClamp: register(s0); +Texture2D g_txDiffuse : register(t0); // basetexture + +//########################################################################## + +float CalcLuminance(float3 color) +{ + return max(dot(color, float3(0.298f, 0.585f, 0.117f)), 0.00001f); +} + +float4 main(VSO_PP IN):SV_TARGET +{ + float4 vColor = g_txDiffuse.Sample(g_sLinearClamp, IN.vTexUV); + + float fLuminance = log(CalcLuminance(vColor)); + + return(float4(fLuminance, 1.0f, 1.0f, 1.0f)); + // return(float4(-10, 1.0f, 1.0f, 1.0f)); +} diff --git a/build/engine/shaders/hdr/hdr_reduction.cs b/build/engine/shaders/hdr/hdr_reduction.cs new file mode 100644 index 0000000000000000000000000000000000000000..f66e11765edc47bc6a96d31f729bd2a12327d789 --- /dev/null +++ b/build/engine/shaders/hdr/hdr_reduction.cs @@ -0,0 +1,40 @@ + +#define THREAD_GROUP_DIM 16 +#define TOTAL_THREADS (THREAD_GROUP_DIM * THREAD_GROUP_DIM) + +Texture2D<float> g_txInput: register(t0); + +RWTexture2D<float> g_txOutput: register(u0); + +groupshared float4 g_vShared[TOTAL_THREADS]; + +[numthreads(THREAD_GROUP_DIM, THREAD_GROUP_DIM, 1)] +void main(uint3 vGroupID: SV_GroupID, uint3 vGroupThreadID: SV_GroupThreadID) +{ + const uint uThreadID = vGroupThreadID.y * THREAD_GROUP_DIM + vGroupThreadID.x; + + const uint2 vSampleID = (vGroupID.xy * THREAD_GROUP_DIM + vGroupThreadID.xy) * 2; + float4 vVal = 0.0f; + vVal.x = g_txInput[vSampleID + uint2(0, 0)]; + vVal.y = g_txInput[vSampleID + uint2(1, 0)]; + vVal.z = g_txInput[vSampleID + uint2(0, 1)]; + vVal.w = g_txInput[vSampleID + uint2(1, 1)]; + + g_vShared[uThreadID] = vVal; + GroupMemoryBarrierWithGroupSync(); + + [unroll(TOTAL_THREADS)] + for(uint s = TOTAL_THREADS / 2; s > 0; s >>= 1) + { + if(uThreadID < s) + g_vShared[uThreadID] += g_vShared[uThreadID + s]; + + GroupMemoryBarrierWithGroupSync(); + } + + if(uThreadID == 0) + { + g_txOutput[vGroupID.xy] = dot(g_vShared[0], 0.25f) / (float)(TOTAL_THREADS); + // g_txOutput[vGroupID.xy] = -10.0f; + } +} diff --git a/build/engine/shaders/hdr/hdr_tonemapping.ps b/build/engine/shaders/hdr/hdr_tonemapping.ps new file mode 100644 index 0000000000000000000000000000000000000000..12b37dd8e7b8f3fc26f656e4969db966a4d444a5 --- /dev/null +++ b/build/engine/shaders/hdr/hdr_tonemapping.ps @@ -0,0 +1,83 @@ + +/* +hdr_tonemapping +*/ + +#include <struct.h> + +//########################################################################## + +SamplerState g_sPointClamp: register(s0); +Texture2D g_txScene: register(t0); +Texture2D g_txLuminance: register(t1); +Texture2D g_txLuminance2: register(t2); + +//########################################################################## + +cbuffer b8: register(b8) +{ + float g_fAdaptationSpeed; + float g_fBaseValue; +}; + +//########################################################################## + +float CalcLuminance(float3 color) +{ + return max(dot(color, float3(0.298f, 0.585f, 0.117f)), 0.00001f); +} + +// Applies the filmic curve from John Hable's presentation +float3 ToneMapFilmicALU(float3 color) +{ + color = max(0, color - 0.004f); + color = (color * (6.2f * color + 0.5f)) / (color * (6.2f * color + 1.7f)+ 0.06f); + + // result has 1/2.2 baked in + return pow(color, 2.2f); +} + +// Determines the color based on exposure settings +float3 CalcExposedColor(float3 color, float avgLuminance, float threshold, out float exposure) +{ + // Use geometric mean + avgLuminance = max(avgLuminance, 0.001f); + float linearExposure = (g_fBaseValue / avgLuminance); + exposure = log2(max(linearExposure, 0.0001f)); + exposure -= threshold; + return exp2(exposure) * color; +} + +// Applies exposure and tone mapping to the specific color, and applies +// the threshold to the exposure value. +float3 ToneMap(float3 color, float avgLuminance, float threshold, out float exposure) +{ + float pixelLuminance = CalcLuminance(color); + color = CalcExposedColor(color, avgLuminance, threshold, exposure); + color = ToneMapFilmicALU(color); + return color; +} + +//########################################################################## + + +float4 main(VSO_PP IN):SV_TARGET +{ + float4 vColor = g_txScene.Sample(g_sPointClamp, IN.vTexUV); + float fLuminance = g_txLuminance.Load(uint3(0, 0, 0)).x; + float fLuminance2 = exp(g_txLuminance2.Load(uint3(0, 0, 0)).x); + + float fExposure = 0; + vColor.xyz = ToneMap(vColor.xyz, fLuminance, 0, fExposure); + + if(IN.vTexUV.x > 0.9 && IN.vTexUV.y > 0.9) + { + vColor.xyz = fLuminance; + } + if(IN.vTexUV.x > 0.9 && IN.vTexUV.y > 0.8 && IN.vTexUV.y < 0.9) + { + vColor.xyz = fLuminance2; + } + + return(vColor); +} diff --git a/build/engine/shaders/lighting/lighting_blend.ps b/build/engine/shaders/lighting/lighting_blend.ps index bf183071e6b4f67b11bddd4cc4924e39d2090b27..12db267f8fec0d1d5babbbb32e5917d9ffe234db 100644 --- a/build/engine/shaders/lighting/lighting_blend.ps +++ b/build/engine/shaders/lighting/lighting_blend.ps @@ -16,6 +16,7 @@ Texture2D g_txNormals: register(t3); Texture2D g_txDepth: register(t4); Texture2D g_txParameters: register(t5); SamplerState g_sPointClamp: register(s0); +SamplerState g_sLinearClamp: register(s1); // sampler2D g_sColor:register(s0); // sampler2D g_sAmbient:register(s1); @@ -88,7 +89,7 @@ float3 GetReflection(float3 texelPosition, float3 texelNormal) float fresnel = /* 0.0 + */2.8 * pow(1+dot(viewDir, texelNormal), 2); - return(g_txAmbient.Sample(g_sPointClamp, nuv.xy).xyz * error * fresnel); + return(g_txAmbient.Sample(g_sLinearClamp, nuv.xy).xyz * error * fresnel); // return(fresnel); } @@ -110,10 +111,10 @@ float4 main(VSO_ResPos IN):COLOR0 vColor.rgb += (1.0f - vParams.x) * GetReflection(vPosition.xyz, vNormalPixel) * lerp((float3)fF0, vAlbedo, vParams.y) * vAlbedo.w; - float fAdaptedLum = 0.2f; + // float fAdaptedLum = 0.2f; - vColor.rgb *= TONE_MAPPING_DENOMENATOR/(fAdaptedLum + TONE_MAPPING_ADAPT_ADD_BIAS); - vColor.rgb /= (fAdaptedLum + vColor.rgb); + // vColor.rgb *= TONE_MAPPING_DENOMENATOR/(fAdaptedLum + TONE_MAPPING_ADAPT_ADD_BIAS); + // vColor.rgb /= (fAdaptedLum + vColor.rgb); // return float4(pow(vColor.rgb, 1.0/2.2), vColor.a); return float4(vColor.rgb, vColor.a); diff --git a/build/engine/shaders/lighting/lighting_com.ps b/build/engine/shaders/lighting/lighting_com.ps index 89a643d636cbc433a9293456d0c09fa983bec0aa..348c17f7b7ce54264796d27cb36834f0b53bfe8b 100644 --- a/build/engine/shaders/lighting/lighting_com.ps +++ b/build/engine/shaders/lighting/lighting_com.ps @@ -133,9 +133,9 @@ float4 GetSpecular(float fRoughness, float4 fF0, float fNdotL, float3 vV, float3 //############################################################################# //IS_SPOT -PSO_Lbuffer main(VSO_ResPos IN) +float4 main(VSO_ResPos IN):SV_TARGET { - PSO_Lbuffer OUT; + float4 OUT; float4 vAlbedo = g_txScene.Sample(g_sPointClamp, IN.vTexUV); float4 vNormals = g_txNormals.Sample(g_sPointClamp, IN.vTexUV); @@ -215,20 +215,9 @@ PSO_Lbuffer main(VSO_ResPos IN) // float fMdiffuse = saturate(fNdotL * 0.5 + 0.5); // float fDiffuse = 1.0f; - OUT.vAmdient.xyz = lerp(vAlbedo.xyz, g_vLightColorPower.xyz * lerp(vAlbedo.xyz * fDiffuse + vSpecular.www, vSpecular.xyz, fMetallic) * fAttenuation * fShadow, vAlbedo.w); + OUT.xyz = lerp(vAlbedo.xyz, g_vLightColorPower.xyz * lerp(vAlbedo.xyz * fDiffuse + vSpecular.www, vSpecular.xyz, fMetallic) * fAttenuation * fShadow, vAlbedo.w); - // OUT.vAmdient.w = /* fDiffuse * */fMdiffuse * vParam.w * g_vLightColorPower.w * 2.0 * fAttenuation; - OUT.vAmdient.w = 1.0f; - - // OUT.vAmdient.xyz *= OUT.vAmdient.w; - - // OUT.vAmdient.xyz = float3(IN.vTexUV.xy, 1); - // OUT.vAmdient.w = 1; - - // OUT.vAmdient.xyz = pow(OUT.vAmdient.xyz, 1.0/2.2); - - // OUT.vSpecular = fSpecular * fAttenuation * g_vLightColorPower.w; - OUT.vSpecular = 0; + OUT.w = 1.0f; return OUT; } diff --git a/build/engine/shaders/material/transparent.ps b/build/engine/shaders/material/transparent.ps index 3a99e54a4753aecba415c2d1b5d76ff5b078212e..b8b8073550b9d6ca1098b0bc12be026905fc9583 100644 --- a/build/engine/shaders/material/transparent.ps +++ b/build/engine/shaders/material/transparent.ps @@ -39,5 +39,6 @@ float4 main(PSI_XMaterial IN):COLOR0 float4 fWorldPos = mul(IN.vPos, g_mInvVP); - return(mtrl.vBaseColor * float4(GetPixelLight(fWorldPos.xyz / fWorldPos.w, mtrl.vNormal), 1.0f)); + // return(mtrl.vBaseColor * float4(GetPixelLight(fWorldPos.xyz / fWorldPos.w, mtrl.vNormal), 1.0f)); + return(mtrl.vBaseColor); } diff --git a/source/ambient/Renderable.cpp b/source/ambient/Renderable.cpp index b328b87cc956fd45b985373997833c96b8656f05..4cce31df1c321fea6172de949d2c88e8a6f49c8c 100644 --- a/source/ambient/Renderable.cpp +++ b/source/ambient/Renderable.cpp @@ -8,7 +8,7 @@ CRenderable::CRenderable(ID idPlugin, CSkyBox *pSkyBox): X_RENDER_STAGE XMETHODCALLTYPE CRenderable::getStages() { - return(XRS_GBUFFER); + return(XRS_GBUFFER | XRS_GI); } UINT XMETHODCALLTYPE CRenderable::getPriorityForStage(X_RENDER_STAGE stage) @@ -30,6 +30,7 @@ void XMETHODCALLTYPE CRenderable::renderStage(X_RENDER_STAGE stage, IXRenderable case XRS_SHADOWS: break; case XRS_GI: + m_pSkyBox->render(); break; case XRS_POSTPROCESS_MAIN: break; diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp index ecd362f7a648083e5de6143769f3418611b00133..c92b35e4b938fc501931f816a31effcddaf88dfd 100644 --- a/source/game/GameData.cpp +++ b/source/game/GameData.cpp @@ -445,7 +445,7 @@ GameData::GameData(HWND hWnd, bool isGame): { // 252, 212, 64 IXLightSun *pSun = m_pLightSystem->createSun(); - pSun->setColor(float3(2.52f, 2.12f, 0.64f) * 1.0f); + pSun->setColor(float3(2.52f, 2.12f, 0.64f) * 2.0f); pSun->setDirection(SMQuaternion(LIGHTS_DIR_BASE, float3(1.0f, -1.0f, 1.0f))); } diff --git a/source/gcore/sxgcore.h b/source/gcore/sxgcore.h index 6cd3bd23124a084ec3c9baf40ebc9182f5e6b51f..958c3927f94739283ac9e1e991dfeeb87f5dff46 100644 --- a/source/gcore/sxgcore.h +++ b/source/gcore/sxgcore.h @@ -120,8 +120,8 @@ enum DS_RT //! эмбиент цвет (цвет света rgb) и диффузное освещение (a) rgba16f DS_RT_AMBIENTDIFF, - //! блики r16f - DS_RT_SPECULAR, + //! яркость + DS_RT_LUMINANCE, //! освещенная сцена rgba16 DS_RT_SCENELIGHT, @@ -272,6 +272,7 @@ SX_LIB_API void SGCore_ShaderUnBind(); enum SHADER_CONST_REGISTER { + SCR_FRAME = 4, SCR_SCENE = 3, SCR_CAMERA = 2, SCR_OBJECT = 1, diff --git a/source/render/RenderPipeline.cpp b/source/render/RenderPipeline.cpp index 414d05601dfa7348b06fcc0b840ad79ef8566996..ff71fce9a571bdd6ff61f992fb8ee78dce0ed8ae 100644 --- a/source/render/RenderPipeline.cpp +++ b/source/render/RenderPipeline.cpp @@ -13,6 +13,8 @@ namespace gdata //! При изменении базовых шейдеров отредактировать https://wiki.skyxengine.com/index.php?title=Стандартные_шейдеры_материалов +#define LUMINANCE_BUFFER_SIZE 1024 + CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): m_pDevice(pDevice) { @@ -24,7 +26,8 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): Core_0RegisterCVarBool("dev_lpv_cubes", false, "Отображать сетку LPV"); Core_0RegisterCVarBool("dev_lpv_points", false, "Отображать VPL при инъекции в LPV"); - Core_0RegisterCVarFloat("hdr_adapted_coef", 0.03f, "Коэфициент привыкания к освещению (0,1] (медлено, быстро)"); + Core_0RegisterCVarFloat("hdr_adapted_coef", 0.3f, "Коэфициент привыкания к освещению (0,1] (медлено, быстро)"); + Core_0RegisterCVarFloat("hdr_base_value", 0.2f, "Базовое значение для тонмаппинга (0,0.5] (темно, ярко)"); XVertexOutputElement voelGeneric[] = { {"vPosition", GXDECLTYPE_FLOAT4, GXDECLUSAGE_POSITION}, @@ -127,18 +130,18 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): { XRenderPassTexturesElement pTextures[] = { - {"GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0}, - {"GBuffer normals(rgb) f0(a)", "g_txGBufferN3F1", 1}, - {"GBuffer depth(r)", "g_txGBufferD1", 2}, - {"", "", 3}, // reserved slot - // {"GBuffer roughness(r) metallic(g) thickness(b) AO(a)", "g_txGBufferR1M1T1AO1", 3}, - {"Lighted scene", "g_txScene", 4}, + // {"GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0}, + // {"GBuffer normals(rgb) f0(a)", "g_txGBufferN3F1", 1}, + // {"GBuffer depth(r)", "g_txGBufferD1", 2}, + // {"", "", 3}, // reserved slot + // // {"GBuffer roughness(r) metallic(g) thickness(b) AO(a)", "g_txGBufferR1M1T1AO1", 3}, + // {"Lighted scene", "g_txScene", 4}, XRENDER_PASS_TEXTURES_LIST_END() }; XRenderPassSamplersElement pSamplers[] = { {"Scene default", "sScene", 0}, - {"Point clamp", "sPointClamp", 1}, + // {"Point clamp", "sPointClamp", 1}, XRENDER_PASS_SAMPLERS_LIST_END() }; @@ -411,7 +414,7 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): XMaterialShaderPass pPasses[] = { {m_pRenderPassGBuffer, "default/sky.ps", "MainGBuffer", pMacro, NULL, NULL}, - //{m_pRenderPassIllumination, "default/sky.ps", "MainIllimination", NULL, NULL, NULL}, + {m_pRenderPassIllumination, "default/sky.ps", "MainIllimination", NULL, NULL, NULL}, XMATERIAL_SHADER_PASS_LIST_END() }; @@ -529,7 +532,13 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): m_pLightAmbientDiffuse = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_A16B16G16R16F); - m_pLightSpecular = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_R16F); + + m_pLightLuminance = m_pDevice->createTexture2D(LUMINANCE_BUFFER_SIZE, LUMINANCE_BUFFER_SIZE, 1, GX_TEXFLAG_RENDERTARGET, GXFMT_R16F); + + m_pLightLuminance32 = m_pDevice->createTexture2D(32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F); + m_pLightLuminance1 = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F); + m_pAdaptedLuminance[0] = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F); + m_pAdaptedLuminance[1] = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F); m_pLightTotal = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_A16B16G16R16F); @@ -568,6 +577,10 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): m_pLightingShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_lightingShaderData.vs)); m_pLightingShaderDataPS = m_pDevice->createConstantBuffer(sizeof(m_lightingShaderData.ps)); + m_pFrameShaderData = m_pDevice->createConstantBuffer(sizeof(m_frameShaderData)); + + m_pToneMappingShaderData = m_pDevice->createConstantBuffer(sizeof(m_toneMappingShaderData)); + { const UINT uSize = 32; m_uGICubesCount = uSize * uSize * uSize; @@ -623,6 +636,8 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): m_idLPVPropagateShader = SGCore_ShaderCreateKit(-1, -1, -1, SGCore_ShaderLoad(SHADER_TYPE_COMPUTE, "gi_propagation.cs")); + m_idLuminanceReductionShader = SGCore_ShaderCreateKit(-1, -1, -1, SGCore_ShaderLoad(SHADER_TYPE_COMPUTE, "hdr_reduction.cs")); + m_pShadowCache = new CShadowCache(this, m_pMaterialSystem); m_pShadowShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_shadowShaderData.vs)); @@ -651,6 +666,8 @@ CRenderPipeline::~CRenderPipeline() mem_release(m_pRefractionScene); + mem_release(m_pToneMappingShaderData); + mem_release(m_pTransparencyShaderClipPlanes); mem_release(m_pMainCameraOcclusionCuller); @@ -673,7 +690,14 @@ CRenderPipeline::~CRenderPipeline() mem_release(m_pGBufferDepth); mem_release(m_pLightAmbientDiffuse); - mem_release(m_pLightSpecular); + mem_release(m_pLightLuminance); + + mem_release(m_pLightLuminance32); + mem_release(m_pLightLuminance1); + mem_release(m_pAdaptedLuminance[0]); + mem_release(m_pAdaptedLuminance[1]); + + mem_release(m_pFrameShaderData); mem_release(m_pLightTotal); @@ -713,6 +737,14 @@ void CRenderPipeline::renderFrame() static const int *r_final_image = GET_PCVAR_INT("r_final_image"); IGXContext *pCtx = m_pDevice->getThreadContext(); + IGXSurface *pBackBuf = pCtx->getColorTarget(); + IGXSurface *pSceneBuf = NULL; + + m_frameShaderData.fFrameTime = (float)timeDelta / 1000.0f; + m_pFrameShaderData->update(&m_frameShaderData); + + pCtx->setVSConstant(m_pFrameShaderData, SCR_FRAME); + pCtx->setPSConstant(m_pFrameShaderData, SCR_FRAME); m_sceneShaderData.vNearFarInvWinSize = float4(gdata::vNearFar, 1.0f / (float)m_uOutWidth, 1.0f / (float)m_uOutHeight); m_pSceneShaderDataPS->update(&m_sceneShaderData); @@ -752,18 +784,17 @@ void CRenderPipeline::renderFrame() if(m_pLightSystem) { - switch(*r_final_image) + if(*r_final_image == DS_RT_AMBIENTDIFF) { - case DS_RT_AMBIENTDIFF: showTexture(m_pLightAmbientDiffuse); goto end; - case DS_RT_SPECULAR: - showTexture(m_pLightSpecular); - goto end; } //m_pSceneTexture = m_pLightAmbientDiffuse; m_pSceneTexture = m_pLightTotal; + + pSceneBuf = m_pLightAmbientDiffuse->asRenderTarget(); + pCtx->setColorTarget(pSceneBuf); } else { @@ -778,7 +809,18 @@ void CRenderPipeline::renderFrame() if(m_pLightSystem) { + pCtx->setColorTarget(pBackBuf); + toneMapping(); + + if(*r_final_image == DS_RT_LUMINANCE) + { + showTexture(m_pLightLuminance); + // showTexture(m_pLightLuminance32); + goto end; + } + + //showTexture(m_pLightAmbientDiffuse); } #if 0 @@ -809,11 +851,19 @@ void CRenderPipeline::renderFrame() #endif end: + mem_release(pBackBuf); + mem_release(pSceneBuf); + const bool *dev_lpv_cubes = GET_PCVAR_BOOL("dev_lpv_cubes"); if(*dev_lpv_cubes) { showGICubes(); } + + Core_PStartSection(PERF_SECTION_RENDER_INFO); + //@FIXME: пока так + SGame_RenderHUD(); + Core_PEndSection(PERF_SECTION_RENDER_INFO); showFrameStats(); @@ -915,8 +965,91 @@ void CRenderPipeline::showGICubes() void CRenderPipeline::toneMapping() { Core_PStartSection(PERF_SECTION_TONEMAPPING); - static const float * hdr_adapted_coef = GET_PCVAR_FLOAT("hdr_adapted_coef"); + static const float *hdr_adapted_coef = GET_PCVAR_FLOAT("hdr_adapted_coef"); + static const float *hdr_base_value = GET_PCVAR_FLOAT("hdr_base_value"); + + //! @todo update only on change + m_toneMappingShaderData.fAdaptationSpeed = *hdr_adapted_coef; + m_toneMappingShaderData.fBaseValue = *hdr_base_value; + m_pToneMappingShaderData->update(&m_toneMappingShaderData); + // SGCore_ToneMappingCom(timeDelta, (hdr_adapted_coef ? (*hdr_adapted_coef) : 0.03f)); + IGXContext *pCtx = m_pDevice->getThreadContext(); + + pCtx->setPSConstant(m_pToneMappingShaderData, 8); + + IGXSurface *pBackBuf = pCtx->getColorTarget(); + + IGXSurface *pRT = m_pLightLuminance->asRenderTarget(); + pCtx->setColorTarget(pRT); + mem_release(pRT); + + pCtx->setPSTexture(m_pLightAmbientDiffuse); + pCtx->setSamplerState(gdata::rstates::pSamplerLinearClamp, 0); + + IGXDepthStencilSurface *pDSSurface = pCtx->getDepthStencilSurface(); + pCtx->unsetDepthStencilSurface(); + + SGCore_ShaderBind(gdata::shaders_id::kit::idHDRinitLuminance); + SGCore_ScreenQuadDraw(); + SGCore_ShaderUnBind(); + + pCtx->setColorTarget(pBackBuf); + + // Reduction + { + SGCore_ShaderBind(m_idLuminanceReductionShader); + + pCtx->setCSTexture(m_pLightLuminance, 0); + pCtx->setCSUnorderedAccessView(m_pLightLuminance32, 0); + pCtx->computeDispatch(32, 32, 1); + pCtx->setCSUnorderedAccessView(NULL, 0); + pCtx->setCSTexture(NULL, 0); + + pCtx->setCSTexture(m_pLightLuminance32, 0); + pCtx->setCSUnorderedAccessView(m_pLightLuminance1, 0); + pCtx->computeDispatch(1, 1, 1); + pCtx->setCSUnorderedAccessView(NULL, 0); + pCtx->setCSTexture(NULL, 0); + + SGCore_ShaderUnBind(); + } + + // Adaptation + { + // m_pLightLuminance1 + pCtx->setPSTexture(m_pAdaptedLuminance[!m_uCurrAdaptedLuminanceTarget]); + pCtx->setPSTexture(m_pLightLuminance1, 1); + IGXSurface *pAdaptedLuminanceBuf = m_pAdaptedLuminance[m_uCurrAdaptedLuminanceTarget]->asRenderTarget(); + pCtx->setColorTarget(pAdaptedLuminanceBuf); + mem_release(pAdaptedLuminanceBuf); + + SGCore_ShaderBind(gdata::shaders_id::kit::idHDRAdaptLuminance); + + SGCore_ScreenQuadDraw(); + + SGCore_ShaderUnBind(); + } + + + pCtx->setColorTarget(pBackBuf); + mem_release(pBackBuf); + + { + pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0); + pCtx->setPSTexture(m_pLightAmbientDiffuse); + pCtx->setPSTexture(m_pAdaptedLuminance[m_uCurrAdaptedLuminanceTarget], 1); + pCtx->setPSTexture(m_pLightLuminance1, 2); + SGCore_ShaderBind(gdata::shaders_id::kit::idHDRToneMapping); + + SGCore_ScreenQuadDraw(); + + SGCore_ShaderUnBind(); + } + + pCtx->setDepthStencilSurface(pDSSurface); + m_uCurrAdaptedLuminanceTarget = !m_uCurrAdaptedLuminanceTarget; + Core_PEndSection(PERF_SECTION_TONEMAPPING); } @@ -998,7 +1131,6 @@ void CRenderPipeline::renderGI() return; } - m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow); IGXContext *pCtx = m_pDevice->getThreadContext(); @@ -1016,18 +1148,21 @@ void CRenderPipeline::renderGI() m_pShadowCache->nextFrame(); - IGXSurface *pAmbientSurf, *pSpecDiffSurf, *pBackBuf; + IGXSurface *pAmbientSurf, *pBackBuf; pAmbientSurf = m_pLightAmbientDiffuse->getMipmap(); - pSpecDiffSurf = m_pLightSpecular->getMipmap(); pBackBuf = pCtx->getColorTarget(); pCtx->setColorTarget(pAmbientSurf); - pCtx->setColorTarget(pSpecDiffSurf, 1); //очищаем рт и стенсил pCtx->clear(GX_CLEAR_COLOR | GX_CLEAR_STENCIL); + rfunc::SetRenderSceneFilter(); + m_pMaterialSystem->bindRenderPass(m_pRenderPassIllumination); + renderStage(XRS_GI); + + m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow); m_lightingShaderData.vs.mViewInv = SMMatrixTranspose(SMMatrixInverse(NULL, gdata::mCamView)); m_lightingShaderData.vs.mVP = SMMatrixTranspose(gdata::mCamView * gdata::mCamProj); m_lightingShaderData.vs.vNearFar = gdata::vNearFar; @@ -1128,7 +1263,6 @@ void CRenderPipeline::renderGI() while((uShadowCount = m_pShadowCache->processNextBunch())) { pCtx->setColorTarget(pAmbientSurf); - pCtx->setColorTarget(pSpecDiffSurf, 1); pCtx->setDepthStencilSurface(pOldDSSurface); pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne); @@ -1175,7 +1309,6 @@ void CRenderPipeline::renderGI() pShadow->genShadow(m_pShadow, m_pGBufferDepth, m_pGBufferNormals); pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne); pCtx->setColorTarget(pAmbientSurf); - pCtx->setColorTarget(pSpecDiffSurf, 1); // pCtx->setPSTexture(m_pShadow, 4); //idshaderkit = gdata::shaders_id::kit::idComLightingShadow; @@ -1336,48 +1469,52 @@ void CRenderPipeline::renderGI() { SGCore_ShaderBind(m_idLPVPropagateShader); UINT uStepCount[] = {4, 6, 8}; - for(UINT j = 0; j < 3; ++j) - { - for(UINT i = 0; i < uStepCount[j]; ++i) + + //for(UINT k = 0; k < 1000; ++k) + //{ + for(UINT j = 0; j < 3; ++j) { - pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed, 0); - pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen, 1); - pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue, 2); + for(UINT i = 0; i < uStepCount[j]; ++i) + { + pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed, 0); + pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen, 1); + pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue, 2); - pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed2, 0); - pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen2, 1); - pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue2, 2); + pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed2, 0); + pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen2, 1); + pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue2, 2); - pCtx->computeDispatch(2, 16, 32); + pCtx->computeDispatch(4, 4, 32); - pCtx->setCSUnorderedAccessView(NULL, 0); - pCtx->setCSUnorderedAccessView(NULL, 1); - pCtx->setCSUnorderedAccessView(NULL, 2); + pCtx->setCSUnorderedAccessView(NULL, 0); + pCtx->setCSUnorderedAccessView(NULL, 1); + pCtx->setCSUnorderedAccessView(NULL, 2); - pCtx->setCSTexture(NULL, 0); - pCtx->setCSTexture(NULL, 1); - pCtx->setCSTexture(NULL, 2); + pCtx->setCSTexture(NULL, 0); + pCtx->setCSTexture(NULL, 1); + pCtx->setCSTexture(NULL, 2); - pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed2, 0); - pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen2, 1); - pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue2, 2); + pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed2, 0); + pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen2, 1); + pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue2, 2); - pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed, 0); - pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen, 1); - pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue, 2); + pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed, 0); + pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen, 1); + pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue, 2); - pCtx->computeDispatch(2, 16, 32); + pCtx->computeDispatch(4, 4, 32); - pCtx->setCSUnorderedAccessView(NULL, 0); - pCtx->setCSUnorderedAccessView(NULL, 1); - pCtx->setCSUnorderedAccessView(NULL, 2); + pCtx->setCSUnorderedAccessView(NULL, 0); + pCtx->setCSUnorderedAccessView(NULL, 1); + pCtx->setCSUnorderedAccessView(NULL, 2); - pCtx->setCSTexture(NULL, 0); - pCtx->setCSTexture(NULL, 1); - pCtx->setCSTexture(NULL, 2); + pCtx->setCSTexture(NULL, 0); + pCtx->setCSTexture(NULL, 1); + pCtx->setCSTexture(NULL, 2); + } } - } + //} SGCore_ShaderUnBind(); } @@ -1385,7 +1522,6 @@ void CRenderPipeline::renderGI() { pCtx->setColorTarget(pAmbientSurf); - pCtx->setColorTarget(pSpecDiffSurf, 1); //gdata::pDXDevice->setRasterizerState(NULL); pCtx->setRasterizerState(gdata::rstates::pRasterizerCullNone); pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne); @@ -1426,14 +1562,15 @@ void CRenderPipeline::renderGI() pCtx->setSamplerState(gdata::rstates::pSamplerLinearClamp, 1); } + + pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateNoZ); pCtx->setRasterizerState(NULL); pCtx->setBlendState(NULL); - pCtx->setColorTarget(NULL, 1); + //pCtx->setColorTarget(NULL, 1); mem_release(pAmbientSurf); - mem_release(pSpecDiffSurf); //------------------------------- @@ -1441,7 +1578,8 @@ void CRenderPipeline::renderGI() //{{ pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0); - + pCtx->setSamplerState(gdata::rstates::pSamplerLinearClamp, 1); + IGXSurface *pComLightSurf = m_pLightTotal->getMipmap(); pCtx->setColorTarget(pComLightSurf); @@ -1450,7 +1588,7 @@ void CRenderPipeline::renderGI() pCtx->setPSTexture(m_pGBufferColor); pCtx->setPSTexture(m_pLightAmbientDiffuse, 1); - pCtx->setPSTexture(m_pLightSpecular, 2); + //pCtx->setPSTexture(m_pLightSpecular, 2); pCtx->setPSTexture(m_pGBufferNormals, 3); pCtx->setPSTexture(m_pGBufferDepth, 4); //gdata::pDXDevice->setTexture(SGCore_GbufferGetRT(DS_RT_ADAPTEDLUM), 4); @@ -1485,6 +1623,8 @@ void CRenderPipeline::renderTransparent() IGXContext *pCtx = m_pDevice->getThreadContext(); + IGXSurface *pBackBuff = pCtx->getColorTarget(); + //pCtx->setPSConstant(m_pSceneShaderDataPS, SCR_SCENE); pCtx->setVSConstant(m_pCameraShaderDataVS, SCR_CAMERA); rfunc::SetRenderSceneFilter(); @@ -1638,7 +1778,8 @@ void CRenderPipeline::renderTransparent() } pCtx->setBlendState(NULL); - pCtx->setColorTarget(NULL); + pCtx->setColorTarget(pBackBuff); + mem_release(pBackBuff); if(m_iRefractiveSource == -1) { showTexture(m_pSceneTexture); @@ -2091,11 +2232,6 @@ void CRenderPipeline::renderPostprocessFinal() rfunc::SetRenderSceneFilter(); m_pMaterialSystem->bindRenderPass(m_pRenderPassPostprocess); - - Core_PStartSection(PERF_SECTION_RENDER_INFO); - //@FIXME: пока так - SGame_RenderHUD(); - Core_PEndSection(PERF_SECTION_RENDER_INFO); } void CRenderPipeline::renderEditor2D() { diff --git a/source/render/RenderPipeline.h b/source/render/RenderPipeline.h index 6325376c95eec80e9145b10237088bb7ae4067df..a64ac3fd3e103d6ab3f932d93fbe1c75721671bd 100644 --- a/source/render/RenderPipeline.h +++ b/source/render/RenderPipeline.h @@ -94,7 +94,12 @@ protected: //! Буфер освещения IGXTexture2D *m_pLightAmbientDiffuse = NULL; - IGXTexture2D *m_pLightSpecular = NULL; + //! Буфер яркости + IGXTexture2D *m_pLightLuminance = NULL; + IGXTexture2D *m_pLightLuminance32 = NULL; + IGXTexture2D *m_pLightLuminance1 = NULL; + IGXTexture2D *m_pAdaptedLuminance[2]; + UINT m_uCurrAdaptedLuminanceTarget = 0; //! Буфер освещения IGXTexture2D *m_pLightTotal = NULL; @@ -109,6 +114,21 @@ protected: IXMaterialSystem *m_pMaterialSystem = NULL; + struct + { + float fFrameTime; + float _padding[3]; + } m_frameShaderData; + IGXConstantBuffer *m_pFrameShaderData = NULL; + + struct + { + float fAdaptationSpeed; + float fBaseValue; + float _padding[2]; + } m_toneMappingShaderData; + IGXConstantBuffer *m_pToneMappingShaderData = NULL; + struct { /*struct @@ -260,6 +280,7 @@ protected: ID m_idLightBoundShader = -1; ID m_idLPVPropagateShader = -1; + ID m_idLuminanceReductionShader = -1; //################################### diff --git a/source/render/gdata.cpp b/source/render/gdata.cpp index 18fabfff025a23ebb6e5d03697a52c10b80550e4..31b6fb2bbab21111b3aa664e5a1a50cfd677ef77 100644 --- a/source/render/gdata.cpp +++ b/source/render/gdata.cpp @@ -73,6 +73,10 @@ namespace gdata ID idStencilColumn; ID idStencilStrColumn; //ID idUnionAlpha; + + ID idHDRinitLuminance; + ID idHDRAdaptLuminance; + ID idHDRToneMapping; }; namespace kit @@ -89,6 +93,10 @@ namespace gdata ID idComLightingSpotShadow; ID idComLightingPSSMShadow; ID idComLightingGI; + + ID idHDRinitLuminance; + ID idHDRAdaptLuminance; + ID idHDRToneMapping; }; }; @@ -307,4 +315,13 @@ void gdata::shaders_id::InitAllShaders() gdata::shaders_id::ps::idComLightingGI = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_gi.ps"); gdata::shaders_id::kit::idComLightingGI = SGCore_ShaderCreateKit(gdata::shaders_id::vs::idResPos, gdata::shaders_id::ps::idComLightingGI); + + gdata::shaders_id::ps::idHDRinitLuminance = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "hdr_luminance.ps"); + gdata::shaders_id::kit::idHDRinitLuminance = SGCore_ShaderCreateKit(gdata::shaders_id::vs::idScreenOut, gdata::shaders_id::ps::idHDRinitLuminance); + + gdata::shaders_id::ps::idHDRAdaptLuminance = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "hdr_adapt.ps"); + gdata::shaders_id::kit::idHDRAdaptLuminance = SGCore_ShaderCreateKit(gdata::shaders_id::vs::idScreenOut, gdata::shaders_id::ps::idHDRAdaptLuminance); + + gdata::shaders_id::ps::idHDRToneMapping = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "hdr_tonemapping.ps"); + gdata::shaders_id::kit::idHDRToneMapping = SGCore_ShaderCreateKit(gdata::shaders_id::vs::idScreenOut, gdata::shaders_id::ps::idHDRToneMapping); } diff --git a/source/render/gdata.h b/source/render/gdata.h index 3f769a1050ac7e5a17d9ee86e27c80284d336a3c..be2f2485fb4d7a8b4ea9bba287932cfa9086533e 100644 --- a/source/render/gdata.h +++ b/source/render/gdata.h @@ -126,6 +126,10 @@ namespace gdata extern ID idStencilColumn; extern ID idStencilStrColumn; //extern ID idUnionAlpha; + + extern ID idHDRinitLuminance; + extern ID idHDRAdaptLuminance; + extern ID idHDRToneMapping; }; namespace kit @@ -142,6 +146,10 @@ namespace gdata extern ID idComLightingSpotShadow; extern ID idComLightingPSSMShadow; extern ID idComLightingGI; + + extern ID idHDRinitLuminance; + extern ID idHDRAdaptLuminance; + extern ID idHDRToneMapping; }; };