Page 1 of 1

[2.1] Emissive textures not working?

Posted: Wed Jun 12, 2019 11:57 am
by elisagroup
Hello!

I'm trying to do a cheap simulation of a ceiling lights. For that I use multiple light sources and an emissve texture that is supposed to brighthen the spots on the ceiling where the light sources are located. I can't seem to get neither emissive colors nor emissive textures to work on Ogre 2.1 (latest code from v2-1 branch in the ogrecave repository). Here's the code I'm using:

Code: Select all


    ...

   // Create ceiling texture
    Ogre::TexturePtr ccText = Ogre::TextureManager::getSingleton().createManual(textureName, "Textures", Ogre::TEX_TYPE_2D, imgWidth, imgHeight, Ogre::MIP_UNLIMITED, Ogre::PF_A8R8G8B8, Ogre::TU_DEFAULT);
    Ogre::v1::HardwarePixelBufferSharedPtr pixelBuffer = ccText->getBuffer();
    pixelBuffer->lock(Ogre::v1::HardwareBuffer::HBL_DISCARD);
    const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
    Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
    memset(pDest, 0, ccText->getWidth() * ccText->getHeight() * 4);
    QImage hud(pDest, ccText->getWidth(), ccText->getHeight(), QImage::Format_ARGB32);
    QPainter painter1(&hud);
    painter1.drawImage(QRect(0, ccText->getHeight() - imgHeight, imgWidth, imgHeight), ccImage, QRect(0, 0, ccImage.width(), ccImage.height()));
    painter1.end();
    pixelBuffer->unlock();


    // Create ceiling emissive texture

    QImage emissiveTextureImage;
    generateEmissiveTextureImage(imgWidth, imgHeight, emissiveTextureImage);

    Ogre::String emissiveTextureName = "CeilTexture_" + typeName + "_emissive.jpg";
    Ogre::TexturePtr emissiveTexture = Ogre::TextureManager::getSingletonPtr()->getByName(emissiveTextureName);
    if(emissiveTexture.isNull())
    {
        emissiveTexture = Ogre::TextureManager::getSingleton().createManual(
            emissiveTextureName,
            "Textures",
            Ogre::TEX_TYPE_2D,
            imgWidth,
            imgHeight,
            Ogre::MIP_UNLIMITED,
            Ogre::PF_A8R8G8B8,
            Ogre::TU_DEFAULT
        );
        Ogre::v1::HardwarePixelBufferSharedPtr pixelBuffer = emissiveTexture->getBuffer();
        pixelBuffer->lock(Ogre::v1::HardwareBuffer::HBL_DISCARD);
        const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
        Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
        memset(pDest, 0, emissiveTexture->getWidth() * emissiveTexture->getHeight() * 4);
        QImage hud(pDest, emissiveTexture->getWidth(), emissiveTexture->getHeight(), QImage::Format_ARGB32);
        QPainter painter(&hud);
        painter.drawImage(
            QRect(0, emissiveTexture->getHeight() - imgHeight, imgWidth, imgHeight),
            emissiveTextureImage,
            QRect(0, 0, emissiveTextureImage.width(), emissiveTextureImage.height())
        );
        painter.end();
        pixelBuffer->unlock();
    }

    // apply regular texture
    MaterialManager::getSingletonPtr()->SetDatablockTexturePtrPbs(dataBlock, Ogre::PBSM_DETAIL0, ccText);
    MaterialManager::getSingletonPtr()->SetDatablockTexturePtrPbs(dataBlock, Ogre::PBSM_DETAIL0_NM, ccText);
    MaterialManager::getSingletonPtr()->SetDatablockTextureMappingPbs(dataBlock, Ogre::PBSM_DETAIL0, Ogre::TAM_WRAP, Ogre::TFO_ANISOTROPIC);
    MaterialManager::getSingletonPtr()->SetDatablockTextureMappingPbs(dataBlock, Ogre::PBSM_DETAIL0_NM, Ogre::TAM_WRAP, Ogre::TFO_ANISOTROPIC);

    // apply emissive texture
    // MaterialManager::getSingletonPtr()->SetDatablockTexturePtrPbs(dataBlock, Ogre::PBSM_EMISSIVE, emissiveTexture);
    // MaterialManager::getSingletonPtr()->SetDatablockTextureMappingPbs(dataBlock, Ogre::PBSM_EMISSIVE, Ogre::TAM_WRAP, Ogre::TFO_ANISOTROPIC);

    Ogre::HlmsPbsDatablock *pbs = static_cast<Ogre::HlmsPbsDatablock*>(dataBlock);
    pbs->setDiffuse(Ogre::Vector3(1.1, 1.1, 1.1)); // make the ceiling 10% brighter

    // apply emissive texture
    //pbs->setEmissive(Ogre::Vector3(1.0, 1.0, 1.0));    // <- emissive colors doesn't work either
    pbs->setTexture(Ogre::PBSM_EMISSIVE, 0, emissiveTexture);

And here's the implementation of MaterialManager::SetDatablockTexturePtrPbs() method:

Code: Select all

void MaterialManager::SetDatablockTexturePtrPbs(Ogre::HlmsDatablock* dataBlock, Ogre::PbsTextureTypes type, Ogre::TexturePtr texture, int uvSet)
{
	Ogre::HlmsManager* hlmsMgr = Ogre::Root::getSingleton().getHlmsManager();
	Ogre::HlmsTextureManager *hlmsTextureManager = hlmsMgr->getTextureManager();

	Ogre::HlmsPbsDatablock *pbsBlock = static_cast<Ogre::HlmsPbsDatablock*>(dataBlock);
	pbsBlock->setTexture(type, 0, texture);
	pbsBlock->setTextureUvSource(type, uvSet);
}
Qt-generated textures look correct and work fine if I assign them to PBSM_DETAIL0, but doesn't work with PBSM_EMISSIVE. Is there anything I'm doing wrong?

Any help would be greatly appreciated

Re: [2.1] Emissive textures not working?

Posted: Thu Jun 13, 2019 12:09 am
by TaaTT4
Shouldn't the emissive texture use floating values greater than 1.0? Use PF_FLOAT16 as pixel format and generate a floating point texture with "high" values (I'm not sure QT is able to do this).

Re: [2.1] Emissive textures not working?

Posted: Thu Jun 13, 2019 12:49 am
by dark_sylinc
If you're doing HDR rendering, TaaTT4 could be be right. The emissive texture may be getting applied but it's just not bright enough to be noticeable.

Instead of using FLOAT16 textures, try multiplying the colour to scale it up, e.g. pbsDatablock->setEmissive( Ogre::Vector3( 20.0f ) );

Edit: This is important: Create your texture as TEX_TYPE_2D_ARRAY, you're currently creating it as TEX_TYPE_2D.

Re: [2.1] Emissive textures not working?

Posted: Thu Jun 13, 2019 7:46 am
by elisagroup
Thank you both for your response! I'm not using HDR. will try your suggestion.

Cheers