Re: Modify Material opacity via C++ code

#14
In MaterialHelpers::SetXmlFromLighting

Code: Select all

node->setAttr("Opacity", pShaderResources.m_LMaterial.m_Opacity);

CMatMan::InitDefaults()

Code: Select all

SInputShaderResourcesPtr pIsr = GetRenderer()->EF_CreateInputShaderResource(); pIsr->m_LMaterial.m_Opacity = 1; pIsr->m_LMaterial.m_Diffuse.set(1, 1, 1, 1); pIsr->m_Textures[EFTT_DIFFUSE].m_Name = szReplaceMe; SShaderItem si = GetRenderer()->EF_LoadShaderItem(shader_name, true, 0, pIsr); if (si.m_pShaderResources) si.m_pShaderResources->SetMaterialName(mat_name); mi->AssignShaderItem(si);
and
IEntity::SetOpacity(float fAmount)

Re: Modify Material opacity via C++ code

#15
Okay, I did further tests and got the following results.
1. "diffuse" modifications do work without problems
2. "opacity" modifications DO WORK ->ONLY<- if the transparency does not reach 1.f

So with a material which opacity value is < 1 by default can be modifed to all values. But as soon as I set the opacity parameter to 1.f once, it never can get transparent again.
I started at 0.5, and switched it between 0.1 and 0.9. After switching to 1.f which removed transparency, it never was able to go back to values beneath 1.f.

The described behavior does occur when using this function:

Code: Select all

pMat->SetGetMaterialParamFloat("opacity", m_fTransparentValue, false);

Code: Select all

GetEntity()->SetOpacity(0.1f);
The above one does not work at all. No matter what I set as value, he does set transparency to 1.f all the time.

Not sure why this happens. I need both states but maybe I just have to write my own shader for it.
Last edited by savi on Thu Jul 20, 2017 4:43 pm, edited 2 times in total.

Re: Modify Material opacity via C++ code

#18
After all this time I can put the answer to this thread. Thanks @Cry-Flare for providing that solution. This can be used as a workaround due issues in the engines shader/texture/flags handling. It is not meant as final solution, is not that much tested and therefore really just acts as a temporary unofficial workaround until the issues gets resolved on the engine side.
Also it could cause crashes when there is no normal map assigned.

Code: Select all

void SetOpacity(const char * szEntityName, float fValue)
{
if (IEntity* pEntity = gEnv->pEntitySystem->FindEntityByName(szEntityName))
{
if (IRenderNode* pRenderNode = pEntity->GetRenderNode())
{
if (IMaterial* pMaterial = pRenderNode->GetMaterial())
{
const SShaderItem& oldShaderItem = pMaterial->GetShaderItem();

// Create new shader resources
SInputShaderResources* pInputShaderResources = gEnv->pRenderer->EF_CreateInputShaderResource(oldShaderItem.m_pShaderResources);

// Set material property
pInputShaderResources->m_LMaterial.m_Opacity = fValue;

// Refresh the shader item with the new resources
SShaderItem newShaderItem = gEnv->pRenderer->EF_LoadShaderItem(oldShaderItem.m_pShader->GetName(), false, oldShaderItem.m_pShader->GetFlags(), pInputShaderResources);

// Assign the new shader item to the material
pMaterial->AssignShaderItem(newShaderItem);

// Sync with render thread so we dont get any pop-in
gEnv->pRenderer->FlushRTCommands(true, true, true);
}
}
}
}

Who is online

Users browsing this forum: No registered users and 2 guests

cron