ffr WIP
This commit is contained in:
parent
baeaf81839
commit
63fde5871a
14 changed files with 419 additions and 71 deletions
|
@ -475,7 +475,7 @@ public:
|
|||
m_engine->update(*m_universe);
|
||||
m_pipeline->render();
|
||||
auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
|
||||
static_cast<Renderer*>(renderer)->frame(false);
|
||||
static_cast<Renderer*>(renderer)->frame();
|
||||
m_engine->getFileSystem().updateAsyncTransactions();
|
||||
if (frame_time < 1 / 60.0f)
|
||||
{
|
||||
|
|
|
@ -65,8 +65,8 @@ struct System
|
|||
MT::Event m_work_signal;
|
||||
Array<MT::Task*> m_workers;
|
||||
Array<Job> m_job_queue;
|
||||
FiberDecl m_fiber_pool[256];
|
||||
int m_free_fibers_indices[256];
|
||||
FiberDecl m_fiber_pool[512];
|
||||
int m_free_fibers_indices[512];
|
||||
int m_num_free_fibers;
|
||||
Array<SleepingFiber> m_sleeping_fibers;
|
||||
IAllocator& m_allocator;
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#include "stb/mf_resource.h"
|
||||
const mf_resource* mf_resources = nullptr;
|
||||
int mf_resources_count = 0;
|
|
@ -1515,12 +1515,13 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
|
|||
|
||||
void generateCubemap(ComponentUID cmp)
|
||||
{
|
||||
// TODO
|
||||
/*static const int TEXTURE_SIZE = 1024;
|
||||
ASSERT(cmp.isValid());
|
||||
const EntityRef entity = (EntityRef)cmp.entity;
|
||||
|
||||
static const int TEXTURE_SIZE = 1024;
|
||||
|
||||
Universe* universe = m_app.getWorldEditor().getUniverse();
|
||||
if (universe->getName()[0] == '\0')
|
||||
{
|
||||
if (universe->getName()[0] == '\0') {
|
||||
g_log_error.log("Editor") << "Universe must be saved before environment probe can be generated.";
|
||||
return;
|
||||
}
|
||||
|
@ -1532,46 +1533,40 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
|
|||
|
||||
Vec3 probe_position = universe->getPosition((EntityRef)cmp.entity);
|
||||
auto* scene = static_cast<RenderScene*>(universe->getScene(CAMERA_TYPE));
|
||||
EntityRef camera_entity = scene->getCameraInSlot("probe");
|
||||
if (!camera_entity.isValid())
|
||||
{
|
||||
g_log_error.log("Renderer") << "No camera in slot 'probe'.";
|
||||
return;
|
||||
}
|
||||
|
||||
scene->setCameraFOV(camera_entity, Math::degreesToRadians(90));
|
||||
Viewport viewport;
|
||||
viewport.is_ortho = false;
|
||||
viewport.fov = Math::degreesToRadians(90.f);
|
||||
viewport.near = 0.1f;
|
||||
viewport.far = 10000.f;
|
||||
viewport.w = TEXTURE_SIZE;
|
||||
viewport.h = TEXTURE_SIZE;
|
||||
|
||||
m_pipeline->setScene(scene);
|
||||
// TODO
|
||||
//m_pipeline->resize(TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
m_pipeline->setViewport(viewport);
|
||||
|
||||
Renderer* renderer = static_cast<Renderer*>(plugin_manager.getPlugin("renderer"));
|
||||
|
||||
Vec3 dirs[] = {{-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};
|
||||
Vec3 ups[] = {{0, 1, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, 1, 0}};
|
||||
Vec3 ups_opengl[] = { { 0, -1, 0 },{ 0, -1, 0 },{ 0, 0, 1 },{ 0, 0, -1 },{ 0, -1, 0 },{ 0, -1, 0 } };
|
||||
|
||||
Array<u8> data(allocator);
|
||||
data.resize(6 * TEXTURE_SIZE * TEXTURE_SIZE * 4);
|
||||
ffr::TextureHandle texture = ffr::allocTextureHandle();
|
||||
ffr::createTexture(texture, TEXTURE_SIZE, TEXTURE_SIZE, ffr::TextureFormat::RGBA8, 0, nullptr);
|
||||
renderer->frame(false); // submit
|
||||
renderer->frame(false); // wait for gpu
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
Matrix mtx = Matrix::IDENTITY;
|
||||
mtx.setTranslation(probe_position);
|
||||
renderer->startCapture();
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
const bool ndc_bottom_left = ffr::isOriginBottomLeft();
|
||||
Vec3 side = crossProduct(ndc_bottom_left ? ups_opengl[i] : ups[i], dirs[i]);
|
||||
Matrix mtx = Matrix::IDENTITY;
|
||||
mtx.setZVector(dirs[i]);
|
||||
mtx.setYVector(ndc_bottom_left ? ups_opengl[i] : ups[i]);
|
||||
mtx.setXVector(side);
|
||||
universe->setMatrix(camera_entity, mtx);
|
||||
viewport.pos = probe_position;
|
||||
viewport.rot = mtx.getRotation();
|
||||
m_pipeline->setViewport(viewport);
|
||||
m_pipeline->render();
|
||||
|
||||
const ffr::TextureHandle res = m_pipeline->getOutput();
|
||||
ffr::getTextureImage(res, TEXTURE_SIZE * TEXTURE_SIZE * 4, &data[i * TEXTURE_SIZE * TEXTURE_SIZE * 4]);
|
||||
renderer->getTextureImage(res, TEXTURE_SIZE * TEXTURE_SIZE * 4, &data[i * TEXTURE_SIZE * TEXTURE_SIZE * 4]);
|
||||
|
||||
if (ndc_bottom_left) continue;
|
||||
|
||||
|
@ -1585,6 +1580,10 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
|
|||
flipX(tmp, TEXTURE_SIZE);
|
||||
}
|
||||
}
|
||||
renderer->stopCapture();
|
||||
renderer->frame();
|
||||
renderer->frame();
|
||||
|
||||
cmft::Image image;
|
||||
cmft::Image irradiance;
|
||||
|
||||
|
@ -1612,29 +1611,38 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
|
|||
cmft::imageFromRgba32f(image, cmft::TextureFormat::RGBA8);
|
||||
cmft::imageFromRgba32f(irradiance, cmft::TextureFormat::RGBA8);
|
||||
|
||||
|
||||
|
||||
int irradiance_size = 32;
|
||||
int radiance_size = 128;
|
||||
int reflection_size = TEXTURE_SIZE;
|
||||
|
||||
if (scene->isEnvironmentProbeCustomSize(cmp.entity))
|
||||
{
|
||||
irradiance_size = scene->getEnvironmentProbeIrradianceSize(cmp.entity);
|
||||
radiance_size = scene->getEnvironmentProbeRadianceSize(cmp.entity);
|
||||
reflection_size = scene->getEnvironmentProbeReflectionSize(cmp.entity);
|
||||
if (scene->isEnvironmentProbeCustomSize(entity)) {
|
||||
irradiance_size = scene->getEnvironmentProbeIrradianceSize(entity);
|
||||
radiance_size = scene->getEnvironmentProbeRadianceSize(entity);
|
||||
reflection_size = scene->getEnvironmentProbeReflectionSize(entity);
|
||||
}
|
||||
|
||||
for (int i = 3; i < data.size(); i += 4) data[i] = 0xff;
|
||||
saveCubemap(cmp, (u8*)irradiance.m_data, irradiance_size, "_irradiance");
|
||||
saveCubemap(cmp, (u8*)image.m_data, radiance_size, "_radiance");
|
||||
if (scene->isEnvironmentProbeReflectionEnabled(cmp.entity))
|
||||
{
|
||||
if (scene->isEnvironmentProbeReflectionEnabled(entity)) {
|
||||
auto& fs = m_app.getWorldEditor().getEngine().getFileSystem();
|
||||
for(int i = 0; i < 6; ++i) {
|
||||
const char* pp[] = {
|
||||
"test0.tga",
|
||||
"test1.tga",
|
||||
"test2.tga",
|
||||
"test3.tga",
|
||||
"test4.tga",
|
||||
"test5.tga",
|
||||
};
|
||||
auto* f = fs.open(fs.getDefaultDevice(), Path(pp[i]), FS::Mode::CREATE_AND_WRITE);
|
||||
Lumix::Texture::saveTGA(f, TEXTURE_SIZE, TEXTURE_SIZE, 4, data.begin() + 4 * TEXTURE_SIZE * TEXTURE_SIZE * i, Path(pp[i]), m_app.getWorldEditor().getAllocator());
|
||||
fs.close(*f);
|
||||
}
|
||||
saveCubemap(cmp, &data[0], reflection_size, "");
|
||||
}
|
||||
ffr::destroy(texture);
|
||||
|
||||
|
||||
scene->reloadEnvironmentProbe(cmp.entity);*/
|
||||
scene->reloadEnvironmentProbe(entity);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2878,7 +2886,7 @@ struct EditorUIRenderPlugin final : public StudioApp::GUIPlugin
|
|||
cmd->plugin = this;
|
||||
|
||||
renderer->push(cmd);
|
||||
renderer->frame(false);
|
||||
renderer->frame();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -893,6 +893,16 @@ void applyUniformMatrix4x3f(int location, const float* value)
|
|||
glUniformMatrix4x3fv(location, 1, false, value);
|
||||
}
|
||||
|
||||
void applyUniform1i(int location, int value)
|
||||
{
|
||||
glUniform1i(location, value);
|
||||
}
|
||||
|
||||
void applyUniform4f(int location, const float* value)
|
||||
{
|
||||
glUniform4fv(location, 1, value);
|
||||
}
|
||||
|
||||
void applyUniformMatrix3x4f(int location, const float* value)
|
||||
{
|
||||
glUniformMatrix3x4fv(location, 1, false, value);
|
||||
|
@ -933,6 +943,9 @@ void useProgram(ProgramHandle handle)
|
|||
case UniformType::INT:
|
||||
glUniform1i(pu.loc, *(int*)u.data);
|
||||
break;
|
||||
case UniformType::IVEC2:
|
||||
glUniform2iv(pu.loc, u.count, (int*)u.data);
|
||||
break;
|
||||
default: ASSERT(false); break;
|
||||
}
|
||||
}
|
||||
|
@ -1160,6 +1173,22 @@ void update(BufferHandle buffer, const void* data, size_t offset, size_t size)
|
|||
}
|
||||
|
||||
|
||||
void startCapture()
|
||||
{
|
||||
if (g_ffr.rdoc_api) {
|
||||
g_ffr.rdoc_api->StartFrameCapture(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stopCapture()
|
||||
{
|
||||
if (g_ffr.rdoc_api) {
|
||||
g_ffr.rdoc_api->EndFrameCapture(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
checkThread();
|
||||
|
@ -1553,6 +1582,7 @@ static uint getSize(UniformType type)
|
|||
{
|
||||
case UniformType::INT: return sizeof(int);
|
||||
case UniformType::FLOAT: return sizeof(float);
|
||||
case UniformType::IVEC2: return sizeof(int) * 2;
|
||||
case UniformType::VEC2: return sizeof(float) * 2;
|
||||
case UniformType::VEC3: return sizeof(float) * 3;
|
||||
case UniformType::VEC4: return sizeof(float) * 4;
|
||||
|
@ -1700,6 +1730,7 @@ ProgramHandle createProgram(const char** srcs, const ShaderType* types, int num,
|
|||
case GL_FLOAT_MAT4: ffr_type = UniformType::MAT4; break;
|
||||
case GL_FLOAT_MAT4x3: ffr_type = UniformType::MAT4X3; break;
|
||||
case GL_FLOAT_MAT3x4: ffr_type = UniformType::MAT3X4; break;
|
||||
case GL_INT_VEC2: ffr_type = UniformType::IVEC2; break;
|
||||
default: ASSERT(false); ffr_type = UniformType::VEC4; break;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ enum class UniformType : uint {
|
|||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
IVEC2,
|
||||
MAT4,
|
||||
MAT4X3,
|
||||
MAT3X4
|
||||
|
@ -151,6 +152,8 @@ bool isHomogenousDepth();
|
|||
bool isOriginBottomLeft();
|
||||
void checkThread();
|
||||
void shutdown();
|
||||
void startCapture();
|
||||
void stopCapture();
|
||||
|
||||
void clear(uint flags, const float* color, float depth);
|
||||
|
||||
|
@ -210,6 +213,8 @@ void setUniformMatrix3x4f(UniformHandle uniform, const float* value);
|
|||
void setUniformMatrix4f(UniformHandle uniform, const float* value);
|
||||
void setUniformMatrix4x3f(UniformHandle uniform, const float* value);
|
||||
int getUniformLocation(ProgramHandle program_handle, UniformHandle uniform);
|
||||
void applyUniform1i(int location, int value);
|
||||
void applyUniform4f(int location, const float* value);
|
||||
void applyUniformMatrix3x4f(int location, const float* value);
|
||||
void applyUniformMatrix4f(int location, const float* value);
|
||||
void applyUniformMatrix4fv(int location, uint count, const float* value);
|
||||
|
|
|
@ -85,6 +85,7 @@ FFR_GL_IMPORT(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri);
|
|||
FFR_GL_IMPORT(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D);
|
||||
FFR_GL_IMPORT(PFNGLTEXTURESTORAGE3DPROC, glTextureStorage3D);
|
||||
FFR_GL_IMPORT(PFNGLUNIFORM1IPROC, glUniform1i);
|
||||
FFR_GL_IMPORT(PFNGLUNIFORM2IVPROC, glUniform2iv);
|
||||
FFR_GL_IMPORT(PFNGLUNIFORM1FVPROC, glUniform1fv);
|
||||
FFR_GL_IMPORT(PFNGLUNIFORM2FVPROC, glUniform2fv);
|
||||
FFR_GL_IMPORT(PFNGLUNIFORM3FVPROC, glUniform3fv);
|
||||
|
|
|
@ -75,6 +75,7 @@ struct PipelineImpl final : Pipeline
|
|||
m_draw2d.PushClipRectFullScreen();
|
||||
m_draw2d.PushTextureID(font_atlas.TexID);
|
||||
|
||||
m_position_radius_uniform = ffr::allocUniform("u_pos_radius", ffr::UniformType::VEC4, 1);
|
||||
m_terrain_params_uniform = ffr::allocUniform("u_terrain_params", ffr::UniformType::VEC4, 1);
|
||||
m_rel_camera_pos_uniform = ffr::allocUniform("u_rel_camera_pos", ffr::UniformType::VEC4, 1);
|
||||
m_terrain_scale_uniform = ffr::allocUniform("u_terrain_scale", ffr::UniformType::VEC4, 1);
|
||||
|
@ -87,6 +88,37 @@ struct PipelineImpl final : Pipeline
|
|||
m_radiance_map_uniform = ffr::allocUniform("u_radiancemap", ffr::UniformType::INT, 1);
|
||||
m_material_params_uniform = ffr::allocUniform("u_material_params", ffr::UniformType::VEC4, 1);
|
||||
m_material_color_uniform = ffr::allocUniform("u_material_color", ffr::UniformType::VEC4, 1);
|
||||
|
||||
float cube_verts[] = {
|
||||
-1, -1, -1,
|
||||
1, -1, -1,
|
||||
1, -1, 1,
|
||||
-1, -1, 1,
|
||||
-1, 1, -1,
|
||||
1, 1, -1,
|
||||
1, 1, 1,
|
||||
-1, 1, 1
|
||||
};
|
||||
const Renderer::MemRef vb_mem = m_renderer.copy(cube_verts, sizeof(cube_verts));
|
||||
m_cube_vb = m_renderer.createBuffer(vb_mem);
|
||||
|
||||
u16 cube_indices[] = {
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
4, 6, 5,
|
||||
4, 7, 6,
|
||||
0, 4, 5,
|
||||
0, 5, 1,
|
||||
2, 6, 7,
|
||||
2, 7, 3,
|
||||
0, 3, 7,
|
||||
0, 7, 4,
|
||||
1, 2, 6,
|
||||
1, 6, 5
|
||||
};
|
||||
|
||||
const Renderer::MemRef ib_mem = m_renderer.copy(cube_indices, sizeof(cube_indices));
|
||||
m_cube_ib = m_renderer.createBuffer(ib_mem);
|
||||
}
|
||||
|
||||
|
||||
|
@ -350,6 +382,8 @@ struct PipelineImpl final : Pipeline
|
|||
state.camera_inv_view_projection = state.camera_view_projection;
|
||||
state.camera_inv_view_projection.inverse();
|
||||
state.time = m_timer->getTimeSinceStart();
|
||||
state.framebuffer_size.x = m_viewport.w;
|
||||
state.framebuffer_size.y = m_viewport.h;
|
||||
|
||||
const EntityPtr global_light = m_scene->getActiveGlobalLight();
|
||||
if(global_light.isValid()) {
|
||||
|
@ -516,7 +550,6 @@ struct PipelineImpl final : Pipeline
|
|||
vertex_decl.addAttribute(2, ffr::AttributeType::FLOAT, false, false);
|
||||
vertex_decl.addAttribute(4, ffr::AttributeType::U8, true, false);
|
||||
|
||||
|
||||
ffr::BufferHandle vb = ffr::allocBufferHandle();
|
||||
ffr::BufferHandle ib = ffr::allocBufferHandle();
|
||||
ffr::createBuffer(vb, vtx_buffer_mem.size, vtx_buffer_mem.data);
|
||||
|
@ -835,6 +868,168 @@ struct PipelineImpl final : Pipeline
|
|||
return cp;
|
||||
}
|
||||
|
||||
|
||||
static int bindTextures(lua_State* L)
|
||||
{
|
||||
struct Cmd : Renderer::RenderCommandBase {
|
||||
void setup() override {}
|
||||
void execute() override
|
||||
{
|
||||
for(int i = 0; i < m_textures_count; ++i) {
|
||||
ffr::bindTexture(m_offset + i, m_textures[i].handle);
|
||||
ffr::setUniform1i(m_textures[i].uniform, i + m_offset);
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
ffr::TextureHandle handle;
|
||||
ffr::UniformHandle uniform;
|
||||
} m_textures[16];
|
||||
int m_offset = 0;
|
||||
int m_textures_count = 0;
|
||||
};
|
||||
|
||||
const int pipeline_idx = lua_upvalueindex(1);
|
||||
if (lua_type(L, pipeline_idx) != LUA_TLIGHTUSERDATA) {
|
||||
LuaWrapper::argError<PipelineImpl*>(L, pipeline_idx);
|
||||
}
|
||||
PipelineImpl* pipeline = LuaWrapper::toType<PipelineImpl*>(L, pipeline_idx);
|
||||
LuaWrapper::checkTableArg(L, 1);
|
||||
|
||||
const int offset = lua_gettop(L) > 1 ? LuaWrapper::checkArg<int>(L, 2) : 0;
|
||||
|
||||
Cmd* cmd = LUMIX_NEW(pipeline->m_renderer.getAllocator(), Cmd);
|
||||
cmd->m_offset = offset;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1) != 0) {
|
||||
if(lua_type(L, -1) != LUA_TNUMBER) {
|
||||
LUMIX_DELETE(pipeline->m_renderer.getAllocator(), cmd);
|
||||
return luaL_error(L, "%s", "Incorrect texture arguments of bindTextures");
|
||||
}
|
||||
|
||||
if(lua_type(L, -2) != LUA_TSTRING) {
|
||||
LUMIX_DELETE(pipeline->m_renderer.getAllocator(), cmd);
|
||||
return luaL_error(L, "%s", "Incorrect texture arguments of bindTextures");
|
||||
}
|
||||
|
||||
if (cmd->m_textures_count > lengthOf(cmd->m_textures)) {
|
||||
LUMIX_DELETE(pipeline->m_renderer.getAllocator(), cmd);
|
||||
return luaL_error(L, "%s", "Too many texture in bindTextures call");
|
||||
}
|
||||
|
||||
const char* uniform_name = lua_tostring(L, -2);
|
||||
cmd->m_textures[cmd->m_textures_count].uniform = ffr::allocUniform(uniform_name, ffr::UniformType::INT, 1);
|
||||
|
||||
const int rb_idx = (int)lua_tointeger(L, -1);
|
||||
cmd->m_textures[cmd->m_textures_count].handle = pipeline->m_renderbuffers[rb_idx].handle;
|
||||
++cmd->m_textures_count;
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
pipeline->m_renderer.push(cmd);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
static int renderEnvProbeVolumes(lua_State* L)
|
||||
{
|
||||
const int pipeline_idx = lua_upvalueindex(1);
|
||||
if (lua_type(L, pipeline_idx) != LUA_TLIGHTUSERDATA) {
|
||||
LuaWrapper::argError<PipelineImpl*>(L, pipeline_idx);
|
||||
}
|
||||
PipelineImpl* pipeline = LuaWrapper::toType<PipelineImpl*>(L, pipeline_idx);
|
||||
const int shader_id = LuaWrapper::checkArg<int>(L, 1);
|
||||
const Shader* shader = [&] {
|
||||
for (const ShaderRef& s : pipeline->m_shaders) {
|
||||
if(s.id == shader_id) {
|
||||
return s.res;
|
||||
}
|
||||
}
|
||||
return (Shader*)nullptr;
|
||||
}();
|
||||
if (!shader) {
|
||||
return luaL_error(L, "Unknown shader id %d in renderEnvProbeVolumes.", shader_id);
|
||||
}
|
||||
const CameraParams cp = checkCameraParams(L, 2);
|
||||
|
||||
struct Cmd : public Renderer::RenderCommandBase
|
||||
{
|
||||
struct Probe
|
||||
{
|
||||
Vec3 pos;
|
||||
ffr::TextureHandle texture;
|
||||
};
|
||||
|
||||
Cmd(IAllocator& allocator) : m_probes(allocator) {}
|
||||
|
||||
void setup() override
|
||||
{
|
||||
m_pipeline->getScene()->getEnvironmentProbes(m_probes);
|
||||
}
|
||||
|
||||
|
||||
void execute() override
|
||||
{
|
||||
PROFILE_FUNCTION();
|
||||
if(m_probes.empty()) return;
|
||||
|
||||
ffr::pushDebugGroup("environment");
|
||||
const Shader::Program& prog = Shader::getProgram(m_shader, 0);
|
||||
if(!prog.handle.isValid()) return;
|
||||
|
||||
const int pos_radius_uniform_loc = ffr::getUniformLocation(prog.handle, m_pos_radius_uniform);
|
||||
|
||||
ffr::VertexDecl decl;
|
||||
decl.addAttribute(3, ffr::AttributeType::FLOAT, false, false);
|
||||
|
||||
ffr::setVertexBuffer(&decl, m_vb, 0, nullptr);
|
||||
ffr::setIndexBuffer(m_ib);
|
||||
ffr::useProgram(prog.handle);
|
||||
ffr::setState(0);
|
||||
const int irradiance_map_loc = ffr::getUniformLocation(prog.handle, m_irradiance_map_uniform);
|
||||
const int radiance_map_loc = ffr::getUniformLocation(prog.handle, m_radiance_map_uniform);
|
||||
const Vec3 cam_pos = m_camera_params.pos;
|
||||
for (const EnvProbeInfo& probe : m_probes) {
|
||||
const Vec4 pos_radius(probe.position - cam_pos, probe.radius);
|
||||
ffr::bindTexture(0, probe.radiance);
|
||||
ffr::applyUniform1i(irradiance_map_loc, 0);
|
||||
ffr::bindTexture(1, probe.radiance);
|
||||
ffr::applyUniform1i(radiance_map_loc, 1);
|
||||
ffr::applyUniform4f(pos_radius_uniform_loc, &pos_radius.x);
|
||||
ffr::drawTriangles(36);
|
||||
}
|
||||
ffr::popDebugGroup();
|
||||
}
|
||||
|
||||
ffr::BufferHandle m_ib;
|
||||
ffr::BufferHandle m_vb;
|
||||
ffr::UniformHandle m_pos_radius_uniform;
|
||||
ffr::UniformHandle m_irradiance_map_uniform;
|
||||
ffr::UniformHandle m_radiance_map_uniform;
|
||||
CameraParams m_camera_params;
|
||||
PipelineImpl* m_pipeline;
|
||||
Array<EnvProbeInfo> m_probes;
|
||||
Shader::RenderData* m_shader;
|
||||
};
|
||||
|
||||
if(shader->isReady()) {
|
||||
IAllocator& allocator = pipeline->m_renderer.getAllocator();
|
||||
Cmd* cmd = LUMIX_NEW(allocator, Cmd)(allocator);
|
||||
cmd->m_pipeline = pipeline;
|
||||
cmd->m_shader = shader->m_render_data;
|
||||
cmd->m_ib = pipeline->m_cube_ib;
|
||||
cmd->m_vb = pipeline->m_cube_vb;
|
||||
cmd->m_camera_params = cp;
|
||||
cmd->m_irradiance_map_uniform = pipeline->m_irradiance_map_uniform;
|
||||
cmd->m_radiance_map_uniform = pipeline->m_radiance_map_uniform;
|
||||
cmd->m_pos_radius_uniform = pipeline->m_position_radius_uniform;
|
||||
pipeline->m_renderer.push(cmd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int renderMeshes(lua_State* L)
|
||||
{
|
||||
|
@ -2090,9 +2285,11 @@ struct PipelineImpl final : Pipeline
|
|||
registerConst("STENCIL_KEEP", (uint)ffr::StencilOps::KEEP);
|
||||
registerConst("STENCIL_REPLACE", (uint)ffr::StencilOps::REPLACE);
|
||||
|
||||
registerCFunction("bindTextures", PipelineImpl::bindTextures);
|
||||
registerCFunction("drawArray", PipelineImpl::drawArray);
|
||||
registerCFunction("getCameraParams", PipelineImpl::getCameraParams);
|
||||
registerCFunction("getShadowCameraParams", PipelineImpl::getShadowCameraParams);
|
||||
registerCFunction("renderEnvProbeVolumes", PipelineImpl::renderEnvProbeVolumes);
|
||||
registerCFunction("renderMeshes", PipelineImpl::renderMeshes);
|
||||
registerCFunction("renderParticles", PipelineImpl::renderParticles);
|
||||
registerCFunction("renderTerrains", PipelineImpl::renderTerrains);
|
||||
|
@ -2151,6 +2348,7 @@ struct PipelineImpl final : Pipeline
|
|||
Array<ShaderRef> m_shaders;
|
||||
Timer* m_timer;
|
||||
|
||||
ffr::UniformHandle m_position_radius_uniform;
|
||||
ffr::UniformHandle m_terrain_params_uniform;
|
||||
ffr::UniformHandle m_rel_camera_pos_uniform;
|
||||
ffr::UniformHandle m_terrain_scale_uniform;
|
||||
|
@ -2163,6 +2361,8 @@ struct PipelineImpl final : Pipeline
|
|||
ffr::UniformHandle m_radiance_map_uniform;
|
||||
ffr::UniformHandle m_material_params_uniform;
|
||||
ffr::UniformHandle m_material_color_uniform;
|
||||
ffr::BufferHandle m_cube_vb;
|
||||
ffr::BufferHandle m_cube_ib;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ struct EnvironmentProbe
|
|||
Texture* texture;
|
||||
Texture* irradiance;
|
||||
Texture* radiance;
|
||||
float radius;
|
||||
u64 guid;
|
||||
FlagSet<Flags, u32> flags;
|
||||
u16 radiance_size = 128;
|
||||
|
@ -1093,6 +1094,7 @@ public:
|
|||
EnvironmentProbe& probe = m_environment_probes[entity];
|
||||
serializer.write("guid", probe.guid);
|
||||
serializer.write("flags", probe.flags.base);
|
||||
serializer.write("radius", probe.radius);
|
||||
serializer.write("radiance_size", probe.radiance_size);
|
||||
serializer.write("irradiance_size", probe.irradiance_size);
|
||||
serializer.write("reflection_size", probe.reflection_size);
|
||||
|
@ -1109,6 +1111,7 @@ public:
|
|||
EnvironmentProbe& probe = m_environment_probes.insert(entity);
|
||||
serializer.read(&probe.guid);
|
||||
serializer.read(&probe.flags.base);
|
||||
serializer.read(&probe.radius);
|
||||
serializer.read(&probe.radiance_size);
|
||||
serializer.read(&probe.irradiance_size);
|
||||
serializer.read(&probe.reflection_size);
|
||||
|
@ -1319,6 +1322,7 @@ public:
|
|||
EntityRef entity = m_environment_probes.getKey(i);
|
||||
serializer.write(entity);
|
||||
const EnvironmentProbe& probe = m_environment_probes.at(i);
|
||||
serializer.write(probe.radius);
|
||||
serializer.write(probe.guid);
|
||||
serializer.write(probe.flags.base);
|
||||
serializer.write(probe.radiance_size);
|
||||
|
@ -3417,32 +3421,31 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
|
|||
|
||||
void reloadEnvironmentProbe(EntityRef entity) override
|
||||
{
|
||||
// TODO
|
||||
ASSERT(false);
|
||||
/*
|
||||
auto& probe = m_environment_probes[entity];
|
||||
auto* texture_manager = m_engine.getResourceManager().get(Texture::TYPE);
|
||||
if (probe.texture) texture_manager->unload(*probe.texture);
|
||||
ResourceManagerHub& rm = m_engine.getResourceManager();
|
||||
if (probe.texture) probe.texture->getResourceManager().unload(*probe.texture);
|
||||
probe.texture = nullptr;
|
||||
StaticString<MAX_PATH_LENGTH> path;
|
||||
if (probe.flags.isSet(EnvironmentProbe::REFLECTION))
|
||||
{
|
||||
if (probe.flags.isSet(EnvironmentProbe::REFLECTION)) {
|
||||
path << "universes/" << m_universe.getName() << "/probes/" << probe.guid << ".dds";
|
||||
probe.texture = static_cast<Texture*>(texture_manager->load(Path(path)));
|
||||
probe.texture->setFlag(BGFX_TEXTURE_SRGB, true);
|
||||
probe.texture = rm.load<Texture>(Path(path));
|
||||
// TODO
|
||||
//probe.texture->setFlag(BGFX_TEXTURE_SRGB, true);
|
||||
}
|
||||
path = "universes/";
|
||||
path << m_universe.getName() << "/probes/" << probe.guid << "_irradiance.dds";
|
||||
probe.irradiance = static_cast<Texture*>(texture_manager->load(Path(path)));
|
||||
probe.irradiance->setFlag(BGFX_TEXTURE_SRGB, true);
|
||||
probe.irradiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
|
||||
probe.irradiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);
|
||||
if(probe.irradiance) probe.irradiance->getResourceManager().unload(*probe.irradiance);
|
||||
probe.irradiance = rm.load<Texture>(Path(path));
|
||||
//probe.irradiance->setFlag(BGFX_TEXTURE_SRGB, true);
|
||||
//probe.irradiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
|
||||
//probe.irradiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);
|
||||
path = "universes/";
|
||||
path << m_universe.getName() << "/probes/" << probe.guid << "_radiance.dds";
|
||||
probe.radiance = static_cast<Texture*>(texture_manager->load(Path(path)));
|
||||
probe.radiance->setFlag(BGFX_TEXTURE_SRGB, true);
|
||||
probe.radiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
|
||||
probe.radiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);*/
|
||||
if (probe.radiance) probe.irradiance->getResourceManager().unload(*probe.radiance);
|
||||
probe.radiance = rm.load<Texture>(Path(path));
|
||||
//probe.radiance->setFlag(BGFX_TEXTURE_SRGB, true);
|
||||
//probe.radiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
|
||||
//probe.radiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3465,38 +3468,67 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
|
|||
return nearest;
|
||||
}
|
||||
|
||||
|
||||
void getEnvironmentProbes(Array<EnvProbeInfo>& probes) override
|
||||
{
|
||||
PROFILE_FUNCTION();
|
||||
probes.resize(m_environment_probes.size());
|
||||
for (int i = 0; i < m_environment_probes.size(); ++i) {
|
||||
const EnvironmentProbe& probe = m_environment_probes.at(i);
|
||||
const EntityRef entity = m_environment_probes.getKey(i);
|
||||
EnvProbeInfo& out = probes[i];
|
||||
out.radius = probe.radius;
|
||||
out.position = m_universe.getPosition(entity);
|
||||
out.radiance = probe.radiance && probe.radiance->isReady() ? probe.radiance->handle : ffr::INVALID_TEXTURE;
|
||||
out.irradiance = probe.irradiance && probe.irradiance->isReady() ? probe.irradiance->handle : ffr::INVALID_TEXTURE;
|
||||
out.reflection = probe.texture && probe.texture->isReady() ? probe.texture->handle : ffr::INVALID_TEXTURE;
|
||||
}
|
||||
}
|
||||
|
||||
int getEnvironmentProbeIrradianceSize(EntityRef entity)
|
||||
|
||||
int getEnvironmentProbeIrradianceSize(EntityRef entity) override
|
||||
{
|
||||
return m_environment_probes[entity].irradiance_size;
|
||||
}
|
||||
|
||||
|
||||
void setEnvironmentProbeIrradianceSize(EntityRef entity, int size)
|
||||
void setEnvironmentProbeIrradianceSize(EntityRef entity, int size) override
|
||||
{
|
||||
m_environment_probes[entity].irradiance_size = size;
|
||||
}
|
||||
|
||||
|
||||
int getEnvironmentProbeRadianceSize(EntityRef entity)
|
||||
float getEnvironmentProbeRadius(EntityRef entity) override
|
||||
{
|
||||
return m_environment_probes[entity].radius;
|
||||
}
|
||||
|
||||
|
||||
void setEnvironmentProbeRadius(EntityRef entity, float radius) override
|
||||
{
|
||||
m_environment_probes[entity].radius = radius;
|
||||
}
|
||||
|
||||
|
||||
int getEnvironmentProbeRadianceSize(EntityRef entity) override
|
||||
{
|
||||
return m_environment_probes[entity].radiance_size;
|
||||
}
|
||||
|
||||
|
||||
void setEnvironmentProbeRadianceSize(EntityRef entity, int size)
|
||||
void setEnvironmentProbeRadianceSize(EntityRef entity, int size) override
|
||||
{
|
||||
m_environment_probes[entity].radiance_size = size;
|
||||
}
|
||||
|
||||
|
||||
int getEnvironmentProbeReflectionSize(EntityRef entity)
|
||||
int getEnvironmentProbeReflectionSize(EntityRef entity) override
|
||||
{
|
||||
return m_environment_probes[entity].reflection_size;
|
||||
}
|
||||
|
||||
|
||||
void setEnvironmentProbeReflectionSize(EntityRef entity, int size)
|
||||
void setEnvironmentProbeReflectionSize(EntityRef entity, int size) override
|
||||
{
|
||||
m_environment_probes[entity].reflection_size = size;
|
||||
}
|
||||
|
@ -3916,6 +3948,7 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
|
|||
probe.irradiance->setFlag(Texture::Flags::SRGB, true);
|
||||
probe.radiance = rm.load<Texture>(Path("models/common/default_probe.dds"));
|
||||
probe.radiance->setFlag(Texture::Flags::SRGB, true);
|
||||
probe.radius = 1;
|
||||
probe.guid = Math::randGUID();
|
||||
|
||||
m_universe.onComponentCreated(entity, ENVIRONMENT_PROBE_TYPE, this);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "engine/flag_set.h"
|
||||
#include "engine/matrix.h"
|
||||
#include "engine/iplugin.h"
|
||||
#include "ffr/ffr.h"
|
||||
|
||||
|
||||
struct lua_State;
|
||||
|
@ -102,6 +103,16 @@ struct GrassInfo
|
|||
};
|
||||
|
||||
|
||||
struct EnvProbeInfo
|
||||
{
|
||||
Vec3 position;
|
||||
float radius;
|
||||
ffr::TextureHandle reflection;
|
||||
ffr::TextureHandle radiance;
|
||||
ffr::TextureHandle irradiance;
|
||||
};
|
||||
|
||||
|
||||
struct DebugTriangle
|
||||
{
|
||||
Vec3 p0;
|
||||
|
@ -355,6 +366,7 @@ public:
|
|||
virtual float getPointLightSpecularIntensity(EntityRef entity) = 0;
|
||||
virtual void setPointLightSpecularIntensity(EntityRef entity, float color) = 0;
|
||||
|
||||
virtual void getEnvironmentProbes(Array<EnvProbeInfo>& probes) = 0;
|
||||
virtual int getEnvironmentProbeIrradianceSize(EntityRef entity) = 0;
|
||||
virtual void setEnvironmentProbeIrradianceSize(EntityRef entity, int size) = 0;
|
||||
virtual int getEnvironmentProbeRadianceSize(EntityRef entity) = 0;
|
||||
|
@ -371,6 +383,8 @@ public:
|
|||
virtual void reloadEnvironmentProbe(EntityRef entity) = 0;
|
||||
virtual EntityPtr getNearestEnvironmentProbe(const Vec3& pos) const = 0;
|
||||
virtual u64 getEnvironmentProbeGUID(EntityRef entity) const = 0;
|
||||
virtual float getEnvironmentProbeRadius(EntityRef entity) = 0;
|
||||
virtual void setEnvironmentProbeRadius(EntityRef entity, float radius) = 0;
|
||||
|
||||
virtual void setTextMeshText(EntityRef entity, const char* text) = 0;
|
||||
virtual const char* getTextMeshText(EntityRef entity) = 0;
|
||||
|
|
|
@ -281,6 +281,7 @@ static void registerProperties(IAllocator& allocator)
|
|||
BoneProperty()
|
||||
),
|
||||
component("environment_probe",
|
||||
property("Radius", LUMIX_PROP(RenderScene, EnvironmentProbeRadius)),
|
||||
property("Enabled reflection", LUMIX_PROP_FULL(RenderScene, isEnvironmentProbeReflectionEnabled, enableEnvironmentProbeReflection)),
|
||||
property("Override global size", LUMIX_PROP_FULL(RenderScene, isEnvironmentProbeCustomSize, enableEnvironmentProbeCustomSize)),
|
||||
property("Radiance size", LUMIX_PROP(RenderScene, EnvironmentProbeRadianceSize)),
|
||||
|
@ -506,6 +507,29 @@ struct RendererImpl final : public Renderer
|
|||
}
|
||||
|
||||
|
||||
void getTextureImage(ffr::TextureHandle texture, int size, void* data) override
|
||||
{
|
||||
struct Cmd : RenderCommandBase {
|
||||
void setup() override {}
|
||||
void execute() override {
|
||||
ffr::pushDebugGroup("get image data");
|
||||
ffr::getTextureImage(handle, size, buf);
|
||||
ffr::popDebugGroup();
|
||||
}
|
||||
|
||||
ffr::TextureHandle handle;
|
||||
uint size;
|
||||
void* buf;
|
||||
};
|
||||
|
||||
Cmd* cmd = LUMIX_NEW(m_render_task.m_allocator, Cmd);
|
||||
cmd->handle = texture;
|
||||
cmd->size = size;
|
||||
cmd->buf = data;
|
||||
push(cmd);
|
||||
}
|
||||
|
||||
|
||||
ffr::TextureHandle loadTexture(const MemRef& memory, u32 flags, ffr::TextureInfo* info) override
|
||||
{
|
||||
ASSERT(memory.size > 0);
|
||||
|
@ -840,6 +864,34 @@ struct RendererImpl final : public Renderer
|
|||
}
|
||||
|
||||
|
||||
void startCapture() override
|
||||
{
|
||||
struct Cmd : RenderCommandBase {
|
||||
void setup() override {}
|
||||
void execute() override {
|
||||
PROFILE_FUNCTION();
|
||||
ffr::startCapture();
|
||||
}
|
||||
};
|
||||
Cmd* cmd = LUMIX_NEW(m_allocator, Cmd);
|
||||
push(cmd);
|
||||
}
|
||||
|
||||
|
||||
void stopCapture() override
|
||||
{
|
||||
struct Cmd : RenderCommandBase {
|
||||
void setup() override {}
|
||||
void execute() override {
|
||||
PROFILE_FUNCTION();
|
||||
ffr::stopCapture();
|
||||
}
|
||||
};
|
||||
Cmd* cmd = LUMIX_NEW(m_allocator, Cmd);
|
||||
push(cmd);
|
||||
}
|
||||
|
||||
|
||||
void pushSwapCommand()
|
||||
{
|
||||
struct SwapCmd : RenderCommandBase {
|
||||
|
@ -852,6 +904,7 @@ struct RendererImpl final : public Renderer
|
|||
renderer->m_render_task.m_transient_buffer_offset = 0;
|
||||
}
|
||||
RendererImpl* renderer;
|
||||
bool capture;
|
||||
};
|
||||
SwapCmd* swap_cmd = LUMIX_NEW(m_allocator, SwapCmd);
|
||||
swap_cmd->renderer = this;
|
||||
|
@ -859,7 +912,7 @@ struct RendererImpl final : public Renderer
|
|||
}
|
||||
|
||||
|
||||
void frame(bool capture) override
|
||||
void frame() override
|
||||
{
|
||||
PROFILE_FUNCTION();
|
||||
pushSwapCommand();
|
||||
|
|
|
@ -80,7 +80,9 @@ class LUMIX_RENDERER_API Renderer : public IPlugin
|
|||
enum { MAX_SHADER_DEFINES = 32 };
|
||||
public:
|
||||
virtual ~Renderer() {}
|
||||
virtual void frame(bool capture) = 0;
|
||||
virtual void startCapture() = 0;
|
||||
virtual void stopCapture() = 0;
|
||||
virtual void frame() = 0;
|
||||
virtual void resize(int width, int height) = 0;
|
||||
virtual void makeScreenshot(const Path& filename) = 0;
|
||||
virtual u8 getShaderDefineIdx(const char* define) = 0;
|
||||
|
@ -112,6 +114,7 @@ class LUMIX_RENDERER_API Renderer : public IPlugin
|
|||
|
||||
virtual ffr::TextureHandle createTexture(uint w, uint h, ffr::TextureFormat format, u32 flags, const MemRef& memory) = 0;
|
||||
virtual ffr::TextureHandle loadTexture(const MemRef& memory, u32 flags, ffr::TextureInfo* info) = 0;
|
||||
virtual void getTextureImage(ffr::TextureHandle texture, int size, void* data) = 0;
|
||||
virtual void destroy(ffr::TextureHandle tex) = 0;
|
||||
|
||||
virtual void push(RenderCommandBase* cmd) = 0;
|
||||
|
|
|
@ -63,6 +63,7 @@ const Shader::Program& Shader::getProgram(RenderData* rd, u32 defines)
|
|||
" float u_light_intensity;\n"
|
||||
" float u_light_indirect_intensity;\n"
|
||||
" float u_time;\n"
|
||||
" ivec2 u_framebuffer_size;\n"
|
||||
"};\n"
|
||||
"uniform samplerCube u_irradiancemap;\n"
|
||||
"uniform samplerCube u_radiancemap;\n"
|
||||
|
@ -94,7 +95,7 @@ const Shader::Program& Shader::getProgram(RenderData* rd, u32 defines)
|
|||
|
||||
for(int& i : program.attribute_by_semantics) i = -1;
|
||||
// TODO shader path - last argument
|
||||
program.handle = ffr::createProgram(codes, types, rd->sources.size(), prefixes, 2 + defines_count, "TODO");
|
||||
program.handle = ffr::createProgram(codes, types, rd->sources.size(), prefixes, 2 + defines_count, rd->path.c_str());
|
||||
program.use_semantics = false;
|
||||
if (program.handle.isValid()) {
|
||||
ffr::uniformBlockBinding(program.handle, "GlobalState", 0);
|
||||
|
@ -397,6 +398,7 @@ bool Shader::load(FS::IFile& file)
|
|||
|
||||
IAllocator& allocator = m_renderer.getAllocator();
|
||||
m_render_data = LUMIX_NEW(allocator, RenderData)(m_renderer, allocator);
|
||||
m_render_data->path = getPath();
|
||||
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "this");
|
||||
|
|
|
@ -101,6 +101,7 @@ public:
|
|||
Array<Source> sources;
|
||||
Array<u8> include;
|
||||
Array<AttributeInfo> attributes;
|
||||
Path path;
|
||||
}* m_render_data;
|
||||
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue