mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-03 14:10:33 +03:00
0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
Metallic-Roughness shading model Graphic3d_TOSM_PBR has been implemented. New materials descriptors Graphic3d_PBRMaterial have been added to Graphic3d_MaterialAspect. PBR shading model requires OpenGL 3.0+ or OpenGL ES 3.0+ hardware. Environment cubemap is expected to be provided for realistic look of metallic materials. occLight_IsHeadlight() now returns bool instead of int. Avoid using lowp for enumerations to workaround occLight_IsHeadlight() ignorance on Adreno 308 caused by some GLSL optimizator bugs. OpenGl_Texture::EstimatedDataSize() - fixed estimation for Cubemap textures. OpenGl_Sampler::applySamplerParams() - fixed uninitialized GL_TEXTURE_WRAP_R in case of GL_TEXTURE_CUBE_MAP target.
This commit is contained in:
@@ -39,6 +39,8 @@
|
||||
#include <OpenGl_Structure.hxx>
|
||||
#include <OpenGl_ArbFBO.hxx>
|
||||
|
||||
#include "../Textures/Textures_EnvLUT.pxx"
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Format Frame Buffer format for logging messages.
|
||||
@@ -344,6 +346,65 @@ void OpenGl_View::Redraw()
|
||||
}
|
||||
}
|
||||
|
||||
// process PBR environment
|
||||
if (myShadingModel == Graphic3d_TOSM_PBR
|
||||
|| myShadingModel == Graphic3d_TOSM_PBR_FACET)
|
||||
{
|
||||
if (!myPBREnvironment.IsNull()
|
||||
&& myPBREnvironment->SizesAreDifferent (myRenderParams.PbrEnvPow2Size,
|
||||
myRenderParams.PbrEnvSpecMapNbLevels))
|
||||
{
|
||||
myPBREnvironment->Release (aCtx.get());
|
||||
myPBREnvironment.Nullify();
|
||||
myPBREnvState = OpenGl_PBREnvState_NONEXISTENT;
|
||||
myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
|
||||
++myLightsRevision;
|
||||
}
|
||||
|
||||
if (myPBREnvState == OpenGl_PBREnvState_NONEXISTENT
|
||||
&& aCtx->HasPBR())
|
||||
{
|
||||
myPBREnvironment = OpenGl_PBREnvironment::Create (aCtx, myRenderParams.PbrEnvPow2Size, myRenderParams.PbrEnvSpecMapNbLevels);
|
||||
myPBREnvState = myPBREnvironment.IsNull() ? OpenGl_PBREnvState_UNAVAILABLE : OpenGl_PBREnvState_CREATED;
|
||||
if (myPBREnvState == OpenGl_PBREnvState_CREATED)
|
||||
{
|
||||
Handle(OpenGl_Texture) anEnvLUT;
|
||||
static const TCollection_AsciiString THE_SHARED_ENV_LUT_KEY("EnvLUT");
|
||||
if (!aCtx->GetResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT))
|
||||
{
|
||||
Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams();
|
||||
aParams->SetFilter (Graphic3d_TOTF_BILINEAR);
|
||||
aParams->SetRepeat (Standard_False);
|
||||
aParams->SetTextureUnit (aCtx->PBREnvLUTTexUnit());
|
||||
anEnvLUT = new OpenGl_Texture(THE_SHARED_ENV_LUT_KEY, aParams);
|
||||
Handle(Image_PixMap) aPixMap = new Image_PixMap();
|
||||
aPixMap->InitWrapper (Image_Format_RGF, (Standard_Byte*)Textures_EnvLUT, Textures_EnvLUTSize, Textures_EnvLUTSize);
|
||||
OpenGl_TextureFormat aTexFormat = OpenGl_TextureFormat::FindFormat (aCtx, aPixMap->Format(), false);
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
// GL_RG32F is not texture-filterable format on OpenGL ES without OES_texture_float_linear extension.
|
||||
// GL_RG16F is texture-filterable since OpenGL ES 3.0 and can be initialized from 32-bit floats.
|
||||
// Note that it is expected that GL_RG16F has enough precision for this table, so that it can be used also on desktop OpenGL.
|
||||
//if (!aCtx->hasTexFloatLinear)
|
||||
aTexFormat.SetInternalFormat (GL_RG16F);
|
||||
#endif
|
||||
if (!aTexFormat.IsValid()
|
||||
|| !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TOT_2D, aPixMap.get()))
|
||||
{
|
||||
aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Failed allocation of LUT for PBR");
|
||||
anEnvLUT.Nullify();
|
||||
}
|
||||
aCtx->ShareResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT);
|
||||
}
|
||||
if (!anEnvLUT.IsNull())
|
||||
{
|
||||
anEnvLUT->Bind (aCtx);
|
||||
}
|
||||
myWorkspace->ApplyAspects();
|
||||
}
|
||||
}
|
||||
processPBREnvRequest (aCtx);
|
||||
}
|
||||
|
||||
// create color and coverage accumulation buffers required for OIT algorithm
|
||||
if (toUseOit)
|
||||
{
|
||||
@@ -938,7 +999,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
|| aLightsRevision != myLightsRevision)
|
||||
{
|
||||
myLightsRevision = aLightsRevision;
|
||||
aManager->UpdateLightSourceStateTo (aLights);
|
||||
aManager->UpdateLightSourceStateTo (aLights, SpecIBLMapLevels());
|
||||
myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
|
||||
}
|
||||
|
||||
@@ -1020,7 +1081,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
}
|
||||
#endif
|
||||
|
||||
aManager->SetShadingModel (myShadingModel);
|
||||
aManager->SetShadingModel (OpenGl_ShaderManager::PBRShadingModelFallback (myShadingModel, checkPBRAvailability()));
|
||||
|
||||
// Redraw 3d scene
|
||||
if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
|
||||
@@ -1848,3 +1909,64 @@ bool OpenGl_View::chooseOitColorConfiguration (const Handle(OpenGl_Context)& the
|
||||
}
|
||||
return false; // color combination does not exist
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : checkPBRAvailability
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_View::checkPBRAvailability() const
|
||||
{
|
||||
return myWorkspace->GetGlContext()->HasPBR()
|
||||
&& !myPBREnvironment.IsNull();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : bakePBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
const Handle(OpenGl_TextureSet)& aTextureSet = myCubeMapParams->TextureSet (theCtx);
|
||||
if (!aTextureSet.IsNull()
|
||||
&& !aTextureSet->IsEmpty())
|
||||
{
|
||||
myPBREnvironment->Bake (theCtx,
|
||||
aTextureSet->First(),
|
||||
myBackgroundCubeMap->ZIsInverted(),
|
||||
myBackgroundCubeMap->IsTopDown(),
|
||||
myRenderParams.PbrEnvBakingDiffNbSamples,
|
||||
myRenderParams.PbrEnvBakingSpecNbSamples,
|
||||
myRenderParams.PbrEnvBakingProbability);
|
||||
}
|
||||
else
|
||||
{
|
||||
myPBREnvironment->Clear (theCtx);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : clearPBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::clearPBREnvironment (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
myPBREnvironment->Clear (theCtx);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : clearPBREnvironment
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_View::processPBREnvRequest (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
if (myPBREnvState == OpenGl_PBREnvState_CREATED)
|
||||
{
|
||||
switch (myPBREnvRequest)
|
||||
{
|
||||
case OpenGl_PBREnvRequest_NONE: return;
|
||||
case OpenGl_PBREnvRequest_BAKE: bakePBREnvironment (theCtx); break;
|
||||
case OpenGl_PBREnvRequest_CLEAR: clearPBREnvironment (theCtx); break;
|
||||
}
|
||||
}
|
||||
myPBREnvRequest = OpenGl_PBREnvRequest_NONE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user