Bloom Example (#1491)

* add bloom demo

* remove modification to readme

* add references for the bloom implementation
This commit is contained in:
Eric Arnebäck 2018-09-19 21:24:52 +02:00 committed by Branimir Karadžić
parent 9eaa42adc8
commit ab1080ae94
30 changed files with 830 additions and 0 deletions

642
examples/38-bloom/bloom.cpp Normal file
View File

@ -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 <math.h>
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.");

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -447,6 +447,8 @@ or _OPTIONS["with-combined-examples"] then
, "35-dynamic" , "35-dynamic"
, "36-sky" , "36-sky"
, "37-gpudrivenrendering" , "37-gpudrivenrendering"
, "38-bloom"
) )
-- C99 source doesn't compile under WinRT settings -- C99 source doesn't compile under WinRT settings