Added more examples.

This commit is contained in:
bkaradzic
2012-10-07 20:41:18 -07:00
parent f1597ee25c
commit cfac3feb85
2357 changed files with 389777 additions and 116988 deletions

View File

@@ -0,0 +1,131 @@
$input v_color0, v_texcoord0
/*
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
// References:
// Sphere tracing: a geometric method for the antialiased ray tracing of implicit surfaces - John C. Hart
// http://web.archive.org/web/20110331200546/http://graphics.cs.uiuc.edu/~jch/papers/zeno.pdf
//
// Modeling with distance functions
// http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
#include "../common/common.sh"
#include "iq_sdf.sh"
uniform float u_time;
uniform mat4 u_mtx;
uniform vec3 u_lightDir;
float sceneDist(vec3 _pos)
{
float d1 = udRoundBox(_pos, vec3(2.5, 2.5, 2.5), 0.5);
float d2 = sdSphere(_pos + vec3( 4.0, 0.0, 0.0), 1.0);
float d3 = sdSphere(_pos + vec3(-4.0, 0.0, 0.0), 1.0);
float d4 = sdSphere(_pos + vec3( 0.0, 4.0, 0.0), 1.0);
float d5 = sdSphere(_pos + vec3( 0.0,-4.0, 0.0), 1.0);
float d6 = sdSphere(_pos + vec3( 0.0, 0.0, 4.0), 1.0);
float d7 = sdSphere(_pos + vec3( 0.0, 0.0,-4.0), 1.0);
float dist = min(min(min(min(min(min(d1, d2), d3), d4), d5), d6), d7);
return dist;
}
vec3 calcNormal(vec3 _pos)
{
const vec2 delta = vec2(0.002, 0.0);
float nx = sceneDist(_pos + delta.xyy) - sceneDist(_pos - delta.xyy);
float ny = sceneDist(_pos + delta.yxy) - sceneDist(_pos - delta.yxy);
float nz = sceneDist(_pos + delta.yyx) - sceneDist(_pos - delta.yyx);
return normalize(vec3(nx, ny, nz) );
}
float calcAmbOcc(vec3 _pos, vec3 _normal)
{
float occ = 0.0;
float aostep = 0.2;
for (int ii = 1; ii < 4; ii++)
{
float fi = float(ii);
float dist = sceneDist(_pos + _normal * fi * aostep);
occ += (fi * aostep - dist) / pow(2.0, fi);
}
return 1.0 - occ;
}
float trace(vec3 _ray, vec3 _dir, float _maxd)
{
float tt = 0.0;
float epsilon = 0.001;
for (int ii = 0; ii < 64; ii++)
{
float dist = sceneDist(_ray + _dir*tt);
if (dist > epsilon)
{
tt += dist;
}
}
return tt < _maxd ? tt : 0.0;
}
vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir)
{
float ndotl = dot(_normal, _lightDir);
vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal);
float rdotv = dot(reflected, _viewDir);
return vec2(ndotl, rdotv);
}
float fresnel(float _ndotl, float _bias, float _pow)
{
float facing = (1.0 - _ndotl);
return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0);
}
vec4 lit(float _ndotl, float _rdotv, float _m)
{
float diff = max(0.0, _ndotl);
float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m);
return vec4(1.0, diff, spec, 1.0);
}
void main()
{
vec4 tmp;
tmp = mul(u_mtx, vec4(v_texcoord0.x, v_texcoord0.y, 0.0, 1.0) );
vec3 eye = tmp.xyz/tmp.w;
tmp = mul(u_mtx, vec4(v_texcoord0.x, v_texcoord0.y, 1.0, 1.0) );
vec3 at = tmp.xyz/tmp.w;
float maxd = length(at - eye);
vec3 dir = normalize(at - eye);
float dist = trace(eye, dir, maxd);
if (dist > 0.5)
{
vec3 pos = eye + dir*dist;
vec3 normal = calcNormal(pos);
vec2 bln = blinn(u_lightDir, normal, dir);
vec4 lc = lit(bln.x, bln.y, 1.0);
float fres = fresnel(bln.x, 0.2, 5.0);
float val = 0.9*lc.y + pow(lc.z, 128.0)*fres;
val *= calcAmbOcc(pos, normal);
val = pow(val, 1.0/2.2);
gl_FragColor = vec4(val, val, val, 1.0);
gl_FragDepth = dist/maxd;
}
else
{
gl_FragColor = v_color0;
gl_FragDepth = 1.0;
}
}

View File

@@ -0,0 +1,82 @@
//
// References:
// Modeling with distance functions
// http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
//
// primitives
float sdSphere(vec3 _pos, float _radius)
{
return length(_pos) - _radius;
}
float udBox(vec3 _pos, vec3 _extents)
{
return length(max(abs(_pos) - _extents, 0.0) );
}
float udRoundBox(vec3 _pos, vec3 _extents, float r)
{
return length(max(abs(_pos) - _extents, 0.0) ) - r;
}
float sdBox(vec3 _pos, vec3 _extents)
{
vec3 d = abs(_pos) - _extents;
return min(max(d.x, max(d.y, d.z) ), 0.0) +
length(max(d, 0.0) );
}
float sdTorus(vec3 _pos, vec2 t)
{
vec2 q = vec2(length(_pos.xz) - t.x, _pos.y);
return length(q) - t.y;
}
float sdCylinder(vec3 _pos, vec3 c)
{
return length(_pos.xz - c.xy) - c.z;
}
float sdCone(vec3 _pos, vec2 c)
{
// c must be normalized
float q = length(_pos.xy);
return dot(c, vec2(q, _pos.z) );
}
float sdPlane(vec3 _pos, vec4 n)
{
// n must be normalized
return dot(_pos, n.xyz) + n.w;
}
float sdHexPrism(vec3 _pos, vec2 h)
{
vec3 q = abs(_pos);
return max(q.z - h.y, max(q.x + q.y * 0.57735, q.y * 1.1547) - h.x);
}
float sdTriPrism(vec3 _pos, vec2 h)
{
vec3 q = abs(_pos);
return max(q.z - h.y, max(q.x * 0.866025 + _pos.y * 0.5, -_pos.y) - h.x * 0.5);
}
// domain operations
float opUnion(float d1, float d2)
{
return min(d1, d2);
}
float opSubtract(float d1, float d2)
{
return max(-d1, d2);
}
float opIntersect(float d1, float d2)
{
return max(d1, d2);
}

View File

@@ -0,0 +1,9 @@
#
# Copyright 2011-2012 Branimir Karadzic. All rights reserved.
# License: http://www.opensource.org/licenses/BSD-2-Clause
#
BGFX_DIR=../..
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
include $(BGFX_DIR)/premake/shader.mk

View File

@@ -0,0 +1,323 @@
/*
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include <bgfx.h>
#include <bx/bx.h>
#include <bx/timer.h>
#include "../common/dbg.h"
#include "../common/math.h"
#include <stdio.h>
#include <string.h>
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
{
DBG("%x: %s", _code, _str);
}
struct PosColorTexCoord0Vertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_abgr;
float m_u;
float m_v;
};
static bgfx::VertexDecl s_PosColorTexCoord0Decl;
static const char* s_shaderPath = NULL;
static bool s_flipV = false;
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);
fread(mem->data, 1, size, file);
fclose(file);
mem->data[mem->size-1] = '\0';
return mem;
}
return NULL;
}
static const bgfx::Memory* loadShader(const char* _name, const char* _default = NULL)
{
char filePath[512];
shaderFilePath(filePath, _name);
BX_UNUSED(_default);
return load(filePath);
}
static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
{
const bgfx::Memory* mem;
// Load vertex shader.
mem = loadShader(_vsName);
bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
// Load fragment shader.
mem = loadShader(_fsName);
bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem);
// Create program from shaders.
bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh);
// We can destroy vertex and fragment shader here since
// their reference is kept inside bgfx after calling createProgram.
// Vertex and fragment shader will be destroyed once program is
// destroyed.
bgfx::destroyVertexShader(vsh);
bgfx::destroyFragmentShader(fsh);
return program;
}
bool allocTransientBuffers(const bgfx::TransientVertexBuffer*& _vb, const bgfx::VertexDecl& _decl, uint16_t _numVertices, const bgfx::TransientIndexBuffer*& _ib, uint16_t _numIndices)
{
if (bgfx::checkAvailTransientVertexBuffer(_numVertices, _decl)
&& bgfx::checkAvailTransientIndexBuffer(_numIndices) )
{
_vb = bgfx::allocTransientVertexBuffer(_numVertices, _decl);
_ib = bgfx::allocTransientIndexBuffer(_numIndices);
return true;
}
return false;
}
void renderScreenSpaceQuad(uint32_t _view, bgfx::ProgramHandle _program, float _x, float _y, float _width, float _height)
{
const bgfx::TransientVertexBuffer* vb;
const bgfx::TransientIndexBuffer* ib;
if (allocTransientBuffers(vb, s_PosColorTexCoord0Decl, 4, ib, 6) )
{
PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb->data;
float zz = 0.0f;
const float minx = _x;
const float maxx = _x + _width;
const float miny = _y;
const float maxy = _y + _height;
float minu = -1.0f;
float minv = -1.0f;
float maxu = 1.0f;
float maxv = 1.0f;
vertex[0].m_x = minx;
vertex[0].m_y = miny;
vertex[0].m_z = zz;
vertex[0].m_abgr = 0xff0000ff;
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_abgr = 0xff00ff00;
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_abgr = 0xffff0000;
vertex[2].m_u = maxu;
vertex[2].m_v = maxv;
vertex[3].m_x = minx;
vertex[3].m_y = maxy;
vertex[3].m_z = zz;
vertex[3].m_abgr = 0xffffffff;
vertex[3].m_u = minu;
vertex[3].m_v = maxv;
uint16_t* indices = (uint16_t*)ib->data;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 0;
indices[4] = 2;
indices[5] = 3;
bgfx::setProgram(_program);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_DEPTH_TEST_LESS|BGFX_STATE_DEPTH_WRITE);
bgfx::setIndexBuffer(ib);
bgfx::setVertexBuffer(vb);
bgfx::submit(_view);
}
}
int _main_(int _argc, char** _argv)
{
bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
bgfx::reset(1280, 720);
// Enable debug text.
bgfx::setDebug(BGFX_DEBUG_TEXT);
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, 1280, 720);
// Set view 1 default viewport.
bgfx::setViewRect(1, 0, 0, 1280, 720);
// Set view 0 clear state.
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
, 0x303030ff
, 1.0f
, 0
);
// Setup root path for binary shaders. Shader binaries are different
// for each renderer.
switch (bgfx::getRendererType() )
{
case bgfx::RendererType::Null:
case bgfx::RendererType::Direct3D9:
s_shaderPath = "shaders/dx9/";
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:
s_shaderPath = "shaders/gles/";
s_flipV = true;
break;
}
// Create vertex stream declaration.
s_PosColorTexCoord0Decl.begin();
s_PosColorTexCoord0Decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
s_PosColorTexCoord0Decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
s_PosColorTexCoord0Decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
s_PosColorTexCoord0Decl.end();
bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::ConstantType::Uniform1f);
bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::ConstantType::Uniform4x4fv);
bgfx::UniformHandle u_lightDir = bgfx::createUniform("u_lightDir", bgfx::ConstantType::Uniform3fv);
bgfx::ProgramHandle raymarching = loadProgram("vs_raymarching", "fs_raymarching");
while (true)
{
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to viewZ 0.
bgfx::submit(0);
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;
// Use debug font to print information about this example.
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/03-raymarch");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating uniforms.");
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, -15.0f };
float view[16];
float proj[16];
mtxLookAt(view, eye, at);
mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f);
// Set view and projection matrix for view 1.
bgfx::setViewTransform(0, view, proj);
float ortho[16];
mtxOrtho(ortho, 0.0f, 1280.0f, 720.0f, 0.0f, 0.0f, 100.0f);
// Set view and projection matrix for view 0.
bgfx::setViewTransform(1, NULL, ortho);
float time = (float)(bx::getHPCounter()/double(bx::getHPFrequency() ) );
float vp[16];
mtxMul(vp, view, proj);
float mtx[16];
mtxRotateXY(mtx
, time
, time*0.37f
);
{
float mtxInv[16];
mtxInverse(mtxInv, mtx);
float lightDirModel[4] = { -0.4f, -0.5f, -1.0f, 0.0f };
float lightDirModelN[4];
vec3Norm(lightDirModelN, lightDirModel);
float lightDir[4];
vec4MulMtx(lightDir, lightDirModelN, mtxInv);
bgfx::setUniform(u_lightDir, lightDir);
}
float mvp[16];
mtxMul(mvp, mtx, vp);
float invMvp[16];
mtxInverse(invMvp, mvp);
bgfx::setUniform(u_mtx, invMvp);
bgfx::setUniform(u_time, &time);
renderScreenSpaceQuad(1, raymarching, 0.0f, 0.0f, 1280.0f, 720.0f);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
}
// Cleanup.
bgfx::destroyProgram(raymarching);
bgfx::destroyUniform(u_time);
bgfx::destroyUniform(u_mtx);
bgfx::destroyUniform(u_lightDir);
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}

View File

@@ -0,0 +1,6 @@
vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 a_position : POSITION;
vec4 a_color : COLOR0;
vec2 a_texcoord0 : TEXCOORD0;

View File

@@ -0,0 +1,16 @@
$input a_position, a_color, a_texcoord0
$output v_color0, v_texcoord0
/*
* Copyright 2011-2012 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_color0 = a_color;
v_texcoord0 = a_texcoord0;
}