Merge pull request #46 from dariomanesku/master

Fixed lightning problem in the second scene.
This commit is contained in:
Branimir Karadžić 2013-10-20 12:33:44 -07:00
commit c3e70a5909
3 changed files with 240 additions and 133 deletions

View file

@ -6,18 +6,21 @@ $input v_normal, v_view
*/ */
#include "../common/common.sh" #include "../common/common.sh"
#define MAX_NUM_LIGHTS 5
uniform vec4 u_params; uniform vec4 u_params;
uniform vec3 u_ambient; uniform vec3 u_ambient;
uniform vec3 u_diffuse; uniform vec3 u_diffuse;
uniform vec4 u_color; uniform vec4 u_color;
uniform vec4 u_specular_shininess; uniform vec4 u_specular_shininess;
uniform vec4 u_lightPosRadius[5]; uniform vec4 u_lightPosRadius[MAX_NUM_LIGHTS];
uniform vec4 u_lightRgbInnerR[5]; uniform vec4 u_lightRgbInnerR[MAX_NUM_LIGHTS];
#define u_ambientPass u_params.x #define u_ambientPass u_params.x
#define u_lightningPass u_params.y #define u_lightningPass u_params.y
#define u_alpha u_params.z #define u_lightCount u_params.z
#define u_lightCount u_params.w #define u_lightIndex u_params.w
#define u_specular u_specular_shininess.xyz #define u_specular u_specular_shininess.xyz
#define u_shininess u_specular_shininess.w #define u_shininess u_specular_shininess.w
@ -38,9 +41,6 @@ vec4 lit(float _ndotl, float _rdotv, float _m)
vec3 calcLight(int _idx, vec3 _view, vec3 _normal, vec3 _viewDir) vec3 calcLight(int _idx, vec3 _view, vec3 _normal, vec3 _viewDir)
{ {
if (float(_idx) >= u_lightCount)
return vec3_splat(0.0);
vec3 lightPos = mul(u_view, vec4(u_lightPosRadius[_idx].xyz, 1.0)).xyz; vec3 lightPos = mul(u_view, vec4(u_lightPosRadius[_idx].xyz, 1.0)).xyz;
vec3 toLight = lightPos - _view; vec3 toLight = lightPos - _view;
vec3 lightDir = normalize(toLight); vec3 lightDir = normalize(toLight);
@ -49,7 +49,7 @@ vec3 calcLight(int _idx, vec3 _view, vec3 _normal, vec3 _viewDir)
vec4 lc = lit(bln.x, bln.y, u_shininess); vec4 lc = lit(bln.x, bln.y, u_shininess);
float dist = max(length(toLight), u_lightPosRadius[_idx].w); float dist = max(length(toLight), u_lightPosRadius[_idx].w);
float attn = 100.0 * pow(dist, -2.0); float attn = 150.0 * pow(dist, -2.0);
vec3 rgb = (lc.y * u_diffuse + lc.z * u_specular) * u_lightRgbInnerR[_idx].rgb * attn; vec3 rgb = (lc.y * u_diffuse + lc.z * u_specular) * u_lightRgbInnerR[_idx].rgb * attn;
return rgb; return rgb;
@ -63,9 +63,18 @@ void main()
vec3 ambientColor = u_ambient * u_ambientPass; vec3 ambientColor = u_ambient * u_ambientPass;
vec3 lightColor = vec3_splat(0.0); vec3 lightColor = vec3_splat(0.0);
for(int ii = 0; ii < 5; ++ii) for(int ii = 0; ii < MAX_NUM_LIGHTS; ++ii)
{ {
lightColor += calcLight(ii, v_view, normal, viewDir); float condition = 0.0;
if (u_lightCount > 1.0)
{
condition = 1.0 - step(u_lightCount, float(ii));
}
else
{
condition = float(float(ii) == u_lightIndex);
}
lightColor += calcLight(ii, v_view, normal, viewDir) * condition;
} }
lightColor *= u_lightningPass; lightColor *= u_lightningPass;
@ -75,5 +84,5 @@ void main()
vec3 diffuse = toGamma(lightColor * color); vec3 diffuse = toGamma(lightColor * color);
gl_FragColor.xyz = clamp(ambient + diffuse, 0.0, 1.0); gl_FragColor.xyz = clamp(ambient + diffuse, 0.0, 1.0);
gl_FragColor.w = u_alpha; gl_FragColor.w = 1.0;
} }

View file

@ -6,19 +6,22 @@ $input v_normal, v_view, v_texcoord0
*/ */
#include "../common/common.sh" #include "../common/common.sh"
#define MAX_NUM_LIGHTS 5
uniform vec4 u_params; uniform vec4 u_params;
uniform vec3 u_ambient; uniform vec3 u_ambient;
uniform vec3 u_diffuse; uniform vec3 u_diffuse;
uniform vec4 u_color; uniform vec4 u_color;
uniform vec4 u_specular_shininess; uniform vec4 u_specular_shininess;
uniform vec4 u_lightPosRadius[5]; uniform vec4 u_lightPosRadius[MAX_NUM_LIGHTS];
uniform vec4 u_lightRgbInnerR[5]; uniform vec4 u_lightRgbInnerR[MAX_NUM_LIGHTS];
SAMPLER2D(u_texColor, 0); SAMPLER2D(u_texColor, 0);
#define u_ambientPass u_params.x #define u_ambientPass u_params.x
#define u_lightningPass u_params.y #define u_lightningPass u_params.y
#define u_alpha u_params.z #define u_lightCount u_params.z
#define u_lightCount u_params.w #define u_lightIndex u_params.w
#define u_specular u_specular_shininess.xyz #define u_specular u_specular_shininess.xyz
#define u_shininess u_specular_shininess.w #define u_shininess u_specular_shininess.w
@ -39,9 +42,6 @@ vec4 lit(float _ndotl, float _rdotv, float _m)
vec3 calcLight(int _idx, vec3 _view, vec3 _normal, vec3 _viewDir) vec3 calcLight(int _idx, vec3 _view, vec3 _normal, vec3 _viewDir)
{ {
if (float(_idx) >= u_lightCount)
return vec3_splat(0.0);
vec3 lightPos = mul(u_view, vec4(u_lightPosRadius[_idx].xyz, 1.0)).xyz; vec3 lightPos = mul(u_view, vec4(u_lightPosRadius[_idx].xyz, 1.0)).xyz;
vec3 toLight = lightPos - _view; vec3 toLight = lightPos - _view;
vec3 lightDir = normalize(toLight); vec3 lightDir = normalize(toLight);
@ -50,7 +50,7 @@ vec3 calcLight(int _idx, vec3 _view, vec3 _normal, vec3 _viewDir)
vec4 lc = lit(bln.x, bln.y, u_shininess); vec4 lc = lit(bln.x, bln.y, u_shininess);
float dist = max(length(toLight), u_lightPosRadius[_idx].w); float dist = max(length(toLight), u_lightPosRadius[_idx].w);
float attn = 100.0 * pow(dist, -2.0); float attn = 150.0 * pow(dist, -2.0);
vec3 rgb = (lc.y * u_diffuse + lc.z * u_specular) * u_lightRgbInnerR[_idx].rgb * attn; vec3 rgb = (lc.y * u_diffuse + lc.z * u_specular) * u_lightRgbInnerR[_idx].rgb * attn;
return rgb; return rgb;
@ -64,9 +64,18 @@ void main()
vec3 ambientColor = u_ambient * u_ambientPass; vec3 ambientColor = u_ambient * u_ambientPass;
vec3 lightColor = vec3_splat(0.0); vec3 lightColor = vec3_splat(0.0);
for(int ii = 0; ii < 5; ++ii) for(int ii = 0; ii < MAX_NUM_LIGHTS; ++ii)
{ {
lightColor += calcLight(ii, v_view, normal, viewDir); float condition = 0.0;
if (u_lightCount > 1.0)
{
condition = 1.0 - step(u_lightCount, float(ii));
}
else
{
condition = float(float(ii) == u_lightIndex);
}
lightColor += calcLight(ii, v_view, normal, viewDir) * condition;
} }
lightColor *= u_lightningPass; lightColor *= u_lightningPass;
@ -76,5 +85,5 @@ void main()
vec3 diffuse = toGamma(lightColor * color); vec3 diffuse = toGamma(lightColor * color);
gl_FragColor.xyz = clamp(ambient + diffuse, 0.0, 1.0); gl_FragColor.xyz = clamp(ambient + diffuse, 0.0, 1.0);
gl_FragColor.w = u_alpha; gl_FragColor.w = 1.0;
} }

View file

@ -22,7 +22,9 @@
#define RENDER_VIEWID_RANGE1_PASS_4 5 #define RENDER_VIEWID_RANGE1_PASS_4 5
#define RENDER_VIEWID_RANGE1_PASS_5 6 #define RENDER_VIEWID_RANGE1_PASS_5 6
#define RENDER_VIEWID_RANGE5_PASS_6 7 #define RENDER_VIEWID_RANGE5_PASS_6 7
#define RENDER_VIEWID_RANGE1_PASS_7 13 #define RENDER_VIEWID_RANGE1_PASS_7 13
#define MAX_NUM_LIGHTS 5
uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w) uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
{ {
@ -324,6 +326,142 @@ void mtxBillboard(float* __restrict _result
_result[15] = 1.0f; _result[15] = 1.0f;
} }
struct Uniforms
{
void init()
{
m_params.m_ambientPass = 1.0f;
m_params.m_lightningPass = 1.0f;
m_params.m_lightCount = 4.0f;
m_params.m_lightIndex = 4.0f;
m_ambient[0] = 0.05f;
m_ambient[1] = 0.05f;
m_ambient[2] = 0.05f;
m_ambient[3] = 0.0f; //unused
m_diffuse[0] = 0.8f;
m_diffuse[1] = 0.8f;
m_diffuse[2] = 0.8f;
m_diffuse[3] = 0.0f; //unused
m_specular_shininess[0] = 1.0f;
m_specular_shininess[1] = 1.0f;
m_specular_shininess[2] = 1.0f;
m_specular_shininess[3] = 25.0f; //shininess
m_color[0] = 1.0f;
m_color[1] = 1.0f;
m_color[2] = 1.0f;
m_color[3] = 1.0;
m_time = 0.0f;
for (uint8_t ii = 0; ii < MAX_NUM_LIGHTS; ++ii)
{
m_lightPosRadius[ii][0] = 0.0f;
m_lightPosRadius[ii][1] = 0.0f;
m_lightPosRadius[ii][2] = 0.0f;
m_lightPosRadius[ii][3] = 1.0f;
m_lightRgbInnerR[ii][0] = 1.0f;
m_lightRgbInnerR[ii][1] = 1.0f;
m_lightRgbInnerR[ii][2] = 1.0f;
m_lightRgbInnerR[ii][3] = 1.0f;
}
u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
u_ambient = bgfx::createUniform("u_ambient", bgfx::UniformType::Uniform4fv);
u_diffuse = bgfx::createUniform("u_diffuse", bgfx::UniformType::Uniform4fv);
u_specular_shininess = bgfx::createUniform("u_specular_shininess", bgfx::UniformType::Uniform4fv);
u_color = bgfx::createUniform("u_color", bgfx::UniformType::Uniform4fv);
u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f );
u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv, MAX_NUM_LIGHTS);
u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, MAX_NUM_LIGHTS);
}
//call this once at initialization
void submitConstUniforms()
{
bgfx::setUniform(u_ambient, &m_ambient);
bgfx::setUniform(u_diffuse, &m_diffuse);
bgfx::setUniform(u_specular_shininess, &m_specular_shininess);
}
//call this once per frame
void submitPerFrameUniforms()
{
bgfx::setUniform(u_time, &m_time);
}
//call this before each draw call
void submitPerDrawUniforms()
{
bgfx::setUniform(u_params, &m_params);
bgfx::setUniform(u_color, &m_color);
bgfx::setUniform(u_lightPosRadius, &m_lightPosRadius, MAX_NUM_LIGHTS);
bgfx::setUniform(u_lightRgbInnerR, &m_lightRgbInnerR, MAX_NUM_LIGHTS);
}
void destroy()
{
bgfx::destroyUniform(u_params);
bgfx::destroyUniform(u_ambient);
bgfx::destroyUniform(u_diffuse);
bgfx::destroyUniform(u_specular_shininess);
bgfx::destroyUniform(u_time);
bgfx::destroyUniform(u_lightPosRadius);
bgfx::destroyUniform(u_lightRgbInnerR);
}
struct Params
{
float m_ambientPass;
float m_lightningPass;
float m_lightCount;
float m_lightIndex;
};
struct SvParams
{
float m_useStencilTex;
float m_dfail;
float m_unused0;
float m_unused1;
};
Params m_params;
SvParams m_svparams;
float m_ambient[4];
float m_diffuse[4];
float m_specular_shininess[4];
float m_color[4];
float m_time;
float m_lightPosRadius[MAX_NUM_LIGHTS][4];
float m_lightRgbInnerR[MAX_NUM_LIGHTS][4];
/**
* u_params.x - u_ambientPass
* u_params.y - u_lightningPass
* u_params.z - u_lightCount
* u_params.w - u_lightIndex
*/
bgfx::UniformHandle u_params;
bgfx::UniformHandle u_ambient;
bgfx::UniformHandle u_diffuse;
bgfx::UniformHandle u_specular_shininess;
bgfx::UniformHandle u_color;
bgfx::UniformHandle u_time;
bgfx::UniformHandle u_lightPosRadius;
bgfx::UniformHandle u_lightRgbInnerR;
};
static Uniforms s_uniforms;
//-------------------------------------------------
// Render state
//-------------------------------------------------
struct RenderState struct RenderState
{ {
enum Enum enum Enum
@ -435,8 +573,7 @@ static RenderState s_renderStates[RenderState::Count] =
}, },
{ // ProjectionShadows_DrawDiffuse { // ProjectionShadows_DrawDiffuse
BGFX_STATE_RGB_WRITE BGFX_STATE_RGB_WRITE
| BGFX_STATE_DEPTH_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE)
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_ONE)
| BGFX_STATE_DEPTH_TEST_EQUAL | BGFX_STATE_DEPTH_TEST_EQUAL
| BGFX_STATE_CULL_CCW | BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA | BGFX_STATE_MSAA
@ -754,6 +891,9 @@ struct Mesh
{ {
const Group& group = *it; const Group& group = *it;
// Set uniforms
s_uniforms.submitPerDrawUniforms();
// Set model matrix for rendering. // Set model matrix for rendering.
bgfx::setTransform(_mtx); bgfx::setTransform(_mtx);
bgfx::setProgram(_program); bgfx::setProgram(_program);
@ -834,30 +974,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
PosNormalTexcoordDecl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float); PosNormalTexcoordDecl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
PosNormalTexcoordDecl.end(); PosNormalTexcoordDecl.end();
const uint8_t MAX_NUM_LIGHTS = 5; s_uniforms.init();
s_uniforms.submitConstUniforms();
//u_params.x - u_ambientPass u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv);
//u_params.y - u_lightningPass
//u_params.z - u_alpha
//u_params.w - u_lightCount
struct UniformParams
{
float m_ambientPass;
float m_lightningPass;
float m_alpha;
float m_lightCount;
} params;
u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv);
bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
bgfx::UniformHandle u_ambient = bgfx::createUniform("u_ambient", bgfx::UniformType::Uniform3fv);
bgfx::UniformHandle u_diffuse = bgfx::createUniform("u_diffuse", bgfx::UniformType::Uniform3fv);
bgfx::UniformHandle u_specular = bgfx::createUniform("u_specular_shininess", bgfx::UniformType::Uniform4fv);
bgfx::UniformHandle u_color = bgfx::createUniform("u_color", bgfx::UniformType::Uniform4fv);
bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f );
bgfx::UniformHandle u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv, MAX_NUM_LIGHTS);
bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, MAX_NUM_LIGHTS);
bgfx::ProgramHandle programTextureLightning = loadProgram("vs_stencil_texture_lightning", "fs_stencil_texture_lightning"); bgfx::ProgramHandle programTextureLightning = loadProgram("vs_stencil_texture_lightning", "fs_stencil_texture_lightning");
bgfx::ProgramHandle programColorLightning = loadProgram("vs_stencil_color_lightning", "fs_stencil_color_lightning" ); bgfx::ProgramHandle programColorLightning = loadProgram("vs_stencil_color_lightning", "fs_stencil_color_lightning" );
@ -887,9 +1007,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
mem = loadTexture("fieldstone-rgba.dds"); mem = loadTexture("fieldstone-rgba.dds");
bgfx::TextureHandle fieldstoneTex = bgfx::createTexture(mem); bgfx::TextureHandle fieldstoneTex = bgfx::createTexture(mem);
//setup lights // Setup lights.
uint8_t numLights = 5; const uint8_t colorCount = 5;
const float rgbInnerR[5][4] = const float rgbInnerR[colorCount][4] =
{ {
{ 1.0f, 0.7f, 0.2f, 0.0f }, //yellow { 1.0f, 0.7f, 0.2f, 0.0f }, //yellow
{ 0.7f, 0.2f, 1.0f, 0.0f }, //purple { 0.7f, 0.2f, 1.0f, 0.0f }, //purple
@ -899,32 +1019,15 @@ int _main_(int /*_argc*/, char** /*_argv*/)
}; };
float lightRgbInnerR[MAX_NUM_LIGHTS][4]; float lightRgbInnerR[MAX_NUM_LIGHTS][4];
for (uint8_t ii = 0, jj = 0; ii < numLights; ++ii, ++jj) for (uint8_t ii = 0, jj = 0; ii < MAX_NUM_LIGHTS; ++ii, ++jj)
{ {
const uint8_t index = jj%numLights; const uint8_t index = jj%colorCount;
lightRgbInnerR[ii][0] = rgbInnerR[index][0]; lightRgbInnerR[ii][0] = rgbInnerR[index][0];
lightRgbInnerR[ii][1] = rgbInnerR[index][1]; lightRgbInnerR[ii][1] = rgbInnerR[index][1];
lightRgbInnerR[ii][2] = rgbInnerR[index][2]; lightRgbInnerR[ii][2] = rgbInnerR[index][2];
lightRgbInnerR[ii][3] = rgbInnerR[index][3]; lightRgbInnerR[ii][3] = rgbInnerR[index][3];
} }
bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR, numLights); memcpy(s_uniforms.m_lightRgbInnerR, lightRgbInnerR, MAX_NUM_LIGHTS * 4*sizeof(float));
//init uniforms
params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f;
params.m_lightCount = 4.0f;
params.m_alpha = 1.0f;
bgfx::setUniform(u_params, (const void*)&params);
float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
bgfx::setUniform(u_color, color);
float ambient[3] = { 0.02f, 0.02f, 0.02f };
float diffuse[3] = { 0.8f, 0.8f, 0.8f };
float specular[4] = { 1.0f, 1.0f, 1.0f, 5.0f };
bgfx::setUniform(u_ambient, ambient);
bgfx::setUniform(u_diffuse, diffuse);
bgfx::setUniform(u_specular, specular);
int64_t timeOffset = bx::getHPCounter(); int64_t timeOffset = bx::getHPCounter();
@ -974,7 +1077,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
} }
imguiSeparatorLine(); imguiSeparatorLine();
imguiSlider("Lights", &settings_numLights, 1.0f, 5.0f, 1.0f); imguiSlider("Lights", &settings_numLights, 1.0f, float(MAX_NUM_LIGHTS), 1.0f);
if (scene == StencilReflectionScene) if (scene == StencilReflectionScene)
{ {
imguiSlider("Reflection value", &settings_reflectionValue, 0.0f, 1.0f, 0.01f); imguiSlider("Reflection value", &settings_reflectionValue, 0.0f, 1.0f, 0.01f);
@ -994,11 +1097,12 @@ int _main_(int /*_argc*/, char** /*_argv*/)
imguiEndFrame(); imguiEndFrame();
// Update settings. // Update settings.
numLights = (uint8_t)settings_numLights; uint8_t numLights = (uint8_t)settings_numLights;
params.m_ambientPass = 1.0f; s_uniforms.m_params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f; s_uniforms.m_params.m_lightningPass = 1.0f;
params.m_lightCount = settings_numLights; s_uniforms.m_params.m_lightCount = settings_numLights;
bgfx::setUniform(u_params, (const void*)&params); s_uniforms.m_params.m_lightIndex = 0.0f;
s_uniforms.submitPerFrameUniforms();
// Time. // Time.
int64_t now = bx::getHPCounter(); int64_t now = bx::getHPCounter();
@ -1009,7 +1113,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
const double toMs = 1000.0/freq; const double toMs = 1000.0/freq;
float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) ); float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) );
const float deltaTime = float(frameTime/freq); const float deltaTime = float(frameTime/freq);
bgfx::setUniform(u_time, &time); s_uniforms.m_time = time;
// Use debug font to print information about this example. // Use debug font to print information about this example.
bgfx::dbgTextClear(); bgfx::dbgTextClear();
@ -1037,15 +1141,15 @@ int _main_(int /*_argc*/, char** /*_argv*/)
} }
float lightPosRadius[MAX_NUM_LIGHTS][4]; float lightPosRadius[MAX_NUM_LIGHTS][4];
const float radius = (scene == StencilReflectionScene) ? 0.0f : 60.0f; const float radius = (scene == StencilReflectionScene) ? 15.0f : 25.0f;
for (uint8_t ii = 0; ii < numLights; ++ii) for (uint8_t ii = 0; ii < numLights; ++ii)
{ {
lightPosRadius[ii][0] = sin( (lightTimeAccumulator*(1.1f + ii*0.07f) + float(ii*M_PI_2)*1.07f ) )*25.0f; lightPosRadius[ii][0] = sin( (lightTimeAccumulator*1.1f + ii*0.03f + float(ii*M_PI_2)*1.07f ) )*20.0f;
lightPosRadius[ii][1] = 7.0f + (1.0f - cos( (lightTimeAccumulator*(1.2f + ii*0.29f) + float(ii*M_PI_2)*1.49f ) ))*5.0f; lightPosRadius[ii][1] = 8.0f + (1.0f - cos( (lightTimeAccumulator*1.5f + ii*0.29f + float(ii*M_PI_2)*1.49f ) ))*4.0f;
lightPosRadius[ii][2] = cos( (lightTimeAccumulator*(1.3f + ii*0.09f) + float(ii*M_PI_2)*1.79f ) )*20.0f; lightPosRadius[ii][2] = cos( (lightTimeAccumulator*1.3f + ii*0.13f + float(ii*M_PI_2)*1.79f ) )*20.0f;
lightPosRadius[ii][3] = radius; lightPosRadius[ii][3] = radius;
} }
bgfx::setUniform(u_lightPosRadius, lightPosRadius, numLights); memcpy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float));
// Floor position. // Floor position.
float floorMtx[16]; float floorMtx[16];
@ -1068,7 +1172,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, 5.0f , 5.0f
, 5.0f , 5.0f
, 0.0f , 0.0f
, 1.56f + sceneTimeAccumulator , 1.56f - sceneTimeAccumulator
, 0.0f , 0.0f
, 0.0f , 0.0f
, 2.0f , 2.0f
@ -1112,9 +1216,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, 0.0f , 0.0f
, 0.0f , 0.0f
, 0.0f , 0.0f
, sin(ii * 2.0f + 13.0f + sceneTimeAccumulator) * 13.0f , sin(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f
, 4.0f , 4.0f
, cos(ii * 2.0f + 13.0f + sceneTimeAccumulator) * 13.0f , cos(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f
); );
} }
@ -1122,11 +1226,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
clearView(0, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT | BGFX_CLEAR_STENCIL_BIT, clearValues); clearView(0, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT | BGFX_CLEAR_STENCIL_BIT, clearValues);
submit(0); submit(0);
// White bunny and columns. // Bunny and columns color.
color[0] = 1.0f; s_uniforms.m_color[0] = 0.70f;
color[1] = 1.0f; s_uniforms.m_color[1] = 0.65f;
color[2] = 1.0f; s_uniforms.m_color[2] = 0.60f;
bgfx::setUniform(u_color, color);
switch (scene) switch (scene)
{ {
@ -1134,7 +1237,11 @@ int _main_(int /*_argc*/, char** /*_argv*/)
{ {
// First pass - Draw plane. // First pass - Draw plane.
// Floor // Setup params for this scene.
s_uniforms.m_params.m_ambientPass = 1.0f;
s_uniforms.m_params.m_lightningPass = 1.0f;
// Floor.
hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
, floorMtx , floorMtx
, programColorBlack , programColorBlack
@ -1156,7 +1263,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx); vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx);
reflectedLights[ii][3] = lightPosRadius[ii][3]; reflectedLights[ii][3] = lightPosRadius[ii][3];
} }
bgfx::setUniform(u_lightPosRadius, reflectedLights, numLights); memcpy(s_uniforms.m_lightPosRadius, reflectedLights, numLights * 4*sizeof(float));
// Reflect and submit bunny. // Reflect and submit bunny.
float mtxReflectedBunny[16]; float mtxReflectedBunny[16];
@ -1180,7 +1287,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
} }
// Set lights back. // Set lights back.
bgfx::setUniform(u_lightPosRadius, lightPosRadius, numLights); memcpy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float));
// Third pass - Darken reflected objects. // Third pass - Darken reflected objects.
@ -1233,9 +1340,8 @@ int _main_(int /*_argc*/, char** /*_argv*/)
case ProjectionShadowsScene: case ProjectionShadowsScene:
{ {
// First pass - Draw entire scene. (ambient only). // First pass - Draw entire scene. (ambient only).
params.m_ambientPass = 1.0f; s_uniforms.m_params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f; s_uniforms.m_params.m_lightningPass = 0.0f;
bgfx::setUniform(u_params, (const void*)&params);
// Bunny. // Bunny.
bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0 bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
@ -1249,7 +1355,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, floorMtx , floorMtx
, programTextureLightning , programTextureLightning
, s_renderStates[RenderState::ProjectionShadows_DrawAmbient] , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
, fieldstoneTex , fieldstoneTex
); );
// Cubes. // Cubes.
@ -1270,9 +1376,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
memcpy(ground, normal, sizeof(float) * 3); memcpy(ground, normal, sizeof(float) * 3);
ground[3] = -vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting ground[3] = -vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting
for (uint8_t ii = 0; ii < numLights; ++ii) for (uint8_t ii = 0, viewId = RENDER_VIEWID_RANGE5_PASS_6; ii < numLights; ++ii, ++viewId)
{ {
uint8_t viewId = RENDER_VIEWID_RANGE5_PASS_6+ii; // Clear stencil for this light source.
clearView(viewId, BGFX_CLEAR_STENCIL_BIT, clearValues); clearView(viewId, BGFX_CLEAR_STENCIL_BIT, clearValues);
// Draw shadow projection of scene objects. // Draw shadow projection of scene objects.
@ -1292,36 +1398,27 @@ int _main_(int /*_argc*/, char** /*_argv*/)
mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx); mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx);
bunnyMesh.submit(viewId bunnyMesh.submit(viewId
, mtxShadowedBunny , mtxShadowedBunny
, programColorLightning , programColorBlack
, s_renderStates[RenderState::ProjectionShadows_CraftStencil] , s_renderStates[RenderState::ProjectionShadows_CraftStencil]
); );
// Submit cube shadows. // Submit cube shadows.
float mtxShadowedCube[16]; float mtxShadowedCube[16];
for (uint8_t ii = 0; ii < numCubes; ++ii) for (uint8_t jj = 0; jj < numCubes; ++jj)
{ {
mtxMul(mtxShadowedCube, cubeMtx[ii], shadowMtx); mtxMul(mtxShadowedCube, cubeMtx[jj], shadowMtx);
cubeMesh.submit(viewId cubeMesh.submit(viewId
, mtxShadowedCube , mtxShadowedCube
, programTextureLightning , programColorBlack
, s_renderStates[RenderState::ProjectionShadows_CraftStencil] , s_renderStates[RenderState::ProjectionShadows_CraftStencil]
); );
} }
// Draw entire scene. (lightning pass only. blending is on) // Draw entire scene. (lightning pass only. blending is on)
s_uniforms.m_params.m_ambientPass = 0.0f;
params.m_ambientPass = 0.0f; s_uniforms.m_params.m_lightningPass = 1.0f;
params.m_lightningPass = 1.0f; s_uniforms.m_params.m_lightCount = 1.0f;
bgfx::setUniform(u_params, (const void*)&params); s_uniforms.m_params.m_lightIndex = float(ii);
// Set blending factor based on number of lights.
uint32_t factor = 0xff / (numLights < 1 ? 1 : numLights);
factor = (factor << 24)
| (factor << 16)
| (factor << 8 )
| (factor << 0 )
;
s_renderStates[RenderState::ProjectionShadows_DrawDiffuse].m_blendFactorRgba = factor;
// Bunny. // Bunny.
bunnyMesh.submit(viewId bunnyMesh.submit(viewId
@ -1335,7 +1432,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, floorMtx , floorMtx
, programTextureLightning , programTextureLightning
, s_renderStates[RenderState::ProjectionShadows_DrawDiffuse] , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
, fieldstoneTex , fieldstoneTex
); );
// Cubes. // Cubes.
@ -1351,9 +1448,8 @@ int _main_(int /*_argc*/, char** /*_argv*/)
} }
// Reset these to default.. // Reset these to default..
params.m_ambientPass = 1.0f; s_uniforms.m_params.m_ambientPass = 1.0f;
params.m_lightningPass = 1.0f; s_uniforms.m_params.m_lightningPass = 1.0f;
bgfx::setUniform(u_params, (const void*)&params);
} }
break; break;
}; };
@ -1363,10 +1459,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
float lightMtx[16]; float lightMtx[16];
for (uint8_t ii = 0; ii < numLights; ++ii) for (uint8_t ii = 0; ii < numLights; ++ii)
{ {
color[0] = lightRgbInnerR[ii][0]; s_uniforms.m_color[0] = lightRgbInnerR[ii][0];
color[1] = lightRgbInnerR[ii][1]; s_uniforms.m_color[1] = lightRgbInnerR[ii][1];
color[2] = lightRgbInnerR[ii][2]; s_uniforms.m_color[2] = lightRgbInnerR[ii][2];
bgfx::setUniform(u_color, color);
mtxBillboard(lightMtx, viewState.m_view, lightPosRadius[ii], lightScale); mtxBillboard(lightMtx, viewState.m_view, lightPosRadius[ii], lightScale);
vplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7 vplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7
@ -1428,16 +1523,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
bgfx::destroyProgram(programColorBlack); bgfx::destroyProgram(programColorBlack);
bgfx::destroyProgram(programTexture); bgfx::destroyProgram(programTexture);
bgfx::destroyUniform(u_params);
bgfx::destroyUniform(u_ambient);
bgfx::destroyUniform(u_diffuse);
bgfx::destroyUniform(u_specular);
bgfx::destroyUniform(u_color);
bgfx::destroyUniform(u_time);
bgfx::destroyUniform(u_lightPosRadius);
bgfx::destroyUniform(u_lightRgbInnerR);
bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_texColor);
s_uniforms.destroy();
imguiDestroy(); imguiDestroy();
// Shutdown bgfx. // Shutdown bgfx.