efkbgfx icon indicating copy to clipboard operation
efkbgfx copied to clipboard

Particles Messed Up

Open michaelsgames opened this issue 3 years ago • 12 comments

I added the base to my engine, same as the example, compiled the shaders got them loading, same as in git. I tested out Laser01.efk as well as the others, and this is the kind of results I am getting. Laser01

michaelsgames avatar Apr 04 '22 13:04 michaelsgames

@junjie020

cloudwu avatar Apr 05 '22 02:04 cloudwu

@michaelsgames Could you tell me more info? Like, which platform, renderer(OpenGL, DX)? Or some code?

junjie020 avatar Apr 06 '22 02:04 junjie020

@michaelsgames Could you try current HEAD ? I fixed some BGFX transient vertex buffer issue.

cloudwu avatar Apr 06 '22 07:04 cloudwu

I was using DX12, then I switched to DX11 to see if that was in fact the issue. Init code

void Scene::Init() {
 skybox->Init();

 auto inter = bgfx_get_interface(BGFX_API_VERSION);

 bgfx::setViewMode(1, bgfx::ViewMode::Sequential);

 /**
  * Initialize Effekseer
  */
 EffekseerRendererBGFX::InitArgs efkArgs {
         2048, 199, inter,
         Scene::ShaderLoad,
         Scene::TextureLoad,
         Scene::TextureGet,
         Scene::TextureUnload,
         this,
 };

 m_sceneViewId = 20;
 m_sceneTex 	= bgfx::createTexture2D((*GetHatchet3D())->width, (*GetHatchet3D())->height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
 m_sceneDepth = bgfx::createTexture2D((*GetHatchet3D())->width, (*GetHatchet3D())->height, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT);
 const bgfx::TextureHandle handles[] = {m_sceneTex, m_sceneDepth};
 m_frameBuffer = bgfx::createFrameBuffer(2, handles, false);

 bgfx::setViewFrameBuffer(m_sceneViewId, m_frameBuffer);
 bgfx::setViewRect(m_sceneViewId, 0, 0, (*GetHatchet3D())->width, (*GetHatchet3D())->height);
 bgfx::setViewClear(m_sceneViewId
         , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
         , 0x30ffffff
         , 1.0f
         , 0
 );

 bgfx::ShaderHandle fs = bgfx::createShader(loadMem(getFileReader(), "Shaders/dx11/effekseer_fs_fullscreen.bin"));
 m_fullscreenProg = bgfx::createProgram(
         bgfx::createShader(loadMem(getFileReader(), "Shaders/dx11/effekseer_vs_fullscreen.bin")),
         fs,
         true);

 bgfx::UniformHandle uniforms[16];
 uint32_t numUniform = bgfx::getShaderUniforms(fs, uniforms, 16);
 for (uint32_t ii=0; ii<numUniform; ++ii){
     bgfx::UniformInfo info;
     const bgfx::UniformHandle h = uniforms[ii];
     bgfx::getUniformInfo(h, info);
     if (info.name == "s_scene"){
         m_fullscreenTextureUniformHandle = h;
         break;
     }
 }

 m_efkRenderer = EffekseerRendererBGFX::CreateRenderer(&efkArgs);
 m_efkManager = Effekseer::Manager::Create(8000);
 m_efkManager->GetSetting()->SetCoordinateSystem(Effekseer::CoordinateSystem::LH);

 m_efkManager->SetModelRenderer(CreateModelRenderer(m_efkRenderer, &efkArgs));
 m_efkManager->SetSpriteRenderer(m_efkRenderer->CreateSpriteRenderer());
 m_efkManager->SetRibbonRenderer(m_efkRenderer->CreateRibbonRenderer());
 m_efkManager->SetRingRenderer(m_efkRenderer->CreateRingRenderer());
 m_efkManager->SetTrackRenderer(m_efkRenderer->CreateTrackRenderer());
 m_efkManager->SetTextureLoader(m_efkRenderer->CreateTextureLoader());
 m_efkManager->SetModelLoader(m_efkRenderer->CreateModelLoader());
 m_efkManager->SetMaterialLoader(m_efkRenderer->CreateMaterialLoader());
 m_efkManager->SetCurveLoader(Effekseer::MakeRefPtr<Effekseer::CurveLoader>());
bgfx_texture_handle_t Scene::TextureGet(int texture_type, void *parm, void *ud) {
    Scene *that = (Scene *)ud;
    if (texture_type == TEXTURE_BACKGROUND)
        return {that->m_sceneTex.idx};

    if (texture_type == TEXTURE_DEPTH){
        EffekseerRenderer::DepthReconstructionParameter *p = (EffekseerRenderer::DepthReconstructionParameter*)parm;
        p->DepthBufferScale = 1.0f;
        p->DepthBufferOffset = 0.0f;

        p->ProjectionMatrix33 = (*that->GetCurrentCamera())->projMatrix()[2][2];
        p->ProjectionMatrix34 = (*that->GetCurrentCamera())->projMatrix()[2][3];
        p->ProjectionMatrix43 = (*that->GetCurrentCamera())->projMatrix()[3][2];
        p->ProjectionMatrix44 = (*that->GetCurrentCamera())->projMatrix()[4][4];
        return {that->m_sceneDepth.idx};
    }
    assert(false && "invalid texture type");
    return {BGFX_INVALID_HANDLE};
}

bgfx_shader_handle_t Scene::ShaderLoad(const char *mat, const char *name, const char *type, void *ud) {
    assert(mat == nullptr);
    const char* shaderfile = findShaderFile(name, type);
    bgfx::ShaderHandle handle = bgfx::createShader(loadMem(getFileReader(), shaderfile) );
    bgfx::setName(handle, shaderfile);

    return bgfx_shader_handle_t{handle.idx};
}

bgfx::TextureHandle Scene::createTexture(const char *filename, uint64_t state) {
    if (isPngFile(filename)){
        auto image = imageLoad(filename, bgfx::TextureFormat::RGBA8);
        assert(image && "invalid png file");
        auto h = bgfx::createTexture2D(
                (uint16_t)image->m_width
                , (uint16_t)image->m_height
                , false
                , 1
                , bgfx::TextureFormat::BGRA8
                , state
                , bgfx::copy(image->m_data, image->m_size)
        );
        imageFree(image);
        return h;
    }

    return bgfx::createTexture(loadMem(getFileReader(), filename), state);
}

bgfx_texture_handle_t Scene::TextureLoad(const char *name, int srgb, void *ud) {
    const uint64_t state = (srgb ? BGFX_TEXTURE_SRGB : BGFX_TEXTURE_NONE)|BGFX_SAMPLER_NONE;
    auto handle = createTexture(name, state);
    bgfx::setName(handle, name);
    return {handle.idx};
}

void Scene::TextureUnload(bgfx_texture_handle_t handle, void *ud) {
    bgfx::destroy(bgfx::TextureHandle{handle.idx});
}

Render Code

void Renderer::blitToScreen(bgfx::ViewId view)
{
    //Cut out code you don't need to see 
    /**
     * Render Particles
     */
    if(GetCurrentH3DProject() != nullptr){
        if(H3DGetCurrentScene() != nullptr){
            (*H3DGetCurrentScene())->h3dScene->m_efkRenderer->BeginRendering();

            Effekseer::Manager::DrawParameter drawParams;
            drawParams.ZNear = 0.0f;
            drawParams.ZFar = 1.0f;
            drawParams.ViewProjectionMatrix = (*H3DGetCurrentScene())->h3dScene->m_efkRenderer->GetCameraProjectionMatrix();
            (*H3DGetCurrentScene())->h3dScene->m_efkManager->Draw(drawParams);

            (*H3DGetCurrentScene())->h3dScene->m_efkRenderer->EndRendering();
        }
    }
}

Emitter class / Init

void H3DEmitter::InitComponent() {
    efkEffect = Effekseer::Effect::Create((*H3DGetCurrentScene())->h3dScene->m_efkManager, u"C:\\Users\\micha\\Desktop\\MichaelsTutorials\\DisturbedArts\\Hatchet3D\\bin\\Example\\Data\\resources\\Laser01.efk");
    efkEffectHandle = (*H3DGetCurrentScene())->h3dScene->m_efkManager->Play(efkEffect, 0, 0, 0);
}

I'll try HEAD once I get some more free time, just wanted to show you this. If we can get this fixed, I'll be very impressed and happy to save a ton of time! Awesome work so far!

EDIT: Almost forgot the camera / projection code!

void Renderer::setViewProjection(bgfx::ViewId view, bool setViewTrans)
{
    // view matrix
    viewMat = (*((*H3DGetCurrentScene()))->h3dScene->GetCurrentCamera())->matrix();
    // projection matrix
    bx::mtxProj(glm::value_ptr(projMat),
                (*((*H3DGetCurrentScene()))->h3dScene->GetCurrentCamera())-> fov,
                float(width) / height,
                (*((*H3DGetCurrentScene()))->h3dScene->GetCurrentCamera())->zNear,
                (*((*H3DGetCurrentScene()))->h3dScene->GetCurrentCamera())->zFar,
                bgfx::getCaps()->homogeneousDepth,
                bx::Handness::Left);
    bgfx::setViewTransform(view, glm::value_ptr(viewMat), glm::value_ptr(projMat));

    Effekseer::Matrix44	m_projMat;
    Effekseer::Matrix44	m_viewMat;


    for(int x = 0; x < 4; x++){
        for(int y = 0; y < 4; y++){
            m_viewMat.Values[x][y] = viewMat[x][y];
        }
    }

    for(int x = 0; x < 4; x++){
        for(int y = 0; y < 4; y++){
            m_projMat.Values[x][y] = projMat[x][y];
        }
    }

    (*H3DGetCurrentScene())->h3dScene->m_efkRenderer->SetProjectionMatrix(m_projMat);
    (*H3DGetCurrentScene())->h3dScene->m_efkRenderer->SetCameraMatrix(m_viewMat);

    if(setViewTrans){
        bgfx::setViewTransform(view, m_viewMat.Values, m_projMat.Values);
    }
}

michaelsgames avatar Apr 06 '22 11:04 michaelsgames

Ok, all set, just tried HEAD and it works flawlessly! Epic! Thank you so much!

michaelsgames avatar Apr 06 '22 11:04 michaelsgames

bgfx still has some issues with multiple layouts dynamic vertex buffer. Maybe I need to rewrite StandardRenderer (https://github.com/effekseer/Effekseer/blob/master/Dev/Cpp/EffekseerRendererCommon/EffekseerRenderer.StandardRenderer.h#L278 ) to avoid them.

cloudwu avatar Apr 06 '22 13:04 cloudwu

@michaelsgames The StandardRenderer is rewritten https://github.com/cloudwu/efkbgfx/pull/15 .

cloudwu avatar Apr 07 '22 07:04 cloudwu

Ok got time again, adding the rewrite now. Will edit and let you know how it goes. EDIT 3: Ok fixed altogether. Epic!

https://gyazo.com/e9fe7d37becafe02a5ce67c8701da807

At this point I'd say it's time to look into making it perform a bit better with more particles.

michaelsgames avatar Apr 09 '22 11:04 michaelsgames

If you add about 4 of the sword lightning fx to the scene, it crashes my client. Definitely going to want to look into performance here, EDIT: Appears to just be the lightning acting out.

michaelsgames avatar Apr 09 '22 14:04 michaelsgames

@michaelsgames I add 4 sword lightning effect, but no crash appear.

Corld you take a try with my new example?

junjie020 avatar Apr 11 '22 02:04 junjie020

I ended up fixing that, was something I changed in my own code, works great! Does it currently support rotating the fx? I might also add a tint uniform so we can color them differently.

michaelsgames avatar Apr 11 '22 13:04 michaelsgames

What about rotating the fx? You mean efkManager->SetRotation(efkhandle, x, y, z) ?

junjie020 avatar Apr 27 '22 03:04 junjie020