Graphic3d_TextureUnit.hxx
Graphic3d_TextureSet.cxx
Graphic3d_TextureSet.hxx
+Graphic3d_TextureSetBits.hxx
Graphic3d_ToneMappingMethod.hxx
Graphic3d_TransformError.hxx
Graphic3d_TransformPers.hxx
aBsdf.Ks.SetValues (Graphic3d_Vec3 (thePbr.Alpha()), aRougness2);
aBsdf.Kt = Graphic3d_Vec3 (1.0f - thePbr.Alpha());
aBsdf.Kd = aDiff * (1.0f - thePbr.Metallic());
+ aBsdf.Le = thePbr.Emission();
return aBsdf;
}
: myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
+ myTextureSetBits (Graphic3d_TextureSetBits_NONE),
myHasDefSampler (true),
myHasAlphaTest (false),
myHasWeightOitOutput (false),
#include <Graphic3d_ShaderObject.hxx>
#include <Graphic3d_ShaderVariable.hxx>
#include <Graphic3d_TextureParams.hxx>
+#include <Graphic3d_TextureSetBits.hxx>
#include <NCollection_Sequence.hxx>
//! List of shader objects.
void SetWeightOitOutput (Standard_Boolean theOutput) { myHasWeightOitOutput = theOutput; }
//! Return TRUE if standard program header should define functions and variables used in PBR pipeline.
- //! FALSE by default
+ //! FALSE by default.
Standard_Boolean IsPBR() const { return myIsPBR; }
//! Sets whether standard program header should define functions and variables used in PBR pipeline.
void SetPBR (Standard_Boolean theIsPBR) { myIsPBR = theIsPBR; }
+ //! Return texture units declared within the program, @sa Graphic3d_TextureSetBits.
+ Standard_Integer TextureSetBits() const { return myTextureSetBits; }
+
+ //! Set texture units declared within the program.
+ void SetTextureSetBits (Standard_Integer theBits) { myTextureSetBits = theBits; }
+
//! Pushes custom uniform variable to the program.
//! The list of pushed variables is automatically cleared after applying to GLSL program.
//! Thus after program recreation even unchanged uniforms should be pushed anew.
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
+ Standard_Integer myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
Standard_Boolean myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader performs alpha test
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
--- /dev/null
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_TextureSetBits_HeaderFile
+#define _Graphic3d_TextureSetBits_HeaderFile
+
+#include <Graphic3d_TextureUnit.hxx>
+
+//! Standard texture units combination bits.
+enum Graphic3d_TextureSetBits
+{
+ Graphic3d_TextureSetBits_NONE = 0,
+ Graphic3d_TextureSetBits_BaseColor = (unsigned int )(1 << int(Graphic3d_TextureUnit_BaseColor)),
+ Graphic3d_TextureSetBits_Emissive = (unsigned int )(1 << int(Graphic3d_TextureUnit_Emissive)),
+ Graphic3d_TextureSetBits_Occlusion = (unsigned int )(1 << int(Graphic3d_TextureUnit_Occlusion)),
+ Graphic3d_TextureSetBits_Normal = (unsigned int )(1 << int(Graphic3d_TextureUnit_Normal)),
+ Graphic3d_TextureSetBits_MetallicRoughness = (unsigned int )(1 << int(Graphic3d_TextureUnit_MetallicRoughness)),
+};
+
+#endif // _Graphic3d_TextureSetBits_HeaderFile
Graphic3d_TextureUnit_14,
Graphic3d_TextureUnit_15,
- Graphic3d_TextureUnit_BaseColor = Graphic3d_TextureUnit_0, //!< base color of the material
- //Graphic3d_TextureUnit_Normal = Graphic3d_TextureUnit_1, //!< tangent space normal map
- //Graphic3d_TextureUnit_MetallicRoughness = Graphic3d_TextureUnit_2, //!< metalness+roughness of the material
- //Graphic3d_TextureUnit_Emissive = Graphic3d_TextureUnit_3, //!< emissive map controls the color and intensity of the light being emitted by the material
- //Graphic3d_TextureUnit_Occlusion = Graphic3d_TextureUnit_4, //!< occlusion map indicating areas of indirect lighting
+ // aliases
- Graphic3d_TextureUnit_EnvMap = Graphic3d_TextureUnit_0 //!< environment cubemap for background
+ //! sampler2D occSamplerBaseColor.
+ //! RGB(A) base color of the material and alpha mask/opacity.
+ Graphic3d_TextureUnit_BaseColor = Graphic3d_TextureUnit_0,
+ //! sampler2D occSamplerEmissive.
+ //! RGB emissive map controls the color and intensity of the light being emitted by the material.
+ Graphic3d_TextureUnit_Emissive = Graphic3d_TextureUnit_1,
+ //! sampler2D occSamplerOcclusion.
+ //! Occlusion map indicating areas of indirect lighting.
+ //! Encoded into RED channel, with 1.0 meaning no occlusion (full color intensity) and 0.0 complete occlusion (black).
+ Graphic3d_TextureUnit_Occlusion = Graphic3d_TextureUnit_2,
+ //! sampler2D occSamplerNormal.
+ //! XYZ tangent space normal map.
+ Graphic3d_TextureUnit_Normal = Graphic3d_TextureUnit_3,
+ //! sampler2D occSamplerMetallicRoughness.
+ //! Metalness + roughness of the material.
+ //! Encoded into GREEN (roughness) + BLUE (metallic) channels,
+ //! so that it can be optionally combined with occlusion texture (RED channel).
+ Graphic3d_TextureUnit_MetallicRoughness = Graphic3d_TextureUnit_4,
+
+ //! samplerCube occSampler0.
+ //! Environment cubemap for background. Rendered by dedicated program and normally occupies first texture unit.
+ Graphic3d_TextureUnit_EnvMap = Graphic3d_TextureUnit_0,
+
+ //! sampler2D occSamplerPointSprite.
+ //! Sprite alpha-mask or RGBA image mapped using point UV, additional to BaseColor (mapping using vertex UV).
+ //! This texture unit is set Graphic3d_TextureUnit_1, so that it can be combined with Graphic3d_TextureUnit_BaseColor,
+ //! while other texture maps (normal map and others) are unexpected and unsupported for points.
+ //! Note that it can be overridden to Graphic3d_TextureUnit_0 for FFP fallback on hardware without multi-texturing.
+ Graphic3d_TextureUnit_PointSprite = Graphic3d_TextureUnit_1,
+
+ //! sampler2D occEnvLUT.
+ //! Lookup table for approximated PBR environment lighting.
+ //! Configured as index at the end of available texture units - 3.
+ Graphic3d_TextureUnit_PbrEnvironmentLUT = -3,
+ //! sampler2D occDiffIBLMapSHCoeffs.
+ //! Diffuse (irradiance) IBL map's spherical harmonics coefficients baked for PBR from environment cubemap image.
+ //! Configured as index at the end of available texture units - 2.
+ Graphic3d_TextureUnit_PbrIblDiffuseSH = -2,
+ //! samplerCube occSpecIBLMap.
+ //! Specular IBL (Image-Based Lighting) environment map baked for PBR from environment cubemap image.
+ //! Configured as index at the end of available texture units - 1.
+ Graphic3d_TextureUnit_PbrIblSpecular = -1,
};
enum
{
- Graphic3d_TextureUnit_NB = Graphic3d_TextureUnit_15 + 1
+ Graphic3d_TextureUnit_NB = Graphic3d_TextureUnit_15 + 1,
};
#endif // _Graphic3d_TextureUnit_HeaderFile
{
// just invalidate texture parameters
aResource->Sampler()->SetParameters (aTexture->GetParams());
+ aResIter.ChangeUnit() = aResource->Sampler()->Parameters()->TextureUnit();
}
}
}
}
}
+ Standard_Integer& aTextureSetBits = myTextures[0]->ChangeTextureSetBits();
+ aTextureSetBits = Graphic3d_TextureSetBits_NONE;
if (theAspect->ToMapTexture())
{
Graphic3d_TextureSet::Iterator aTextureIter (aNewTextureSet);
{
if (aResource->Init(theCtx, aTexture))
{
+ aResIter0.ChangeUnit() = aResource->Sampler()->Parameters()->TextureUnit();
aResource->Sampler()->SetParameters(aTexture->GetParams());
aResource->SetRevision (aTexture->Revision());
}
}
aResource->Sampler()->SetParameters (aTexture->GetParams());
}
+
+ // update occupation of texture units
+ const Graphic3d_TextureUnit aTexUnit = aResource->Sampler()->Parameters()->TextureUnit();
+ aResIter0.ChangeUnit() = aTexUnit;
+ if (aTexUnit >= Graphic3d_TextureUnit_0 && aTexUnit <= Graphic3d_TextureUnit_5)
+ {
+ aTextureSetBits |= (1 << int(aTexUnit));
+ }
}
}
}
if (hasSprite)
{
myTextures[0]->ChangeLast() = theSprite;
+ myTextures[0]->ChangeLastUnit() = theCtx->SpriteTextureUnit();
+ // Graphic3d_TextureUnit_PointSprite
if (!theSprite.IsNull())
{
theSprite ->Sampler()->Parameters()->SetTextureUnit (theCtx->SpriteTextureUnit());
return;
}
+ myTextures[1]->ChangeTextureSetBits() = aTextureSetBits;
for (OpenGl_TextureSet::Iterator aResIter0 (myTextures[0]), aResIter1 (myTextures[1]); aResIter0.More(); aResIter0.Next(), aResIter1.Next())
{
aResIter1.ChangeValue() = aResIter0.Value();
+ aResIter1.ChangeUnit() = aResIter0.Unit();
}
if (hasSprite)
{
myTextures[1]->ChangeLast() = theSpriteA;
+ myTextures[1]->ChangeLastUnit() = theCtx->SpriteTextureUnit();
}
}
myIsInitialized (Standard_False),
myIsStereoBuffers (Standard_False),
myIsGlNormalizeEnabled (Standard_False),
- mySpriteTexUnit (Graphic3d_TextureUnit_0),
+ mySpriteTexUnit (Graphic3d_TextureUnit_PointSprite),
myHasRayTracing (Standard_False),
myHasRayTracingTextures (Standard_False),
myHasRayTracingAdaptiveSampling (Standard_False),
myHasRayTracingAdaptiveSamplingAtomic (Standard_False),
myHasPBR (Standard_False),
- myPBREnvLUTTexUnit (Graphic3d_TextureUnit_0),
- myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_0),
- myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_0),
+ myPBREnvLUTTexUnit (Graphic3d_TextureUnit_PbrEnvironmentLUT),
+ myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH),
+ myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_PbrIblSpecular),
myFrameStats (new OpenGl_FrameStats()),
+ myActiveMockTextures (0),
#if !defined(GL_ES_VERSION_2_0)
myPointSpriteOrig (GL_UPPER_LEFT),
myRenderMode (GL_RENDER),
myDefaultVao = 0;
#endif
+ // release mock textures
+ if (!myTextureRgbaBlack.IsNull())
+ {
+ myTextureRgbaBlack->Release (this);
+ myTextureRgbaBlack.Nullify();
+ }
+ if (!myTextureRgbaWhite.IsNull())
+ {
+ myTextureRgbaWhite->Release (this);
+ myTextureRgbaWhite.Nullify();
+ }
+
// release default FBO
if (!myDefaultFbo.IsNull())
{
glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
}
mySpriteTexUnit = myMaxTexCombined >= 2
- ? Graphic3d_TextureUnit_1
+ ? Graphic3d_TextureUnit_PointSprite
: Graphic3d_TextureUnit_0;
GLint aMaxVPortSize[2] = {0, 0};
);
if (myHasPBR)
{
- myPBREnvLUTTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 3);
- myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 2);
- myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 1);
+ myPBREnvLUTTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrEnvironmentLUT);
+ myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblDiffuseSH);
+ myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular);
}
}
// function : BindTextures
// purpose :
// =======================================================================
-Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures)
+Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures,
+ const Handle(OpenGl_ShaderProgram)& theProgram)
{
- if (myActiveTextures == theTextures)
- {
- return myActiveTextures;
+ const Standard_Integer aTextureSetBits = !theTextures.IsNull() ? theTextures->TextureSetBits() : 0;
+ const Standard_Integer aProgramBits = !theProgram.IsNull() ? theProgram->TextureSetBits() : 0;
+ Standard_Integer aMissingBits = aProgramBits & ~aTextureSetBits;
+ if (aMissingBits != 0
+ && myTextureRgbaBlack.IsNull())
+ {
+ // allocate mock textures
+ myTextureRgbaBlack = new OpenGl_Texture();
+ myTextureRgbaWhite = new OpenGl_Texture();
+ Image_PixMap anImage;
+ anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )0);
+ if (!myTextureRgbaBlack->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
+ {
+ PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
+ "Error: unable to create unit mock PBR texture map.");
+ }
+ anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )255);
+ if (!myTextureRgbaWhite->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
+ {
+ PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
+ "Error: unable to create normal mock PBR texture map.");
+ }
}
- Handle(OpenGl_Context) aThisCtx (this);
- OpenGl_TextureSet::Iterator aTextureIterOld (myActiveTextures), aTextureIterNew (theTextures);
- for (;;)
+ Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
+ if (myActiveTextures != theTextures)
{
- if (!aTextureIterNew.More())
+ Handle(OpenGl_Context) aThisCtx (this);
+ OpenGl_TextureSet::Iterator aTextureIterOld (myActiveTextures), aTextureIterNew (theTextures);
+ for (;;)
{
- for (; aTextureIterOld.More(); aTextureIterOld.Next())
+ if (!aTextureIterNew.More())
{
- if (const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value())
+ for (; aTextureIterOld.More(); aTextureIterOld.Next())
{
- aTextureOld->Unbind(aThisCtx);
- #if !defined(GL_ES_VERSION_2_0)
- if (core11 != NULL)
+ if (const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value())
{
- OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
+ aTextureOld->Unbind (aThisCtx, aTextureIterOld.Unit());
+ #if !defined(GL_ES_VERSION_2_0)
+ if (core11 != NULL)
+ {
+ OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
+ }
+ #endif
}
- #endif
}
+ break;
}
- break;
- }
- const Handle(OpenGl_Texture)& aTextureNew = aTextureIterNew.Value();
- if (aTextureIterOld.More())
- {
- const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value();
- if (aTextureNew == aTextureOld)
+ const Handle(OpenGl_Texture)& aTextureNew = aTextureIterNew.Value();
+ if (aTextureIterOld.More())
{
- aTextureIterNew.Next();
- aTextureIterOld.Next();
- continue;
- }
- else if (aTextureNew.IsNull()
- || !aTextureNew->IsValid())
- {
- if (!aTextureOld.IsNull())
+ const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value();
+ if (aTextureNew == aTextureOld
+ && aTextureIterNew.Unit() == aTextureIterOld.Unit())
{
- aTextureOld->Unbind(aThisCtx);
- #if !defined(GL_ES_VERSION_2_0)
- if (core11 != NULL)
+ aTextureIterNew.Next();
+ aTextureIterOld.Next();
+ continue;
+ }
+ else if (aTextureNew.IsNull()
+ || !aTextureNew->IsValid())
+ {
+ if (!aTextureOld.IsNull())
{
- OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
+ aTextureOld->Unbind (aThisCtx, aTextureIterOld.Unit());
+ #if !defined(GL_ES_VERSION_2_0)
+ if (core11 != NULL)
+ {
+ OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
+ }
+ #endif
}
- #endif
+
+ aTextureIterNew.Next();
+ aTextureIterOld.Next();
+ continue;
}
- aTextureIterNew.Next();
aTextureIterOld.Next();
+ }
+ if (aTextureNew.IsNull())
+ {
+ aTextureIterNew.Next();
continue;
}
- aTextureIterOld.Next();
- }
- if (aTextureNew.IsNull())
- {
- aTextureIterNew.Next();
- continue;
- }
-
- const Graphic3d_TextureUnit aTexUnit = aTextureNew->Sampler()->Parameters()->TextureUnit();
- if (aTexUnit >= myMaxTexCombined)
- {
- PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
- aTextureIterNew.Next();
- continue;
- }
+ const Graphic3d_TextureUnit aTexUnit = aTextureIterNew.Unit();
+ if (aTexUnit >= myMaxTexCombined)
+ {
+ PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
+ aTextureIterNew.Next();
+ continue;
+ }
- aTextureNew->Bind (aThisCtx);
- if (aTextureNew->Sampler()->ToUpdateParameters())
- {
- if (aTextureNew->Sampler()->IsImmutable())
+ aTextureNew->Bind (aThisCtx, aTexUnit);
+ if (aTextureNew->Sampler()->ToUpdateParameters())
{
- aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
+ if (aTextureNew->Sampler()->IsImmutable())
+ {
+ aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
+ }
+ else
+ {
+ OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->HasMipmaps());
+ }
}
- else
+ #if !defined(GL_ES_VERSION_2_0)
+ if (core11 != NULL)
{
- OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->HasMipmaps());
+ OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
}
+ #endif
+ aTextureIterNew.Next();
}
- #if !defined(GL_ES_VERSION_2_0)
- if (core11 != NULL)
+ myActiveTextures = theTextures;
+ }
+
+ if (myActiveMockTextures != aMissingBits)
+ {
+ myActiveMockTextures = aMissingBits;
+ for (Standard_Integer aBitIter = 0; aMissingBits != 0; ++aBitIter)
{
- OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
+ Standard_Integer aUnitMask = 1 << aBitIter;
+ if ((aUnitMask & aMissingBits) != 0)
+ {
+ aMissingBits = aMissingBits & ~aUnitMask;
+ if (aBitIter == Graphic3d_TextureUnit_Normal)
+ {
+ myTextureRgbaBlack->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
+ }
+ else
+ {
+ myTextureRgbaWhite->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
+ }
+ }
}
- #endif
- aTextureIterNew.Next();
}
- Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
- myActiveTextures = theTextures;
return anOldTextures;
}
//! @return value for GL_MAX_TEXTURE_UNITS
Standard_Integer MaxTextureUnitsFFP() const { return myMaxTexUnitsFFP; }
- //! @return texture unit to be used for sprites
+ //! Return texture unit to be used for sprites (Graphic3d_TextureUnit_PointSprite by default).
Graphic3d_TextureUnit SpriteTextureUnit() const { return mySpriteTexUnit; }
//! @return value for GL_MAX_SAMPLES
//! @return active textures
const Handle(OpenGl_TextureSet)& ActiveTextures() const { return myActiveTextures; }
- //! Bind specified texture set to current context,
- //! or unbind previous one when NULL specified.
- Standard_EXPORT Handle(OpenGl_TextureSet) BindTextures (const Handle(OpenGl_TextureSet)& theTextures);
+ //! Bind specified texture set to current context taking into account active GLSL program.
+ Standard_DEPRECATED("BindTextures() with explicit GLSL program should be used instead")
+ Handle(OpenGl_TextureSet) BindTextures (const Handle(OpenGl_TextureSet)& theTextures)
+ {
+ return BindTextures (theTextures, myActiveProgram);
+ }
+
+ //! Bind specified texture set to current context, or unbind previous one when NULL specified.
+ //! @param theTextures [in] texture set to bind
+ //! @param theProgram [in] program attributes; when not NULL,
+ //! mock textures will be bound to texture units expected by GLSL program, but undefined by texture set
+ //! @return previous texture set
+ Standard_EXPORT Handle(OpenGl_TextureSet) BindTextures (const Handle(OpenGl_TextureSet)& theTextures,
+ const Handle(OpenGl_ShaderProgram)& theProgram);
//! @return active GLSL program
const Handle(OpenGl_ShaderProgram)& ActiveProgram() const
Standard_Boolean myIsStereoBuffers; //!< context supports stereo buffering
Standard_Boolean myIsGlNormalizeEnabled; //!< GL_NORMALIZE flag
//!< Used to tell OpenGl that normals should be normalized
- Graphic3d_TextureUnit mySpriteTexUnit; //!< texture unit for point sprite texture
+ Graphic3d_TextureUnit mySpriteTexUnit; //!< sampler2D occSamplerPointSprite, texture unit for point sprite texture
Standard_Boolean myHasRayTracing; //! indicates whether ray tracing mode is supported
Standard_Boolean myHasRayTracingTextures; //! indicates whether textures in ray tracing mode are supported
Standard_Boolean myHasRayTracingAdaptiveSamplingAtomic; //! indicates whether atomic adaptive screen sampling in ray tracing mode is supported
Standard_Boolean myHasPBR; //!< indicates whether PBR shading model is supported
- Graphic3d_TextureUnit myPBREnvLUTTexUnit; //!< texture unit where environment lookup table is expected to be binded (0 if PBR is not supported)
- Graphic3d_TextureUnit myPBRDiffIBLMapSHTexUnit; //!< texture unit where diffuse (irradiance) IBL map's spherical harmonics coefficients is expected to be binded
+ Graphic3d_TextureUnit myPBREnvLUTTexUnit; //!< sampler2D occEnvLUT, texture unit where environment lookup table is expected to be binded (0 if PBR is not supported)
+ Graphic3d_TextureUnit myPBRDiffIBLMapSHTexUnit; //!< sampler2D occDiffIBLMapSHCoeffs, texture unit where diffuse (irradiance) IBL map's spherical harmonics coefficients is expected to be binded
//! (0 if PBR is not supported)
- Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit; //!< texture unit where specular IBL map is expected to be binded (0 if PBR is not supported)
+ Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit; //!< samplerCube occSpecIBLMap, texture unit where specular IBL map is expected to be binded (0 if PBR is not supported)
Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs
Handle(OpenGl_ShaderProgram) myActiveProgram; //!< currently active GLSL program
Handle(OpenGl_TextureSet) myActiveTextures; //!< currently bound textures
//!< currently active sampler objects
+ Standard_Integer myActiveMockTextures; //!< currently active mock sampler objects
Handle(OpenGl_FrameBuffer) myDefaultFbo; //!< default Frame Buffer Object
Handle(OpenGl_LineAttributes) myHatchStyles; //!< resource holding predefined hatch styles patterns
+ Handle(OpenGl_Texture) myTextureRgbaBlack;//!< mock black texture returning (0, 0, 0, 0)
+ Handle(OpenGl_Texture) myTextureRgbaWhite;//!< mock white texture returning (1, 1, 1, 1)
Standard_Integer myViewport[4]; //!< current viewport
Standard_Integer myViewportVirt[4]; //!< virtual viewport
Standard_Integer myPointSpriteOrig; //!< GL_POINT_SPRITE_COORD_ORIGIN state (GL_UPPER_LEFT by default)
// Bind full screen quad buffer and framebuffer resources.
aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
- const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
theOitAccumFbo->ColorTexture (0)->Bind (aCtx, Graphic3d_TextureUnit_0);
theOitAccumFbo->ColorTexture (1)->Bind (aCtx, Graphic3d_TextureUnit_1);
if (!aTextureBack.IsNull())
{
- aCtx->BindTextures (aTextureBack);
+ aCtx->BindTextures (aTextureBack, Handle(OpenGl_ShaderProgram)());
}
}
else
return;
}
- const OpenGl_Aspects* anAspectFace = theWorkspace->ApplyAspects();
+ const OpenGl_Aspects* anAspectFace = theWorkspace->Aspects();
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const bool toEnableEnvMap = !aCtx->ActiveTextures().IsNull()
- && aCtx->ActiveTextures() == theWorkspace->EnvironmentTexture();
- bool toDrawArray = true;
+ bool toDrawArray = true, toSetLinePolygMode = false;
int toDrawInteriorEdges = 0; // 0 - no edges, 1 - glsl edges, 2 - polygonMode
if (myIsFillType)
{
}
else
{
- aCtx->SetPolygonMode (GL_LINE);
+ toSetLinePolygMode = true;
}
}
}
}
Graphic3d_TypeOfShadingModel aShadingModel = Graphic3d_TOSM_UNLIT;
+ anAspectFace = theWorkspace->ApplyAspects (false); // do not bind textures before binding the program
+ const Handle(OpenGl_TextureSet)& aTextureSet = theWorkspace->TextureSet();
+ const bool toEnableEnvMap = !aTextureSet.IsNull()
+ && aTextureSet == theWorkspace->EnvironmentTexture();
if (toDrawArray)
{
const bool hasColorAttrib = !myVboAttribs.IsNull()
case GL_POINTS:
{
aShadingModel = aCtx->ShaderManager()->ChooseMarkerShadingModel (anAspectFace->ShadingModel(), hasVertNorm);
- aCtx->ShaderManager()->BindMarkerProgram (aCtx->ActiveTextures(),
+ aCtx->ShaderManager()->BindMarkerProgram (aTextureSet,
aShadingModel, Graphic3d_AlphaMode_Opaque,
hasVertColor, anAspectFace->ShaderProgramRes (aCtx));
break;
default:
{
aShadingModel = aCtx->ShaderManager()->ChooseFaceShadingModel (anAspectFace->ShadingModel(), hasVertNorm);
- aCtx->ShaderManager()->BindFaceProgram (aCtx->ActiveTextures(),
+ aCtx->ShaderManager()->BindFaceProgram (aTextureSet,
aShadingModel,
aCtx->ShaderManager()->MaterialState().HasAlphaCutoff() ? Graphic3d_AlphaMode_Mask : Graphic3d_AlphaMode_Opaque,
toDrawInteriorEdges == 1 ? anAspectFace->Aspect()->InteriorStyle() : Aspect_IS_SOLID,
{
aCtx->ShaderManager()->PushInteriorState (aCtx->ActiveProgram(), anAspectFace->Aspect());
}
+ #if !defined (GL_ES_VERSION_2_0)
+ else if (toSetLinePolygMode)
+ {
+ aCtx->SetPolygonMode (GL_LINE);
+ }
+ #else
+ (void )toSetLinePolygMode;
+ #endif
break;
}
}
}
#endif
- if (!aCtx->ActiveTextures().IsNull()
- && !aCtx->ActiveTextures()->IsEmpty()
- && !aCtx->ActiveTextures()->First().IsNull()
+ // bind textures after GLSL program to set mock textures to slots used by program
+ aCtx->BindTextures (aTextureSet, aCtx->ActiveProgram());
+ if (!aTextureSet.IsNull()
+ && !aTextureSet->IsEmpty()
&& myDrawMode != GL_POINTS) // transformation is not supported within point sprites
{
- aCtx->SetTextureMatrix (aCtx->ActiveTextures()->First()->Sampler()->Parameters());
+ if (const Handle(OpenGl_Texture)& aFirstTexture = aTextureSet->First())
+ {
+ aCtx->SetTextureMatrix (aFirstTexture->Sampler()->Parameters());
+ }
}
aCtx->SetSampleAlphaToCoverage (aCtx->ShaderManager()->MaterialState().HasAlphaCutoff());
enum OpenGl_ProgramOptions
{
OpenGl_PO_VertColor = 0x0001, //!< per-vertex color
- OpenGl_PO_TextureRGB = 0x0002, //!< handle RGB texturing
- OpenGl_PO_PointSimple = 0x0004, //!< point marker without sprite
- OpenGl_PO_PointSprite = 0x0008, //!< point sprite with RGB image
+ OpenGl_PO_TextureRGB = 0x0002, //!< handle RGB texturing
+ OpenGl_PO_TextureEnv = 0x0004, //!< handle environment map (obsolete, to be removed)
+ OpenGl_PO_TextureNormal = OpenGl_PO_TextureRGB|OpenGl_PO_TextureEnv, //!< extended texture set (with normal map)
+ OpenGl_PO_PointSimple = 0x0008, //!< point marker without sprite
+ OpenGl_PO_PointSprite = 0x0010, //!< point sprite with RGB image
OpenGl_PO_PointSpriteA = OpenGl_PO_PointSimple|OpenGl_PO_PointSprite, //!< point sprite with Alpha image
- OpenGl_PO_TextureEnv = 0x0010, //!< handle environment map
OpenGl_PO_StippleLine = 0x0020, //!< stipple line
OpenGl_PO_ClipPlanes1 = 0x0040, //!< handle 1 clipping plane
OpenGl_PO_ClipPlanes2 = 0x0080, //!< handle 2 clipping planes
//
OpenGl_PO_NB = 0x1000, //!< overall number of combinations
OpenGl_PO_IsPoint = OpenGl_PO_PointSimple|OpenGl_PO_PointSprite|OpenGl_PO_PointSpriteA,
- OpenGl_PO_HasTextures = OpenGl_PO_TextureRGB,
+ OpenGl_PO_HasTextures = OpenGl_PO_TextureRGB|OpenGl_PO_TextureEnv,
OpenGl_PO_NeedsGeomShader = OpenGl_PO_MeshEdges,
};
EOL"vec3 DirectLighting;" //!< Accumulator of direct lighting from light sources
EOL"vec4 BaseColor;" //!< Base color (albedo) of material for PBR
EOL"float Metallic;" //!< Metallic coefficient of material
+ EOL"float NormalizedRoughness;" //!< Normalized roughness coefficient of material
EOL"float Roughness;" //!< Roughness coefficient of material
EOL"vec3 Emission;" //!< Light intensity emitted by material
EOL"float IOR;"; //!< Material's index of refraction
{
int aBits = theBits;
const bool toUseDerivates = theUsesDerivates
- || (theBits & OpenGl_PO_StippleLine) != 0;
+ || (theBits & OpenGl_PO_StippleLine) != 0
+ || (theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureNormal;
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core32 != NULL)
{
aSrcFragGetColor =
EOL"vec4 getColor(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord "); }";
}
- else if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+ else if ((theBits & OpenGl_PO_TextureRGB) != 0
&& (theBits & OpenGl_PO_VertColor) == 0)
{
+ aProgramSrc->SetTextureSetBits (Graphic3d_TextureSetBits_BaseColor);
aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
aSrcVertExtraMain +=
}
else
{
- if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+ if ((theBits & OpenGl_PO_TextureRGB) != 0
&& (theBits & OpenGl_PO_VertColor) == 0)
{
+ aProgramSrc->SetTextureSetBits (Graphic3d_TextureSetBits_BaseColor);
aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
aSrcVertExtraMain +=
}
else
{
- if ((theBits & OpenGl_PO_TextureRGB) != 0 || (theBits & OpenGl_PO_TextureEnv) != 0)
+ if ((theBits & OpenGl_PO_HasTextures) != 0)
{
aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
- }
- if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
- {
- aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
+ if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureEnv)
+ {
+ aSrcVertExtraFunc = THE_FUNC_transformNormal_view;
- aSrcFragGetColor =
- EOL"vec4 getColor(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w); }";
- }
- else if ((theBits & OpenGl_PO_TextureEnv) != 0)
- {
- aSrcVertExtraFunc = THE_FUNC_transformNormal_view;
+ aSrcVertExtraMain +=
+ EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+ EOL" vec3 aNormal = transformNormal (occNormal);"
+ EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
+ EOL" aReflect.z += 1.0;"
+ EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
- aSrcVertExtraMain +=
- EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
- EOL" vec3 aNormal = transformNormal (occNormal);"
- EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
- EOL" aReflect.z += 1.0;"
- EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
+ aSrcFragGetColor =
+ EOL"vec4 getColor(void) { return occTexture2D (occSamplerBaseColor, TexCoord.st); }";
+ }
+ else
+ {
+ aProgramSrc->SetTextureSetBits (Graphic3d_TextureSetBits_BaseColor);
+ aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
- aSrcFragGetColor =
- EOL"vec4 getColor(void) { return occTexture2D (occSamplerBaseColor, TexCoord.st); }";
+ aSrcFragGetColor =
+ EOL"vec4 getColor(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w); }";
+ }
}
}
if ((theBits & OpenGl_PO_VertColor) != 0)
// =======================================================================
TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
Standard_Boolean theHasVertColor,
- Standard_Boolean theIsPBR)
+ Standard_Boolean theIsPBR,
+ Standard_Boolean theHasEmissive)
{
TCollection_AsciiString aLightsFunc, aLightsLoop;
theNbLights = 0;
+ EOL" vec4 aMatAmbient = " + aGetMatAmbient
+ EOL" vec4 aMatDiffuse = " + aGetMatDiffuse
+ EOL" vec4 aMatSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
- EOL" vec4 aMatEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
- EOL" vec3 aColor = Ambient * aMatAmbient.rgb"
- EOL" + Diffuse * aMatDiffuse.rgb"
- EOL" + Specular * aMatSpecular.rgb"
- EOL" + aMatEmission.rgb;"
- EOL" return vec4 (aColor, aMatDiffuse.a);"
+ EOL" vec3 aColor = Ambient * aMatAmbient.rgb + Diffuse * aMatDiffuse.rgb + Specular * aMatSpecular.rgb;"
+ EOL" occTextureOcclusion(aColor, TexCoord.st);"
+ + (theHasEmissive
+ ? EOL" vec4 aMatEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
+ EOL" aColor += aMatEmission.rgb;" : "")
+ + EOL" return vec4 (aColor, aMatDiffuse.a);"
EOL"}";
}
else
EOL" in bool theIsFront)"
EOL"{"
EOL" DirectLighting = vec3(0.0);"
- EOL" BaseColor = " + (theHasVertColor ? "getVertColor();" : "getBaseColor (theIsFront);")
- + EOL" Metallic = theIsFront ? occPBRFrontMaterial_Metallic() : occPBRBackMaterial_Metallic();"
- EOL" Roughness = theIsFront ? occPBRFrontMaterial_Roughness() : occPBRBackMaterial_Roughness();"
- EOL" IOR = theIsFront ? occPBRFrontMaterial_IOR() : occPBRBackMaterial_IOR();"
- EOL" Emission = theIsFront ? occPBRFrontMaterial_Emission() : occPBRBackMaterial_Emission();"
+ EOL" BaseColor = " + (theHasVertColor ? "getVertColor();" : "occTextureColor(occPBRMaterial_Color (theIsFront), TexCoord.st);")
+ + EOL" Emission = occTextureEmissive(occPBRMaterial_Emission (theIsFront), TexCoord.st);"
+ EOL" Metallic = occTextureMetallic(occPBRMaterial_Metallic (theIsFront), TexCoord.st);"
+ EOL" NormalizedRoughness = occTextureRoughness(occPBRMaterial_NormalizedRoughness (theIsFront), TexCoord.st);"
+ EOL" Roughness = occRoughness (NormalizedRoughness);"
+ EOL" IOR = occPBRMaterial_IOR (theIsFront);"
EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
+ aLightsLoop
+ EOL" vec3 aColor = DirectLighting;"
EOL" vec3 anIndirectLightingSpec = occPBRFresnel (BaseColor.rgb, Metallic, IOR);"
- EOL" Roughness = theIsFront ? occPBRFrontMaterial_NormalizedRoughness() : occPBRBackMaterial_NormalizedRoughness();"
- EOL" vec2 aCoeff = occTexture2D (occEnvLUT, vec2(abs(dot(theView, theNormal)), Roughness)).xy;"
+ EOL" vec2 aCoeff = occTexture2D (occEnvLUT, vec2(abs(dot(theView, theNormal)), NormalizedRoughness)).xy;"
EOL" anIndirectLightingSpec *= aCoeff.x;"
EOL" anIndirectLightingSpec += aCoeff.y;"
- EOL" anIndirectLightingSpec *= occTextureCubeLod (occSpecIBLMap, -reflect (theView, theNormal), Roughness * float (occNbSpecIBLLevels - 1)).rgb;"
- EOL" vec3 aRefractionCoeff = 1.0 - occPBRFresnel (BaseColor.rgb, Metallic, Roughness, IOR, abs(dot(theView, theNormal)));"
+ EOL" anIndirectLightingSpec *= occTextureCubeLod (occSpecIBLMap, -reflect (theView, theNormal), NormalizedRoughness * float (occNbSpecIBLLevels - 1)).rgb;"
+ EOL" vec3 aRefractionCoeff = 1.0 - occPBRFresnel (BaseColor.rgb, Metallic, NormalizedRoughness, IOR, abs(dot(theView, theNormal)));"
EOL" aRefractionCoeff *= (1.0 - Metallic);"
EOL" vec3 anIndirectLightingDiff = aRefractionCoeff * BaseColor.rgb * BaseColor.a;"
EOL" anIndirectLightingDiff *= occDiffIBLMap (theNormal).rgb;"
EOL" aColor += occLightAmbient.rgb * (anIndirectLightingDiff + anIndirectLightingSpec);"
EOL" aColor += Emission;"
+ EOL" occTextureOcclusion(aColor, TexCoord.st);"
EOL" return vec4 (aColor, mix(1.0, BaseColor.a, aRefractionCoeff.x));"
EOL"}";
}
aSrcFragGetColor = pointSpriteShadingSrc ("gl_FrontFacing ? FrontColor : BackColor", theBits);
}
- if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+ if ((theBits & OpenGl_PO_TextureRGB) != 0
&& (theBits & OpenGl_PO_VertColor) == 0)
{
+ aProgramSrc->SetTextureSetBits (Graphic3d_TextureSetBits_BaseColor);
aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
aSrcVertColor = EOL"vec4 getVertColor(void) { return occTexture2D (occSamplerBaseColor, occTexCoord.xy); }";
}
}
else
{
- if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
+ if ((theBits & OpenGl_PO_TextureRGB) != 0)
{
+ aProgramSrc->SetTextureSetBits (Graphic3d_TextureSetBits_BaseColor);
aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 BackColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
Standard_Integer aNbLights = 0;
- const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty(), false);
+ const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty(), false, true);
aSrcVert = TCollection_AsciiString()
+ THE_FUNC_transformNormal_view
+ EOL
aProgramSrc->SetPBR (theIsPBR);
TCollection_AsciiString aSrcVert, aSrcVertExtraFunc, aSrcVertExtraMain;
- TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
+ TCollection_AsciiString aSrcFrag, aSrcFragExtraFunc, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
TCollection_AsciiString aSrcFragGetColor = TCollection_AsciiString() + EOL"vec4 getColor(void) { return " + aPhongCompLight + "; }";
- TCollection_AsciiString aSrcFragPBRGetBaseColor = TCollection_AsciiString() +
- EOL"vec4 getBaseColor(in bool theIsFront)"
- EOL"{"
- EOL" return theIsFront ? occPBRFrontMaterial_Color() : occPBRBackMaterial_Color();"
- EOL"}";
OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
if ((theBits & OpenGl_PO_IsPoint) != 0)
{
aSrcFragGetColor = pointSpriteShadingSrc (aPhongCompLight, theBits);
}
- if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+ if ((theBits & OpenGl_PO_TextureRGB) != 0
&& (theBits & OpenGl_PO_VertColor) == 0)
{
+ aProgramSrc->SetTextureSetBits (Graphic3d_TextureSetBits_BaseColor);
aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
}
else
{
- if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
+ if ((theBits & OpenGl_PO_TextureRGB) != 0)
{
aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
+ Standard_Integer aTextureBits = Graphic3d_TextureSetBits_BaseColor | Graphic3d_TextureSetBits_Occlusion | Graphic3d_TextureSetBits_Emissive;
if (!theIsPBR)
{
aSrcFragGetColor = TCollection_AsciiString() +
EOL"vec4 getColor(void)"
EOL"{"
+ EOL" vec2 aTexUV = TexCoord.st / TexCoord.w;"
EOL" vec4 aColor = " + aPhongCompLight + ";"
- EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
+ EOL" aColor *= occTexture2D(occSamplerBaseColor, aTexUV);"
+ EOL" vec3 anEmission = occTextureEmissive((gl_FrontFacing ? occFrontMaterial_Emission() : occBackMaterial_Emission()).rgb, aTexUV);"
+ EOL" aColor.rgb += anEmission;"
+ EOL" return aColor;"
EOL"}";
}
else
{
- aSrcFragPBRGetBaseColor = TCollection_AsciiString() +
- EOL"vec4 getBaseColor (in bool theIsFront)"
- EOL"{"
- EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) *"
- EOL" (theIsFront ? occPBRFrontMaterial_Color() : occPBRBackMaterial_Color());"
- EOL"}";
+ aTextureBits |= Graphic3d_TextureSetBits_MetallicRoughness;
+ }
+ if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureNormal
+ && !isFlatNormal)
+ {
+ if (myContext->hasFlatShading != OpenGl_FeatureNotAvailable)
+ {
+ aTextureBits |= Graphic3d_TextureSetBits_Normal;
+ }
+ else
+ {
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
+ "Warning: ignoring Normal Map texture due to hardware capabilities");
+ }
}
+ aProgramSrc->SetTextureSetBits (aTextureBits);
}
}
}
else
{
- aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 Normal", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
- aSrcVertExtraFunc += theIsPBR ? THE_FUNC_transformNormal_world : THE_FUNC_transformNormal_view;
- aSrcVertExtraMain += EOL" Normal = transformNormal (occNormal);";
+ aStageInOuts.Append(OpenGl_ShaderObject::ShaderVariable("vec3 vNormal", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+ aSrcVertExtraFunc += THE_FUNC_transformNormal_world;
+ aSrcVertExtraMain += EOL" vNormal = transformNormal (occNormal);";
+ aSrcFragExtraFunc += EOL" vec3 Normal = vNormal;";
+
+ if ((theBits & OpenGl_PO_IsPoint) == 0
+ && (theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureNormal
+ && myContext->hasFlatShading != OpenGl_FeatureNotAvailable)
+ {
+ // apply normal map texture
+ aSrcFragExtraMain +=
+ EOL"#if defined(THE_HAS_TEXTURE_NORMAL)"
+ EOL" vec4 aMapNormalValue = occTextureNormal(TexCoord.st / TexCoord.w);"
+ EOL" if (aMapNormalValue.w > 0.5)"
+ EOL" {"
+ EOL" aMapNormalValue.xyz = normalize (aMapNormalValue.xyz * 2.0 - vec3(1.0));"
+ EOL" mat2 aDeltaUVMatrix = mat2 (dFdx(TexCoord.st / TexCoord.w), dFdy(TexCoord.st / TexCoord.w));"
+ EOL" aDeltaUVMatrix = mat2 (aDeltaUVMatrix[1][1], -aDeltaUVMatrix[0][1], -aDeltaUVMatrix[1][0], aDeltaUVMatrix[0][0]);"
+ EOL" mat2x3 aDeltaVectorMatrix = mat2x3 (dFdx (PositionWorld.xyz), dFdy (PositionWorld.xyz));"
+ EOL" aDeltaVectorMatrix = aDeltaVectorMatrix * aDeltaUVMatrix;"
+ EOL" aDeltaVectorMatrix[0] = aDeltaVectorMatrix[0] - dot(Normal, aDeltaVectorMatrix[0]) * Normal;"
+ EOL" aDeltaVectorMatrix[1] = aDeltaVectorMatrix[1] - dot(Normal, aDeltaVectorMatrix[1]) * Normal;"
+ EOL" Normal = mat3 (-normalize(aDeltaVectorMatrix[0]), -normalize(aDeltaVectorMatrix[1]), Normal) * aMapNormalValue.xyz;"
+ EOL" }"
+ EOL"#endif";
+ }
+ if (!theIsPBR)
+ {
+ aSrcFragExtraMain +=
+ EOL" Normal = normalize ((occWorldViewMatrixInverseTranspose * vec4 (Normal, 0.0)).xyz);";
+ }
}
aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
: EOL"#define getFinalColor getColor";
Standard_Integer aNbLights = 0;
- const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty(), theIsPBR);
+ const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty(), theIsPBR,
+ (theBits & OpenGl_PO_TextureRGB) == 0
+ || (theBits & OpenGl_PO_IsPoint) != 0);
aSrcFrag = TCollection_AsciiString()
+ EOL
+ + aSrcFragExtraFunc
+ aSrcFragExtraOut
+ aSrcFragGetVertColor
- + (theIsPBR ? aSrcFragPBRGetBaseColor : "")
+ aLights
+ aSrcFragGetColor
+ EOL
&& theTextures->HasNonPointSprite())
{
aBits |= OpenGl_PO_TextureRGB;
+ if ((theTextures->TextureSetBits() & Graphic3d_TextureSetBits_Normal) != 0)
+ {
+ aBits |= OpenGl_PO_TextureNormal;
+ }
}
if (theHasVertColor
&& theInteriorStyle != Aspect_IS_HIDDENLINE)
Standard_Integer theBits)
{
if (theShadingModel == Graphic3d_TOSM_UNLIT
- || (theBits & OpenGl_PO_TextureEnv) != 0)
+ || (theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureEnv)
{
// If environment map is enabled lighting calculations are
// not needed (in accordance with default OCCT behavior)
//! @param theNbLights [out] number of defined light sources
//! @param theHasVertColor [in] flag to use getVertColor() instead of Ambient and Diffuse components of active material
//! @param theIsPBR [in] flag to activate PBR pipeline
+ //! @param theHasEmissive [in] flag to include emissive
Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
Standard_Boolean theHasVertColor,
- Standard_Boolean theIsPBR);
+ Standard_Boolean theIsPBR,
+ Standard_Boolean theHasEmissive = true);
//! Bind specified program to current context and apply state.
Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram);
myNbLightsMax (0),
myNbClipPlanesMax (0),
myNbFragOutputs (1),
+ myTextureSetBits (Graphic3d_TextureSetBits_NONE),
myHasAlphaTest (false),
myHasWeightOitOutput (false),
myHasTessShader (false)
}
myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
+ myTextureSetBits = Graphic3d_TextureSetBits_NONE;
myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest();
myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
{
aHeaderConstants += "#define THE_HAS_DEFAULT_SAMPLER\n";
}
- if (!myProxy.IsNull()
- && myProxy->IsPBR())
+ if (!myProxy.IsNull())
{
- aHeaderConstants += "#define THE_IS_PBR\n";
+ if (myProxy->IsPBR())
+ {
+ aHeaderConstants += "#define THE_IS_PBR\n";
+ }
+ if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_BaseColor) != 0)
+ {
+ aHeaderConstants += "#define THE_HAS_TEXTURE_COLOR\n";
+ }
+ if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_Emissive) != 0)
+ {
+ aHeaderConstants += "#define THE_HAS_TEXTURE_EMISSIVE\n";
+ }
+ if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_Normal) != 0)
+ {
+ aHeaderConstants += "#define THE_HAS_TEXTURE_NORMAL\n";
+ }
+ if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_Occlusion) != 0)
+ {
+ aHeaderConstants += "#define THE_HAS_TEXTURE_OCCLUSION\n";
+ }
+ if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_MetallicRoughness) != 0)
+ {
+ aHeaderConstants += "#define THE_HAS_TEXTURE_METALROUGHNESS\n";
+ }
}
const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
}
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerBaseColor"))
{
+ myTextureSetBits |= Graphic3d_TextureSetBits_BaseColor;
SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_BaseColor));
}
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerPointSprite"))
{
+ // Graphic3d_TextureUnit_PointSprite
+ //myTextureSetBits |= Graphic3d_TextureSetBits_PointSprite;
SetUniform (theCtx, aLocSampler, GLint(theCtx->SpriteTextureUnit()));
}
+ if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerMetallicRoughness"))
+ {
+ myTextureSetBits |= Graphic3d_TextureSetBits_MetallicRoughness;
+ SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_MetallicRoughness));
+ }
+ if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerEmissive"))
+ {
+ myTextureSetBits |= Graphic3d_TextureSetBits_Emissive;
+ SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_Emissive));
+ }
+ if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerOcclusion"))
+ {
+ myTextureSetBits |= Graphic3d_TextureSetBits_Occlusion;
+ SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_Occlusion));
+ }
+ if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerNormal"))
+ {
+ myTextureSetBits |= Graphic3d_TextureSetBits_Normal;
+ SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_Normal));
+ }
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDiffIBLMapSHCoeffs"))
{
SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRDiffIBLMapSHTexUnit()));
#include <Graphic3d_ShaderObject.hxx>
#include <Graphic3d_ShaderProgram.hxx>
+#include <Graphic3d_TextureSetBits.hxx>
#include <OpenGl_Vec.hxx>
#include <OpenGl_Matrix.hxx>
//! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
+ //! Return texture units declared within the program, @sa Graphic3d_TextureSetBits.
+ Standard_Integer TextureSetBits() const { return myTextureSetBits; }
+
private:
//! Returns index of last modification of variables of specified state type.
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
+ Standard_Integer myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader should perform alpha-test
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage
}
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
const Graphic3d_Vec3d aMoveVec = myTrsfPers.IsNull()
&& !aLayer.OriginTransformation().IsNull()
aCtx->core11->glDisableClientState (GL_VERTEX_ARRAY);
}
#endif
- aCtx->BindTextures (aPrevTexture);
+ aCtx->BindTextures (aPrevTexture, Handle(OpenGl_ShaderProgram)());
}
// =======================================================================
// =======================================================================
void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
- const OpenGl_Aspects* aTextAspect = theWorkspace->ApplyAspects();
+ const OpenGl_Aspects* aTextAspect = theWorkspace->ApplyAspects (false); // do not bind textures as they will be disabled anyway
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
// Bind custom shader program or generate default version
aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
+ const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
if (myText->HasPlane() && myText->HasOwnAnchorPoint())
{
// restore aspects
if (!aPrevTexture.IsNull())
{
- aCtx->BindTextures (aPrevTexture);
+ aCtx->BindTextures (aPrevTexture, Handle(OpenGl_ShaderProgram)());
}
// restore Z buffer settings
//! Initialize the texture with Graphic3d_TextureMap.
//! It is an universal way to initialize.
- //! Sitable initialization method will be chosen.
+ //! Suitable initialization method will be chosen.
Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
const Handle(Graphic3d_TextureMap)& theTextureMap);
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureSet, Standard_Transient)
+// =======================================================================
+// function : OpenGl_TextureSet
+// purpose :
+// =======================================================================
+OpenGl_TextureSet::OpenGl_TextureSet (const Handle(OpenGl_Texture)& theTexture)
+: myTextures (0, 0),
+ myTextureSetBits (Graphic3d_TextureSetBits_NONE)
+{
+ if (!theTexture.IsNull())
+ {
+ myTextures.ChangeFirst().Texture = theTexture;
+ myTextures.ChangeFirst().Unit = theTexture->Sampler()->Parameters()->TextureUnit();
+ }
+}
+
// =======================================================================
// function : IsModulate
// purpose :
bool OpenGl_TextureSet::IsModulate() const
{
return myTextures.IsEmpty()
- || myTextures.First().IsNull()
- || myTextures.First()->Sampler()->Parameters()->IsModulate();
+ || myTextures.First().Texture.IsNull()
+ || myTextures.First().Texture->Sampler()->Parameters()->IsModulate();
}
// =======================================================================
}
else if (myTextures.Size() == 1)
{
- return !myTextures.First().IsNull()
- && !myTextures.First()->IsPointSprite();
+ return !myTextures.First().Texture.IsNull()
+ && !myTextures.First().Texture->IsPointSprite();
}
- return !myTextures.First().IsNull();
+ return !myTextures.First().Texture.IsNull();
}
// =======================================================================
bool OpenGl_TextureSet::HasPointSprite() const
{
return !myTextures.IsEmpty()
- && !myTextures.Last().IsNull()
- && myTextures.Last()->IsPointSprite();
+ && !myTextures.Last().Texture.IsNull()
+ && myTextures.Last().Texture->IsPointSprite();
}
#define _OpenGl_TextureSet_Header
#include <Graphic3d_TextureSet.hxx>
+#include <Graphic3d_TextureSetBits.hxx>
class OpenGl_Texture;
DEFINE_STANDARD_RTTIEXT(OpenGl_TextureSet, Standard_Transient)
public:
+ //! Texture slot - combination of Texture and binding Unit.
+ struct TextureSlot
+ {
+ Handle(OpenGl_Texture) Texture;
+ Graphic3d_TextureUnit Unit;
+
+ operator const Handle(OpenGl_Texture)& () const { return Texture; }
+ operator Handle(OpenGl_Texture)& () { return Texture; }
+
+ TextureSlot() : Unit (Graphic3d_TextureUnit_0) {}
+ };
+
//! Class for iterating texture set.
- class Iterator : public NCollection_Array1<Handle(OpenGl_Texture)>::Iterator
+ class Iterator : public NCollection_Array1<TextureSlot>::Iterator
{
public:
//! Empty constructor.
{
if (!theSet.IsNull())
{
- NCollection_Array1<Handle(OpenGl_Texture)>::Iterator::Init (theSet->myTextures);
+ NCollection_Array1<TextureSlot>::Iterator::Init (theSet->myTextures);
}
}
+
+ //! Access texture.
+ const Handle(OpenGl_Texture)& Value() const { return NCollection_Array1<TextureSlot>::Iterator::Value().Texture; }
+ Handle(OpenGl_Texture)& ChangeValue() { return NCollection_Array1<TextureSlot>::Iterator::ChangeValue().Texture; }
+
+ //! Access texture unit.
+ Graphic3d_TextureUnit Unit() const { return NCollection_Array1<TextureSlot>::Iterator::Value().Unit; }
+ Graphic3d_TextureUnit& ChangeUnit() { return NCollection_Array1<TextureSlot>::Iterator::ChangeValue().Unit; }
};
public:
//! Empty constructor.
- OpenGl_TextureSet() {}
+ OpenGl_TextureSet() : myTextureSetBits (Graphic3d_TextureSetBits_NONE) {}
//! Constructor.
OpenGl_TextureSet (Standard_Integer theNbTextures)
- : myTextures (0, theNbTextures - 1) {}
+ : myTextures (0, theNbTextures - 1),
+ myTextureSetBits (Graphic3d_TextureSetBits_NONE) {}
//! Constructor for a single texture.
- OpenGl_TextureSet (const Handle(OpenGl_Texture)& theTexture)
- : myTextures (0, 0)
- {
- myTextures.ChangeFirst() = theTexture;
- }
+ Standard_EXPORT OpenGl_TextureSet (const Handle(OpenGl_Texture)& theTexture);
+
+ //! Return texture units declared within the program, @sa Graphic3d_TextureSetBits.
+ Standard_Integer TextureSetBits() const { return myTextureSetBits; }
+
+ //! Return texture units declared within the program, @sa Graphic3d_TextureSetBits.
+ Standard_Integer& ChangeTextureSetBits() { return myTextureSetBits; }
//! Return TRUE if texture array is empty.
Standard_Boolean IsEmpty() const { return myTextures.IsEmpty(); }
Standard_Integer Upper() const { return myTextures.Upper(); }
//! Return the first texture.
- const Handle(OpenGl_Texture)& First() const { return myTextures.First(); }
+ const Handle(OpenGl_Texture)& First() const { return myTextures.First().Texture; }
//! Return the first texture.
- Handle(OpenGl_Texture)& ChangeFirst() { return myTextures.ChangeFirst(); }
+ Handle(OpenGl_Texture)& ChangeFirst() { return myTextures.ChangeFirst().Texture; }
//! Return the last texture.
- const Handle(OpenGl_Texture)& Last() const { return myTextures.Last(); }
+ const Handle(OpenGl_Texture)& Last() const { return myTextures.Last().Texture; }
//! Return the last texture.
- Handle(OpenGl_Texture)& ChangeLast() { return myTextures.ChangeLast(); }
+ Handle(OpenGl_Texture)& ChangeLast() { return myTextures.ChangeLast().Texture; }
+
+ //! Return the last texture unit.
+ Graphic3d_TextureUnit& ChangeLastUnit() { return myTextures.ChangeLast().Unit; }
//! Return the texture at specified position within [0, Size()) range.
- const Handle(OpenGl_Texture)& Value (Standard_Integer theIndex) const { return myTextures.Value (theIndex); }
+ const Handle(OpenGl_Texture)& Value (Standard_Integer theIndex) const { return myTextures.Value (theIndex).Texture; }
//! Return the texture at specified position within [0, Size()) range.
- Handle(OpenGl_Texture)& ChangeValue (Standard_Integer theIndex) { return myTextures.ChangeValue (theIndex); }
+ Handle(OpenGl_Texture)& ChangeValue (Standard_Integer theIndex) { return myTextures.ChangeValue (theIndex).Texture; }
//! Return TRUE if texture color modulation has been enabled for the first texture
//! or if texture is not set at all.
//! Nullify all handles.
void InitZero()
{
- myTextures.Init (Handle(OpenGl_Texture)());
+ myTextures.Init (TextureSlot());
+ myTextureSetBits = Graphic3d_TextureSetBits_NONE;
}
protected:
- NCollection_Array1<Handle(OpenGl_Texture)> myTextures;
+ NCollection_Array1<TextureSlot> myTextures;
+ Standard_Integer myTextureSetBits;
};
return;
}
- myTextureEnv = new OpenGl_TextureSet (1);
- Handle(OpenGl_Texture)& aTextureEnv = myTextureEnv->ChangeFirst();
- aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
- Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
- if (!anImage.IsNull())
+ Handle(OpenGl_Texture) aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
+ if (Handle(Image_PixMap) anImage = myTextureEnvData->GetImage())
{
aTextureEnv->Init (theContext, *anImage, myTextureEnvData->Type(), true);
}
+ myTextureEnv = new OpenGl_TextureSet (aTextureEnv);
+ myTextureEnv->ChangeTextureSetBits() = Graphic3d_TextureSetBits_BaseColor;
}
// =======================================================================
aResMat.BSDF.Kc = aBSDF.Kc;
aResMat.BSDF.Ks = aBSDF.Ks;
- aResMat.BSDF.Kd = BVH_Vec4f (aBSDF.Kd, -1.f); // no texture
- aResMat.BSDF.Kt = BVH_Vec4f (aBSDF.Kt, 0.f);
- aResMat.BSDF.Le = BVH_Vec4f (aBSDF.Le, 0.f);
+ aResMat.BSDF.Kd = BVH_Vec4f (aBSDF.Kd, -1.0f); // no base color texture
+ aResMat.BSDF.Kt = BVH_Vec4f (aBSDF.Kt, -1.0f); // no metallic-roughness texture
+ aResMat.BSDF.Le = BVH_Vec4f (aBSDF.Le, -1.0f); // no emissive texture
aResMat.BSDF.Absorption = aBSDF.Absorption;
if (theGlContext->HasRayTracingTextures())
{
- const Handle(OpenGl_Texture)& aTexture = aTextureSet->First();
- buildTextureTransform (aTexture->Sampler()->Parameters(), aResMat.TextureTransform);
-
- // write texture ID to diffuse w-component
- aResMat.Diffuse.w() = aResMat.BSDF.Kd.w() = static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (aTexture));
+ // write texture ID to diffuse w-components
+ for (OpenGl_TextureSet::Iterator aTexIter (aTextureSet); aTexIter.More(); aTexIter.Next())
+ {
+ const Handle(OpenGl_Texture)& aTexture = aTexIter.Value();
+ if (aTexIter.Unit() == Graphic3d_TextureUnit_BaseColor)
+ {
+ buildTextureTransform (aTexture->Sampler()->Parameters(), aResMat.TextureTransform);
+ aResMat.Diffuse.w() = aResMat.BSDF.Kd.w() = static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (aTexture));
+ }
+ else if (aTexIter.Unit() == Graphic3d_TextureUnit_MetallicRoughness)
+ {
+ buildTextureTransform (aTexture->Sampler()->Parameters(), aResMat.TextureTransform);
+ aResMat.BSDF.Kt.w() = static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (aTexture));
+ }
+ else if (aTexIter.Unit() == Graphic3d_TextureUnit_Emissive)
+ {
+ buildTextureTransform (aTexture->Sampler()->Parameters(), aResMat.TextureTransform);
+ aResMat.BSDF.Le.w() = static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (aTexture));
+ }
+ }
}
else if (!myIsRaytraceWarnTextures)
{
}
renderStructs (theProjection, theReadDrawFbo, theOitAccumFbo, theToDrawImmediate);
- aContext->BindTextures (Handle(OpenGl_TextureSet)());
+ aContext->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
// Apply restored view matrix.
aContext->ApplyWorldViewMatrix();
}
#endif
- aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
const Graphic3d_TypeOfTextureFilter aFilter = (aDrawSizeX == aReadSizeX && aDrawSizeY == aReadSizeY) ? Graphic3d_TOTF_NEAREST : Graphic3d_TOTF_BILINEAR;
const GLint aFilterGl = aFilter == Graphic3d_TOTF_NEAREST ? GL_NEAREST : GL_LINEAR;
aCtx->core20fwd->glDepthMask (GL_TRUE);
aCtx->core20fwd->glEnable (GL_DEPTH_TEST);
- aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
OpenGl_VertexBuffer* aVerts = initBlitQuad (myToFlipOutput);
const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
// function : ApplyAspects
// purpose :
// =======================================================================
-const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects()
+const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects (bool theToBindTextures)
{
if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
{
myGlContext->SetShadingMaterial (myAspectsSet, myHighlightStyle);
}
- const Handle(OpenGl_TextureSet)& aTextureSet = myAspectsSet->TextureSet (myGlContext, ToHighlight());
- if (!aTextureSet.IsNull()
- || myAspectsSet->Aspect()->ToMapTexture())
+ if (theToBindTextures)
{
- myGlContext->BindTextures (aTextureSet);
- }
- else
- {
- myGlContext->BindTextures (myEnvironmentTexture);
+ const Handle(OpenGl_TextureSet)& aTextureSet = TextureSet();
+ myGlContext->BindTextures (aTextureSet, Handle(OpenGl_ShaderProgram)());
}
if ((myView->myShadingModel == Graphic3d_TOSM_PBR
// create the FBO
const Handle(OpenGl_Context)& aCtx = GetGlContext();
- aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_SRGB8_ALPHA8, GL_DEPTH24_STENCIL8, 0))
{
//! Assign new aspects (will be applied within ApplyAspects()).
Standard_EXPORT const OpenGl_Aspects* SetAspects (const OpenGl_Aspects* theAspect);
+ //! Return TextureSet from set Aspects or Environment texture.
+ const Handle(OpenGl_TextureSet)& TextureSet() const
+ {
+ const Handle(OpenGl_TextureSet)& aTextureSet = myAspectsSet->TextureSet (myGlContext, ToHighlight());
+ return !aTextureSet.IsNull()
+ || myAspectsSet->Aspect()->ToMapTexture()
+ ? aTextureSet
+ : myEnvironmentTexture;
+ }
+
//! Apply aspects.
+ //! @param theToBindTextures flag to bind texture set defined by applied aspect
//! @return aspect set by SetAspects()
- Standard_EXPORT const OpenGl_Aspects* ApplyAspects();
+ Standard_EXPORT const OpenGl_Aspects* ApplyAspects (bool theToBindTextures = true);
//! Clear the applied aspect state to default values.
void ResetAppliedAspect();
#endif
#endif
-// Converts roughness value from range [0, 1] to real value for calculations
+#if defined(THE_IS_PBR)
+//! Converts roughness value from range [0, 1] to real value for calculations
float occRoughness (in float theNormalizedRoughness);
-// Front material properties accessors
-#if !defined(THE_IS_PBR)
-vec4 occFrontMaterial_Emission(void); //!< Emission color
-vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection
-vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection
-vec4 occFrontMaterial_Specular(void); //!< Specular reflection
-float occFrontMaterial_Shininess(void); //!< Specular exponent
-float occFrontMaterial_Transparency(void); //!< Transparency coefficient
+// Front/back material properties accessors
+vec4 occPBRMaterial_Color(in bool theIsFront); //!< Base color of PBR material
+float occPBRMaterial_Metallic(in bool theIsFront); //!< Metallic coefficient
+float occPBRMaterial_NormalizedRoughness(in bool theIsFront); //!< Normalized roughness coefficient
+vec3 occPBRMaterial_Emission(in bool theIsFront); //!< Light intensity emitted by material
+float occPBRMaterial_IOR(in bool theIsFront); //!< Index of refraction
#else
-vec4 occPBRFrontMaterial_Color(void); //!< Base color of PBR material
-float occPBRFrontMaterial_Metallic(void); //!< Metallic coefficient
-float occPBRFrontMaterial_Roughness(void); //!< Roughness coefficient
-float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
-vec3 occPBRFrontMaterial_Emission(void); //!< Light intensity emitted by material
-float occPBRFrontMaterial_IOR(void); //!< Index of refraction
-#endif
+// Front material properties accessors
+vec4 occFrontMaterial_Emission(void); //!< Emission color
+vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection
+vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection
+vec4 occFrontMaterial_Specular(void); //!< Specular reflection
+float occFrontMaterial_Shininess(void); //!< Specular exponent
+float occFrontMaterial_Transparency(void); //!< Transparency coefficient
// Back material properties accessors
-#if !defined(THE_IS_PBR)
vec4 occBackMaterial_Emission(void); //!< Emission color
vec4 occBackMaterial_Ambient(void); //!< Ambient reflection
vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection
vec4 occBackMaterial_Specular(void); //!< Specular reflection
float occBackMaterial_Shininess(void); //!< Specular exponent
float occBackMaterial_Transparency(void); //!< Transparency coefficient
-#else
-vec4 occPBRBackMaterial_Color(void); //!< Base color of PBR material
-float occPBRBackMaterial_Metallic(void); //!< Metallic coefficient
-float occPBRBackMaterial_Roughness(void); //!< Roughness coefficient
-float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
-vec3 occPBRBackMaterial_Emission(void); //!< Light intensity emitted by material
-float occPBRBackMaterial_IOR(void); //!< Index of refraction
#endif
#ifdef THE_HAS_DEFAULT_SAMPLER
-#define occActiveSampler occSampler0 //!< alias for backward compatibility
-#define occSamplerBaseColor occSampler0 //!< alias to a base color texture
-uniform sampler2D occSampler0; //!< current active sampler;
+#define occActiveSampler occSampler0 //!< alias for backward compatibility
+#define occSamplerBaseColor occSampler0 //!< alias to a base color texture
+uniform sampler2D occSampler0; //!< current active sampler;
+#endif //! occSampler1, occSampler2,... should be defined in GLSL program body for multitexturing
+
+#if defined(THE_HAS_TEXTURE_COLOR)
+#define occTextureColor(theMatColor, theTexCoord) (theMatColor * occTexture2D(occSamplerBaseColor, theTexCoord))
+#else
+#define occTextureColor(theMatColor, theTexCoord) theMatColor
+#endif
+
+#if defined(THE_HAS_TEXTURE_OCCLUSION) && defined(FRAGMENT_SHADER)
+uniform sampler2D occSamplerOcclusion; //!< R occlusion texture sampler
+#define occTextureOcclusion(theColor, theTexCoord) theColor *= occTexture2D(occSamplerOcclusion, theTexCoord).r;
+#else
+#define occTextureOcclusion(theColor, theTexCoord)
#endif
- //! occSampler1, occSampler2,... should be defined in GLSL program body for multitexturing
+
+#if defined(THE_HAS_TEXTURE_EMISSIVE) && defined(FRAGMENT_SHADER)
+uniform sampler2D occSamplerEmissive; //!< RGB emissive texture sampler
+#define occTextureEmissive(theMatEmis, theTexCoord) (theMatEmis * occTexture2D(occSamplerEmissive, theTexCoord).rgb)
+#else
+#define occTextureEmissive(theMatEmis, theTexCoord) theMatEmis
+#endif
+
+#if defined(THE_HAS_TEXTURE_NORMAL) && defined(FRAGMENT_SHADER)
+uniform sampler2D occSamplerNormal; //!< XYZ normal texture sampler with W==0 indicating no texture
+#define occTextureNormal(theTexCoord) occTexture2D(occSamplerNormal, theTexCoord)
+#else
+#define occTextureNormal(theTexCoord) vec4(0.0) // no normal map
+#endif
+
+#if defined(THE_HAS_TEXTURE_METALROUGHNESS) && defined(FRAGMENT_SHADER)
+uniform sampler2D occSamplerMetallicRoughness; //!< BG metallic-roughness texture sampler
+#define occTextureRoughness(theRoug, theTexCoord) (theRoug * occTexture2D(occSamplerMetallicRoughness, theTexCoord).g)
+#define occTextureMetallic(theMet, theTexCoord) (theMet * occTexture2D(occSamplerMetallicRoughness, theTexCoord).b)
+#else
+#define occTextureRoughness(theRoug, theTexCoord) theRoug
+#define occTextureMetallic(theMet, theTexCoord) theMet
+#endif
+
uniform vec4 occColor; //!< color value (in case of disabled lighting)
uniform THE_PREC_ENUM int occDistinguishingMode; //!< Are front and back faces distinguished?
uniform THE_PREC_ENUM int occTextureEnable; //!< Is texture enabled?
uniform vec4 occPbrBackMaterial[3];
#define MIN_ROUGHNESS 0.01
-// Converts roughness value from range [0, 1] to real value for calculations
float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }
-
-vec4 occPBRFrontMaterial_Color(void) { return occPbrFrontMaterial[0]; }
-vec3 occPBRFrontMaterial_Emission(void) { return occPbrFrontMaterial[1].rgb; }
-float occPBRFrontMaterial_IOR(void) { return occPbrFrontMaterial[1].w; }
-float occPBRFrontMaterial_Metallic(void) { return occPbrFrontMaterial[2].b; }
-float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }
-float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }
-
-vec4 occPBRBackMaterial_Color(void) { return occPbrBackMaterial[0]; }
-vec3 occPBRBackMaterial_Emission(void) { return occPbrBackMaterial[1].rgb; }
-float occPBRBackMaterial_IOR(void) { return occPbrBackMaterial[1].w; }
-float occPBRBackMaterial_Metallic(void) { return occPbrBackMaterial[2].b; }
-float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }
-float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }
+vec4 occPBRMaterial_Color(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[0] : occPbrBackMaterial[0]; }
+vec3 occPBRMaterial_Emission(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[1].rgb : occPbrBackMaterial[1].rgb; }
+float occPBRMaterial_IOR(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[1].w : occPbrBackMaterial[1].w; }
+float occPBRMaterial_Metallic(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[2].b : occPbrBackMaterial[2].b; }
+float occPBRMaterial_NormalizedRoughness(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[2].g : occPbrBackMaterial[2].g; }
#else
uniform vec4 occFrontMaterial[5];
uniform vec4 occBackMaterial[5];
//! Weight of coat specular/glossy BRDF.
vec4 Kc;
- //! Weight of base diffuse BRDF.
+ //! Weight of base diffuse BRDF + base color texture index in W.
vec4 Kd;
//! Weight of base specular/glossy BRDF.
vec4 Ks;
- //! Weight of base specular/glossy BTDF.
- vec3 Kt;
+ //! Weight of base specular/glossy BTDF + metallic-roughness texture index in W.
+ vec4 Kt;
//! Fresnel coefficients of coat layer.
vec3 FresnelCoat;
aBSDF.Kc = texelFetch (uRaytraceMaterialTexture, MATERIAL_KC (aTriIndex.w));
aBSDF.Kd = texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriIndex.w));
aBSDF.Ks = texelFetch (uRaytraceMaterialTexture, MATERIAL_KS (aTriIndex.w));
- aBSDF.Kt = texelFetch (uRaytraceMaterialTexture, MATERIAL_KT (aTriIndex.w)).rgb;
+ aBSDF.Kt = texelFetch (uRaytraceMaterialTexture, MATERIAL_KT (aTriIndex.w));
+
+ // fetch Fresnel reflectance for both layers
+ aBSDF.FresnelCoat = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_COAT (aTriIndex.w)).xyz;
+ aBSDF.FresnelBase = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_BASE (aTriIndex.w)).xyz;
+
+ vec4 anLE = texelFetch (uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w));
// compute smooth normal (in parallel with fetch)
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
-
aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
dot (aInvTransf1, aNormal),
dot (aInvTransf2, aNormal)));
SLocalSpace aSpace = buildLocalSpace (aNormal);
#ifdef USE_TEXTURES
- if (aBSDF.Kd.w >= 0.f)
+ if (aBSDF.Kd.w >= 0.0 || aBSDF.Kt.w >= 0.0 || anLE.w >= 0.0)
{
vec4 aTexCoord = vec4 (SmoothUV (aHit.UV, aTriIndex), 0.f, 1.f);
vec4 aTrsfRow1 = texelFetch (uRaytraceMaterialTexture, MATERIAL_TRS1 (aTriIndex.w));
aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),
dot (aTrsfRow2, aTexCoord));
- vec4 aTexColor = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kd.w)]), aTexCoord.st, 0.f);
- aBSDF.Kd.rgb *= aTexColor.rgb * aTexColor.w;
- if (aTexColor.w != 1.0f)
+ if (anLE.w >= 0.0)
+ {
+ anLE.rgb *= textureLod (sampler2D (uTextureSamplers[int (anLE.w)]), aTexCoord.st, 0.0).rgb;
+ }
+ if (aBSDF.Kt.w >= 0.0)
{
- // mix transparency BTDF with texture alpha-channel
- aBSDF.Kt = (UNIT - aTexColor.www) + aTexColor.w * aBSDF.Kt;
+ vec2 aTexMetRough = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kt.w)]), aTexCoord.st, 0.0).bg;
+ float aPbrMetal = aTexMetRough.x;
+ float aPbrRough2 = aTexMetRough.y * aTexMetRough.y;
+ aBSDF.Ks.a *= aPbrRough2;
+ // when using metal-roughness texture, global metalness of material (encoded in FresnelBase) is expected to be 1.0 so that Kd will be 0.0
+ aBSDF.Kd.rgb = aBSDF.FresnelBase * (1.0 - aPbrMetal);
+ aBSDF.FresnelBase *= aPbrMetal;
+ }
+ if (aBSDF.Kd.w >= 0.0)
+ {
+ vec4 aTexColor = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kd.w)]), aTexCoord.st, 0.0);
+ vec3 aDiff = aTexColor.rgb * aTexColor.a;
+ aBSDF.Kd.rgb *= aDiff;
+ aBSDF.FresnelBase *= aDiff;
+ if (aTexColor.a != 1.0)
+ {
+ // mix transparency BTDF with texture alpha-channel
+ aBSDF.Ks.rgb *= aTexColor.a;
+ aBSDF.Kt.rgb = (UNIT - aTexColor.aaa) + aTexColor.a * aBSDF.Kt.rgb;
+ }
}
}
#endif
- // fetch Fresnel reflectance for both layers
- aBSDF.FresnelCoat = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_COAT (aTriIndex.w)).xyz;
- aBSDF.FresnelBase = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_BASE (aTriIndex.w)).xyz;
-
if (uLightCount > 0 && IsNotZero (aBSDF, aThroughput))
{
aExpPDF = 1.f / uLightCount;
}
// account for self-emission
- aRadiance += aThroughput * texelFetch (uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w)).rgb;
+ aRadiance += aThroughput * anLE.rgb;
if (aInMedium) // handle attenuation
{
"uniform vec4 occPbrBackMaterial[3];\n"
"\n"
"#define MIN_ROUGHNESS 0.01\n"
- "// Converts roughness value from range [0, 1] to real value for calculations\n"
"float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }\n"
- "\n"
- "vec4 occPBRFrontMaterial_Color(void) { return occPbrFrontMaterial[0]; }\n"
- "vec3 occPBRFrontMaterial_Emission(void) { return occPbrFrontMaterial[1].rgb; }\n"
- "float occPBRFrontMaterial_IOR(void) { return occPbrFrontMaterial[1].w; }\n"
- "float occPBRFrontMaterial_Metallic(void) { return occPbrFrontMaterial[2].b; }\n"
- "float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }\n"
- "float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }\n"
- "\n"
- "vec4 occPBRBackMaterial_Color(void) { return occPbrBackMaterial[0]; }\n"
- "vec3 occPBRBackMaterial_Emission(void) { return occPbrBackMaterial[1].rgb; }\n"
- "float occPBRBackMaterial_IOR(void) { return occPbrBackMaterial[1].w; }\n"
- "float occPBRBackMaterial_Metallic(void) { return occPbrBackMaterial[2].b; }\n"
- "float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }\n"
- "float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }\n"
+ "vec4 occPBRMaterial_Color(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[0] : occPbrBackMaterial[0]; }\n"
+ "vec3 occPBRMaterial_Emission(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[1].rgb : occPbrBackMaterial[1].rgb; }\n"
+ "float occPBRMaterial_IOR(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[1].w : occPbrBackMaterial[1].w; }\n"
+ "float occPBRMaterial_Metallic(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[2].b : occPbrBackMaterial[2].b; }\n"
+ "float occPBRMaterial_NormalizedRoughness(in bool theIsFront) { return theIsFront ? occPbrFrontMaterial[2].g : occPbrBackMaterial[2].g; }\n"
"#else\n"
"uniform vec4 occFrontMaterial[5];\n"
"uniform vec4 occBackMaterial[5];\n"
"#endif\n"
"#endif\n"
"\n"
- "// Converts roughness value from range [0, 1] to real value for calculations\n"
+ "#if defined(THE_IS_PBR)\n"
+ "//! Converts roughness value from range [0, 1] to real value for calculations\n"
"float occRoughness (in float theNormalizedRoughness);\n"
"\n"
- "// Front material properties accessors\n"
- "#if !defined(THE_IS_PBR)\n"
- "vec4 occFrontMaterial_Emission(void); //!< Emission color\n"
- "vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection\n"
- "vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection\n"
- "vec4 occFrontMaterial_Specular(void); //!< Specular reflection\n"
- "float occFrontMaterial_Shininess(void); //!< Specular exponent\n"
- "float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
+ "// Front/back material properties accessors\n"
+ "vec4 occPBRMaterial_Color(in bool theIsFront); //!< Base color of PBR material\n"
+ "float occPBRMaterial_Metallic(in bool theIsFront); //!< Metallic coefficient\n"
+ "float occPBRMaterial_NormalizedRoughness(in bool theIsFront); //!< Normalized roughness coefficient\n"
+ "vec3 occPBRMaterial_Emission(in bool theIsFront); //!< Light intensity emitted by material\n"
+ "float occPBRMaterial_IOR(in bool theIsFront); //!< Index of refraction\n"
"#else\n"
- "vec4 occPBRFrontMaterial_Color(void); //!< Base color of PBR material\n"
- "float occPBRFrontMaterial_Metallic(void); //!< Metallic coefficient\n"
- "float occPBRFrontMaterial_Roughness(void); //!< Roughness coefficient\n"
- "float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
- "vec3 occPBRFrontMaterial_Emission(void); //!< Light intensity emitted by material\n"
- "float occPBRFrontMaterial_IOR(void); //!< Index of refraction\n"
- "#endif\n"
+ "// Front material properties accessors\n"
+ "vec4 occFrontMaterial_Emission(void); //!< Emission color\n"
+ "vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection\n"
+ "vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection\n"
+ "vec4 occFrontMaterial_Specular(void); //!< Specular reflection\n"
+ "float occFrontMaterial_Shininess(void); //!< Specular exponent\n"
+ "float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
"\n"
"// Back material properties accessors\n"
- "#if !defined(THE_IS_PBR)\n"
"vec4 occBackMaterial_Emission(void); //!< Emission color\n"
"vec4 occBackMaterial_Ambient(void); //!< Ambient reflection\n"
"vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection\n"
"vec4 occBackMaterial_Specular(void); //!< Specular reflection\n"
"float occBackMaterial_Shininess(void); //!< Specular exponent\n"
"float occBackMaterial_Transparency(void); //!< Transparency coefficient\n"
- "#else\n"
- "vec4 occPBRBackMaterial_Color(void); //!< Base color of PBR material\n"
- "float occPBRBackMaterial_Metallic(void); //!< Metallic coefficient\n"
- "float occPBRBackMaterial_Roughness(void); //!< Roughness coefficient\n"
- "float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
- "vec3 occPBRBackMaterial_Emission(void); //!< Light intensity emitted by material\n"
- "float occPBRBackMaterial_IOR(void); //!< Index of refraction\n"
"#endif\n"
"\n"
"#ifdef THE_HAS_DEFAULT_SAMPLER\n"
- "#define occActiveSampler occSampler0 //!< alias for backward compatibility\n"
- "#define occSamplerBaseColor occSampler0 //!< alias to a base color texture\n"
- "uniform sampler2D occSampler0; //!< current active sampler;\n"
+ "#define occActiveSampler occSampler0 //!< alias for backward compatibility\n"
+ "#define occSamplerBaseColor occSampler0 //!< alias to a base color texture\n"
+ "uniform sampler2D occSampler0; //!< current active sampler;\n"
+ "#endif //! occSampler1, occSampler2,... should be defined in GLSL program body for multitexturing\n"
+ "\n"
+ "#if defined(THE_HAS_TEXTURE_COLOR)\n"
+ "#define occTextureColor(theMatColor, theTexCoord) (theMatColor * occTexture2D(occSamplerBaseColor, theTexCoord))\n"
+ "#else\n"
+ "#define occTextureColor(theMatColor, theTexCoord) theMatColor\n"
+ "#endif\n"
+ "\n"
+ "#if defined(THE_HAS_TEXTURE_OCCLUSION) && defined(FRAGMENT_SHADER)\n"
+ "uniform sampler2D occSamplerOcclusion; //!< R occlusion texture sampler\n"
+ "#define occTextureOcclusion(theColor, theTexCoord) theColor *= occTexture2D(occSamplerOcclusion, theTexCoord).r;\n"
+ "#else\n"
+ "#define occTextureOcclusion(theColor, theTexCoord)\n"
"#endif\n"
- " //! occSampler1, occSampler2,... should be defined in GLSL program body for multitexturing\n"
+ "\n"
+ "#if defined(THE_HAS_TEXTURE_EMISSIVE) && defined(FRAGMENT_SHADER)\n"
+ "uniform sampler2D occSamplerEmissive; //!< RGB emissive texture sampler\n"
+ "#define occTextureEmissive(theMatEmis, theTexCoord) (theMatEmis * occTexture2D(occSamplerEmissive, theTexCoord).rgb)\n"
+ "#else\n"
+ "#define occTextureEmissive(theMatEmis, theTexCoord) theMatEmis\n"
+ "#endif\n"
+ "\n"
+ "#if defined(THE_HAS_TEXTURE_NORMAL) && defined(FRAGMENT_SHADER)\n"
+ "uniform sampler2D occSamplerNormal; //!< XYZ normal texture sampler with W==0 indicating no texture\n"
+ "#define occTextureNormal(theTexCoord) occTexture2D(occSamplerNormal, theTexCoord)\n"
+ "#else\n"
+ "#define occTextureNormal(theTexCoord) vec4(0.0) // no normal map\n"
+ "#endif\n"
+ "\n"
+ "#if defined(THE_HAS_TEXTURE_METALROUGHNESS) && defined(FRAGMENT_SHADER)\n"
+ "uniform sampler2D occSamplerMetallicRoughness; //!< BG metallic-roughness texture sampler\n"
+ "#define occTextureRoughness(theRoug, theTexCoord) (theRoug * occTexture2D(occSamplerMetallicRoughness, theTexCoord).g)\n"
+ "#define occTextureMetallic(theMet, theTexCoord) (theMet * occTexture2D(occSamplerMetallicRoughness, theTexCoord).b)\n"
+ "#else\n"
+ "#define occTextureRoughness(theRoug, theTexCoord) theRoug\n"
+ "#define occTextureMetallic(theMet, theTexCoord) theMet\n"
+ "#endif\n"
+ "\n"
"uniform vec4 occColor; //!< color value (in case of disabled lighting)\n"
"uniform THE_PREC_ENUM int occDistinguishingMode; //!< Are front and back faces distinguished?\n"
"uniform THE_PREC_ENUM int occTextureEnable; //!< Is texture enabled?\n"
" //! Weight of coat specular/glossy BRDF.\n"
" vec4 Kc;\n"
"\n"
- " //! Weight of base diffuse BRDF.\n"
+ " //! Weight of base diffuse BRDF + base color texture index in W.\n"
" vec4 Kd;\n"
"\n"
" //! Weight of base specular/glossy BRDF.\n"
" vec4 Ks;\n"
"\n"
- " //! Weight of base specular/glossy BTDF.\n"
- " vec3 Kt;\n"
+ " //! Weight of base specular/glossy BTDF + metallic-roughness texture index in W.\n"
+ " vec4 Kt;\n"
"\n"
" //! Fresnel coefficients of coat layer.\n"
" vec3 FresnelCoat;\n"
" aBSDF.Kc = texelFetch (uRaytraceMaterialTexture, MATERIAL_KC (aTriIndex.w));\n"
" aBSDF.Kd = texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriIndex.w));\n"
" aBSDF.Ks = texelFetch (uRaytraceMaterialTexture, MATERIAL_KS (aTriIndex.w));\n"
- " aBSDF.Kt = texelFetch (uRaytraceMaterialTexture, MATERIAL_KT (aTriIndex.w)).rgb;\n"
+ " aBSDF.Kt = texelFetch (uRaytraceMaterialTexture, MATERIAL_KT (aTriIndex.w));\n"
+ "\n"
+ " // fetch Fresnel reflectance for both layers\n"
+ " aBSDF.FresnelCoat = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_COAT (aTriIndex.w)).xyz;\n"
+ " aBSDF.FresnelBase = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_BASE (aTriIndex.w)).xyz;\n"
+ "\n"
+ " vec4 anLE = texelFetch (uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w));\n"
"\n"
" // compute smooth normal (in parallel with fetch)\n"
" vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);\n"
- "\n"
" aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),\n"
" dot (aInvTransf1, aNormal),\n"
" dot (aInvTransf2, aNormal)));\n"
" SLocalSpace aSpace = buildLocalSpace (aNormal);\n"
"\n"
"#ifdef USE_TEXTURES\n"
- " if (aBSDF.Kd.w >= 0.f)\n"
+ " if (aBSDF.Kd.w >= 0.0 || aBSDF.Kt.w >= 0.0 || anLE.w >= 0.0)\n"
" {\n"
" vec4 aTexCoord = vec4 (SmoothUV (aHit.UV, aTriIndex), 0.f, 1.f);\n"
" vec4 aTrsfRow1 = texelFetch (uRaytraceMaterialTexture, MATERIAL_TRS1 (aTriIndex.w));\n"
" aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),\n"
" dot (aTrsfRow2, aTexCoord));\n"
"\n"
- " vec4 aTexColor = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kd.w)]), aTexCoord.st, 0.f);\n"
- " aBSDF.Kd.rgb *= aTexColor.rgb * aTexColor.w;\n"
- " if (aTexColor.w != 1.0f)\n"
+ " if (anLE.w >= 0.0)\n"
+ " {\n"
+ " anLE.rgb *= textureLod (sampler2D (uTextureSamplers[int (anLE.w)]), aTexCoord.st, 0.0).rgb;\n"
+ " }\n"
+ " if (aBSDF.Kt.w >= 0.0)\n"
" {\n"
- " // mix transparency BTDF with texture alpha-channel\n"
- " aBSDF.Kt = (UNIT - aTexColor.www) + aTexColor.w * aBSDF.Kt;\n"
+ " vec2 aTexMetRough = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kt.w)]), aTexCoord.st, 0.0).bg;\n"
+ " float aPbrMetal = aTexMetRough.x;\n"
+ " float aPbrRough2 = aTexMetRough.y * aTexMetRough.y;\n"
+ " aBSDF.Ks.a *= aPbrRough2;\n"
+ " // when using metal-roughness texture, global metalness of material (encoded in FresnelBase) is expected to be 1.0 so that Kd will be 0.0\n"
+ " aBSDF.Kd.rgb = aBSDF.FresnelBase * (1.0 - aPbrMetal);\n"
+ " aBSDF.FresnelBase *= aPbrMetal;\n"
+ " }\n"
+ " if (aBSDF.Kd.w >= 0.0)\n"
+ " {\n"
+ " vec4 aTexColor = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kd.w)]), aTexCoord.st, 0.0);\n"
+ " vec3 aDiff = aTexColor.rgb * aTexColor.a;\n"
+ " aBSDF.Kd.rgb *= aDiff;\n"
+ " aBSDF.FresnelBase *= aDiff;\n"
+ " if (aTexColor.a != 1.0)\n"
+ " {\n"
+ " // mix transparency BTDF with texture alpha-channel\n"
+ " aBSDF.Ks.rgb *= aTexColor.a;\n"
+ " aBSDF.Kt.rgb = (UNIT - aTexColor.aaa) + aTexColor.a * aBSDF.Kt.rgb;\n"
+ " }\n"
" }\n"
" }\n"
"#endif\n"
"\n"
- " // fetch Fresnel reflectance for both layers\n"
- " aBSDF.FresnelCoat = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_COAT (aTriIndex.w)).xyz;\n"
- " aBSDF.FresnelBase = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_BASE (aTriIndex.w)).xyz;\n"
- "\n"
" if (uLightCount > 0 && IsNotZero (aBSDF, aThroughput))\n"
" {\n"
" aExpPDF = 1.f / uLightCount;\n"
" }\n"
"\n"
" // account for self-emission\n"
- " aRadiance += aThroughput * texelFetch (uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w)).rgb;\n"
+ " aRadiance += aThroughput * anLE.rgb;\n"
"\n"
" if (aInMedium) // handle attenuation\n"
" {\n"
aPbr.SetColor (myPbrMat.BaseColor);
aPbr.SetMetallic (myPbrMat.Metallic);
aPbr.SetRoughness(myPbrMat.Roughness);
- if (myPbrMat.EmissiveTexture.IsNull()) // TODO Temporal measure until emissive map will be implemented
- {
- aPbr.SetEmission(myPbrMat.EmissiveFactor);
- }
+ aPbr.SetEmission (myPbrMat.EmissiveFactor);
theAspect.SetPBRMaterial (aPbr);
theAspect.SetBSDF (Graphic3d_BSDF::CreateMetallicRoughness (aPbr));
}
theAspect->SetAlphaMode (myAlphaMode , myAlphaCutOff);
theAspect->SetSuppressBackFaces (!myIsDoubleSided);
- Handle(Image_Texture) aColorTexture, aNormTexture;
- if (!myCommonMat.DiffuseTexture.IsNull())
+ const Handle(Image_Texture)& aColorTexture = !myPbrMat.BaseColorTexture.IsNull() ? myPbrMat.BaseColorTexture : myCommonMat.DiffuseTexture;
+ Standard_Integer aNbTexUnits = 0;
+ if (!aColorTexture.IsNull()) { ++aNbTexUnits; }
+ if (!myPbrMat.EmissiveTexture.IsNull()) { ++aNbTexUnits; }
+ if (!myPbrMat.NormalTexture.IsNull()) { ++aNbTexUnits; }
+ if (!myPbrMat.OcclusionTexture.IsNull()) { ++aNbTexUnits; }
+ if (!myPbrMat.MetallicRoughnessTexture.IsNull()) { ++aNbTexUnits; }
+ if (aNbTexUnits == 0)
{
- aColorTexture = myCommonMat.DiffuseTexture;
+ return;
}
- else if (!myPbrMat.BaseColorTexture.IsNull())
+
+ Standard_Integer aTexIter = 0;
+ Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNbTexUnits);
+ if (!aColorTexture.IsNull())
{
- aColorTexture = myPbrMat.BaseColorTexture;
+ aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_BaseColor));
}
-
- if (!myPbrMat.NormalTexture.IsNull())
+ if (!myPbrMat.EmissiveTexture.IsNull())
{
- aNormTexture = myPbrMat.NormalTexture;
+ aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.EmissiveTexture, Graphic3d_TextureUnit_Emissive));
}
-
- Standard_Integer aNbTextures = 0;
- if (!aColorTexture.IsNull())
+ if (!myPbrMat.OcclusionTexture.IsNull())
{
- ++aNbTextures;
+ aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.OcclusionTexture, Graphic3d_TextureUnit_Occlusion));
}
- if (!aNormTexture.IsNull())
+ if (!myPbrMat.NormalTexture.IsNull())
{
- //++aNbTextures;
+ aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.NormalTexture, Graphic3d_TextureUnit_Normal));
}
- if (aNbTextures != 0)
+ if (!myPbrMat.MetallicRoughnessTexture.IsNull())
{
- Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNbTextures);
- Standard_Integer aTextureIndex = 0;
- if (!aColorTexture.IsNull())
- {
- aTextureSet->SetValue (aTextureIndex++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_BaseColor));
- }
- if (!aNormTexture.IsNull())
- {
- //aTextureSet->SetValue (aTextureIndex++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_Normal));
- }
- theAspect->SetTextureSet (aTextureSet);
- theAspect->SetTextureMapOn (true);
+ aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.MetallicRoughnessTexture, Graphic3d_TextureUnit_MetallicRoughness));
}
+
+ theAspect->SetTextureSet (aTextureSet);
+ theAspect->SetTextureMapOn (true);
}
myTexId = myImageSource.TextureId();
}
myParams->SetTextureUnit (theUnit);
+ myIsColorMap = theUnit == Graphic3d_TextureUnit_BaseColor
+ || theUnit == Graphic3d_TextureUnit_Emissive;
}
//=======================================================================
--- /dev/null
+puts "========"
+puts "0031096: Visualization, TKOpenGl - support metallic-roughness texture mapping"
+puts "========"
+
+pload XDE OCAF MODELING VISUALIZATION
+catch { Close D }
+ReadGltf D [locate_data_file bug30691_DamagedHelmet.gltf]
+
+vclear
+vinit View1
+XDisplay -dispMode 1 D
+vaxo
+vcamera -persp
+vviewparams -scale 0.412548 -proj 0.54479 -0.790649 0.279424 -up -0.248339 0.166151 0.954317 -at -27.3419 382.603 -233.934
+
+vtextureenv on 2
+vlight -change 0 -intensity 2.5
+vlight -change 1 -intensity 0.3
+
+vrenderparams -shadingModel PBR
+vdump ${imagedir}/${casename}_pbr.png
+
+vrenderparams -ray -gi -rayDepth 10
+vfps 200
+vdump ${imagedir}/${casename}_pt.png