Added 19-oit example.

This commit is contained in:
Branimir Karadžić 2014-03-26 22:01:22 -07:00
parent 5b87eece6f
commit 72aa38a5fa
42 changed files with 661 additions and 0 deletions

View file

@ -212,6 +212,12 @@ Image based lighting.
![example-18-ibl](https://github.com/bkaradzic/bgfx/raw/master/examples/18-ibl/screenshot.png)
### [19-oit](https://github.com/bkaradzic/bgfx/tree/master/examples/19-oit)
Weighted, Blended Order-Independent Transparency
![example-19-oit](https://github.com/bkaradzic/bgfx/raw/master/examples/19-oit/screenshot.png)
Dependencies
------------

15
examples/19-oit/fs_oit.sc Normal file
View file

@ -0,0 +1,15 @@
$input v_pos
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
uniform vec4 u_color;
void main()
{
gl_FragColor = u_color;
}

View file

@ -0,0 +1,22 @@
$input v_pos
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
uniform vec4 u_color;
void main()
{
vec4 color = u_color;
float depth = v_pos.z/v_pos.w;
color.xyz *= color.w;
float weight = color.w * clamp(0.03 / (1e-5 + pow(depth / 200.0, 5.0) ), 0.01, 3000.0);
gl_FragData[0] = color * weight;
gl_FragData[1] = color.wwww;
}

View file

@ -0,0 +1,18 @@
$input v_texcoord0
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
SAMPLER2D(u_texColor0, 0);
SAMPLER2D(u_texColor1, 1);
void main()
{
vec4 accum = texture2D(u_texColor0, v_texcoord0);
float opacity = texture2D(u_texColor1, v_texcoord0).x;
gl_FragColor = vec4(accum.xyz / clamp(accum.w, 1e-4, 5e4), opacity);
}

View file

@ -0,0 +1,21 @@
$input v_pos
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
uniform vec4 u_color;
void main()
{
vec4 color = u_color;
float depth = v_pos.z/v_pos.w;
float weight = color.w * clamp(0.03 / (1e-5 + pow(depth / 200.0, 5.0) ), 0.01, 3000.0);
gl_FragData[0] = color * weight;
gl_FragData[1] = vec4_splat(weight);
}

View file

@ -0,0 +1,19 @@
$input v_texcoord0
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
SAMPLER2D(u_texColor0, 0);
SAMPLER2D(u_texColor1, 1);
void main()
{
vec4 accum = texture2D(u_texColor0, v_texcoord0);
float opacity = accum.w;
float weight = texture2D(u_texColor1, v_texcoord0).x;
gl_FragColor = vec4(accum.xyz / clamp(weight, 1e-4, 5e4), opacity);
}

17
examples/19-oit/makefile Normal file
View file

@ -0,0 +1,17 @@
#
# Copyright 2011-2014 Branimir Karadzic. All rights reserved.
# License: http://www.opensource.org/licenses/BSD-2-Clause
#
BGFX_DIR=../..
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
BUILD_DIR=../../.build
include $(BGFX_DIR)/premake/shader.mk
rebuild:
@make -s --no-print-directory TARGET=0 clean all
@make -s --no-print-directory TARGET=1 clean all
@make -s --no-print-directory TARGET=2 clean all
@make -s --no-print-directory TARGET=3 clean all
@make -s --no-print-directory TARGET=4 clean all

499
examples/19-oit/oit.cpp Normal file
View file

@ -0,0 +1,499 @@
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "common.h"
#include <bgfx.h>
#include <bx/timer.h>
#include "fpumath.h"
#include "imgui/imgui.h"
#include <stdio.h>
#include <string.h>
struct PosColorVertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_abgr;
static void init()
{
ms_decl.begin();
ms_decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
ms_decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
ms_decl.end();
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosColorVertex::ms_decl;
struct PosColorTexCoord0Vertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_rgba;
float m_u;
float m_v;
static void init()
{
ms_decl.begin();
ms_decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
ms_decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
ms_decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
ms_decl.end();
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosColorTexCoord0Vertex::ms_decl;
static PosColorVertex s_cubeVertices[8] =
{
{-1.0f, 1.0f, 1.0f, 0xff000000 },
{ 1.0f, 1.0f, 1.0f, 0xff0000ff },
{-1.0f, -1.0f, 1.0f, 0xff00ff00 },
{ 1.0f, -1.0f, 1.0f, 0xff00ffff },
{-1.0f, 1.0f, -1.0f, 0xffff0000 },
{ 1.0f, 1.0f, -1.0f, 0xffff00ff },
{-1.0f, -1.0f, -1.0f, 0xffffff00 },
{ 1.0f, -1.0f, -1.0f, 0xffffffff },
};
static const uint16_t s_cubeIndices[36] =
{
0, 1, 2, // 0
1, 3, 2,
4, 6, 5, // 2
5, 6, 7,
0, 2, 4, // 4
4, 2, 6,
1, 5, 3, // 6
5, 7, 3,
0, 4, 1, // 8
4, 5, 1,
2, 3, 6, // 10
6, 3, 7,
};
static const char* s_shaderPath = NULL;
static void shaderFilePath(char* _out, const char* _name)
{
strcpy(_out, s_shaderPath);
strcat(_out, _name);
strcat(_out, ".bin");
}
long int fsize(FILE* _file)
{
long int pos = ftell(_file);
fseek(_file, 0L, SEEK_END);
long int size = ftell(_file);
fseek(_file, pos, SEEK_SET);
return size;
}
static const bgfx::Memory* load(const char* _filePath)
{
FILE* file = fopen(_filePath, "rb");
if (NULL != file)
{
uint32_t size = (uint32_t)fsize(file);
const bgfx::Memory* mem = bgfx::alloc(size+1);
size_t ignore = fread(mem->data, 1, size, file);
BX_UNUSED(ignore);
fclose(file);
mem->data[mem->size-1] = '\0';
return mem;
}
return NULL;
}
static const bgfx::Memory* loadShader(const char* _name)
{
char filePath[512];
shaderFilePath(filePath, _name);
return load(filePath);
}
static bgfx::ProgramHandle loadProgram(const char* _vshName, const char* _fshName)
{
const bgfx::Memory* mem;
mem = loadShader(_vshName);
bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
mem = loadShader(_fshName);
bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem);
return bgfx::createProgram(vsh, fsh, true);
}
static float s_texelHalf = 0.0f;
static bool s_flipV = false;
void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBottomLeft = false, float _width = 1.0f, float _height = 1.0f)
{
if (bgfx::checkAvailTransientVertexBuffer(3, PosColorTexCoord0Vertex::ms_decl) )
{
bgfx::TransientVertexBuffer vb;
bgfx::allocTransientVertexBuffer(&vb, 3, PosColorTexCoord0Vertex::ms_decl);
PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb.data;
const float zz = 0.0f;
const float minx = -_width;
const float maxx = _width;
const float miny = 0.0f;
const float maxy = _height*2.0f;
const float texelHalfW = s_texelHalf/_textureWidth;
const float texelHalfH = s_texelHalf/_textureHeight;
const float minu = -1.0f + texelHalfW;
const float maxu = 1.0f + texelHalfW;
float minv = texelHalfH;
float maxv = 2.0f + texelHalfH;
if (_originBottomLeft)
{
float tmp = minv;
minv = maxv;
maxv = tmp;
minv -= 1.0f;
maxv -= 1.0f;
}
vertex[0].m_x = minx;
vertex[0].m_y = miny;
vertex[0].m_z = zz;
vertex[0].m_rgba = 0xffffffff;
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_rgba = 0xffffffff;
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_rgba = 0xffffffff;
vertex[2].m_u = maxu;
vertex[2].m_v = maxv;
bgfx::setVertexBuffer(&vb);
}
}
int _main_(int /*_argc*/, char** /*_argv*/)
{
// Create vertex stream declaration.
PosColorVertex::init();
PosColorTexCoord0Vertex::init();
uint32_t width = 1280;
uint32_t height = 720;
uint32_t debug = BGFX_DEBUG_TEXT;
uint32_t reset = BGFX_RESET_VSYNC;
bgfx::init();
bgfx::reset(width, height, reset);
// Enable debug text.
bgfx::setDebug(debug);
// Get renderer capabilities info.
const bgfx::Caps* caps = bgfx::getCaps();
// Setup root path for binary shaders. Shader binaries are different
// for each renderer.
switch (caps->rendererType)
{
default:
case bgfx::RendererType::Direct3D9:
s_shaderPath = "shaders/dx9/";
s_texelHalf = 0.5f;
break;
case bgfx::RendererType::Direct3D11:
s_shaderPath = "shaders/dx11/";
break;
case bgfx::RendererType::OpenGL:
s_shaderPath = "shaders/glsl/";
s_flipV = true;
break;
case bgfx::RendererType::OpenGLES2:
case bgfx::RendererType::OpenGLES3:
s_shaderPath = "shaders/gles/";
s_flipV = true;
break;
}
// Imgui.
FILE* file = fopen("font/droidsans.ttf", "rb");
uint32_t size = (uint32_t)fsize(file);
void* data = malloc(size);
size_t ignore = fread(data, 1, size, file);
BX_UNUSED(ignore);
fclose(file);
imguiCreate(data, size);
const bgfx::Memory* mem;
// Create static vertex buffer.
mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) );
bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, PosColorVertex::ms_decl);
// Create static index buffer.
mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) );
bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem);
// Create texture sampler uniforms.
bgfx::UniformHandle u_texColor0 = bgfx::createUniform("u_texColor0", bgfx::UniformType::Uniform1iv);
bgfx::UniformHandle u_texColor1 = bgfx::createUniform("u_texColor1", bgfx::UniformType::Uniform1iv);
bgfx::UniformHandle u_color = bgfx::createUniform("u_color", bgfx::UniformType::Uniform4fv);
bgfx::ProgramHandle blend = loadProgram("vs_oit", "fs_oit" );
bgfx::ProgramHandle wbSeparatePass = loadProgram("vs_oit", "fs_oit_wb_separate" );
bgfx::ProgramHandle wbSeparateBlit = loadProgram("vs_oit_blit", "fs_oit_wb_separate_blit" );
bgfx::ProgramHandle wbPass = loadProgram("vs_oit", "fs_oit_wb" );
bgfx::ProgramHandle wbBlit = loadProgram("vs_oit_blit", "fs_oit_wb_blit" );
bgfx::TextureHandle fbtextures[] =
{
bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::RGBA16F, BGFX_TEXTURE_RT),
bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::R16F, BGFX_TEXTURE_RT),
bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY),
};
bgfx::FrameBufferHandle fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
int64_t timeOffset = bx::getHPCounter();
uint32_t mode = 1;
int32_t scrollArea = 0;
bool frontToBack = true;
bool fadeInOut = false;
entry::MouseState mouseState;
while (!entry::processEvents(width, height, debug, reset, &mouseState) )
{
imguiBeginFrame(mouseState.m_mx
, mouseState.m_my
, (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
| (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
, 0
, width
, height
);
imguiBeginScrollArea("Settings", width - width / 4 - 10, 10, width / 4, height / 3, &scrollArea);
imguiSeparatorLine();
imguiLabel("Blend mode:");
mode = imguiChoose(mode
, "None"
, "Separate"
, "MRT Independent"
);
imguiSeparatorLine();
if (imguiCheck("Front to back", frontToBack) )
{
frontToBack ^= true;
}
if (imguiCheck("Fade in/out", fadeInOut) )
{
fadeInOut ^= true;
}
imguiEndScrollArea();
imguiEndFrame();
// Set view 0 default viewport.
bgfx::setViewRectMask(0x3, 0, 0, width, height);
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 double toMs = 1000.0/freq;
float time = (float)( (now-timeOffset)/freq);
// Use debug font to print information about this example.
bgfx::dbgTextClear();
// Reference:
// Weighted, Blended Order-Independent Transparency
// http://jcgt.org/published/0002/02/09/
// http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/19-oit");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Weighted, Blended Order Independent Transparency.");
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
float at[3] = { 0.0f, 0.0f, 0.0f };
float eye[3] = { 0.0f, 0.0f, -7.0f };
float view[16];
float proj[16];
// Set view and projection matrix for view 0.
mtxLookAt(view, eye, at);
mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
bgfx::setViewTransform(0, view, proj);
bgfx::setViewClearMask(0x3
, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
, 0x00000000
, 1.0f
, 0
);
bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
bgfx::setViewFrameBuffer(0, 0 == mode ? invalid : fbh);
// Set view and projection matrix for view 1.
mtxIdentity(view);
mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
bgfx::setViewTransform(1, view, proj);
for (uint32_t depth = 0; depth < 3; ++depth)
{
uint32_t zz = frontToBack ? 2-depth : depth;
for (uint32_t yy = 0; yy < 3; ++yy)
{
for (uint32_t xx = 0; xx < 3; ++xx)
{
float color[4] = { xx*1.0f/3.0f, zz*1.0f/3.0f, yy*1.0f/3.0f, 0.5f };
if (fadeInOut
&& zz == 1)
{
color[3] = sinf(time*3.0f)*0.49f+0.5f;
}
bgfx::setUniform(u_color, color);
BX_UNUSED(time);
float mtx[16];
mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f);
//mtxIdentity(mtx);
mtx[12] = -2.5f + float(xx)*2.5f;
mtx[13] = -2.5f + float(yy)*2.5f;
mtx[14] = -2.5f + float(zz)*2.5f; //0.0f; // sinf(time + ( (xx+1)*(yy+1)/9.0f)*float(M_PI) )*50.0f+50.0f; //90.0f - (xx+1)*(yy+1)*10.0f;
// Set transform for draw call.
bgfx::setTransform(mtx);
// Set vertex and index buffer.
bgfx::setVertexBuffer(vbh);
bgfx::setIndexBuffer(ibh);
const uint64_t state = 0
| BGFX_STATE_CULL_CW
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_MSAA
;
switch (mode)
{
case 0:
// Set vertex and fragment shaders.
bgfx::setProgram(blend);
// Set render states.
bgfx::setState(state
| BGFX_STATE_BLEND_ALPHA
);
break;
case 1:
// Set vertex and fragment shaders.
bgfx::setProgram(wbSeparatePass);
// Set render states.
bgfx::setState(state
| BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA)
);
break;
default:
// Set vertex and fragment shaders.
bgfx::setProgram(wbPass);
// Set render states.
bgfx::setState(state
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE)
| BGFX_STATE_BLEND_INDEPENDENT
, 0
| BGFX_STATE_BLEND_FUNC_RT_1(BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_SRC_COLOR)
);
break;
}
// Submit primitive for rendering to view 0.
bgfx::submit(0);
}
}
}
if (0 != mode)
{
bgfx::setTexture(0, u_texColor0, fbtextures[0]);
bgfx::setTexture(1, u_texColor1, fbtextures[1]);
bgfx::setProgram(1 == mode ? wbSeparateBlit : wbBlit);
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_SRC_ALPHA, BGFX_STATE_BLEND_SRC_ALPHA)
);
screenSpaceQuad( (float)width, (float)height, s_flipV);
bgfx::submit(1);
}
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
}
// Cleanup.
bgfx::destroyFrameBuffer(fbh);
bgfx::destroyIndexBuffer(ibh);
bgfx::destroyVertexBuffer(vbh);
bgfx::destroyProgram(blend);
bgfx::destroyProgram(wbSeparatePass);
bgfx::destroyProgram(wbSeparateBlit);
bgfx::destroyProgram(wbPass);
bgfx::destroyProgram(wbBlit);
bgfx::destroyUniform(u_texColor0);
bgfx::destroyUniform(u_texColor1);
bgfx::destroyUniform(u_color);
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -0,0 +1,5 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec4 v_pos : TEXCOORD4 = vec4(0.0, 0.0, 0.0, 0.0);
vec3 a_position : POSITION;
vec2 a_texcoord0 : TEXCOORD0;

18
examples/19-oit/vs_oit.sc Normal file
View file

@ -0,0 +1,18 @@
$input a_position
$output v_pos
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/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_pos = gl_Position;
vec4 temp = mul(u_view, vec4(wpos, 1.0) );
v_pos.x = temp.z;
}

View file

@ -0,0 +1,15 @@
$input a_position, a_texcoord0
$output v_texcoord0
/*
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/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

@ -66,6 +66,9 @@ static void imguiFree(void* _ptr, void* /*_userptr*/)
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype/stb_truetype.h>
namespace
{
struct PosColorVertex
{
float m_x;
@ -107,6 +110,8 @@ struct PosColorUvVertex
bgfx::VertexDecl PosColorUvVertex::ms_decl;
} // namespace
struct Imgui
{
Imgui()

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.

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

@ -170,6 +170,7 @@ exampleProject("15-shadowmaps-simple", "a10f22ab-e0ee-471a-b2b6-2f6cb1c63fdc")
exampleProject("16-shadowmaps", "f9a91cb0-7b1b-11e3-981f-0800200c9a66")
exampleProject("17-drawstress", "9aeea4c6-80dc-11e3-b3ca-4da6db0f677b")
exampleProject("18-ibl", "711bcbb0-9531-11e3-a5e2-0800200c9a66")
exampleProject("19-oit", "d7eca4fc-96d7-11e3-a73b-fcafdb0f677b")
dofile "makedisttex.lua"
dofile "shaderc.lua"