diff --git a/examples/38-bloom/bloom.cpp b/examples/38-bloom/bloom.cpp new file mode 100644 index 000000000..42c357947 --- /dev/null +++ b/examples/38-bloom/bloom.cpp @@ -0,0 +1,642 @@ +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2018 Eric Arnebäck. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + + * The bloom effect was based on the following presentation: + * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare + */ + +#include "common.h" +#include "bgfx_utils.h" +#include "imgui/imgui.h" +#include "camera.h" +#include "bounds.h" +#include + +namespace +{ + +// pass that render the geometry of the boxes. +#define RENDER_PASS_GEOMETRY_ID 0 + +// the first downsample pass. +#define RENDER_PASS_DOWNSAMPLE0_ID 1 + +// the first upsample pass. +#define RENDER_PASS_UPSAMPLE0_ID ((TEX_CHAIN_LEN-1) + 1) + +// the final pass the combines the bloom with the g-buffer. +#define RENDER_PASS_COMBINE_ID ((TEX_CHAIN_LEN-1) + 1 + (TEX_CHAIN_LEN-1)) + +// number of downsampled and then upsampled textures(used for bloom.) +#define TEX_CHAIN_LEN 5 + +static float s_texelHalf = 0.0f; + +struct PosVertex +{ + float m_x; + float m_y; + float m_z; + + static void init() + { + ms_decl + .begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .end(); + } + + static bgfx::VertexDecl ms_decl; +}; + +bgfx::VertexDecl PosVertex::ms_decl; + +struct PosTexCoord0Vertex +{ + float m_x; + float m_y; + float m_z; + float m_u; + float m_v; + + static void init() + { + ms_decl + .begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) + .end(); + } + + static bgfx::VertexDecl ms_decl; +}; + +bgfx::VertexDecl PosTexCoord0Vertex::ms_decl; + +float cs = 0.29f; + +static PosVertex s_cubeVertices[24] = +{ + {-cs, cs, cs }, + { cs, cs, cs }, + {-cs, -cs, cs }, + { cs, -cs, cs }, + {-cs, cs, -cs }, + { cs, cs, -cs }, + {-cs, -cs, -cs }, + { cs, -cs, -cs }, + {-cs, cs, cs }, + { cs, cs, cs }, + {-cs, cs, -cs }, + { cs, cs, -cs }, + {-cs, -cs, cs }, + { cs, -cs, cs }, + {-cs, -cs, -cs }, + { cs, -cs, -cs }, + { cs, -cs, cs }, + { cs, cs, cs }, + { cs, -cs, -cs }, + { cs, cs, -cs }, + {-cs, -cs, cs }, + {-cs, cs, cs }, + {-cs, -cs, -cs }, + {-cs, cs, -cs }, +}; + +static const uint16_t s_cubeIndices[36] = +{ + 0, 2, 1, + 1, 2, 3, + 4, 5, 6, + 5, 7, 6, + + 8, 10, 9, + 9, 10, 11, + 12, 13, 14, + 13, 15, 14, + + 16, 18, 17, + 17, 18, 19, + 20, 21, 22, + 21, 23, 22, +}; + +void screenSpaceQuad(float _textureWidth, float _textureHeight, float _texelHalf, bool _originBottomLeft, float _width = 1.0f, float _height = 1.0f) +{ + if (3 == bgfx::getAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_decl) ) + { + bgfx::TransientVertexBuffer vb; + bgfx::allocTransientVertexBuffer(&vb, 3, PosTexCoord0Vertex::ms_decl); + PosTexCoord0Vertex* vertex = (PosTexCoord0Vertex*)vb.data; + + const float minx = -_width; + const float maxx = _width; + const float miny = 0.0f; + const float maxy = _height*2.0f; + + const float texelHalfW = _texelHalf/_textureWidth; + const float texelHalfH = _texelHalf/_textureHeight; + const float minu = -1.0f + texelHalfW; + const float maxu = 1.0f + texelHalfH; + + const float zz = 0.0f; + + float minv = texelHalfH; + float maxv = 2.0f + texelHalfH; + + if (_originBottomLeft) + { + float temp = minv; + minv = maxv; + maxv = temp; + + minv -= 1.0f; + maxv -= 1.0f; + } + + vertex[0].m_x = minx; + vertex[0].m_y = miny; + vertex[0].m_z = zz; + vertex[0].m_u = minu; + vertex[0].m_v = minv; + + vertex[1].m_x = maxx; + vertex[1].m_y = miny; + vertex[1].m_z = zz; + vertex[1].m_u = maxu; + vertex[1].m_v = minv; + + vertex[2].m_x = maxx; + vertex[2].m_y = maxy; + vertex[2].m_z = zz; + vertex[2].m_u = maxu; + vertex[2].m_v = maxv; + + bgfx::setVertexBuffer(0, &vb); + } +} + +class ExampleDeferred : public entry::AppI +{ +public: + ExampleDeferred(const char* _name, const char* _description) + : entry::AppI(_name, _description) + { + } + + void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override + { + Args args(_argc, _argv); + + m_width = _width; + m_height = _height; + m_debug = BGFX_DEBUG_TEXT; + m_reset = BGFX_RESET_VSYNC; + + bgfx::Init init; + + init.type = args.m_type; + init.vendorId = args.m_pciId; + init.resolution.width = m_width; + init.resolution.height = m_height; + init.resolution.reset = m_reset; + bgfx::init(init); + + // Enable m_debug text. + bgfx::setDebug(m_debug); + + // Set palette color for index 0 + bgfx::setPaletteColor(0, UINT32_C(0x00000000) ); + + // Set geometry pass view clear state. + bgfx::setViewClear(RENDER_PASS_GEOMETRY_ID + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 1.0f + , 0 + , 0 + , 0 + ); + + // we need to clear the textures in the chain, before downsampling into them. + for (uint16_t ii = 0; ii < TEX_CHAIN_LEN-1; ++ii) { + bgfx::setViewClear(RENDER_PASS_DOWNSAMPLE0_ID + ii + , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH + , 1.0f + , 0 + , 0 + ); + } + + // Create vertex stream declaration. + PosVertex::init(); + PosTexCoord0Vertex::init(); + + // Create static vertex buffer. + m_vbh = bgfx::createVertexBuffer( + bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ) + , PosVertex::ms_decl + ); + + m_ibh = bgfx::createIndexBuffer(bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ) ); + + s_albedo = bgfx::createUniform("s_albedo", bgfx::UniformType::Int1); + s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Int1); + s_depth = bgfx::createUniform("s_depth", bgfx::UniformType::Int1); + s_light = bgfx::createUniform("s_light", bgfx::UniformType::Int1); + u_pixelSize = bgfx::createUniform("u_pixelSize", bgfx::UniformType::Vec4); + u_intensity = bgfx::createUniform("u_intensity", bgfx::UniformType::Vec4); + u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4); + u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); + + // Create program from shaders. + m_geomProgram = loadProgram("vs_albedo_output", "fs_albedo_output"); + m_downsampleProgram = loadProgram("vs_fullscreen", "fs_downsample"); + m_upsampleProgram = loadProgram("vs_fullscreen", "fs_upsample"); + m_combineProgram = loadProgram("vs_fullscreen", "fs_bloom_combine"); + + m_gbufferTex[0].idx = bgfx::kInvalidHandle; + m_gbufferTex[1].idx = bgfx::kInvalidHandle; + m_gbufferTex[2].idx = bgfx::kInvalidHandle; + m_gbuffer.idx = bgfx::kInvalidHandle; + + for (int ii = 0; ii < TEX_CHAIN_LEN; ++ii) { + m_texChainFb[ii].idx = bgfx::kInvalidHandle; + m_texChainTex[ii].idx = bgfx::kInvalidHandle; + } + + // Imgui. + imguiCreate(); + + m_timeOffset = bx::getHPCounter(); + const bgfx::RendererType::Enum renderer = bgfx::getRendererType(); + s_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f; + + // Get renderer capabilities info. + m_caps = bgfx::getCaps(); + + m_oldWidth = 0; + m_oldHeight = 0; + m_oldReset = m_reset; + + m_scrollArea = 0; + + cameraCreate(); + + const float initialPos[3] = { 0.0f, 0.0f, -15.0f }; + cameraSetPosition(initialPos); + cameraSetVerticalAngle(0.0f); + } + + virtual int shutdown() override + { + // Cleanup. + cameraDestroy(); + imguiDestroy(); + + if (bgfx::isValid(m_gbuffer) ) + { + bgfx::destroy(m_gbuffer); + } + + for (int ii = 0; ii < TEX_CHAIN_LEN; ++ii) { + bgfx::destroy(m_texChainTex[ii]); + bgfx::destroy(m_texChainFb[ii]); + + } + + bgfx::destroy(m_ibh); + bgfx::destroy(m_vbh); + + bgfx::destroy(m_geomProgram); + bgfx::destroy(m_downsampleProgram); + bgfx::destroy(m_upsampleProgram); + bgfx::destroy(m_combineProgram); + + bgfx::destroy(s_albedo); + bgfx::destroy(s_tex); + bgfx::destroy(s_depth); + bgfx::destroy(s_light); + + bgfx::destroy(u_mtx); + bgfx::destroy(u_pixelSize); + bgfx::destroy(u_intensity); + bgfx::destroy(u_color); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; + } + + bool update() override + { + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) + { + imguiBeginFrame(m_mouseState.m_mx + , m_mouseState.m_my + , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) + , m_mouseState.m_mz + , uint16_t(m_width) + , uint16_t(m_height) + ); + + showExampleDialog(this); + + int64_t now = bx::getHPCounter(); + static int64_t last = now; + const int64_t frameTime = now - last; + last = now; + const double freq = double(bx::getHPFrequency() ); + const float deltaTime = float(frameTime/freq); + + float time = (float)( (now-m_timeOffset)/freq); + + if (2 > m_caps->limits.maxFBAttachments) + { + // When multiple render targets (MRT) is not supported by GPU, + // implement alternative code path that doesn't use MRT. + bool blink = uint32_t(time*3.0f)&1; + bgfx::dbgTextPrintf(0, 0, blink ? 0x4f : 0x04, " MRT not supported by GPU. "); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + + // This dummy draw call is here to make sure that view 0 is cleared + // if no other draw calls are submitted to view 0. + bgfx::touch(0); + } + else + { + if (m_oldWidth != m_width + || m_oldHeight != m_height + || m_oldReset != m_reset + || !bgfx::isValid(m_gbuffer) ) + { + // Recreate variable size render targets when resolution changes. + m_oldWidth = m_width; + m_oldHeight = m_height; + m_oldReset = m_reset; + + if (bgfx::isValid(m_gbuffer) ) + { + bgfx::destroy(m_gbuffer); + } + + const uint64_t tsFlags = 0 + | BGFX_TEXTURE_RT + | BGFX_SAMPLER_U_CLAMP + | BGFX_SAMPLER_V_CLAMP + ; + + for (int ii = 0; ii < TEX_CHAIN_LEN; ++ii) { + + if (bgfx::isValid(m_texChainFb[ii])) + { + bgfx::destroy(m_texChainFb[ii]); + } + + m_texChainTex[ii] = bgfx::createTexture2D((uint16_t)m_width / (uint16_t)pow(2, ii), (uint16_t)m_height / (uint16_t)pow(2, ii), false, 1, bgfx::TextureFormat::RGBA32F, tsFlags); + m_texChainFb[ii] = bgfx::createFrameBuffer(1, &m_texChainTex[ii], true); + } + + m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::RGBA32F, tsFlags); + m_gbufferTex[1] = m_texChainTex[0]; + m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::D24S8, tsFlags); + m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(m_gbufferTex), m_gbufferTex, true); + + } + + ImGui::SetNextWindowPos( + ImVec2(m_width/7.0f, m_height - m_height / 2.0f - 10.0f ) + , ImGuiCond_FirstUseEver + ); + ImGui::SetNextWindowSize( + ImVec2(m_width / 5.0f, m_height / 3.0f) + , ImGuiCond_FirstUseEver + ); + ImGui::Begin("Settings" + , NULL + , 0 + ); + + ImGui::SliderFloat("intensity", &m_intensity, 0.0f, 3.0f); + + ImGui::End(); + + // Update camera. + cameraUpdate(deltaTime, m_mouseState); + + float view[16]; + cameraGetViewMtx(view); + + float proj[16]; + // Setup views + { + bgfx::setViewRect(RENDER_PASS_GEOMETRY_ID, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + + for (uint16_t ii = 0; ii < TEX_CHAIN_LEN-1; ++ii) { + bgfx::setViewRect(RENDER_PASS_DOWNSAMPLE0_ID + ii, 0, 0, + uint16_t(m_width / (uint16_t)pow(2, ii+1)), + uint16_t(m_height / (uint16_t)pow(2, ii+1))); + } + + for (uint16_t ii = 0; ii < TEX_CHAIN_LEN-1; ++ii) { + + bgfx::setViewRect(RENDER_PASS_UPSAMPLE0_ID + ii, 0, 0, + uint16_t(m_width / (uint16_t)pow(2, TEX_CHAIN_LEN-ii - 2)), + uint16_t(m_height / (uint16_t)pow(2, TEX_CHAIN_LEN - ii - 2))); + } + + bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 100.0f, m_caps->homogeneousDepth); + bgfx::setViewFrameBuffer(RENDER_PASS_GEOMETRY_ID, m_gbuffer); + bgfx::setViewTransform(RENDER_PASS_GEOMETRY_ID, view, proj); + + bgfx::setViewRect(RENDER_PASS_COMBINE_ID, 0, 0, uint16_t(m_width), uint16_t(m_height)); + + bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, m_caps->homogeneousDepth); + + for (uint16_t ii = 0; ii < TEX_CHAIN_LEN-1; ++ii) { + bgfx::setViewTransform(RENDER_PASS_DOWNSAMPLE0_ID + ii, NULL, proj); + bgfx::setViewFrameBuffer(RENDER_PASS_DOWNSAMPLE0_ID + ii, m_texChainFb[ii+1]); + } + + for (uint16_t ii = 0; ii < TEX_CHAIN_LEN-1; ++ii) { + bgfx::setViewTransform(RENDER_PASS_UPSAMPLE0_ID + ii, NULL, proj); + bgfx::setViewFrameBuffer(RENDER_PASS_UPSAMPLE0_ID + ii, m_texChainFb[TEX_CHAIN_LEN - ii - 2]); + } + + bgfx::setViewTransform(RENDER_PASS_COMBINE_ID, NULL, proj); + } + + const uint32_t dim = 7; + const int COLS = 5; + float color[4*COLS] = { + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f, + }; + + // render a whole bunch of colored cubes to the g-buffer. + for (uint32_t xx = 0; xx < dim; ++xx) + { + bgfx::setUniform(u_color, &color[4 * (xx % COLS) ]); + + float mtx[16]; + + bx::mtxIdentity(mtx); + + float t = (float)xx / (float)dim; + + t += 0.07f * time; + +// float r = (float)sin(0.47f * time * 2.0f * 3.14f) * 1.0f + 1.9f; + float r = (float)sin(0.47f * time * 2.0f * 3.14f) * 1.0f + 1.4f; + + //r = 1.9f; + + mtx[12] = (float)sin(t * 2.0f * 3.14f)*r; + mtx[13] = (float)cos(t * 2.0f * 3.14f)*r; + mtx[14] = 0.2f * ((float)xx / (float)dim); + + // Set transform for draw call. + bgfx::setTransform(mtx); + + // Set vertex and index buffer. + bgfx::setVertexBuffer(0, m_vbh); + bgfx::setIndexBuffer(m_ibh); + + // Set render states. + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + | BGFX_STATE_WRITE_Z + | BGFX_STATE_DEPTH_TEST_LESS + | BGFX_STATE_MSAA + ); + + // Submit primitive for rendering to view 0. + bgfx::submit(RENDER_PASS_GEOMETRY_ID, m_geomProgram); + } + + // now downsample. + for(uint16_t ii = 0; ii < TEX_CHAIN_LEN-1; ++ii) + { + float pixelSize[4] = { + 1.0f / (float)(m_width / (uint16_t)pow(2, ii + 1)), + 1.0f / (float)(m_height / (uint16_t)pow(2, ii + 1)), 0.0f, 0.0f }; + + bgfx::setUniform(u_pixelSize, pixelSize); + bgfx::setTexture(0, s_tex, m_texChainTex[ii]); + + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + ); + + screenSpaceQuad((float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft); + bgfx::submit(RENDER_PASS_DOWNSAMPLE0_ID + ii, m_downsampleProgram); + } + + // now upsample. + for (uint16_t ii = 0; ii < TEX_CHAIN_LEN - 1; ++ii) + { + float pixelSize[4] = { + 1.0f / (float)(m_width / (uint16_t)pow(2, TEX_CHAIN_LEN - 2 - ii)), + 1.0f / (float)(m_height / (uint16_t)pow(2, TEX_CHAIN_LEN - 2 - ii)), 0.0f, 0.0f }; + float intensity[4] = { m_intensity, 0.0f, 0.0f, 0.0f }; + + bgfx::setUniform(u_pixelSize, pixelSize); + bgfx::setUniform(u_intensity, intensity); + + // Combine color and light buffers. + bgfx::setTexture(0, s_tex, m_texChainTex[TEX_CHAIN_LEN - 1 - ii]); + + // as we upscale, we also sum with the previous mip level. We do this by alpha blending. + bgfx::setState( + 0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + | BGFX_STATE_BLEND_ADD + ); + + screenSpaceQuad((float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft); + bgfx::submit(RENDER_PASS_UPSAMPLE0_ID + ii, m_upsampleProgram); + } + + // do final pass, that combines the bloom with the g-buffer. + bgfx::setTexture(0, s_albedo, m_gbufferTex[0]); + bgfx::setTexture(1, s_light, m_texChainTex[0]); + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + ); + screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft); + bgfx::submit(RENDER_PASS_COMBINE_ID, m_combineProgram); + } + + imguiEndFrame(); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(); + + return true; + } + + return false; + } + + bgfx::VertexBufferHandle m_vbh; + bgfx::IndexBufferHandle m_ibh; + + bgfx::UniformHandle s_albedo; + bgfx::UniformHandle s_tex; + bgfx::UniformHandle s_depth; + bgfx::UniformHandle s_light; + bgfx::UniformHandle u_pixelSize; + bgfx::UniformHandle u_intensity; + bgfx::UniformHandle u_color; + + + bgfx::UniformHandle u_mtx; + + bgfx::ProgramHandle m_geomProgram; + bgfx::ProgramHandle m_downsampleProgram; + bgfx::ProgramHandle m_upsampleProgram; + bgfx::ProgramHandle m_combineProgram; + + bgfx::TextureHandle m_gbufferTex[3]; + + bgfx::FrameBufferHandle m_gbuffer; + + bgfx::FrameBufferHandle m_texChainFb[TEX_CHAIN_LEN]; + bgfx::TextureHandle m_texChainTex[TEX_CHAIN_LEN]; + + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; + + float m_intensity = 1.0f; + + uint32_t m_oldWidth; + uint32_t m_oldHeight; + uint32_t m_oldReset; + + int32_t m_scrollArea; + + entry::MouseState m_mouseState; + + const bgfx::Caps* m_caps; + int64_t m_timeOffset; +}; + +} // namespace + +ENTRY_IMPLEMENT_MAIN(ExampleDeferred, "38-bloom", "Bloom."); diff --git a/examples/38-bloom/fs_albedo_output.sc b/examples/38-bloom/fs_albedo_output.sc new file mode 100644 index 000000000..85605736d --- /dev/null +++ b/examples/38-bloom/fs_albedo_output.sc @@ -0,0 +1,22 @@ +$input v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0 + +/* + * Copyright 2018 Eric Arnebäck. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + + +uniform vec4 u_color; + +void main() +{ + // the albedo-buffer of the g-buffer. + gl_FragData[0] = u_color; + + // for convenience, we also output the same color, to the first texture of the texture chain used for bloom. + // this color will now be bloomed, in the following passes. + gl_FragData[1] = u_color; + +} diff --git a/examples/38-bloom/fs_bloom_combine.sc b/examples/38-bloom/fs_bloom_combine.sc new file mode 100644 index 000000000..0fbe74fbe --- /dev/null +++ b/examples/38-bloom/fs_bloom_combine.sc @@ -0,0 +1,24 @@ +$input v_texcoord0 + +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +SAMPLER2D(s_albedo, 0); +SAMPLER2D(s_light, 1); + +void main() +{ + vec3 hdrColor = texture2D(s_albedo, v_texcoord0).rgb; + + hdrColor += texture2D(s_light, v_texcoord0).rgb; + + // instead of some fancy tonemapping operator, we just clamp it, to keep it simple. + vec3 finalColor = clamp(hdrColor, 0.0, 1.0); + + float g = 2.2; + gl_FragColor = vec4(pow(finalColor, vec3(1.0 / g, 1.0 / g, 1.0 / g) ), 1.0); +} diff --git a/examples/38-bloom/fs_downsample.sc b/examples/38-bloom/fs_downsample.sc new file mode 100644 index 000000000..8a4f40ed1 --- /dev/null +++ b/examples/38-bloom/fs_downsample.sc @@ -0,0 +1,42 @@ +$input v_texcoord0 + +/* + * Copyright 2018 Eric Arnebäck. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +SAMPLER2D(s_tex, 0); + +// pixel size of the target texture. +uniform vec4 u_pixelSize; + +void main() +{ + vec2 halfpixel = 0.5 * vec2(u_pixelSize.x, u_pixelSize.y); + vec2 oneepixel = 1.0 * vec2(u_pixelSize.x, u_pixelSize.y); + + vec2 uv = v_texcoord0.xy; + + vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); + + sum += (4.0/32.0) * texture2D(s_tex, uv).rgba; + + sum += (4.0/32.0) * texture2D(s_tex, uv + vec2(-halfpixel.x, -halfpixel.y)); + sum += (4.0/32.0) * texture2D(s_tex, uv + vec2(+halfpixel.x, +halfpixel.y)); + sum += (4.0/32.0) * texture2D(s_tex, uv + vec2(+halfpixel.x, -halfpixel.y)); + sum += (4.0/32.0) * texture2D(s_tex, uv + vec2(-halfpixel.x, +halfpixel.y) ); + + sum += (2.0/32.0) * texture2D(s_tex, uv + vec2(+oneepixel.x, 0.0)); + sum += (2.0/32.0) * texture2D(s_tex, uv + vec2(-oneepixel.x, 0.0)); + sum += (2.0/32.0) * texture2D(s_tex, uv + vec2(0.0, +oneepixel.y)); + sum += (2.0/32.0) * texture2D(s_tex, uv + vec2(0.0, -oneepixel.y)); + + sum += (1.0/32.0) * texture2D(s_tex, uv + vec2(+oneepixel.x, +oneepixel.y)); + sum += (1.0/32.0) * texture2D(s_tex, uv + vec2(-oneepixel.x, +oneepixel.y)); + sum += (1.0/32.0) * texture2D(s_tex, uv + vec2(+oneepixel.x, -oneepixel.y)); + sum += (1.0/32.0) * texture2D(s_tex, uv + vec2(-oneepixel.x, -oneepixel.y)); + + gl_FragColor.xyzw = sum; +} diff --git a/examples/38-bloom/fs_upsample.sc b/examples/38-bloom/fs_upsample.sc new file mode 100644 index 000000000..c6ad1f63c --- /dev/null +++ b/examples/38-bloom/fs_upsample.sc @@ -0,0 +1,31 @@ +$input v_texcoord0 + +#include "../common/common.sh" + +SAMPLER2D(s_tex, 0); +//SAMPLER2D(s_target_tex, 1); + +uniform vec4 u_pixelSize; +uniform vec4 u_intensity; + +void main() +{ + vec2 halfpixel = 1.0 * vec2(u_pixelSize.x, u_pixelSize.y); + vec2 uv = v_texcoord0.xy; + + vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); + + sum += (2.0 / 16.0) * texture2D(s_tex, uv + vec2(-halfpixel.x , 0.0)); + sum += (2.0 / 16.0) * texture2D(s_tex, uv + vec2(0.0, halfpixel.y)); + sum += (2.0 / 16.0) * texture2D(s_tex, uv + vec2(halfpixel.x , 0.0)); + sum += (2.0 / 16.0) * texture2D(s_tex, uv + vec2(0.0, -halfpixel.y)); + + sum += (1.0 / 16.0) * texture2D(s_tex, uv + vec2(-halfpixel.x, -halfpixel.y)); + sum += (1.0 / 16.0) * texture2D(s_tex, uv + vec2(-halfpixel.x, halfpixel.y)); + sum += (1.0 / 16.0) * texture2D(s_tex, uv + vec2(halfpixel.x, -halfpixel.y)); + sum += (1.0 / 16.0) * texture2D(s_tex, uv + vec2(halfpixel.x, halfpixel.y)); + + sum += (4.0 / 16.0) * texture2D(s_tex, uv); + + gl_FragColor.xyzw = u_intensity.x * sum; +} diff --git a/examples/38-bloom/makefile b/examples/38-bloom/makefile new file mode 100644 index 000000000..171709170 --- /dev/null +++ b/examples/38-bloom/makefile @@ -0,0 +1,10 @@ +# +# Copyright 2011-2018 Branimir Karadzic. All rights reserved. +# License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause +# + +BGFX_DIR=../.. +RUNTIME_DIR=$(BGFX_DIR)/examples/runtime +BUILD_DIR=../../.build + +include $(BGFX_DIR)/scripts/shader.mk diff --git a/examples/38-bloom/screenshot.png b/examples/38-bloom/screenshot.png new file mode 100644 index 000000000..531bbd4ba Binary files /dev/null and b/examples/38-bloom/screenshot.png differ diff --git a/examples/38-bloom/varying.def.sc b/examples/38-bloom/varying.def.sc new file mode 100644 index 000000000..4fb6fcf95 --- /dev/null +++ b/examples/38-bloom/varying.def.sc @@ -0,0 +1,13 @@ +vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); +vec3 v_wpos : TEXCOORD1 = vec3(0.0, 0.0, 0.0); +vec3 v_view : TEXCOORD2 = vec3(0.0, 0.0, 0.0); +vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0); +vec3 v_tangent : TANGENT = vec3(1.0, 0.0, 0.0); +vec3 v_bitangent : BINORMAL = vec3(0.0, 1.0, 0.0); +vec4 v_color0 : COLOR = vec4(1.0, 0.0, 0.0, 1.0); + +vec3 a_position : POSITION; +vec4 a_normal : NORMAL; +vec4 a_tangent : TANGENT; +vec2 a_texcoord0 : TEXCOORD0; +vec4 a_color0 : COLOR0; diff --git a/examples/38-bloom/vs_albedo_output.sc b/examples/38-bloom/vs_albedo_output.sc new file mode 100644 index 000000000..c9ec6ee82 --- /dev/null +++ b/examples/38-bloom/vs_albedo_output.sc @@ -0,0 +1,18 @@ +$input a_position, a_normal, a_tangent, a_texcoord0 +$output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0 + +/* + * Copyright 2018 Eric Arnebäck. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + + +#include "../common/common.sh" + +void main() +{ + vec3 wpos = mul(u_model[0], vec4(a_position, 1.0) ).xyz; + gl_Position = mul(u_viewProj, vec4(wpos, 1.0) ); + + v_texcoord0 = a_texcoord0; +} diff --git a/examples/38-bloom/vs_deferred_combine.sc b/examples/38-bloom/vs_deferred_combine.sc new file mode 100644 index 000000000..8c3b7a822 --- /dev/null +++ b/examples/38-bloom/vs_deferred_combine.sc @@ -0,0 +1,15 @@ +$input a_position, a_texcoord0 +$output v_texcoord0 + +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + v_texcoord0 = a_texcoord0; +} diff --git a/examples/38-bloom/vs_fullscreen.sc b/examples/38-bloom/vs_fullscreen.sc new file mode 100644 index 000000000..177dc6f46 --- /dev/null +++ b/examples/38-bloom/vs_fullscreen.sc @@ -0,0 +1,11 @@ +$input a_position, a_texcoord0 +$output v_texcoord0 + + +#include "../common/common.sh" + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + v_texcoord0 = a_texcoord0; +} diff --git a/examples/runtime/shaders/dx11/fs_albedo_output.bin b/examples/runtime/shaders/dx11/fs_albedo_output.bin new file mode 100644 index 000000000..d48f03cd0 Binary files /dev/null and b/examples/runtime/shaders/dx11/fs_albedo_output.bin differ diff --git a/examples/runtime/shaders/dx11/fs_bloom_combine.bin b/examples/runtime/shaders/dx11/fs_bloom_combine.bin new file mode 100644 index 000000000..86c11d50e Binary files /dev/null and b/examples/runtime/shaders/dx11/fs_bloom_combine.bin differ diff --git a/examples/runtime/shaders/dx11/fs_downsample.bin b/examples/runtime/shaders/dx11/fs_downsample.bin new file mode 100644 index 000000000..0d87efe69 Binary files /dev/null and b/examples/runtime/shaders/dx11/fs_downsample.bin differ diff --git a/examples/runtime/shaders/dx11/fs_upsample.bin b/examples/runtime/shaders/dx11/fs_upsample.bin new file mode 100644 index 000000000..f5743187c Binary files /dev/null and b/examples/runtime/shaders/dx11/fs_upsample.bin differ diff --git a/examples/runtime/shaders/dx11/vs_albedo_output.bin b/examples/runtime/shaders/dx11/vs_albedo_output.bin new file mode 100644 index 000000000..d878978bc Binary files /dev/null and b/examples/runtime/shaders/dx11/vs_albedo_output.bin differ diff --git a/examples/runtime/shaders/dx11/vs_fullscreen.bin b/examples/runtime/shaders/dx11/vs_fullscreen.bin new file mode 100644 index 000000000..8df2a6c91 Binary files /dev/null and b/examples/runtime/shaders/dx11/vs_fullscreen.bin differ diff --git a/examples/runtime/shaders/dx9/fs_albedo_output.bin b/examples/runtime/shaders/dx9/fs_albedo_output.bin new file mode 100644 index 000000000..093ae8b63 Binary files /dev/null and b/examples/runtime/shaders/dx9/fs_albedo_output.bin differ diff --git a/examples/runtime/shaders/dx9/fs_bloom_combine.bin b/examples/runtime/shaders/dx9/fs_bloom_combine.bin new file mode 100644 index 000000000..c7c151e9f Binary files /dev/null and b/examples/runtime/shaders/dx9/fs_bloom_combine.bin differ diff --git a/examples/runtime/shaders/dx9/fs_downsample.bin b/examples/runtime/shaders/dx9/fs_downsample.bin new file mode 100644 index 000000000..1191de96e Binary files /dev/null and b/examples/runtime/shaders/dx9/fs_downsample.bin differ diff --git a/examples/runtime/shaders/dx9/fs_upsample.bin b/examples/runtime/shaders/dx9/fs_upsample.bin new file mode 100644 index 000000000..933559d45 Binary files /dev/null and b/examples/runtime/shaders/dx9/fs_upsample.bin differ diff --git a/examples/runtime/shaders/dx9/vs_albedo_output.bin b/examples/runtime/shaders/dx9/vs_albedo_output.bin new file mode 100644 index 000000000..9b75228cf Binary files /dev/null and b/examples/runtime/shaders/dx9/vs_albedo_output.bin differ diff --git a/examples/runtime/shaders/dx9/vs_fullscreen.bin b/examples/runtime/shaders/dx9/vs_fullscreen.bin new file mode 100644 index 000000000..83bdf0809 Binary files /dev/null and b/examples/runtime/shaders/dx9/vs_fullscreen.bin differ diff --git a/examples/runtime/shaders/glsl/fs_albedo_output.bin b/examples/runtime/shaders/glsl/fs_albedo_output.bin new file mode 100644 index 000000000..ebe232706 Binary files /dev/null and b/examples/runtime/shaders/glsl/fs_albedo_output.bin differ diff --git a/examples/runtime/shaders/glsl/fs_bloom_combine.bin b/examples/runtime/shaders/glsl/fs_bloom_combine.bin new file mode 100644 index 000000000..23d53074d Binary files /dev/null and b/examples/runtime/shaders/glsl/fs_bloom_combine.bin differ diff --git a/examples/runtime/shaders/glsl/fs_downsample.bin b/examples/runtime/shaders/glsl/fs_downsample.bin new file mode 100644 index 000000000..055b774bd Binary files /dev/null and b/examples/runtime/shaders/glsl/fs_downsample.bin differ diff --git a/examples/runtime/shaders/glsl/fs_upsample.bin b/examples/runtime/shaders/glsl/fs_upsample.bin new file mode 100644 index 000000000..6195fc97a Binary files /dev/null and b/examples/runtime/shaders/glsl/fs_upsample.bin differ diff --git a/examples/runtime/shaders/glsl/vs_albedo_output.bin b/examples/runtime/shaders/glsl/vs_albedo_output.bin new file mode 100644 index 000000000..490de47ca Binary files /dev/null and b/examples/runtime/shaders/glsl/vs_albedo_output.bin differ diff --git a/examples/runtime/shaders/glsl/vs_fullscreen.bin b/examples/runtime/shaders/glsl/vs_fullscreen.bin new file mode 100644 index 000000000..16256a7f9 Binary files /dev/null and b/examples/runtime/shaders/glsl/vs_fullscreen.bin differ diff --git a/scripts/genie.lua b/scripts/genie.lua index 6def4f450..9098da8b6 100644 --- a/scripts/genie.lua +++ b/scripts/genie.lua @@ -447,6 +447,8 @@ or _OPTIONS["with-combined-examples"] then , "35-dynamic" , "36-sky" , "37-gpudrivenrendering" + , "38-bloom" + ) -- C99 source doesn't compile under WinRT settings