-- - Pewter
-- - Silver
-- - Stone.
-
+
SetMaterial(me:mutable;aName:NameOfMaterial from Graphic3d) is virtual;
---Purpose: Sets the name aName for material defining this
-- display attribute for the interactive object.
//function :
//purpose :
//=======================================================================
-//POP pour K4L
void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
-//void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
{
if( HasColor() || IsTransparent() || HasMaterial() )
{
myOwnMaterial = aName;
hasOwnMaterial = Standard_True;
}
+
//=======================================================================
//function : SetMaterial
//purpose :
//=======================================================================
-
-void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
+void AIS_InteractiveObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
{
- if (HasColor() || IsTransparent() || HasMaterial())
+ if (!HasColor() && !IsTransparent() && !HasMaterial())
{
- myDrawer->ShadingAspect()->SetMaterial(aMat);
- }
- else
- {
- myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
- myDrawer->ShadingAspect()->SetMaterial(aMat);
+ myDrawer->SetShadingAspect (new Prs3d_ShadingAspect);
}
+
+ myDrawer->ShadingAspect()->SetMaterial (theMaterial);
+
hasOwnMaterial = Standard_True;
}
+
//=======================================================================
-//function :
-//purpose :
+//function : UnsetMaterial
+//purpose :
//=======================================================================
void AIS_InteractiveObject::UnsetMaterial()
{
- if( !HasMaterial() ) return;
+ if (!HasMaterial())
+ {
+ return;
+ }
+
if (HasColor() || IsTransparent())
{
if(myDrawer->HasLink())
{
myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
}
- if (HasColor()) SetColor (myOwnColor);
- if (IsTransparent()) SetTransparency (myTransparency);
+
+ if (HasColor())
+ {
+ SetColor (myOwnColor);
+ }
+
+ if (IsTransparent())
+ {
+ SetTransparency (myTransparency);
+ }
}
- else{
- Handle(Prs3d_ShadingAspect) SA;
- myDrawer->SetShadingAspect(SA);
+ else
+ {
+ Handle(Prs3d_ShadingAspect) anAspect;
+ myDrawer->SetShadingAspect (anAspect);
}
+
hasOwnMaterial = Standard_False;
}
Graphic3d_Camera.hxx
Graphic3d_RenderingParams.hxx
Graphic3d_NMapOfTransient.hxx
+Graphic3d_BSDF.hxx
+Graphic3d_BSDF.cxx
imported BndBox4d;
imported BufferType;
+ imported BSDF;
+
imported CBitFields20;
---Category: Imported types
--- /dev/null
+// Created on: 2015-01-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 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.
+
+#include <Graphic3d_BSDF.hxx>
+
+#include <algorithm>
+
+// =======================================================================
+// function : Serialize
+// purpose :
+// =======================================================================
+Graphic3d_Vec4 Graphic3d_Fresnel::Serialize() const
+{
+ Graphic3d_Vec4 aData = Graphic3d_Vec4 (myFresnelData, 0.f);
+
+ if (myFresnelType != Graphic3d_FM_SCHLICK)
+ {
+ aData.x() = -static_cast<Standard_ShortReal> (myFresnelType);
+ }
+
+ return aData;
+}
+
+// =======================================================================
+// function : fresnelNormal
+// purpose :
+// =======================================================================
+inline Standard_ShortReal fresnelNormal (Standard_ShortReal theN,
+ Standard_ShortReal theK)
+{
+ return ((theN - 1.f) * (theN - 1.f) + theK * theK) /
+ ((theN + 1.f) * (theN + 1.f) + theK * theK);
+}
+
+// =======================================================================
+// function : CreateConductor
+// purpose :
+// =======================================================================
+Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theRefractionIndex,
+ const Graphic3d_Vec3& theAbsorptionIndex)
+{
+ return Graphic3d_Fresnel (Graphic3d_FM_SCHLICK,
+ Graphic3d_Vec3 (fresnelNormal (theRefractionIndex.x(), theAbsorptionIndex.x()),
+ fresnelNormal (theRefractionIndex.y(), theAbsorptionIndex.y()),
+ fresnelNormal (theRefractionIndex.z(), theAbsorptionIndex.z())));
+}
+
+// =======================================================================
+// function : Normalize
+// purpose :
+// =======================================================================
+void Graphic3d_BSDF::Normalize()
+{
+ Standard_ShortReal aMax = std::max (Kd.x() + Ks.x() + Kr.x() + Kt.x(),
+ std::max (Kd.y() + Ks.y() + Kr.y() + Kt.y(),
+ Kd.z() + Ks.z() + Kr.z() + Kt.z()));
+
+ if (aMax > 1.f)
+ {
+ Kd /= aMax;
+ Ks /= aMax;
+ Kr /= aMax;
+ Ks /= aMax;
+ }
+}
+
+// =======================================================================
+// function : CreateDiffuse
+// purpose :
+// =======================================================================
+Graphic3d_BSDF Graphic3d_BSDF::CreateDiffuse (const Graphic3d_Vec3& theWeight)
+{
+ Graphic3d_BSDF aBSDF;
+
+ aBSDF.Kd = theWeight;
+
+ return aBSDF;
+}
+
+// =======================================================================
+// function : CreateMetallic
+// purpose :
+// =======================================================================
+Graphic3d_BSDF Graphic3d_BSDF::CreateMetallic (const Graphic3d_Vec3& theWeight,
+ const Graphic3d_Fresnel& theFresnel,
+ const Standard_ShortReal theRoughness)
+{
+ Graphic3d_BSDF aBSDF;
+
+ aBSDF.Roughness = theRoughness;
+
+ // Selecting between specular and glossy
+ // BRDF depending on the given roughness
+ if (aBSDF.Roughness > 0.f)
+ {
+ aBSDF.Ks = theWeight;
+ }
+ else
+ {
+ aBSDF.Kr = theWeight;
+ }
+
+ aBSDF.Fresnel = theFresnel;
+
+ return aBSDF;
+}
+
+// =======================================================================
+// function : CreateTransparent
+// purpose :
+// =======================================================================
+Graphic3d_BSDF Graphic3d_BSDF::CreateTransparent (const Graphic3d_Vec3& theWeight,
+ const Graphic3d_Vec3& theAbsorptionColor,
+ const Standard_ShortReal theAbsorptionCoeff)
+{
+ Graphic3d_BSDF aBSDF;
+
+ aBSDF.Kt = theWeight;
+
+ aBSDF.AbsorptionColor = theAbsorptionColor;
+ aBSDF.AbsorptionCoeff = theAbsorptionCoeff;
+
+ aBSDF.Fresnel = Graphic3d_Fresnel::CreateConstant (0.f);
+
+ return aBSDF;
+}
+
+// =======================================================================
+// function : CreateGlass
+// purpose :
+// =======================================================================
+Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
+ const Graphic3d_Vec3& theAbsorptionColor,
+ const Standard_ShortReal theAbsorptionCoeff,
+ const Standard_ShortReal theRefractionIndex)
+{
+ Graphic3d_BSDF aBSDF;
+
+ aBSDF.Kt = theWeight;
+
+ aBSDF.AbsorptionColor = theAbsorptionColor;
+ aBSDF.AbsorptionCoeff = theAbsorptionCoeff;
+
+ aBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (theRefractionIndex);
+
+ return aBSDF;
+}
\ No newline at end of file
--- /dev/null
+// Created on: 2015-01-15
+// Created by: Danila ULYANOV
+// Copyright (c) 2014 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_BSDF_HeaderFile
+#define _Graphic3d_BSDF_HeaderFile
+
+#include <Graphic3d_Vec3.hxx>
+#include <Graphic3d_Vec4.hxx>
+
+//! Type of the Fresnel model.
+enum Graphic3d_FresnelModel
+{
+ Graphic3d_FM_SCHLICK = 0,
+ Graphic3d_FM_CONSTANT = 1,
+ Graphic3d_FM_CONDUCTOR = 2,
+ Graphic3d_FM_DIELECTRIC = 3
+};
+
+//! Describes Fresnel reflectance parameters.
+class Graphic3d_Fresnel
+{
+public:
+
+ //! Creates uninitialized Fresnel factor.
+ Graphic3d_Fresnel()
+ : myFresnelType (Graphic3d_FM_CONSTANT)
+ {
+ // ideal specular reflector
+ myFresnelData = Graphic3d_Vec3 (0.f, 1.f, 0.f);
+ }
+
+ //! Creates Schlick's approximation of Fresnel factor.
+ static Graphic3d_Fresnel CreateSchlick (const Graphic3d_Vec3& theSpecularColor)
+ {
+ return Graphic3d_Fresnel (Graphic3d_FM_SCHLICK, theSpecularColor);
+ }
+
+ //! Creates Fresnel factor for constant reflection.
+ static Graphic3d_Fresnel CreateConstant (const Standard_ShortReal theReflection)
+ {
+ return Graphic3d_Fresnel (Graphic3d_FM_CONSTANT, Graphic3d_Vec3 (0.f, 1.f, theReflection));
+ }
+
+ //! Creates Fresnel factor for physical-based dielectric model.
+ static Graphic3d_Fresnel CreateDielectric (Standard_ShortReal theRefractionIndex)
+ {
+ return Graphic3d_Fresnel (Graphic3d_FM_DIELECTRIC, Graphic3d_Vec3 (0.f, theRefractionIndex, 0.f));
+ }
+
+ //! Creates Fresnel factor for physical-based conductor model.
+ static Graphic3d_Fresnel CreateConductor (Standard_ShortReal theRefractionIndex,
+ Standard_ShortReal theAbsorptionIndex)
+ {
+ return Graphic3d_Fresnel (Graphic3d_FM_CONDUCTOR, Graphic3d_Vec3 (0.f, theRefractionIndex, theAbsorptionIndex));
+ }
+
+ //! Creates Fresnel factor for physical-based conductor model (spectral version).
+ Standard_EXPORT static Graphic3d_Fresnel CreateConductor (const Graphic3d_Vec3& theRefractionIndex,
+ const Graphic3d_Vec3& theAbsorptionIndex);
+
+public:
+
+ //! Returns serialized representation of Fresnel factor.
+ Standard_EXPORT Graphic3d_Vec4 Serialize() const;
+
+ //! Performs comparison of two objects describing Fresnel factor.
+ bool operator== (const Graphic3d_Fresnel& theOther) const
+ {
+ return myFresnelType == theOther.myFresnelType
+ && myFresnelData == theOther.myFresnelData;
+ }
+
+protected:
+
+ //! Creates new Fresnel reflectance factor.
+ Graphic3d_Fresnel (Graphic3d_FresnelModel theType, const Graphic3d_Vec3& theData)
+ : myFresnelType (theType),
+ myFresnelData (theData)
+ {
+ //
+ }
+
+private:
+
+ //! Type of Fresnel approximation.
+ Graphic3d_FresnelModel myFresnelType;
+
+ //! Serialized parameters of specific approximation.
+ Graphic3d_Vec3 myFresnelData;
+};
+
+//! Describes material's BSDF (Bidirectional Scattering Distribution Function) used
+//! for physically-based rendering (in path tracing engine). BSDF is represented as
+//! weighted mixture of basic BRDFs/BTDFs (Bidirectional Reflectance (Transmittance)
+//! Distribution Functions).
+class Graphic3d_BSDF
+{
+public:
+
+ //! Weight of the Lambertian BRDF.
+ Graphic3d_Vec3 Kd;
+
+ //! Weight of the reflection BRDF.
+ Graphic3d_Vec3 Kr;
+
+ //! Weight of the transmission BTDF.
+ Graphic3d_Vec3 Kt;
+
+ //! Weight of the Blinn's glossy BRDF.
+ Graphic3d_Vec3 Ks;
+
+ //! Self-emitted radiance.
+ Graphic3d_Vec3 Le;
+
+ //! Parameters of Fresnel reflectance.
+ Graphic3d_Fresnel Fresnel;
+
+ //! Roughness (exponent) of Blinn's BRDF.
+ Standard_ShortReal Roughness;
+
+ //! Absorption color of transparent media.
+ Graphic3d_Vec3 AbsorptionColor;
+
+ //! Absorption intensity of transparent media.
+ Standard_ShortReal AbsorptionCoeff;
+
+public:
+
+ //! Creates BSDF describing diffuse (Lambertian) surface.
+ static Standard_EXPORT Graphic3d_BSDF CreateDiffuse (const Graphic3d_Vec3& theWeight);
+
+ //! Creates BSDF describing polished metallic-like surface.
+ static Standard_EXPORT Graphic3d_BSDF CreateMetallic (const Graphic3d_Vec3& theWeight,
+ const Graphic3d_Fresnel& theFresnel,
+ const Standard_ShortReal theRoughness);
+
+ //! Creates BSDF describing transparent object.
+ //! Transparent BSDF models simple transparency without
+ //! refraction (the ray passes straight through the surface).
+ static Standard_EXPORT Graphic3d_BSDF CreateTransparent (const Graphic3d_Vec3& theWeight,
+ const Graphic3d_Vec3& theAbsorptionColor,
+ const Standard_ShortReal theAbsorptionCoeff);
+
+ //! Creates BSDF describing glass-like object.
+ //! Glass-like BSDF mixes refraction and reflection effects at
+ //! grazing angles using physically-based Fresnel dielectric model.
+ static Standard_EXPORT Graphic3d_BSDF CreateGlass (const Graphic3d_Vec3& theWeight,
+ const Graphic3d_Vec3& theAbsorptionColor,
+ const Standard_ShortReal theAbsorptionCoeff,
+ const Standard_ShortReal theRefractionIndex);
+
+public:
+
+ //! Creates uninitialized BSDF.
+ Graphic3d_BSDF()
+ {
+ Roughness = AbsorptionCoeff = 0.f;
+ }
+
+ //! Normalizes BSDF components.
+ Standard_EXPORT void Normalize();
+
+ //! Performs mixing of two BSDFs.
+ Graphic3d_BSDF& operator+ (const Graphic3d_BSDF& theOther)
+ {
+ Kd += theOther.Kd;
+ Kr += theOther.Kr;
+ Kt += theOther.Kt;
+ Ks += theOther.Ks;
+ Le += theOther.Le;
+
+ return *this;
+ }
+
+ //! Performs comparison of two BSDFs.
+ bool operator== (const Graphic3d_BSDF& theOther) const
+ {
+ return Kd == theOther.Kd
+ && Kr == theOther.Kr
+ && Kt == theOther.Kt
+ && Ks == theOther.Ks
+ && Le == theOther.Le
+ && Fresnel == theOther.Fresnel
+ && Roughness == theOther.Roughness
+ && AbsorptionCoeff == theOther.AbsorptionCoeff
+ && AbsorptionColor == theOther.AbsorptionColor;
+ }
+
+};
+
+#endif // _Graphic3d_BSDF_HeaderFile
Graphic3d_Vec4 Params; //!< packed light parameters
Standard_Integer Type; //!< Visual3d_TypeOfLightSource enumeration
Standard_Boolean IsHeadlight; //!< flag to mark head light
+ Standard_ShortReal Smoothness; //!< radius (cone angle) for point (directional) light
+ Standard_ShortReal Intensity; //!< intensity multiplier for light
//! Const attenuation factor of positional light source
Standard_ShortReal ConstAttenuation() const { return Params.x(); }
Direction (0.0f, 0.0f, 0.0f, 0.0f),
Params (0.0f, 0.0f, 0.0f, 0.0f),
Type (0),
- IsHeadlight (Standard_False)
+ IsHeadlight (Standard_False),
+ Smoothness (0.0f),
+ Intensity (1.0f)
{
//
}
// Back Material
const Graphic3d_MaterialAspect& aBack = theAspFill->BackMaterial();
- // Light specificity
- ContextFillArea.Back.Shininess = float (aBack.Shininess());
- ContextFillArea.Back.Ambient = float (aBack.Ambient());
- ContextFillArea.Back.Diffuse = float (aBack.Diffuse());
- ContextFillArea.Back.Specular = float (aBack.Specular());
- ContextFillArea.Back.Transparency = float (aBack.Transparency());
- ContextFillArea.Back.Emission = float (aBack.Emissive());
+ // Material properties
+ ContextFillArea.Back.Shininess = float (aBack.Shininess());
+ ContextFillArea.Back.Ambient = float (aBack.Ambient());
+ ContextFillArea.Back.Diffuse = float (aBack.Diffuse());
+ ContextFillArea.Back.Specular = float (aBack.Specular());
+ ContextFillArea.Back.Transparency = float (aBack.Transparency());
+ ContextFillArea.Back.Emission = float (aBack.Emissive());
ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
+ ContextFillArea.Back.BSDF = aBack.BSDF();
// Reflection mode
ContextFillArea.Back.IsAmbient = aBack.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
// Front Material
const Graphic3d_MaterialAspect& aFront = theAspFill->FrontMaterial();
- // Light specificity
- ContextFillArea.Front.Shininess = float (aFront.Shininess());
- ContextFillArea.Front.Ambient = float (aFront.Ambient());
- ContextFillArea.Front.Diffuse = float (aFront.Diffuse());
- ContextFillArea.Front.Specular = float (aFront.Specular());
- ContextFillArea.Front.Transparency = float (aFront.Transparency());
- ContextFillArea.Front.Emission = float (aFront.Emissive());
+
+ // Material properties
+ ContextFillArea.Front.Shininess = float (aFront.Shininess());
+ ContextFillArea.Front.Ambient = float (aFront.Ambient());
+ ContextFillArea.Front.Diffuse = float (aFront.Diffuse());
+ ContextFillArea.Front.Specular = float (aFront.Specular());
+ ContextFillArea.Front.Transparency = float (aFront.Transparency());
+ ContextFillArea.Front.Emission = float (aFront.Emissive());
ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
+ ContextFillArea.Front.BSDF = aFront.BSDF();
// Reflection mode
ContextFillArea.Front.IsAmbient = aFront.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
ContextFillArea.Back.EnvReflexion = float (aBack.EnvReflexion());
+ ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
+ ContextFillArea.Back.BSDF = aBack.BSDF();
+
// Front Material
const Graphic3d_MaterialAspect& aFront = theAspFill->FrontMaterial();
// Light specificity
ContextFillArea.Front.EnvReflexion = float (aFront.EnvReflexion());
+ ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
+ ContextFillArea.Front.BSDF = aFront.BSDF();
+
ContextFillArea.IsDef = 1; // Material definition ok
ContextFillArea.Texture.TextureMap = theAspFill->TextureMap();
aBack.SetEnvReflexion (anAspFill.Back.EnvReflexion);
+ aBack.SetRefractionIndex (Standard_Real (anAspFill.Back.RefractionIndex));
+ aBack.SetBSDF (anAspFill.Back.BSDF);
+
// Front Material
aFront.SetShininess (Standard_Real (anAspFill.Front.Shininess));
aFront.SetAmbient (Standard_Real (anAspFill.Front.Ambient));
aFront.SetEnvReflexion (anAspFill.Front.EnvReflexion);
+ aFront.SetRefractionIndex (Standard_Real (anAspFill.Front.RefractionIndex));
+ aFront.SetBSDF (anAspFill.Front.BSDF);
+
// Edges
anAspFill.Edge == 1 ? theAspFill->SetEdgeOn() : theAspFill->SetEdgeOff();
// Hatch
uses
- Color from Quantity,
-
- NameOfMaterial from Graphic3d,
- TypeOfReflection from Graphic3d,
- TypeOfMaterial from Graphic3d,
- AsciiString from TCollection
+ Color from Quantity,
+ NameOfMaterial from Graphic3d,
+ TypeOfReflection from Graphic3d,
+ TypeOfMaterial from Graphic3d,
+ BSDF from Graphic3d,
+ AsciiString from TCollection
raises
-- lesser than 1.0.
raises MaterialDefinitionError from Graphic3d is static;
+ SetBSDF ( me : in out;
+ theBSDF : BSDF from Graphic3d )
+ is static;
+ ---Level: Public
+ ---Purpose: Modifies the BSDF (bidirectional scattering distribution function).
+ -- Category: Methods to modify the class definition
+
SetColor ( me : in out;
AColor : Color from Quantity )
is static;
---Purpose: Returns the refraction index of the material
---Category: Inquire methods
+ BSDF ( me )
+ returns BSDF from Graphic3d
+ is static;
+ ---C++: return const&
+ ---Level: Public
+ ---Purpose: Returns BSDF (bidirectional scattering distribution function).
+ ---Category: Inquire methods
+
Emissive ( me )
returns Real from Standard
is static;
myTransparencyCoef : ShortReal from Standard;
myRefractionIndex : ShortReal from Standard;
+ -- BSDF (bidirectional scattering distribution function). Physically based material represented as weighted mixture of BxDFs (BRDFs and BTDFs) and its parameters.
+ myBSDF : BSDF from Graphic3d;
+
-- the specular exponent
myShininess : ShortReal from Standard;
-- the string name of the material
myStringName : AsciiString from TCollection;
-end MaterialAspect;
+end MaterialAspect;
\ No newline at end of file
mySpecularColor.SetValues (1.0, 1.0, 1.0, Quantity_TOC_RGB);
myMaterialName = theName;
+ myBSDF = Graphic3d_BSDF::CreateDiffuse (Graphic3d_Vec3 (0.2f, 0.2f, 0.2f));
+
Standard_Integer index = Standard_Integer (theName);
if (index < NumberOfMaterials())
{
switch (theName)
{
- case Graphic3d_NOM_PLASTIC: // Blue plastic
+ case Graphic3d_NOM_PLASTIC:
myShininess = Standard_ShortReal (0.0078125);
myAmbientCoef = Standard_ShortReal (0.5);
myDiffuseCoef = Standard_ShortReal (0.24);
mySpecularCoef = Standard_ShortReal (0.06);
+
+ myBSDF.Kd = Graphic3d_Vec3 (static_cast<Standard_ShortReal> (myDiffuseColor.Red()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Green()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Blue()));
+ myBSDF.Ks = Graphic3d_Vec3 (0.00784314f, 0.00784314f, 0.00784314f);
+ myBSDF.Normalize();
+ myBSDF.Roughness = 32;
break;
- case Graphic3d_NOM_SHINY_PLASTIC: // black plastic
+ case Graphic3d_NOM_SHINY_PLASTIC:
myShininess = Standard_ShortReal (1.0);
myAmbientCoef = Standard_ShortReal (0.44);
myDiffuseCoef = Standard_ShortReal (0.5);
mySpecularCoef = Standard_ShortReal (1.0);
+
+ myBSDF.Kd = Graphic3d_Vec3 (static_cast<Standard_ShortReal> (myDiffuseColor.Red()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Green()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Blue()));
+ myBSDF.Ks = Graphic3d_Vec3 (0.0156863f, 0.0156863f, 0.0156863f);
+ myBSDF.Normalize();
+ myBSDF.Roughness = 64.f;
break;
case Graphic3d_NOM_SATIN :
myShininess = Standard_ShortReal (0.09375);
myAmbientCoef = Standard_ShortReal (0.33);
myDiffuseCoef = Standard_ShortReal (0.4);
mySpecularCoef = Standard_ShortReal (0.44);
+
+ myBSDF.Kd = Graphic3d_Vec3 (static_cast<Standard_ShortReal> (myDiffuseColor.Red()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Green()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Blue()));
+ myBSDF.Ks = Graphic3d_Vec3 (0.0313726f, 0.0313726f, 0.0313726f);
+ myBSDF.Roughness = 16.f;
+ myBSDF.Normalize();
break;
case Graphic3d_NOM_NEON_GNC:
myShininess = Standard_ShortReal (0.05);
myEmissiveCoef = Standard_ShortReal (1.0);
myEmissiveActivity = Standard_True;
myAmbientActivity = Standard_False;
+
+ myBSDF.Kr = Graphic3d_Vec3 (0.207843f, 0.207843f, 0.207843f);
+ myBSDF.Le = Graphic3d_Vec3 (static_cast<Standard_ShortReal> (myDiffuseColor.Red()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Green()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Blue()));
+ myBSDF.Fresnel == Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.3f, 0.3f, 0.3f));
break;
case Graphic3d_NOM_METALIZED:
myShininess = Standard_ShortReal (0.13);
mySpecularCoef = Standard_ShortReal (0.45);
myAmbientActivity = Standard_False;
- // Color resulting from dispersed
- //myDiffuseColor .SetValues (0.87, 0.96, 1.0, Quantity_TOC_RGB);
- // Color resulting from specular
- //mySpecularColor.SetValues (0.93, 0.95, 0.78, Quantity_TOC_RGB);
+ {
+ Graphic3d_Vec3 aColor (static_cast<Standard_ShortReal> (myDiffuseColor.Red()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Green()),
+ static_cast<Standard_ShortReal> (myDiffuseColor.Blue()));
+
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (aColor), 1024.f);
+ }
break;
// Ascending Compatibility physical materials. The same definition is taken as in the next constructor.
case Graphic3d_NOM_BRASS:
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.58f, 0.42f, 0.20f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.329f, 0.224f, 0.027f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.65f, 0.35f, 0.15f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.213f, 0.128f, 0.054f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.955008f, 0.637427f, 0.538163f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.191f, 0.074f, 0.023f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (1.000000f, 0.765557f, 0.336057f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.300f, 0.230f, 0.095f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateConductor (1.8800f, 3.4900f), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.106f, 0.059f, 0.114f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseColor .SetValues (0.508f, 0.508f, 0.508f, Quantity_TOC_RGB);
// Color resulting from specular
mySpecularColor.SetValues (0.508f, 0.508f, 0.508f, Quantity_TOC_RGB);
+
+ myBSDF.Kd = Graphic3d_Vec3 (0.482353f, 0.482353f, 0.482353f);
+
break;
case Graphic3d_NOM_SILVER:
myMaterialType = Graphic3d_MATERIAL_PHYSIC;
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.971519f, 0.959915f, 0.915324f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.275f, 0.275f, 0.250f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateConductor (Graphic3d_Vec3 (2.90f, 2.80f, 2.53f), Graphic3d_Vec3 (3.08f, 2.90f, 2.74f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.150f, 0.150f, 0.180f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseColor .SetValues (1.0, 0.8, 0.62, Quantity_TOC_RGB);
// Color resulting from specular
mySpecularColor.SetValues (0.98, 1.0, 0.60, Quantity_TOC_RGB);
+
+ myBSDF.Kd = Graphic3d_Vec3 (0.243137f, 0.243137f, 0.243137f);
+ myBSDF.Ks = Graphic3d_Vec3 (0.00392157f, 0.00392157f, 0.00392157f);
+
break;
// Ascending Compatibility of physical materials. Takes the same definition as in the next constructor. New materials
case Graphic3d_NOM_CHROME:
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.549585f, 0.556114f, 0.554256f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.200f, 0.200f, 0.225f, Quantity_TOC_RGB);
// Color resulting from dispersed
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
+ myBSDF = Graphic3d_BSDF::CreateMetallic (Graphic3d_Vec3 (0.985f, 0.985f, 0.985f),
+ Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.913183f, 0.921494f, 0.924524f)), 1024.f);
+
// Color resulting from ambient
myAmbientColor .SetValues (0.300f, 0.300f, 0.300f, Quantity_TOC_RGB);
// Color resulting from dispersed
mySpecularColor.SetValues (1.0, 1.0, 1.0, Quantity_TOC_RGB);
// Color resulting from specular
myEmissiveColor.SetValues (0.0, 1.0, 0.46, Quantity_TOC_RGB);
+
+ myBSDF.Kr = Graphic3d_Vec3 (0.207843f, 0.207843f, 0.207843f);
+ myBSDF.Le = Graphic3d_Vec3 (0.0f, 1.0f, 0.46f);
+ myBSDF.Fresnel == Graphic3d_Fresnel::CreateSchlick (Graphic3d_Vec3 (0.3f, 0.3f, 0.3f));
break;
case Graphic3d_NOM_OBSIDIAN:
myMaterialType = Graphic3d_MATERIAL_PHYSIC;
myDiffuseColor .SetValues (0.183f, 0.170f, 0.225f, Quantity_TOC_RGB);
// Color resulting from specular
mySpecularColor.SetValues (0.333f, 0.329f, 0.346f, Quantity_TOC_RGB);
+
+ myBSDF.Kd = Graphic3d_Vec3 (0.0156863f, 0.f, 0.0155017f);
+ myBSDF.Ks = Graphic3d_Vec3 (0.0156863f, 0.0156863f, 0.0156863f);
+ myBSDF.Roughness = 1024.f;
break;
case Graphic3d_NOM_JADE:
myMaterialType = Graphic3d_MATERIAL_PHYSIC;
myDiffuseColor .SetValues (0.540f, 0.890f, 0.630f, Quantity_TOC_RGB);
// Color resulting from specular
mySpecularColor.SetValues (0.316f, 0.316f, 0.316f, Quantity_TOC_RGB);
+
+ myBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (1.5f);
+ myBSDF.Kd = Graphic3d_Vec3 (0.208658f, 0.415686f, 0.218401f);
+ myBSDF.Ks = Graphic3d_Vec3 (0.611765f, 0.611765f, 0.611765f);
+ myBSDF.Roughness = 512.f;
break;
case Graphic3d_NOM_CHARCOAL:
myMaterialType = Graphic3d_MATERIAL_PHYSIC;
myDiffuseColor .SetValues (0.150f, 0.150f, 0.150f, Quantity_TOC_RGB);
// Color resulting from specular
mySpecularColor.SetValues (0.000f, 0.000f, 0.000f, Quantity_TOC_RGB);
+
+ myBSDF.Kd = Graphic3d_Vec3 (0.0196078f, 0.0196078f, 0.0196078f);
+ myBSDF.Ks = Graphic3d_Vec3 (0.0196078f, 0.0196078f, 0.0196078f);
+ myBSDF.Roughness = 8;
break;
case Graphic3d_NOM_WATER:
myMaterialType = Graphic3d_MATERIAL_PHYSIC;
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
myRefractionIndex = 1.33f;
+ myBSDF = Graphic3d_BSDF::CreateGlass (Graphic3d_Vec3 (1.f),
+ Graphic3d_Vec3 (0.7f, 0.75f, 0.85f),
+ 0.05f,
+ myRefractionIndex);
myTransparencyCoef = 0.80f;
// Color resulting from ambient
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
myRefractionIndex = 1.62f;
+ myBSDF = Graphic3d_BSDF::CreateGlass (Graphic3d_Vec3 (1.f),
+ Graphic3d_Vec3 (0.75f, 0.95f, 0.9f),
+ 0.05f,
+ myRefractionIndex);
myTransparencyCoef = 0.80f;
// Color resulting from ambient
myDiffuseCoef = 1.00f;
mySpecularCoef = 1.00f;
myRefractionIndex = 2.42f;
+ myBSDF = Graphic3d_BSDF::CreateGlass (Graphic3d_Vec3 (1.f),
+ Graphic3d_Vec3 (0.95f, 0.95f, 0.95f),
+ 0.05f,
+ myRefractionIndex);
myTransparencyCoef = 0.80f;
// Color resulting from ambient
myRefractionIndex = static_cast<Standard_ShortReal> (theValue);
}
+// =======================================================================
+// function : SetBSDF
+// purpose :
+// =======================================================================
+void Graphic3d_MaterialAspect::SetBSDF (const Graphic3d_BSDF& theBSDF)
+{
+ myBSDF = theBSDF;
+}
+
// =======================================================================
// function : Color
// purpose :
return myRefractionIndex;
}
+// =======================================================================
+// function : BSDF
+// purpose :
+// =======================================================================
+const Graphic3d_BSDF& Graphic3d_MaterialAspect::BSDF() const
+{
+ return myBSDF;
+}
+
// =======================================================================
// function : Shininess
// purpose :
&& myEmissiveCoef == theOther.myEmissiveCoef
&& myTransparencyCoef == theOther.myTransparencyCoef
&& myRefractionIndex == theOther.myRefractionIndex
+ && myBSDF == theOther.myBSDF
&& myShininess == theOther.myShininess
&& myEnvReflexion == theOther.myEnvReflexion
&& myAmbientColor == theOther.myAmbientColor
{
public:
+ //! Default number of samples per pixel.
+ static const Standard_Integer THE_DEFAULT_SPP = 1;
+
//! Default ray-tracing depth.
static const Standard_Integer THE_DEFAULT_DEPTH = 3;
//! Creates default rendering parameters.
Graphic3d_RenderingParams()
- : Method (Graphic3d_RM_RASTERIZATION),
- RaytracingDepth (THE_DEFAULT_DEPTH),
- IsShadowEnabled (Standard_True),
- IsReflectionEnabled (Standard_False),
- IsAntialiasingEnabled (Standard_False),
- IsTransparentShadowEnabled (Standard_False)
+ : Method (Graphic3d_RM_RASTERIZATION),
+ RaytracingDepth (THE_DEFAULT_DEPTH),
+ SamplesPerPixel (THE_DEFAULT_SPP),
+ IsShadowEnabled (Standard_True),
+ IsReflectionEnabled (Standard_False),
+ IsAntialiasingEnabled (Standard_False),
+ IsTransparentShadowEnabled (Standard_False),
+ IsGlobalIlluminationEnabled (Standard_False),
+ UseEnvironmentMapBackground (Standard_False)
{
//
}
//! Maximum ray-tracing depth.
Standard_Integer RaytracingDepth;
+ //! Number of samples per pixel (SPP).
+ Standard_Integer SamplesPerPixel;
+
//! Enables/disables shadows rendering.
Standard_Boolean IsShadowEnabled;
//! Enables/disables light propagation through transparent media.
Standard_Boolean IsTransparentShadowEnabled;
+ //! Enables/disables global illumination effects (uses path tracing).
+ Standard_Boolean IsGlobalIlluminationEnabled;
+
+ //! Enables/disables environment map background (instead of OCCT background).
+ Standard_Boolean UseEnvironmentMapBackground;
+
};
#endif // _Graphic3d_RenderingParams_HeaderFile
aBack.SetEnvReflexion (myCStructure->ContextFillArea.Back.EnvReflexion);
aBack.SetMaterialType (myCStructure->ContextFillArea.Back.IsPhysic ? Graphic3d_MATERIAL_PHYSIC : Graphic3d_MATERIAL_ASPECT);
+ aBack.SetRefractionIndex (Standard_Real (myCStructure->ContextFillArea.Back.RefractionIndex));
+ aBack.SetBSDF (myCStructure->ContextFillArea.Back.BSDF);
+
// Front Material
Graphic3d_MaterialAspect aFront;
aFront.SetShininess (Standard_Real (myCStructure->ContextFillArea.Front.Shininess));
aFront.SetEnvReflexion (myCStructure->ContextFillArea.Front.EnvReflexion);
aFront.SetMaterialType (myCStructure->ContextFillArea.Front.IsPhysic ? Graphic3d_MATERIAL_PHYSIC : Graphic3d_MATERIAL_ASPECT);
+ aFront.SetRefractionIndex (Standard_Real (myCStructure->ContextFillArea.Front.RefractionIndex));
+ aFront.SetBSDF (myCStructure->ContextFillArea.Front.BSDF);
+
Quantity_Color anIntColor (Standard_Real (myCStructure->ContextFillArea.IntColor.r),
Standard_Real (myCStructure->ContextFillArea.IntColor.g),
Standard_Real (myCStructure->ContextFillArea.IntColor.b), Quantity_TOC_RGB);
myCStructure->ContextFillArea.Back.Specular = float (aBack.Specular());
myCStructure->ContextFillArea.Back.Transparency = float (aBack.Transparency());
myCStructure->ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
+ myCStructure->ContextFillArea.Back.BSDF = aBack.BSDF();
myCStructure->ContextFillArea.Back.Emission = float (aBack.Emissive());
// Reflection mode
myCStructure->ContextFillArea.Front.Specular = float (aFront.Specular());
myCStructure->ContextFillArea.Front.Transparency = float (aFront.Transparency());
myCStructure->ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
+ myCStructure->ContextFillArea.Front.BSDF = aFront.BSDF();
myCStructure->ContextFillArea.Front.Emission = float (aFront.Emissive());
// Reflection mode
#include <InterfaceGraphic_telem.hxx>
#include <Graphic3d_BndBox4f.hxx>
+#include <Graphic3d_BSDF.hxx>
#include <Standard_Transient.hxx>
/* COULEUR */
typedef struct {
- float r, g, b;
+ Standard_ShortReal r;
+ Standard_ShortReal g;
+ Standard_ShortReal b;
} CALL_DEF_COLOR;
typedef struct {
- float x, y, z;
+ Standard_ShortReal x;
+ Standard_ShortReal y;
+ Standard_ShortReal z;
} CALL_DEF_POINT;
typedef struct {
- float Ambient;
- int IsAmbient;
+ Standard_ShortReal Ambient;
+ Standard_Integer IsAmbient;
- float Diffuse;
- int IsDiffuse;
+ Standard_ShortReal Diffuse;
+ Standard_Integer IsDiffuse;
- float Specular;
- int IsSpecular;
+ Standard_ShortReal Specular;
+ Standard_Integer IsSpecular;
- float Emission;
- int IsEmission;
+ Standard_ShortReal Emission;
+ Standard_Integer IsEmission;
- float Shininess;
- float Transparency;
- float RefractionIndex;
+ Graphic3d_BSDF BSDF;
- float EnvReflexion;
+ Standard_ShortReal Shininess;
+ Standard_ShortReal Transparency;
+ Standard_ShortReal RefractionIndex;
- int IsPhysic;
+ Standard_ShortReal EnvReflexion;
- /* Attribut couleur eclairage */
- CALL_DEF_COLOR ColorAmb, ColorDif, ColorSpec, ColorEms, Color;
+ Standard_Integer IsPhysic;
+ /* Color attributes */
+ CALL_DEF_COLOR ColorAmb;
+ CALL_DEF_COLOR ColorDif;
+ CALL_DEF_COLOR ColorSpec;
+ CALL_DEF_COLOR ColorEms;
+ CALL_DEF_COLOR Color;
} CALL_DEF_MATERIAL;
/* Transform persistence struct */
typedef struct
{
- int IsSet;
- int IsDef;
- int Flag;
- CALL_DEF_POINT Point;
+ Standard_Integer IsSet;
+ Standard_Integer IsDef;
+ Standard_Integer Flag;
+ CALL_DEF_POINT Point;
} CALL_DEF_TRANSFORM_PERSISTENCE;
/* USERDRAW DATA */
typedef struct {
- void *Data;
- Graphic3d_BndBox4f *Bounds;
+ void* Data;
+ Graphic3d_BndBox4f* Bounds;
} CALL_DEF_USERDRAW;
// in OpenGl it is opposite.
theSurf.trans = 1.0f - theMat.Transparency;
theSurf.index = theMat.RefractionIndex;
+
+ // material BSDF (for physically-based rendering)
+ theSurf.BSDF = theMat.BSDF;
}
// =======================================================================
#include <Graphic3d_CAspectFillArea.hxx>
#include <Graphic3d_ShaderProgram.hxx>
#include <Graphic3d_TextureMap.hxx>
+#include <Graphic3d_BSDF.hxx>
#define OPENGL_AMBIENT_MASK (1<<0)
#define OPENGL_DIFFUSE_MASK (1<<1)
struct OPENGL_SURF_PROP
{
- float amb, diff, spec, emsv;
- float trans, shine, index;
- float env_reflexion;
- int isphysic;
+ Standard_ShortReal amb;
+ Standard_ShortReal diff;
+ Standard_ShortReal spec;
+ Standard_ShortReal emsv;
+
+ Standard_ShortReal trans;
+ Standard_ShortReal shine;
+ Standard_ShortReal index;
+
+ Standard_ShortReal env_reflexion;
+ Standard_Integer isphysic;
+
unsigned int color_mask;
- TEL_COLOUR speccol, difcol, ambcol, emscol, matcol;
+
+ TEL_COLOUR speccol;
+ TEL_COLOUR difcol;
+ TEL_COLOUR ambcol;
+ TEL_COLOUR emscol;
+ TEL_COLOUR matcol;
+
+ Graphic3d_BSDF BSDF;
+
DEFINE_STANDARD_ALLOC
};
//! Gets background gradient fill method
Aspect_GradientFillMethod GradientFillMethod() const { return myGradientParams.type; }
+ //! Returns color of gradient background for the given index.
+ const OpenGl_Vec4& GradientColor (const Standard_Integer theIndex) const { return (&myGradientParams.color1)[theIndex]; }
+
//! Sets type of gradient fill method
Standard_EXPORT void SetGradientFillMethod (const Aspect_GradientFillMethod theType);
{
if (myVPSizeX == theViewportSizeX
&& myVPSizeY == theViewportSizeY)
+
{
return IsValid();
}
//! Texture transformation matrix.
BVH_Mat4f TextureTransform;
+ //! Physically-based material properties (used in path tracing engine).
+ struct Physical
+ {
+ //! Weight of the diffuse BRDF.
+ BVH_Vec4f Kd;
+
+ //! Weight of the reflection BRDF.
+ BVH_Vec4f Kr;
+
+ //! Weight of the transmission BTDF.
+ BVH_Vec4f Kt;
+
+ //! Weight of the Blinn's glossy BRDF.
+ BVH_Vec4f Ks;
+
+ //! Self-emitted radiance.
+ BVH_Vec4f Le;
+
+ //! Fresnel coefficients.
+ BVH_Vec4f Fresnel;
+
+ //! Absorption color for the transmission BSDF.
+ BVH_Vec4f Absorption;
+
+ } BSDF;
+
public:
//! Creates new default material.
//! Returns structure modification state (for ray-tracing).
Standard_Size ModificationState() const { return myModificationState; }
- //! Resets structure modification state (for ray-tracing)
+ //! Resets structure modification state (for ray-tracing).
void ResetModificationState() const { myModificationState = 0; }
//! Is the structure ray-tracable (contains ray-tracable elements)?
myIsRaytraceDataValid (Standard_False),
myIsRaytraceWarnTextures (Standard_False),
myToUpdateEnvironmentMap (Standard_False),
- myLayersModificationStatus (0)
+ myLayerListState (0)
{
myCurrLightSourceState = myStateCounter->Increment();
}
#include <TColStd_Array2OfReal.hxx>
#include <NCollection_List.hxx>
+#include <math_BullardGenerator.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Aspect_FillMethod.hxx>
{
OpenGl_RT_aPosition,
+ // camera position
OpenGl_RT_uOriginLT,
OpenGl_RT_uOriginLB,
OpenGl_RT_uOriginRT,
OpenGl_RT_uDirectRB,
OpenGl_RT_uUnviewMat,
+ // 3D scene params
OpenGl_RT_uSceneRad,
OpenGl_RT_uSceneEps,
OpenGl_RT_uLightAmbnt,
OpenGl_RT_uLightCount,
- OpenGl_RT_uShadEnabled,
- OpenGl_RT_uReflEnabled,
- OpenGl_RT_uEnvMapEnable,
+ // background params
+ OpenGl_RT_uBackColorTop,
+ OpenGl_RT_uBackColorBot,
+ // ray-tracing params
+ OpenGl_RT_uShadowsEnabled,
+ OpenGl_RT_uReflectEnabled,
+ OpenGl_RT_uSphereMapEnabled,
+ OpenGl_RT_uSphereMapForBack,
+ OpenGl_RT_uTexSamplersArray,
+
+ // sampled frame params
+ OpenGl_RT_uSampleWeight,
+ OpenGl_RT_uFrameRndSeed,
+
+ // adaptive FSAA params
OpenGl_RT_uOffsetX,
OpenGl_RT_uOffsetY,
OpenGl_RT_uSamples,
- OpenGl_RT_uWinSizeX,
- OpenGl_RT_uWinSizeY,
-
- OpenGl_RT_uTextures,
OpenGl_RT_NbVariables // special field
};
OpenGl_RT_RaytraceMaterialTexture = 9,
OpenGl_RT_RaytraceLightSrcTexture = 10,
- OpenGl_RT_FSAAInputTexture = 11,
+ OpenGl_RT_FsaaInputTexture = 11,
+ OpenGl_RT_PrevAccumTexture = 12,
- OpenGl_RT_OpenGlColorTexture = 12,
- OpenGl_RT_OpenGlDepthTexture = 13
+ OpenGl_RT_OpenGlColorTexture = 13,
+ OpenGl_RT_OpenGlDepthTexture = 14
};
//! Tool class for management of shader sources.
{
public:
+ //! Default shader prefix - empty string.
+ static const TCollection_AsciiString EMPTY_PREFIX;
+
//! Creates new uninitialized shader source.
ShaderSource()
{
}
//! Creates new shader source from specified file.
- ShaderSource (const TCollection_AsciiString& theFileName)
+ ShaderSource (const TCollection_AsciiString& theFileName, const TCollection_AsciiString& thePrefix = EMPTY_PREFIX)
{
- Load (&theFileName, 1);
+ TCollection_AsciiString aFileNames[] = { theFileName, "" };
+
+ Load (aFileNames, thePrefix);
}
public:
TCollection_AsciiString Source() const;
//! Loads shader source from specified files.
- void Load (const TCollection_AsciiString* theFileNames, const Standard_Integer theCount);
+ void Load (const TCollection_AsciiString* theFileNames, const TCollection_AsciiString& thePrefix = EMPTY_PREFIX);
private:
//! Enables/disables light propagation through transparent media.
Standard_Boolean TransparentShadows;
+ //! Enables/disables global illumination (GI) effects.
+ Standard_Boolean GlobalIllumination;
+
//! Enables/disables the use of OpenGL bindless textures.
Standard_Boolean UseBindlessTextures;
: StackSize (THE_DEFAULT_STACK_SIZE),
NbBounces (THE_DEFAULT_NB_BOUNCES),
TransparentShadows (Standard_False),
+ GlobalIllumination (Standard_False),
UseBindlessTextures (Standard_False)
{
//
const ShaderSource& theSource,
const Handle(OpenGl_Context)& theGlContext);
+ //! Creates shader program from the given vertex and fragment shaders.
+ Handle(OpenGl_ShaderProgram) initProgram (const Handle(OpenGl_Context)& theGlContext,
+ const Handle(OpenGl_ShaderObject)& theVertShader,
+ const Handle(OpenGl_ShaderObject)& theFragShader);
+
//! Initializes OpenGL/GLSL shader programs.
Standard_Boolean initRaytraceResources (const Graphic3d_CView& theCView,
const Handle(OpenGl_Context)& theGlContext);
Handle(OpenGl_ShaderProgram) myRaytraceProgram;
//! OpenGL/GLSL adaptive-AA shader program.
Handle(OpenGl_ShaderProgram) myPostFSAAProgram;
+ //! OpenGL/GLSL program for displaying texture.
+ Handle(OpenGl_ShaderProgram) myOutImageProgram;
//! Texture buffer of data records of bottom-level BVH nodes.
Handle(OpenGl_TextureBufferArb) mySceneNodeInfoTexture;
//! PrimitiveArray to TriangleSet map for scene partial update.
std::map<Standard_Size, OpenGl_TriangleSet*> myArrayToTrianglesMap;
- //! Graphical ray-tracing filter to filter out all raytracable structures.
+ //! Set of IDs of non-raytracable elements (to detect updates).
+ std::set<Standard_Integer> myNonRaytraceStructureIDs;
+
+ //! Render filter to filter out all raytracable structures.
Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
//! Marks if environment map should be updated.
Standard_Boolean myToUpdateEnvironmentMap;
//! State of OpenGL layer list.
- Standard_Size myLayersModificationStatus;
+ Standard_Size myLayerListState;
+
+ //! Number of accumulated frames (for progressive rendering).
+ Standard_Integer myAccumFrames;
+
+ //! Stored ray origins used for detection of camera movements.
+ OpenGl_Vec3 myPreviousOrigins[3];
+
+ //! Bullard RNG to produce random sequence.
+ math_BullardGenerator myRNG;
public:
#endif
// =======================================================================
-// function : UpdateRaytraceGeometry
+// function : updateRaytraceGeometry
// purpose : Updates 3D scene geometry for ray-tracing
// =======================================================================
Standard_Boolean OpenGl_View::updateRaytraceGeometry (const RaytraceUpdateMode theMode,
// modifications. This is light-weight procedure performed on each frame
if (theMode == OpenGl_GUM_CHECK)
{
- if (myLayersModificationStatus != myZLayers.ModificationState())
+ if (myLayerListState != myZLayers.ModificationState())
{
return updateRaytraceGeometry (OpenGl_GUM_PREPARE, theViewId, theGlContext);
}
// applicable for ray-tracing
std::set<Standard_Size> anArrayIDs;
+ // Set to store all non-raytracable elements allowing tracking
+ // of changes in OpenGL scene (only for path tracing)
+ std::set<Standard_Integer> aNonRaytraceIDs;
+
const OpenGl_Layer& aLayer = myZLayers.Layer (Graphic3d_ZLayerId_Default);
if (aLayer.NbStructures() != 0)
{
return updateRaytraceGeometry (OpenGl_GUM_PREPARE, theViewId, theGlContext);
}
+ else if (aStructure->IsVisible() && myRaytraceParameters.GlobalIllumination)
+ {
+ aNonRaytraceIDs.insert (aStructure->highlight ? aStructure->Id : -aStructure->Id);
+ }
}
else if (theMode == OpenGl_GUM_PREPARE)
{
}
// Actualize OpenGL layer list state
- myLayersModificationStatus = myZLayers.ModificationState();
+ myLayerListState = myZLayers.ModificationState();
// Rebuild two-level acceleration structure
myRaytraceGeometry.ProcessAcceleration();
return uploadRaytraceData (theGlContext);
}
+ if (myRaytraceParameters.GlobalIllumination)
+ {
+ Standard_Boolean toRestart =
+ aNonRaytraceIDs.size() != myNonRaytraceStructureIDs.size();
+
+ for (std::set<Standard_Integer>::iterator anID = aNonRaytraceIDs.begin(); anID != aNonRaytraceIDs.end() && !toRestart; ++anID)
+ {
+ if (myNonRaytraceStructureIDs.find (*anID) == myNonRaytraceStructureIDs.end())
+ {
+ toRestart = Standard_True;
+ }
+ }
+
+ if (toRestart)
+ myAccumFrames = 0;
+
+ myNonRaytraceStructureIDs = aNonRaytraceIDs;
+ }
+
return Standard_True;
}
// =======================================================================
-// function : ToUpdateStructure
+// function : toUpdateStructure
// purpose : Checks to see if the structure is modified
// =======================================================================
Standard_Boolean OpenGl_View::toUpdateStructure (const OpenGl_Structure* theStructure)
}
// =======================================================================
-// function : BuildTextureTransform
+// function : buildTextureTransform
// purpose : Constructs texture transformation matrix
// =======================================================================
-void BuildTextureTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Mat4f& theMatrix)
+void buildTextureTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Mat4f& theMatrix)
{
theMatrix.InitIdentity();
}
// =======================================================================
-// function : ConvertMaterial
+// function : convertMaterial
// purpose : Creates ray-tracing material properties
// =======================================================================
OpenGl_RaytraceMaterial OpenGl_View::convertMaterial (const OpenGl_AspectFace* theAspect,
aProperties.speccol.rgb[2] * aProperties.spec * aReflectionScale,
0.f);
+ // Serialize physically-based material properties
+ const Graphic3d_BSDF& aBSDF = aProperties.BSDF;
+
+ theMaterial.BSDF.Le = BVH_Vec4f (aBSDF.Le, 0.f);
+ theMaterial.BSDF.Kd = BVH_Vec4f (aBSDF.Kd, -1.f /* no tex */);
+ theMaterial.BSDF.Kr = BVH_Vec4f (aBSDF.Kr, 0.f);
+ theMaterial.BSDF.Kt = BVH_Vec4f (aBSDF.Kt, 0.f);
+ theMaterial.BSDF.Ks = BVH_Vec4f (aBSDF.Ks, aBSDF.Roughness);
+
+ theMaterial.BSDF.Fresnel = aBSDF.Fresnel.Serialize();
+
+ theMaterial.BSDF.Absorption = BVH_Vec4f (aBSDF.AbsorptionColor,
+ aBSDF.AbsorptionCoeff);
+
+ // Handle material textures
if (theAspect->DoTextureMap())
{
if (theGlContext->arbTexBindless != NULL)
{
- BuildTextureTransform (theAspect->TextureParams(), theMaterial.TextureTransform);
+ buildTextureTransform (theAspect->TextureParams(), theMaterial.TextureTransform);
- // write texture ID in the w-component
- theMaterial.Diffuse.w() = static_cast<Standard_ShortReal> (
- myRaytraceGeometry.AddTexture (theAspect->TextureRes (theGlContext)));
+ // write texture ID to diffuse w-component
+ theMaterial.Diffuse.w() = theMaterial.BSDF.Kd.w() =
+ static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (theAspect->TextureRes (theGlContext)));
}
else if (!myIsRaytraceWarnTextures)
{
}
// =======================================================================
-// function : AddRaytraceStructure
+// function : addRaytraceStructure
// purpose : Adds OpenGL structure to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure* theStructure,
}
// =======================================================================
-// function : AddRaytraceGroups
+// function : addRaytraceGroups
// purpose : Adds OpenGL groups to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure* theStructure,
}
// =======================================================================
-// function : AddRaytracePrimitiveArray
+// function : addRaytracePrimitiveArray
// purpose : Adds OpenGL primitive array to ray-traced scene geometry
// =======================================================================
OpenGl_TriangleSet* OpenGl_View::addRaytracePrimitiveArray (const OpenGl_PrimitiveArray* theArray,
}
// =======================================================================
-// function : AddRaytraceVertexIndices
+// function : addRaytraceVertexIndices
// purpose : Adds vertex indices to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceVertexIndices (OpenGl_TriangleSet& theSet,
}
// =======================================================================
-// function : AddRaytraceTriangleArray
+// function : addRaytraceTriangleArray
// purpose : Adds OpenGL triangle array to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceTriangleArray (OpenGl_TriangleSet& theSet,
}
// =======================================================================
-// function : AddRaytraceTriangleFanArray
+// function : addRaytraceTriangleFanArray
// purpose : Adds OpenGL triangle fan array to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceTriangleFanArray (OpenGl_TriangleSet& theSet,
}
// =======================================================================
-// function : AddRaytraceTriangleStripArray
+// function : addRaytraceTriangleStripArray
// purpose : Adds OpenGL triangle strip array to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceTriangleStripArray (OpenGl_TriangleSet& theSet,
}
// =======================================================================
-// function : AddRaytraceQuadrangleArray
+// function : addRaytraceQuadrangleArray
// purpose : Adds OpenGL quad array to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceQuadrangleArray (OpenGl_TriangleSet& theSet,
}
// =======================================================================
-// function : AddRaytraceQuadrangleStripArray
+// function : addRaytraceQuadrangleStripArray
// purpose : Adds OpenGL quad strip array to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytraceQuadrangleStripArray (OpenGl_TriangleSet& theSet,
}
// =======================================================================
-// function : AddRaytracePolygonArray
+// function : addRaytracePolygonArray
// purpose : Adds OpenGL polygon array to ray-traced scene geometry
// =======================================================================
Standard_Boolean OpenGl_View::addRaytracePolygonArray (OpenGl_TriangleSet& theSet,
return Standard_True;
}
+const TCollection_AsciiString OpenGl_View::ShaderSource::EMPTY_PREFIX;
+
// =======================================================================
// function : Source
// purpose : Returns shader source combined with prefix
// purpose : Loads shader source from specified files
// =======================================================================
void OpenGl_View::ShaderSource::Load (const TCollection_AsciiString* theFileNames,
- const Standard_Integer theCount)
+ const TCollection_AsciiString& thePrefix)
{
mySource.Clear();
- for (Standard_Integer anIndex = 0; anIndex < theCount; ++anIndex)
+ for (Standard_Integer anIndex = 0; !theFileNames[anIndex].IsEmpty(); ++anIndex)
{
OSD_File aFile (theFileNames[anIndex]);
aFile.Close();
}
+
+ myPrefix = thePrefix;
}
// =======================================================================
-// function : GenerateShaderPrefix
+// function : generateShaderPrefix
// purpose : Generates shader prefix based on current ray-tracing options
// =======================================================================
TCollection_AsciiString OpenGl_View::generateShaderPrefix (const Handle(OpenGl_Context)& theGlContext) const
TCollection_AsciiString ("\n#define MAX_TEX_NUMBER ") + TCollection_AsciiString (OpenGl_RaytraceGeometry::MAX_TEX_NUMBER);
}
+ if (myRaytraceParameters.GlobalIllumination)
+ {
+ aPrefixString += TCollection_AsciiString ("\n#define PATH_TRACING");
+ }
+
return aPrefixString;
}
// =======================================================================
-// function : SafeFailBack
+// function : safeFailBack
// purpose : Performs safe exit when shaders initialization fails
// =======================================================================
Standard_Boolean OpenGl_View::safeFailBack (const TCollection_ExtendedString& theMessage,
}
// =======================================================================
-// function : InitShader
+// function : initShader
// purpose : Creates new shader object with specified source
// =======================================================================
Handle(OpenGl_ShaderObject) OpenGl_View::initShader (const GLenum theType,
}
// =======================================================================
-// function : InitRaytraceResources
+// function : initProgram
+// purpose : Creates GLSL program from the given shader objects
+// =======================================================================
+Handle(OpenGl_ShaderProgram) OpenGl_View::initProgram (const Handle(OpenGl_Context)& theGlContext,
+ const Handle(OpenGl_ShaderObject)& theVertShader,
+ const Handle(OpenGl_ShaderObject)& theFragShader)
+{
+ Handle(OpenGl_ShaderProgram) aProgram = new OpenGl_ShaderProgram;
+
+ if (!aProgram->Create (theGlContext))
+ {
+ theVertShader->Release (theGlContext.operator->());
+
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, "Failed to create shader program");
+
+ return Handle(OpenGl_ShaderProgram)();
+ }
+
+ if (!aProgram->AttachShader (theGlContext, theVertShader)
+ || !aProgram->AttachShader (theGlContext, theFragShader))
+ {
+ theVertShader->Release (theGlContext.operator->());
+
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, "Failed to attach shader objects");
+
+ return Handle(OpenGl_ShaderProgram)();
+ }
+
+ aProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
+
+ TCollection_AsciiString aLinkLog;
+
+ if (!aProgram->Link (theGlContext))
+ {
+ aProgram->FetchInfoLog (theGlContext, aLinkLog);
+
+ const TCollection_ExtendedString aMessage = TCollection_ExtendedString (
+ "Failed to link shader program:\n") + aLinkLog;
+
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMessage);
+
+ return Handle(OpenGl_ShaderProgram)();
+ }
+ else if (theGlContext->caps->glslWarnings)
+ {
+ myRaytraceProgram->FetchInfoLog (theGlContext, aLinkLog);
+
+ if (!aLinkLog.IsEmpty() && !aLinkLog.IsEqual ("No errors.\n"))
+ {
+ const TCollection_ExtendedString aMessage = TCollection_ExtendedString (
+ "Shader program was linked with following warnings:\n") + aLinkLog;
+
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMessage);
+ }
+ }
+
+ return aProgram;
+}
+
+// =======================================================================
+// function : initRaytraceResources
// purpose : Initializes OpenGL/GLSL shader programs
// =======================================================================
Standard_Boolean OpenGl_View::initRaytraceResources (const Graphic3d_CView& theCView, const Handle(OpenGl_Context)& theGlContext)
aToRebuildShaders = Standard_True;
}
+ if (theCView.RenderParams.IsGlobalIlluminationEnabled != myRaytraceParameters.GlobalIllumination)
+ {
+ myRaytraceParameters.GlobalIllumination = theCView.RenderParams.IsGlobalIlluminationEnabled;
+ aToRebuildShaders = Standard_True;
+ }
+
if (aToRebuildShaders)
{
-#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Info: Rebuild shaders with stack size: " << myRaytraceParameters.StackSize << std::endl;
-#endif
+ // Reject accumulated frames
+ myAccumFrames = 0;
- // Change state to force update all uniforms
+ // We need to update environment texture
myToUpdateEnvironmentMap = Standard_True;
TCollection_AsciiString aPrefixString = generateShaderPrefix (theGlContext);
}
TCollection_AsciiString aFiles[] = { aFolder + "/RaytraceBase.fs",
- aFolder + "/RaytraceRender.fs" };
-
- myRaytraceShaderSource.Load (aFiles, 2);
+ aFolder + "/PathtraceBase.fs",
+ aFolder + "/RaytraceRender.fs",
+ "" };
- myRaytraceShaderSource.SetPrefix (aPrefixString);
+ myRaytraceShaderSource.Load (aFiles, aPrefixString);
myRaytraceShader = initShader (GL_FRAGMENT_SHADER, myRaytraceShaderSource, theGlContext);
return safeFailBack ("Failed to initialize ray-trace fragment shader", theGlContext);
}
- myRaytraceProgram = new OpenGl_ShaderProgram;
+ myRaytraceProgram = initProgram (theGlContext, aBasicVertShader, myRaytraceShader);
- if (!myRaytraceProgram->Create (theGlContext))
+ if (myRaytraceProgram.IsNull())
{
- aBasicVertShader->Release (theGlContext.operator->());
-
- return safeFailBack ("Failed to create ray-trace shader program", theGlContext);
- }
-
- if (!myRaytraceProgram->AttachShader (theGlContext, aBasicVertShader)
- || !myRaytraceProgram->AttachShader (theGlContext, myRaytraceShader))
- {
- aBasicVertShader->Release (theGlContext.operator->());
-
- return safeFailBack ("Failed to attach ray-trace shader objects", theGlContext);
- }
-
- myRaytraceProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
-
- TCollection_AsciiString aLinkLog;
-
- if (!myRaytraceProgram->Link (theGlContext))
- {
- myRaytraceProgram->FetchInfoLog (theGlContext, aLinkLog);
-
- return safeFailBack (TCollection_ExtendedString (
- "Failed to link ray-trace shader program:\n") + aLinkLog, theGlContext);
- }
- else if (theGlContext->caps->glslWarnings)
- {
- myRaytraceProgram->FetchInfoLog (theGlContext, aLinkLog);
-
- if (!aLinkLog.IsEmpty() && !aLinkLog.IsEqual ("No errors.\n"))
- {
- const TCollection_ExtendedString aMessage = TCollection_ExtendedString (
- "Ray-trace shader program was linked with following warnings:\n") + aLinkLog;
-
- theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMessage);
- }
+ return safeFailBack ("Failed to initialize ray-trace shader program", theGlContext);
}
}
}
TCollection_AsciiString aFiles[] = { aFolder + "/RaytraceBase.fs",
- aFolder + "/RaytraceSmooth.fs" };
+ aFolder + "/RaytraceSmooth.fs",
+ "" };
- myPostFSAAShaderSource.Load (aFiles, 2);
+ myPostFSAAShaderSource.Load (aFiles, aPrefixString);
- myPostFSAAShaderSource.SetPrefix (aPrefixString);
-
myPostFSAAShader = initShader (GL_FRAGMENT_SHADER, myPostFSAAShaderSource, theGlContext);
if (myPostFSAAShader.IsNull())
return safeFailBack ("Failed to initialize FSAA fragment shader", theGlContext);
}
- myPostFSAAProgram = new OpenGl_ShaderProgram;
+ myPostFSAAProgram = initProgram (theGlContext, aBasicVertShader, myPostFSAAShader);
- if (!myPostFSAAProgram->Create (theGlContext))
+ if (myPostFSAAProgram.IsNull())
{
- aBasicVertShader->Release (theGlContext.operator->());
-
- return safeFailBack ("Failed to create FSAA shader program", theGlContext);
+ return safeFailBack ("Failed to initialize FSAA shader program", theGlContext);
}
+ }
- if (!myPostFSAAProgram->AttachShader (theGlContext, aBasicVertShader)
- || !myPostFSAAProgram->AttachShader (theGlContext, myPostFSAAShader))
- {
- aBasicVertShader->Release (theGlContext.operator->());
+ {
+ Handle(OpenGl_ShaderObject) aBasicVertShader = initShader (
+ GL_VERTEX_SHADER, ShaderSource (aFolder + "/RaytraceBase.vs"), theGlContext);
- return safeFailBack ("Failed to attach FSAA shader objects", theGlContext);
+ if (aBasicVertShader.IsNull())
+ {
+ return safeFailBack ("Failed to set vertex shader source", theGlContext);
}
- myPostFSAAProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
-
- TCollection_AsciiString aLinkLog;
+ Handle(OpenGl_ShaderObject) aDisplayShader = initShader (
+ GL_FRAGMENT_SHADER, ShaderSource (aFolder + "/Display.fs", aPrefixString), theGlContext);
- if (!myPostFSAAProgram->Link (theGlContext))
+ if (aDisplayShader.IsNull())
{
- myPostFSAAProgram->FetchInfoLog (theGlContext, aLinkLog);
-
- return safeFailBack (TCollection_ExtendedString (
- "Failed to link FSAA shader program:\n") + aLinkLog, theGlContext);
+ aBasicVertShader->Release (theGlContext.operator->());
+
+ return safeFailBack ("Failed to set display fragment shader source", theGlContext);
}
- else if (theGlContext->caps->glslWarnings)
- {
- myPostFSAAProgram->FetchInfoLog (theGlContext, aLinkLog);
- if (!aLinkLog.IsEmpty() && !aLinkLog.IsEqual ("No errors.\n"))
- {
- const TCollection_ExtendedString aMessage = TCollection_ExtendedString (
- "FSAA shader program was linked with following warnings:\n") + aLinkLog;
+ myOutImageProgram = initProgram (theGlContext, aBasicVertShader, aDisplayShader);
- theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMessage);
- }
+ if (myOutImageProgram.IsNull())
+ {
+ return safeFailBack ("Failed to initialize output shader program", theGlContext);
}
}
}
if (anIndex == 1)
{
aShaderProgram->SetSampler (theGlContext,
- "uFSAAInputTexture", OpenGl_RT_FSAAInputTexture);
+ "uFSAAInputTexture", OpenGl_RT_FsaaInputTexture);
+ }
+ else
+ {
+ aShaderProgram->SetSampler (theGlContext,
+ "uAccumTexture", OpenGl_RT_PrevAccumTexture);
}
myUniformLocations[anIndex][OpenGl_RT_aPosition] =
aShaderProgram->GetUniformLocation (theGlContext, "uOffsetY");
myUniformLocations[anIndex][OpenGl_RT_uSamples] =
aShaderProgram->GetUniformLocation (theGlContext, "uSamples");
- myUniformLocations[anIndex][OpenGl_RT_uWinSizeX] =
- aShaderProgram->GetUniformLocation (theGlContext, "uWinSizeX");
- myUniformLocations[anIndex][OpenGl_RT_uWinSizeY] =
- aShaderProgram->GetUniformLocation (theGlContext, "uWinSizeY");
- myUniformLocations[anIndex][OpenGl_RT_uTextures] =
+ myUniformLocations[anIndex][OpenGl_RT_uTexSamplersArray] =
aShaderProgram->GetUniformLocation (theGlContext, "uTextureSamplers");
- myUniformLocations[anIndex][OpenGl_RT_uShadEnabled] =
- aShaderProgram->GetUniformLocation (theGlContext, "uShadowsEnable");
- myUniformLocations[anIndex][OpenGl_RT_uReflEnabled] =
- aShaderProgram->GetUniformLocation (theGlContext, "uReflectionsEnable");
- myUniformLocations[anIndex][OpenGl_RT_uEnvMapEnable] =
- aShaderProgram->GetUniformLocation (theGlContext, "uEnvironmentEnable");
+ myUniformLocations[anIndex][OpenGl_RT_uShadowsEnabled] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uShadowsEnabled");
+ myUniformLocations[anIndex][OpenGl_RT_uReflectEnabled] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uReflectEnabled");
+ myUniformLocations[anIndex][OpenGl_RT_uSphereMapEnabled] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapEnabled");
+ myUniformLocations[anIndex][OpenGl_RT_uSphereMapForBack] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapForBack");
+
+ myUniformLocations[anIndex][OpenGl_RT_uSampleWeight] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uSampleWeight");
+ myUniformLocations[anIndex][OpenGl_RT_uFrameRndSeed] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uFrameRndSeed");
+
+ myUniformLocations[anIndex][OpenGl_RT_uBackColorTop] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uBackColorTop");
+ myUniformLocations[anIndex][OpenGl_RT_uBackColorBot] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uBackColorBot");
}
+ theGlContext->BindProgram (myOutImageProgram);
+
+ myOutImageProgram->SetSampler (theGlContext,
+ "uInputTexture", OpenGl_RT_PrevAccumTexture);
+
theGlContext->BindProgram (NULL);
}
if (myRaytraceFBO1.IsNull())
{
- myRaytraceFBO1 = new OpenGl_FrameBuffer;
+ myRaytraceFBO1 = new OpenGl_FrameBuffer (GL_RGBA32F);
}
if (myRaytraceFBO2.IsNull())
{
- myRaytraceFBO2 = new OpenGl_FrameBuffer;
+ myRaytraceFBO2 = new OpenGl_FrameBuffer (GL_RGBA32F);
}
const GLfloat aVertices[] = { -1.f, -1.f, 0.f,
}
// =======================================================================
-// function : NullifyResource
+// function : nullifyResource
// purpose :
// =======================================================================
-inline void NullifyResource (const Handle(OpenGl_Context)& theGlContext,
+inline void nullifyResource (const Handle(OpenGl_Context)& theGlContext,
Handle(OpenGl_Resource)& theResource)
{
if (!theResource.IsNull())
}
// =======================================================================
-// function : ReleaseRaytraceResources
+// function : releaseRaytraceResources
// purpose : Releases OpenGL/GLSL shader programs
// =======================================================================
void OpenGl_View::releaseRaytraceResources (const Handle(OpenGl_Context)& theGlContext)
{
- NullifyResource (theGlContext, myOpenGlFBO);
- NullifyResource (theGlContext, myRaytraceFBO1);
- NullifyResource (theGlContext, myRaytraceFBO2);
+ nullifyResource (theGlContext, myOpenGlFBO);
+ nullifyResource (theGlContext, myRaytraceFBO1);
+ nullifyResource (theGlContext, myRaytraceFBO2);
- NullifyResource (theGlContext, myRaytraceShader);
- NullifyResource (theGlContext, myPostFSAAShader);
+ nullifyResource (theGlContext, myRaytraceShader);
+ nullifyResource (theGlContext, myPostFSAAShader);
- NullifyResource (theGlContext, myRaytraceProgram);
- NullifyResource (theGlContext, myPostFSAAProgram);
+ nullifyResource (theGlContext, myRaytraceProgram);
+ nullifyResource (theGlContext, myPostFSAAProgram);
+ nullifyResource (theGlContext, myOutImageProgram);
- NullifyResource (theGlContext, mySceneNodeInfoTexture);
- NullifyResource (theGlContext, mySceneMinPointTexture);
- NullifyResource (theGlContext, mySceneMaxPointTexture);
+ nullifyResource (theGlContext, mySceneNodeInfoTexture);
+ nullifyResource (theGlContext, mySceneMinPointTexture);
+ nullifyResource (theGlContext, mySceneMaxPointTexture);
- NullifyResource (theGlContext, myGeometryVertexTexture);
- NullifyResource (theGlContext, myGeometryNormalTexture);
- NullifyResource (theGlContext, myGeometryTexCrdTexture);
- NullifyResource (theGlContext, myGeometryTriangTexture);
- NullifyResource (theGlContext, mySceneTransformTexture);
+ nullifyResource (theGlContext, myGeometryVertexTexture);
+ nullifyResource (theGlContext, myGeometryNormalTexture);
+ nullifyResource (theGlContext, myGeometryTexCrdTexture);
+ nullifyResource (theGlContext, myGeometryTriangTexture);
+ nullifyResource (theGlContext, mySceneTransformTexture);
- NullifyResource (theGlContext, myRaytraceLightSrcTexture);
- NullifyResource (theGlContext, myRaytraceMaterialTexture);
+ nullifyResource (theGlContext, myRaytraceLightSrcTexture);
+ nullifyResource (theGlContext, myRaytraceMaterialTexture);
if (myRaytraceScreenQuad.IsValid())
myRaytraceScreenQuad.Release (theGlContext.operator->());
}
// =======================================================================
-// function : ResizeRaytraceBuffers
+// function : resizeRaytraceBuffers
// purpose : Resizes OpenGL frame buffers
// =======================================================================
Standard_Boolean OpenGl_View::resizeRaytraceBuffers (const Standard_Integer theSizeX,
}
// =======================================================================
-// function : UpdateCamera
+// function : updateCamera
// purpose : Generates viewing rays for corners of screen quad
// =======================================================================
void OpenGl_View::updateCamera (const OpenGl_Mat4& theOrientation,
}
// =======================================================================
-// function : UploadRaytraceData
+// function : uploadRaytraceData
// purpose : Uploads ray-trace data to the GPU
// =======================================================================
Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)& theGlContext)
return Standard_False;
}
+ myAccumFrames = 0; // accumulation should be restarted
+
/////////////////////////////////////////////////////////////////////////////
// Prepare OpenGL textures
if (myRaytraceGeometry.Materials.size() != 0)
{
aResult &= myRaytraceMaterialTexture->Init (theGlContext, 4,
- GLsizei (myRaytraceGeometry.Materials.size() * 11), myRaytraceGeometry.Materials.front().Packed());
+ GLsizei (myRaytraceGeometry.Materials.size() * 18), myRaytraceGeometry.Materials.front().Packed());
if (!aResult)
{
}
// =======================================================================
-// function : UpdateRaytraceLightSources
+// function : updateRaytraceLightSources
// purpose : Updates 3D scene light sources for ray-tracing
// =======================================================================
Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& theInvModelView, const Handle(OpenGl_Context)& theGlContext)
myRaytraceGeometry.Ambient = BVH_Vec4f (0.0f, 0.0f, 0.0f, 0.0f);
- for (OpenGl_ListOfLight::Iterator anItl (LightList()); anItl.More(); anItl.Next())
+ for (OpenGl_ListOfLight::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
{
- const OpenGl_Light& aLight = anItl.Value();
+ const OpenGl_Light& aLight = aLightIter.Value();
if (aLight.Type == Visual3d_TOLS_AMBIENT)
{
- myRaytraceGeometry.Ambient += BVH_Vec4f (aLight.Color.r(),
- aLight.Color.g(),
- aLight.Color.b(),
+ myRaytraceGeometry.Ambient += BVH_Vec4f (aLight.Color.r() * aLight.Intensity,
+ aLight.Color.g() * aLight.Intensity,
+ aLight.Color.b() * aLight.Intensity,
0.0f);
continue;
}
- BVH_Vec4f aDiffuse (aLight.Color.r(),
- aLight.Color.g(),
- aLight.Color.b(),
+ BVH_Vec4f aDiffuse (aLight.Color.r() * aLight.Intensity,
+ aLight.Color.g() * aLight.Intensity,
+ aLight.Color.b() * aLight.Intensity,
1.0f);
BVH_Vec4f aPosition (-aLight.Direction.x(),
aLight.Position.y(),
aLight.Position.z(),
1.0f);
+
+ // store smoothing radius in w-component
+ aDiffuse.w() = Max (aLight.Smoothness, 0.f);
+ }
+ else
+ {
+ // store cosine of smoothing angle in w-component
+ aDiffuse.w() = cosf (Min (Max (aLight.Smoothness, 0.f), static_cast<Standard_ShortReal> (M_PI / 2.0)));
}
if (aLight.IsHeadlight)
return Standard_False;
}
}
-
+
if (myRaytraceGeometry.Sources.size() != 0)
{
const GLfloat* aDataPtr = myRaytraceGeometry.Sources.front().Packed();
}
// =======================================================================
-// function : UpdateRaytraceEnvironmentMap
+// function : updateRaytraceEnvironmentMap
// purpose : Updates environment map for ray-tracing
// =======================================================================
Standard_Boolean OpenGl_View::updateRaytraceEnvironmentMap (const Handle(OpenGl_Context)& theGlContext)
GL_TEXTURE0 + OpenGl_RT_EnvironmentMapTexture);
aResult &= aProgram->SetUniform (theGlContext,
- myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 1);
+ myUniformLocations[anIdx][OpenGl_RT_uSphereMapEnabled], 1);
}
else
{
aResult &= aProgram->SetUniform (theGlContext,
- myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 0);
+ myUniformLocations[anIdx][OpenGl_RT_uSphereMapEnabled], 0);
}
}
}
}
// =======================================================================
-// function : SetUniformState
+// function : setUniformState
// purpose : Sets uniform state for the given ray-tracing shader program
// =======================================================================
Standard_Boolean OpenGl_View::setUniformState (const Graphic3d_CView& theCView,
return Standard_False;
}
- Standard_Boolean aResult = Standard_True;
-
const Standard_Integer aLightSourceBufferSize =
static_cast<Standard_Integer> (myRaytraceGeometry.Sources.size());
// Set camera state
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uOriginLB], theOrigins[0]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uOriginRB], theOrigins[1]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uOriginLT], theOrigins[2]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uOriginRT], theOrigins[3]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uDirectLB], theDirects[0]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uDirectRB], theDirects[1]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uDirectLT], theDirects[2]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uDirectRT], theDirects[3]);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uUnviewMat], theUnviewMat);
// Set scene parameters
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uLightCount], aLightSourceBufferSize);
- aResult &= theProgram->SetUniform (theGlContext,
+ theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
// Set run-time rendering options
- aResult &= theProgram->SetUniform (theGlContext,
- myUniformLocations[theProgramId][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
- aResult &= theProgram->SetUniform (theGlContext,
- myUniformLocations[theProgramId][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
+ theProgram->SetUniform (theGlContext,
+ myUniformLocations[theProgramId][OpenGl_RT_uShadowsEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
+ theProgram->SetUniform (theGlContext,
+ myUniformLocations[theProgramId][OpenGl_RT_uReflectEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
// Set array of 64-bit texture handles
if (theGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures())
{
- aResult &= theProgram->SetUniform (theGlContext, "uTextureSamplers", static_cast<GLsizei> (
- myRaytraceGeometry.TextureHandles().size()), &myRaytraceGeometry.TextureHandles()[0]);
+ theProgram->SetUniform (theGlContext, myUniformLocations[theProgramId][OpenGl_RT_uTexSamplersArray],
+ static_cast<GLsizei> (myRaytraceGeometry.TextureHandles().size()), &myRaytraceGeometry.TextureHandles()[0]);
}
- if (!aResult)
+ // Set background colors (only gradient background supported)
+ if (myBgGradientArray != NULL)
{
-#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Info: Not all uniforms were detected for program " << theProgramId << std::endl;
-#endif
+ theProgram->SetUniform (theGlContext,
+ myUniformLocations[theProgramId][OpenGl_RT_uBackColorTop], myBgGradientArray->GradientColor (0));
+ theProgram->SetUniform (theGlContext,
+ myUniformLocations[theProgramId][OpenGl_RT_uBackColorBot], myBgGradientArray->GradientColor (1));
}
- return aResult;
+ theProgram->SetUniform (theGlContext,
+ myUniformLocations[theProgramId][OpenGl_RT_uSphereMapForBack], theCView.RenderParams.UseEnvironmentMapBackground ? 1 : 0);
+
+ return Standard_True;
}
// =======================================================================
-// function : BindRaytraceTextures
+// function : bindRaytraceTextures
// purpose : Binds ray-trace textures to corresponding texture units
// =======================================================================
void OpenGl_View::bindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext)
}
// =======================================================================
-// function : UnbindRaytraceTextures
+// function : unbindRaytraceTextures
// purpose : Unbinds ray-trace textures from corresponding texture units
// =======================================================================
void OpenGl_View::unbindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext)
}
// =======================================================================
-// function : RunRaytraceShaders
+// function : runRaytraceShaders
// purpose : Runs ray-tracing shader programs
// =======================================================================
Standard_Boolean OpenGl_View::runRaytraceShaders (const Graphic3d_CView& theCView,
{
bindRaytraceTextures (theGlContext);
- if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
+ Handle(OpenGl_FrameBuffer) aRenderFramebuffer;
+ Handle(OpenGl_FrameBuffer) anAccumFramebuffer;
+
+ if (myRaytraceParameters.GlobalIllumination) // if path-tracing is used
+ {
+ for (int anIdx = 0; anIdx < 3; ++anIdx)
+ {
+ if (fabsf (theOrigins[anIdx].x() - myPreviousOrigins[anIdx].x()) > std::numeric_limits<Standard_ShortReal>::epsilon()
+ || fabsf (theOrigins[anIdx].y() - myPreviousOrigins[anIdx].y()) > std::numeric_limits<Standard_ShortReal>::epsilon()
+ || fabsf (theOrigins[anIdx].z() - myPreviousOrigins[anIdx].z()) > std::numeric_limits<Standard_ShortReal>::epsilon())
+ {
+ myAccumFrames = 0; // camera has been moved
+ }
+
+ myPreviousOrigins[anIdx] = theOrigins[anIdx];
+ }
+
+ aRenderFramebuffer = myAccumFrames % 2 ? myRaytraceFBO1 : myRaytraceFBO2;
+ anAccumFramebuffer = myAccumFrames % 2 ? myRaytraceFBO2 : myRaytraceFBO1;
+
+ anAccumFramebuffer->ColorTexture()->Bind (
+ theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+
+ aRenderFramebuffer->BindBuffer (theGlContext);
+ }
+ else if (theCView.RenderParams.IsAntialiasingEnabled) // if 2-pass ray-tracing is used
{
myRaytraceFBO1->BindBuffer (theGlContext);
0, // ID of RT program
theGlContext);
- myRaytraceScreenQuad.BindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
+ if (myRaytraceParameters.GlobalIllumination)
{
- if (aResult)
- theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ // Set frame accumulation weight
+ myRaytraceProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1));
+
+ // Set random number generator seed
+ myRaytraceProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_uFrameRndSeed], static_cast<Standard_Integer> (myRNG.NextInt() >> 2));
}
- myRaytraceScreenQuad.UnbindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
- if (!theCView.RenderParams.IsAntialiasingEnabled || !aResult)
- {
- unbindRaytraceTextures (theGlContext);
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- theGlContext->BindProgram (NULL);
+ if (myRaytraceParameters.GlobalIllumination)
+ {
+ // Output accumulated image
+ glDisable (GL_BLEND);
- return aResult;
- }
+ theGlContext->BindProgram (myOutImageProgram);
- myRaytraceFBO1->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+ if (theReadDrawFbo != NULL)
+ {
+ theReadDrawFbo->BindBuffer (theGlContext);
+ }
+ else
+ {
+ aRenderFramebuffer->UnbindBuffer (theGlContext);
+ }
- aResult &= theGlContext->BindProgram (myPostFSAAProgram);
+ aRenderFramebuffer->ColorTexture()->Bind (
+ theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
- aResult &= setUniformState (theCView,
- theOrigins,
- theDirects,
- theUnviewMat,
- 1, // ID of FSAA program
- theGlContext);
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- myRaytraceScreenQuad.BindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
+ ++myAccumFrames;
+ }
+ else if (theCView.RenderParams.IsAntialiasingEnabled)
{
+ myRaytraceFBO1->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FsaaInputTexture);
+
+ aResult &= theGlContext->BindProgram (myPostFSAAProgram);
+
+ aResult &= setUniformState (theCView,
+ theOrigins,
+ theDirects,
+ theUnviewMat,
+ 1, // ID of FSAA program
+ theGlContext);
+
// Perform multi-pass adaptive FSAA using ping-pong technique.
// We use 'FLIPTRI' sampling pattern changing for every pixel
// (3 additional samples per pixel, the 1st sample is already
if (anIt == 3) // disable FBO on last iteration
{
- glEnable (GL_BLEND);
-
if (theReadDrawFbo != NULL)
+ {
theReadDrawFbo->BindBuffer (theGlContext);
+ }
+ else
+ {
+ aFramebuffer->UnbindBuffer (theGlContext);
+ }
}
else
{
if (anIt != 3) // set input for the next pass
{
- aFramebuffer->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+ aFramebuffer->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FsaaInputTexture);
}
}
}
- myRaytraceScreenQuad.UnbindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
unbindRaytraceTextures (theGlContext);
}
// =======================================================================
-// function : Raytrace
+// function : raytrace
// purpose : Redraws the window using OpenGL/GLSL ray-tracing
// =======================================================================
Standard_Boolean OpenGl_View::raytrace (const Graphic3d_CView& theCView,
aDirects,
anUnviewMat);
- glEnable (GL_BLEND);
+ glDisable (GL_BLEND);
glDisable (GL_DEPTH_TEST);
- glBlendFunc (GL_ONE, GL_SRC_ALPHA);
if (theReadDrawFbo != NULL)
{
// Generate ray-traced image
if (myIsRaytraceDataValid)
{
- myRaytraceScreenQuad.Bind (theGlContext);
+ myRaytraceScreenQuad.BindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
if (!myRaytraceGeometry.AcquireTextures (theGlContext))
{
0, GL_DEBUG_SEVERITY_MEDIUM_ARB, "Error: Failed to release OpenGL image textures");
}
- myRaytraceScreenQuad.Unbind (theGlContext);
+ myRaytraceScreenQuad.UnbindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
}
glDisable (GL_BLEND);
--- /dev/null
+//! Input image.
+uniform sampler2D uInputTexture;
+
+//! Output pixel color.
+out vec4 OutColor;
+
+void main (void)
+{
+ vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
+
+ // apply gamma correction (we use gamma = 2)
+ OutColor = vec4 (sqrt (aColor.rgb), aColor.a);
+}
--- /dev/null
+#ifdef PATH_TRACING
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Specific data types
+
+//! Describes local space at the hit point (visualization space).
+struct SLocalSpace
+{
+ //! Local X axis.
+ vec3 AxisX;
+
+ //! Local Y axis.
+ vec3 AxisY;
+
+ //! Local Z axis.
+ vec3 AxisZ;
+};
+
+//! Describes material properties (BSDF).
+struct SMaterial
+{
+ //! Weight of the Lambertian BRDF.
+ vec4 Kd;
+
+ //! Weight of the reflection BRDF.
+ vec3 Kr;
+
+ //! Weight of the transmission BTDF.
+ vec3 Kt;
+
+ //! Weight of the Blinn BRDF (and roughness).
+ vec4 Ks;
+
+ //! Fresnel coefficients.
+ vec3 Fresnel;
+
+ //! Absorption color and intensity of the media.
+ vec4 Absorption;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Support subroutines
+
+//=======================================================================
+// function : LocalSpace
+// purpose : Generates local space for the given normal
+//=======================================================================
+SLocalSpace LocalSpace (in vec3 theNormal)
+{
+ vec3 anAxisX = cross (vec3 (0.f, 1.f, 0.f), theNormal);
+ vec3 anAxisY = cross (vec3 (1.f, 0.f, 0.f), theNormal);
+
+ float aSqrLenX = dot (anAxisX, anAxisX);
+ float aSqrLenY = dot (anAxisY, anAxisY);
+
+ if (aSqrLenX > aSqrLenY)
+ {
+ anAxisX *= inversesqrt (aSqrLenX);
+ anAxisY = cross (anAxisX, theNormal);
+ }
+ else
+ {
+ anAxisY *= inversesqrt (aSqrLenY);
+ anAxisX = cross (anAxisY, theNormal);
+ }
+
+ return SLocalSpace (anAxisX, anAxisY, theNormal);
+}
+
+//=======================================================================
+// function : toLocalSpace
+// purpose : Transforms the vector to local space from world space
+//=======================================================================
+vec3 toLocalSpace (in vec3 theVector, in SLocalSpace theSpace)
+{
+ return vec3 (dot (theVector, theSpace.AxisX),
+ dot (theVector, theSpace.AxisY),
+ dot (theVector, theSpace.AxisZ));
+}
+
+//=======================================================================
+// function : fromLocalSpace
+// purpose : Transforms the vector from local space to world space
+//=======================================================================
+vec3 fromLocalSpace (in vec3 theVector, in SLocalSpace theSpace)
+{
+ return theVector.x * theSpace.AxisX +
+ theVector.y * theSpace.AxisY +
+ theVector.z * theSpace.AxisZ;
+}
+
+//=======================================================================
+// function : convolve
+// purpose : Performs a linear convolution of the vector components
+//=======================================================================
+float convolve (in vec3 theVector, in vec3 theFactor)
+{
+ return dot (theVector, theFactor) * (1.f / max (theFactor.x + theFactor.y + theFactor.z, 1e-15f));
+}
+
+//=======================================================================
+// function : sphericalDirection
+// purpose : Constructs vector from spherical coordinates
+//=======================================================================
+vec3 sphericalDirection (in float theCosTheta, in float thePhi)
+{
+ float aSinTheta = sqrt (1.f - theCosTheta * theCosTheta);
+
+ return vec3 (aSinTheta * cos (thePhi),
+ aSinTheta * sin (thePhi),
+ theCosTheta);
+}
+
+//=======================================================================
+// function : fresnelSchlick
+// purpose : Computes the Fresnel reflection formula using
+// Schlick's approximation.
+//=======================================================================
+vec3 fresnelSchlick (in float theCosI, in vec3 theSpecularColor)
+{
+ return theSpecularColor + (UNIT - theSpecularColor) * pow (1.f - theCosI, 5.f);
+}
+
+//=======================================================================
+// function : fresnelDielectric
+// purpose : Computes the Fresnel reflection formula for dielectric in
+// case of circularly polarized light (Based on PBRT code).
+//=======================================================================
+float fresnelDielectric (in float theCosI,
+ in float theCosT,
+ in float theEtaI,
+ in float theEtaT)
+{
+ float aParl = (theEtaT * theCosI - theEtaI * theCosT) /
+ (theEtaT * theCosI + theEtaI * theCosT);
+
+ float aPerp = (theEtaI * theCosI - theEtaT * theCosT) /
+ (theEtaI * theCosI + theEtaT * theCosT);
+
+ return (aParl * aParl + aPerp * aPerp) * 0.5f;
+}
+
+#define ENVIRONMENT_IOR 1.f
+
+//=======================================================================
+// function : fresnelDielectric
+// purpose : Computes the Fresnel reflection formula for dielectric in
+// case of circularly polarized light (based on PBRT code)
+//=======================================================================
+float fresnelDielectric (in float theCosI, in float theIndex)
+{
+ float anEtaI = theCosI > 0.f ? 1.f : theIndex;
+ float anEtaT = theCosI > 0.f ? theIndex : 1.f;
+
+ float aSinT = (anEtaI / anEtaT) * sqrt (1.f - theCosI * theCosI);
+
+ if (aSinT >= 1.f)
+ {
+ return 1.f;
+ }
+
+ float aCosT = sqrt (1.f - aSinT * aSinT);
+
+ return fresnelDielectric (abs (theCosI), aCosT, anEtaI, anEtaT);
+}
+
+//=======================================================================
+// function : fresnelConductor
+// purpose : Computes the Fresnel reflection formula for conductor in case
+// of circularly polarized light (based on PBRT source code)
+//=======================================================================
+float fresnelConductor (in float theCosI, in float theEta, in float theK)
+{
+ float aTmp = 2.f * theEta * theCosI;
+
+ float aTmp1 = theEta * theEta + theK * theK;
+
+ float aSPerp = (aTmp1 - aTmp + theCosI * theCosI) /
+ (aTmp1 + aTmp + theCosI * theCosI);
+
+ float aTmp2 = aTmp1 * theCosI * theCosI;
+
+ float aSParl = (aTmp2 - aTmp + 1.f) /
+ (aTmp2 + aTmp + 1.f);
+
+ return (aSPerp + aSParl) * 0.5f;
+}
+
+#define FRESNEL_SCHLICK -0.5f
+#define FRESNEL_CONSTANT -1.5f
+#define FRESNEL_CONDUCTOR -2.5f
+#define FRESNEL_DIELECTRIC -3.5f
+
+//=======================================================================
+// function : fresnelMedia
+// purpose : Computes the Fresnel reflection formula for general medium
+// in case of circularly polarized light.
+//=======================================================================
+vec3 fresnelMedia (in float theCosI, in vec3 theFresnelCoeffs)
+{
+ if (theFresnelCoeffs.x > FRESNEL_SCHLICK)
+ {
+ return fresnelSchlick (abs (theCosI), theFresnelCoeffs);
+ }
+
+ if (theFresnelCoeffs.x > FRESNEL_CONSTANT)
+ {
+ return vec3 (theFresnelCoeffs.z);
+ }
+
+ if (theFresnelCoeffs.x > FRESNEL_CONDUCTOR)
+ {
+ return vec3 (fresnelConductor (abs (theCosI), theFresnelCoeffs.y, theFresnelCoeffs.z));
+ }
+
+ return vec3 (fresnelDielectric (theCosI, theFresnelCoeffs.y));
+}
+
+//=======================================================================
+// function : transmitted
+// purpose : Computes transmitted direction in tangent space
+// (in case of TIR returned result is undefined!)
+//=======================================================================
+void transmitted (in float theIndex, in vec3 theIncident, out vec3 theTransmit)
+{
+ // Compute relative index of refraction
+ float anEta = (theIncident.z > 0.f) ? 1.f / theIndex : theIndex;
+
+ // Handle total internal reflection for transmission
+ float aSinT2 = anEta * anEta * (1.f - theIncident.z * theIncident.z);
+
+ // Compute transmitted ray direction
+ float aCosT = sqrt (1.f - min (aSinT2, 1.f)) * (theIncident.z > 0.f ? -1.f : 1.f);
+
+ theTransmit = normalize (vec3 (-anEta * theIncident.x,
+ -anEta * theIncident.y,
+ aCosT));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Handlers and samplers for materials
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+//=======================================================================
+// function : handleLambertianReflection
+// purpose : Handles Lambertian BRDF, with cos(N, PSI)
+//=======================================================================
+float handleLambertianReflection (in vec3 theInput, in vec3 theOutput)
+{
+ return max (0.f, theInput.z) * (1.f / M_PI);
+}
+
+//=======================================================================
+// function : handleBlinnReflection
+// purpose : Handles Blinn glossy BRDF, with cos(N, PSI)
+//=======================================================================
+vec3 handleBlinnReflection (in vec3 theInput, in vec3 theOutput, in vec3 theFresnelCoeffs, in float theExponent)
+{
+ vec3 aWeight = ZERO;
+
+ // Compute half-angle vector
+ vec3 aHalf = theInput + theOutput;
+
+ if (aHalf.z < 0.f)
+ aHalf = -aHalf;
+
+ float aLength = dot (aHalf, aHalf);
+
+ if (aLength <= 0.f)
+ return ZERO;
+
+ aHalf *= inversesqrt (aLength);
+
+ // Compute Fresnel reflectance
+ float aCosDelta = dot (theOutput, aHalf);
+
+ vec3 aFresnel = fresnelMedia (aCosDelta, theFresnelCoeffs);
+
+ // Compute fraction of microfacets that reflect light
+ float aCosThetaH = max (0.f, aHalf.z);
+
+ float aFraction = (theExponent + 2.f) * (M_PI / 2.f) * pow (aCosThetaH, theExponent);
+
+ // Compute geometry attenuation term (already includes cos)
+ float aCosThetaI = max (0.f, theInput.z);
+ float aCosThetaO = max (0.f, theOutput.z);
+
+ float aGeom = min (1.f, 2.f * aCosThetaH / max (0.f, aCosDelta) * min (aCosThetaO, aCosThetaI));
+
+ return aCosThetaO < 1.0e-3f ? ZERO :
+ aFraction * aGeom / (4.f * aCosThetaO) * aFresnel;
+}
+
+//=======================================================================
+// function : handleMaterial
+// purpose : Returns BSDF value for specified material, with cos(N, PSI)
+//=======================================================================
+vec3 handleMaterial (in SMaterial theMaterial, in vec3 theInput, in vec3 theOutput)
+{
+ return theMaterial.Kd.rgb * handleLambertianReflection (theInput, theOutput) +
+ theMaterial.Ks.rgb * handleBlinnReflection (theInput, theOutput, theMaterial.Fresnel, theMaterial.Ks.w);
+}
+
+//=======================================================================
+// function : sampleSpecularReflection
+// purpose : Samples specular BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
+//=======================================================================
+void sampleSpecularReflection (in vec3 theOutput, out vec3 theInput)
+{
+ theInput = vec3 (-theOutput.x,
+ -theOutput.y,
+ theOutput.z);
+}
+
+//=======================================================================
+// function : sampleLambertianReflection
+// purpose : Samples Lambertian BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
+//=======================================================================
+void sampleLambertianReflection (in vec3 theOutput, out vec3 theInput)
+{
+ float aKsi1 = RandFloat();
+ float aKsi2 = RandFloat();
+
+ float aTemp = sqrt (aKsi2);
+
+ theInput = vec3 (aTemp * cos (2.f * M_PI * aKsi1),
+ aTemp * sin (2.f * M_PI * aKsi1),
+ sqrt (1.f - aKsi2));
+
+ if (theOutput.z < 0.f)
+ theInput.z = -theInput.z;
+}
+
+//=======================================================================
+// function : sampleSpecularTransmission
+// purpose : Samples specular BTDF, W = BRDF * cos(N, PSI) / PDF(PSI)
+//=======================================================================
+vec3 sampleSpecularTransmission (in vec3 theOutput, out vec3 theInput,
+ out bool isTransmit, in vec3 theThroughput, in vec3 theFresnelCoeffs)
+{
+ vec3 aFresnel = fresnelMedia (theOutput.z, theFresnelCoeffs);
+
+ float aProbability = convolve (aFresnel, theThroughput);
+
+ // Sample input direction
+ if (RandFloat() <= aProbability)
+ {
+ theInput = vec3 (-theOutput.x,
+ -theOutput.y,
+ theOutput.z);
+
+ isTransmit = false;
+
+ return aFresnel * (1.f / aProbability);
+ }
+
+ transmitted (theFresnelCoeffs.y, theOutput, theInput);
+
+ isTransmit = true;
+
+ return (UNIT - aFresnel) * (1.f / (1.f - aProbability));
+}
+
+//=======================================================================
+// function : sampleSpecularReflection
+// purpose : Samples specular BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
+//=======================================================================
+vec3 sampleSpecularReflection (in vec3 theOutput, out vec3 theInput, in vec3 theFresnelCoeffs)
+{
+ // Sample input direction
+ theInput = vec3 (-theOutput.x,
+ -theOutput.y,
+ theOutput.z);
+
+ return fresnelMedia (theOutput.z, theFresnelCoeffs);
+}
+
+#define MIN_COS 1.0e-20f
+
+//=======================================================================
+// function : sampleBlinnReflection
+// purpose : Samples Blinn BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
+// The BRDF is a product of three main terms, D, G, and F,
+// which is then divided by two cosine terms. Here we perform
+// importance sample the D part of the Blinn model; trying to
+// develop a sampling procedure that accounted for all of the
+// terms would be complex, and it is the D term that accounts
+// for most of the variation.
+//=======================================================================
+vec3 sampleBlinnReflection (in vec3 theOutput, out vec3 theInput, in vec3 theFresnelCoeffs, in float theExponent)
+{
+ vec3 aWeight = ZERO;
+
+ // Generate two random variables
+ float aKsi1 = RandFloat();
+ float aKsi2 = RandFloat();
+
+ // Compute sampled half-angle vector for Blinn distribution
+ float aCosThetaH = pow (aKsi1, 1.f / (theExponent + 1.f));
+
+ vec3 aHalf = sphericalDirection (aCosThetaH, aKsi2 * 2.f * M_PI);
+
+ if (aHalf.z < 0)
+ {
+ aHalf = -aHalf;
+ }
+
+ // Compute incident direction by reflecting about half-vector
+ float aCosDelta = dot (theOutput, aHalf);
+
+ vec3 anInput = 2.f * aCosDelta * aHalf - theOutput;
+
+ if (theOutput.z * anInput.z <= 0.f)
+ {
+ return ZERO;
+ }
+
+ theInput = anInput;
+
+ // Compute Fresnel reflectance
+ vec3 aFresnel = fresnelMedia (aCosDelta, theFresnelCoeffs);
+
+ // Compute geometry attenuation term
+ float aCosThetaI = max (MIN_COS, theInput.z);
+ float aCosThetaO = max (MIN_COS, theOutput.z);
+
+ float aGeom = min (max (MIN_COS, aCosDelta), 2.f * aCosThetaH * min (aCosThetaO, aCosThetaI));
+
+ // Compute weight of the ray sample
+ return aFresnel * ((theExponent + 2.f) / (theExponent + 1.f) * aGeom / aCosThetaO);
+}
+
+// Enables expiremental russian roulette sampling
+// #define RUSSIAN_ROULETTE
+
+//=======================================================================
+// function : sampleMaterial
+// purpose : Samples specified composite material (BSDF)
+//=======================================================================
+bool sampleMaterial (in SMaterial theMaterial,
+ in vec3 theOutput,
+ in vec3 theFactor,
+ out vec3 theInput,
+ out vec3 theWeight,
+ inout bool isTransmit)
+{
+ theWeight = ZERO;
+
+ // Compute the probability of ray reflection
+ float aPd = convolve (theMaterial.Kd.rgb, theFactor);
+ float aPs = convolve (theMaterial.Ks.rgb, theFactor);
+ float aPr = convolve (theMaterial.Kr.rgb, theFactor);
+ float aPt = convolve (theMaterial.Kt.rgb, theFactor);
+
+ float aReflection = aPd + aPs + aPr + aPt;
+
+#ifndef RUSSIAN_ROULETTE
+ if (aReflection < 1e-2f)
+ {
+ return false; // path termination
+ }
+#else
+ float aSurvival = max (dot (theFactor, LUMA), 0.1f);
+
+ if (RandFloat() > aSurvival)
+ {
+ return false; // path termination
+ }
+#endif
+
+ isTransmit = false;
+
+ // Choose BSDF component to sample
+ float aKsi = aReflection * RandFloat();
+
+ if (aKsi < aPd) // diffuse reflection
+ {
+ sampleLambertianReflection (theOutput, theInput);
+
+#ifndef RUSSIAN_ROULETTE
+ theWeight = theMaterial.Kd.rgb * (aReflection / aPd);
+#else
+ theWeight = theMaterial.Kd.rgb * (aReflection / aPd / aSurvival);
+#endif
+
+ return false; // non-specular bounce
+ }
+ else if (aKsi < aPd + aPs) // glossy reflection
+ {
+ theWeight = sampleBlinnReflection (theOutput, theInput, theMaterial.Fresnel, theMaterial.Ks.w);
+
+#ifndef RUSSIAN_ROULETTE
+ theWeight *= theMaterial.Ks.rgb * (aReflection / aPs);
+#else
+ theWeight *= theMaterial.Ks.rgb * (aReflection / aPs / aSurvival);
+#endif
+
+ return false; // non-specular bounce
+ }
+ else if (aKsi < aPd + aPs + aPr) // specular reflection
+ {
+ theWeight = sampleSpecularReflection (theOutput, theInput, theMaterial.Fresnel);
+
+#ifndef RUSSIAN_ROULETTE
+ theWeight *= theMaterial.Kr.rgb * (aReflection / aPr);
+#else
+ theWeight *= theMaterial.Kr.rgb * (aReflection / aPr / aSurvival);
+#endif
+
+ return true; // specular bounce
+ }
+ else // specular transmission
+ {
+ theWeight = sampleSpecularTransmission (theOutput, theInput,
+ isTransmit, theFactor, theMaterial.Fresnel);
+
+#ifndef RUSSIAN_ROULETTE
+ theWeight *= theMaterial.Kt.rgb * (aReflection / aPt);
+#else
+ theWeight *= theMaterial.Kt.rgb * (aReflection / aPt / aSurvival);
+#endif
+
+ return true; // specular bounce
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Handlers and samplers for light sources
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+//=======================================================================
+// function : handlePointLight
+// purpose :
+//=======================================================================
+float handlePointLight (in vec3 theInput, in vec3 theToLight, in float theRadius)
+{
+ float aCosMax = sqrt (1.f - theRadius * theRadius / dot (theToLight, theToLight));
+
+ return step (aCosMax, dot (theInput, theToLight));
+}
+
+//=======================================================================
+// function : handleDirectLight
+// purpose :
+//=======================================================================
+float handleDirectLight (in vec3 theInput, in vec3 theToLight, in float theCosMax)
+{
+ return step (theCosMax, dot (theInput, theToLight));
+}
+
+//=======================================================================
+// function : samplePointLight
+// purpose :
+//=======================================================================
+vec3 samplePointLight (in vec3 theToLight, in float theRadius, inout float thePDF)
+{
+ SLocalSpace aSpace = LocalSpace (theToLight);
+
+ float aCosMax = sqrt (1.f - theRadius * theRadius / dot (theToLight, theToLight));
+
+ float aKsi1 = RandFloat();
+ float aKsi2 = RandFloat();
+
+ float aTmp = 1.f - aKsi2 * (1.f - aCosMax);
+
+ vec3 anInput = vec3 (sqrt (1.f - aTmp * aTmp) * cos (2.f * M_PI * aKsi1),
+ sqrt (1.f - aTmp * aTmp) * sin (2.f * M_PI * aKsi1),
+ aTmp);
+
+ thePDF *= (theRadius > 0.f) ? 1.f / (2.f * M_PI) / (1.f - aCosMax) : 1.f;
+
+ return normalize (fromLocalSpace (anInput, aSpace));
+}
+
+//=======================================================================
+// function : sampleDirectLight
+// purpose :
+//=======================================================================
+vec3 sampleDirectLight (in vec3 theToLight, in float theCosMax, inout float thePDF)
+{
+ SLocalSpace aSpace = LocalSpace (theToLight);
+
+ float aKsi1 = RandFloat();
+ float aKsi2 = RandFloat();
+
+ float aTmp = 1.f - aKsi2 * (1.f - theCosMax);
+
+ vec3 anInput = vec3 (sqrt (1.f - aTmp * aTmp) * cos (2.f * M_PI * aKsi1),
+ sqrt (1.f - aTmp * aTmp) * sin (2.f * M_PI * aKsi1),
+ aTmp);
+
+ thePDF *= (theCosMax < 1.f) ? 1.f / (2.f * M_PI) / (1.f - theCosMax) : 1.f;
+
+ return normalize (fromLocalSpace (anInput, aSpace));
+}
+
+// =======================================================================
+// function : Latlong
+// purpose : Converts world direction to environment texture coordinates
+// =======================================================================
+vec2 Latlong (in vec3 thePoint)
+{
+ float aPsi = acos (-thePoint.z);
+
+ float aPhi = atan (thePoint.y, thePoint.x) + M_PI;
+
+ return vec2 (aPhi * 0.1591549f,
+ aPsi * 0.3183098f);
+}
+
+// =======================================================================
+// function : EnvironmentRadiance
+// purpose :
+// =======================================================================
+vec3 EnvironmentRadiance (in SRay theRay, in bool isSpecular, in bool isBackground)
+{
+ vec3 aRadiance = ZERO;
+
+ if (uSphereMapForBack != 0 || !isBackground)
+ {
+ aRadiance += FetchEnvironment (Latlong (theRay.Direct)).xyz;
+ }
+ else
+ {
+ aRadiance += BackgroundColor().xyz;
+ }
+
+ // Apply gamma correction (gamma is 2)
+ aRadiance *= aRadiance;
+
+ for (int aLightIdx = 0; aLightIdx < uLightCount && isSpecular; ++aLightIdx)
+ {
+ vec4 aLight = texelFetch (
+ uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
+ vec4 aParam = texelFetch (
+ uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
+
+ if (aLight.w != 0.f) // point light source
+ {
+ aRadiance += aParam.rgb * handlePointLight (theRay.Direct, aLight.xyz - theRay.Origin, aParam.w /* radius */);
+ }
+ else // directional light source
+ {
+ aRadiance += aParam.rgb * handleDirectLight (theRay.Direct, aLight.xyz, aParam.w /* angle cosine */);
+ }
+ }
+
+ return aRadiance;
+}
+
+#define MIN_THROUGHPUT vec3 (0.02f)
+#define MIN_CONTRIBUTION vec3 (0.01f)
+
+#define MATERIAL_KD(index) (18 * index + 11)
+#define MATERIAL_KR(index) (18 * index + 12)
+#define MATERIAL_KT(index) (18 * index + 13)
+#define MATERIAL_KS(index) (18 * index + 14)
+#define MATERIAL_LE(index) (18 * index + 15)
+#define MATERIAL_FRESNEL(index) (18 * index + 16)
+#define MATERIAL_ABSORPT(index) (18 * index + 17)
+
+//=======================================================================
+// function : PathTrace
+// purpose : Calculates radiance along the given ray
+//=======================================================================
+vec4 PathTrace (in SRay theRay, in vec3 theInverse)
+{
+ float anOpenGlDepth = ComputeOpenGlDepth (theRay);
+
+ vec3 aRadiance = ZERO;
+ vec3 aThroughput = UNIT;
+
+ bool isInMedium = false;
+ bool isSpecular = false;
+ bool isTransmit = false;
+
+ int anObjectId; // ID of intersected triangle
+
+ for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
+ {
+ SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
+
+ ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, anObjectId);
+
+ if (aTriIndex.x == -1)
+ {
+ return vec4 (aRadiance + aThroughput *
+ EnvironmentRadiance (theRay, isSpecular, aDepth == 0 || isTransmit), 0.f);
+ }
+
+ vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0).xyz;
+ vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1).xyz;
+ vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2).xyz;
+
+ aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
+ dot (aInvTransf1, aHit.Normal),
+ dot (aInvTransf2, aHit.Normal)));
+
+ // For polygons that are parallel to the screen plane, the depth slope
+ // is equal to 1, resulting in small polygon offset. For polygons that
+ // that are at a large angle to the screen, the depth slope tends to 1,
+ // resulting in a larger polygon offset
+ float aPolygonOffset = uSceneEpsilon * EPS_SCALE /
+ max (abs (dot (theRay.Direct, aHit.Normal)), MIN_SLOPE);
+
+ if (anOpenGlDepth < aHit.Time + aPolygonOffset)
+ {
+ vec4 aSrcColorRGBA = ComputeOpenGlColor();
+
+ aRadiance += aThroughput.xyz * aSrcColorRGBA.xyz;
+ aThroughput *= aSrcColorRGBA.w;
+ }
+
+ theRay.Origin += theRay.Direct * aHit.Time; // intersection point
+
+ // Fetch material (BSDF)
+ SMaterial aMaterial = SMaterial (
+ vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriIndex.w))),
+ vec3 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KR (aTriIndex.w))),
+ vec3 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KT (aTriIndex.w))),
+ vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KS (aTriIndex.w))),
+ vec3 (texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL (aTriIndex.w))),
+ vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_ABSORPT (aTriIndex.w))));
+
+#ifdef USE_TEXTURES
+ if (aMaterial.Kd.w >= 0.f)
+ {
+ vec4 aTexCoord = vec4 (SmoothUV (aHit.UV, aTriIndex), 0.f, 1.f);
+
+ vec4 aTrsfRow1 = texelFetch (
+ uRaytraceMaterialTexture, MATERIAL_TRS1 (aTriIndex.w));
+ vec4 aTrsfRow2 = texelFetch (
+ uRaytraceMaterialTexture, MATERIAL_TRS2 (aTriIndex.w));
+
+ aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),
+ dot (aTrsfRow2, aTexCoord));
+
+ vec3 aTexColor = textureLod (
+ uTextureSamplers[int (aMaterial.Kd.w)], aTexCoord.st, 0.f).rgb;
+
+ aMaterial.Kd.rgb *= aTexColor;
+ }
+#endif
+
+ vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
+
+ aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
+ dot (aInvTransf1, aNormal),
+ dot (aInvTransf2, aNormal)));
+
+ SLocalSpace aSpace = LocalSpace (aNormal);
+
+ // Account for self-emission (not stored in the material)
+ aRadiance += aThroughput * texelFetch (
+ uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w)).rgb;
+
+ if (uLightCount > 0 && convolve (aMaterial.Kd.rgb + aMaterial.Ks.rgb, aThroughput) > 0.f)
+ {
+ int aLightIdx = min (int (floor (RandFloat() * uLightCount)), uLightCount - 1);
+
+ vec4 aLight = texelFetch (
+ uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
+ vec4 aParam = texelFetch (
+ uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
+
+ float aPDF = 1.f / uLightCount, aDistance = MAXFLOAT;
+
+ if (aLight.w != 0.f) // point light source
+ {
+ aDistance = length (aLight.xyz -= theRay.Origin);
+
+ aLight.xyz = samplePointLight (aLight.xyz, aParam.w /* radius */, aPDF);
+ }
+ else // directional light source
+ {
+ aLight.xyz = sampleDirectLight (aLight.xyz, aParam.w /* angle cosine */, aPDF);
+ }
+
+ vec3 aContrib = (1.f / aPDF) * aParam.rgb /* Le */ * handleMaterial (
+ aMaterial, toLocalSpace (aLight.xyz, aSpace), toLocalSpace (-theRay.Direct, aSpace));
+
+ if (any (greaterThan (aContrib, MIN_CONTRIBUTION))) // first check if light source is important
+ {
+ SRay aShadow = SRay (theRay.Origin + aLight.xyz * uSceneEpsilon, aLight.xyz);
+
+ aShadow.Origin += aHit.Normal * mix (
+ -uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, aLight.xyz)));
+
+ float aVisibility = SceneAnyHit (aShadow,
+ InverseDirection (aLight.xyz), aDistance);
+
+ aRadiance += aVisibility * aThroughput * aContrib;
+ }
+ }
+
+ vec3 anInput;
+ vec3 aWeight;
+
+ isSpecular = sampleMaterial (aMaterial,
+ toLocalSpace (-theRay.Direct, aSpace), aThroughput, anInput, aWeight, isTransmit);
+
+ if (isInMedium)
+ {
+ aThroughput *= exp (-aHit.Time *
+ aMaterial.Absorption.w * (UNIT - aMaterial.Absorption.rgb));
+ }
+
+ isInMedium = isTransmit ? !isInMedium : isInMedium;
+
+ aThroughput *= aWeight;
+
+ if (all (lessThan (aThroughput, MIN_THROUGHPUT)))
+ {
+ return vec4 (aRadiance, 0.f);
+ }
+
+ anInput = normalize (fromLocalSpace (anInput, aSpace));
+
+ theRay = SRay (theRay.Origin + anInput * uSceneEpsilon +
+ aHit.Normal * mix (-uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, anInput))), anInput);
+
+ theInverse = InverseDirection (anInput);
+
+ anOpenGlDepth = MAXFLOAT; // disable combining image with OpenGL output
+ }
+
+ return vec4 (aRadiance, 0.f);
+}
+
+#endif
//! Intensity of global ambient light.
uniform vec4 uGlobalAmbient;
-//! Enables/disables environment map.
-uniform int uEnvironmentEnable;
-//! Enables/disables computation of shadows.
-uniform int uShadowsEnable;
-//! Enables/disables computation of reflections.
-uniform int uReflectionsEnable;
+//! Enables/disables hard shadows.
+uniform int uShadowsEnabled;
+//! Enables/disables specular reflections.
+uniform int uReflectEnabled;
+//! Enables/disables spherical environment map.
+uniform int uSphereMapEnabled;
+//! Enables/disables environment map background.
+uniform int uSphereMapForBack;
//! Radius of bounding sphere of the scene.
uniform float uSceneRadius;
uniform sampler2D uTextureSamplers[MAX_TEX_NUMBER];
#endif
+//! Top color of gradient background.
+uniform vec4 uBackColorTop = vec4 (0.0);
+//! Bottom color of gradient background.
+uniform vec4 uBackColorBot = vec4 (0.0);
+
/////////////////////////////////////////////////////////////////////////////////////////
// Specific data types
-
+
//! Stores ray parameters.
struct SRay
{
vec3 Origin;
-
+
vec3 Direct;
};
struct SIntersect
{
float Time;
-
+
vec2 UV;
-
+
vec3 Normal;
};
#define AXIS_Y vec3 (0.0f, 1.0f, 0.0f)
#define AXIS_Z vec3 (0.0f, 0.0f, 1.0f)
+#define M_PI 3.14159265f
+
+#define LUMA vec3 (0.2126f, 0.7152f, 0.0722f)
+
+// =======================================================================
+// function : MatrixRowMultiplyDir
+// purpose : Multiplies a vector by matrix
+// =======================================================================
+vec3 MatrixRowMultiplyDir (in vec3 v,
+ in vec4 m0,
+ in vec4 m1,
+ in vec4 m2)
+{
+ return vec3 (dot (m0.xyz, v),
+ dot (m1.xyz, v),
+ dot (m2.xyz, v));
+}
+
//! 32-bit state of random number generator.
uint RandState;
// purpose : Applies hash function by Thomas Wang to randomize seeds
// (see http://www.burtleburtle.net/bob/hash/integer.html)
// =======================================================================
-void SeedRand (in int theSeed)
+void SeedRand (in int theSeed, in int theSizeX)
{
- RandState = uint (int (gl_FragCoord.y) * uWinSizeX + int (gl_FragCoord.x) + theSeed);
+ RandState = uint (int (gl_FragCoord.y) * theSizeX + int (gl_FragCoord.x) + theSeed);
RandState = (RandState + 0x479ab41du) + (RandState << 8);
RandState = (RandState ^ 0xe4aa10ceu) ^ (RandState >> 5);
m0[2] * v.x + m1[2] * v.y + m2[2] * v.z);
}
+//=======================================================================
+// function : InverseDirection
+// purpose : Returns safely inverted direction of the given one
+//=======================================================================
+vec3 InverseDirection (in vec3 theInput)
+{
+ vec3 anInverse = 1.f / max (abs (theInput), SMALL);
+
+ return mix (-anInverse, anInverse, step (ZERO, theInput));
+}
+
+//=======================================================================
+// function : BackgroundColor
+// purpose : Returns color of gradient background
+//=======================================================================
+vec4 BackgroundColor()
+{
+ return mix (uBackColorBot, uBackColorTop, vPixel.y);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// Functions for compute ray-object intersection
// function : ComputeOpenGlColor
// purpose :
// =======================================================================
-vec4 ComputeOpenGlColor (in SRay theRay)
+vec4 ComputeOpenGlColor()
{
vec4 anOpenGlColor = texelFetch (uOpenGlColorTexture, ivec2 (gl_FragCoord.xy), 0);
// During blending with factors GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA (for text and markers)
return aTriIndex;
}
-#define MATERIAL_AMBN(index) (11 * index + 0)
-#define MATERIAL_DIFF(index) (11 * index + 1)
-#define MATERIAL_SPEC(index) (11 * index + 2)
-#define MATERIAL_EMIS(index) (11 * index + 3)
-#define MATERIAL_REFL(index) (11 * index + 4)
-#define MATERIAL_REFR(index) (11 * index + 5)
-#define MATERIAL_TRAN(index) (11 * index + 6)
-#define MATERIAL_TRS1(index) (11 * index + 7)
-#define MATERIAL_TRS2(index) (11 * index + 8)
-#define MATERIAL_TRS3(index) (11 * index + 9)
+#define MATERIAL_AMBN(index) (18 * index + 0)
+#define MATERIAL_DIFF(index) (18 * index + 1)
+#define MATERIAL_SPEC(index) (18 * index + 2)
+#define MATERIAL_EMIS(index) (18 * index + 3)
+#define MATERIAL_REFL(index) (18 * index + 4)
+#define MATERIAL_REFR(index) (18 * index + 5)
+#define MATERIAL_TRAN(index) (18 * index + 6)
+#define MATERIAL_TRS1(index) (18 * index + 7)
+#define MATERIAL_TRS2(index) (18 * index + 8)
+#define MATERIAL_TRS3(index) (18 * index + 9)
// =======================================================================
// function : ObjectAnyHit
}
#endif
+// =======================================================================
+// function : FetchEnvironment
+// purpose :
+// =======================================================================
+vec4 FetchEnvironment (in vec2 theTexCoord)
+{
+ return mix (vec4 (0.0f, 0.0f, 0.0f, 1.0f),
+ textureLod (uEnvironmentMapTexture, theTexCoord, 0.0f), float (uSphereMapEnabled));
+}
+
// =======================================================================
// function : Refract
// purpose : Computes refraction ray (also handles TIR)
// =======================================================================
+#ifndef PATH_TRACING
vec3 Refract (in vec3 theInput,
in vec3 theNormal,
in float theRefractIndex,
return normalize (anIndex * theInput -
(anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
}
+#endif
#define MIN_SLOPE 0.0001f
#define EPS_SCALE 8.0000f
// function : Radiance
// purpose : Computes color along the given ray
// =======================================================================
+#ifndef PATH_TRACING
vec4 Radiance (in SRay theRay, in vec3 theInverse)
{
vec3 aResult = vec3 (0.0f);
if (aTriIndex.x == -1)
{
- vec4 aColor = vec4 (0.0f);
+ vec4 aColor = vec4 (0.0);
- if (aWeight.w != 0.0f)
- {
- aColor = anOpenGlDepth != MAXFLOAT ?
- ComputeOpenGlColor (theRay) : vec4 (0.0f, 0.0f, 0.0f, 1.0f);
- }
- else if (bool(uEnvironmentEnable))
+ if (bool(uSphereMapForBack) || aWeight.w == 0.0f /* reflection */)
{
float aTime = IntersectSphere (theRay, uSceneRadius);
- aColor = textureLod (uEnvironmentMapTexture, Latlong (
- theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.0f);
+ aColor = FetchEnvironment (Latlong (
+ theRay.Direct * aTime + theRay.Origin, uSceneRadius));
+ }
+ else
+ {
+ vec4 aGlColor = ComputeOpenGlColor();
+ aColor = vec4 (BackgroundColor().rgb * aGlColor.w + ComputeOpenGlColor().rgb, aGlColor.w);
}
return vec4 (aResult.xyz + aWeight.xyz * aColor.xyz, aWeight.w * aColor.w);
if (anOpenGlDepth < aHit.Time + aPolygonOffset)
{
- vec4 aGlColor = ComputeOpenGlColor (theRay);
+ vec4 aGlColor = ComputeOpenGlColor();
aResult += aWeight.xyz * aGlColor.xyz;
aWeight *= aGlColor.w;
{
float aVisibility = 1.0f;
- if (bool(uShadowsEnable))
+ if (bool(uShadowsEnabled))
{
SRay aShadow = SRay (theRay.Origin, aLight.xyz);
}
else
{
- aWeight *= bool(uReflectionsEnable) ?
+ aWeight *= bool(uReflectEnabled) ?
texelFetch (uRaytraceMaterialTexture, MATERIAL_REFL (aTriIndex.w)) : vec4 (0.0f);
vec3 aReflect = reflect (theRay.Direct, aNormal);
aResult.z,
aWeight.w);
}
+#endif
out vec4 OutColor;
+// Seed for random number generator
+uniform int uFrameRndSeed;
+
+// Weight of current frame related to accumulated frames.
+uniform float uSampleWeight;
+
+//! Input accumulated image.
+uniform sampler2D uAccumTexture;
+
// =======================================================================
// function : main
// purpose :
// =======================================================================
void main (void)
{
+#ifndef PATH_TRACING
SRay aRay = GenerateRay (vPixel);
-
+#else
+ ivec2 aWinSize = textureSize (uAccumTexture, 0);
+
+ SeedRand (uFrameRndSeed, aWinSize.x);
+
+ SRay aRay = GenerateRay (vPixel +
+ vec2 (RandFloat() + 1.f, RandFloat() + 1.f) / vec2 (aWinSize));
+#endif
+
vec3 aInvDirect = 1.f / max (abs (aRay.Direct), SMALL);
-
+
aInvDirect = vec3 (aRay.Direct.x < 0.f ? -aInvDirect.x : aInvDirect.x,
aRay.Direct.y < 0.f ? -aInvDirect.y : aInvDirect.y,
aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);
+#ifdef PATH_TRACING
+
+ vec4 aColor = PathTrace (aRay, aInvDirect);
+
+ if (any (isnan (aColor.xyz)))
+ {
+ aColor.xyz = ZERO;
+ }
+
+ OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
+
+#else
+
OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
+
+#endif
}
\ No newline at end of file
#define LUM_DIFFERENCE 0.085f
-#define LUMA vec3 (0.2126f, 0.7152f, 0.0722f)
-
// =======================================================================
// function : main
// purpose :
// =======================================================================
void main (void)
{
+#ifndef PATH_TRACING
+
int aPixelX = int (gl_FragCoord.x);
int aPixelY = int (gl_FragCoord.y);
}
OutColor = aColor;
+
+#endif
}
\ No newline at end of file
---Level: Public
---Purpose: Calls SetDisplayPosition method.
+ SetSmoothAngle ( me : mutable;
+ theValue : Real from Standard )
+ ---Level: Public
+ ---Purpose: Modifies the smoothing angle (in radians)
+ is static;
+
---------------------------------------------------
---Category: display methods
---------------------------------------------------
//-Methods, in order
+// =======================================================================
+// function : SetSmoothAngle
+// purpose :
+// =======================================================================
+void V3d_DirectionalLight::SetSmoothAngle (const Standard_Real theValue)
+{
+ MyLight->SetSmoothAngle (theValue);
+}
+
void V3d_DirectionalLight::SetDirection(const V3d_TypeOfOrientation Direction) {
Graphic3d_Vector V = V3d::GetProjAxis(Direction) ;
---Level: Public
---Purpose: Setup headlight flag.
+ SetIntensity ( me : mutable;
+ theValue : Real from Standard )
+ ---Level: Public
+ ---Purpose: Modifies the intensity of light source.
+ is static;
+
+ Intensity ( me ) returns Real from Standard is static;
+ ---Level: Public
+ ---Purpose: returns the intensity of light source
+
+ Smoothness ( me ) returns Real from Standard is static;
+ ---Level: Public
+ ---Purpose: returns the smoothness of light source
+
IsDisplayed( me ) returns Boolean from Standard;
---Level: Public
---Purpose: Returns TRUE when a light representation is displayed
return MyType;
}
+// =======================================================================
+// function : SetIntensity
+// purpose :
+// =======================================================================
+void V3d_Light::SetIntensity (const Standard_Real theValue)
+{
+ MyLight->SetIntensity (theValue);
+}
+
+// =======================================================================
+// function : Intensity
+// purpose :
+// =======================================================================
+Standard_Real V3d_Light::Intensity() const
+{
+ return MyLight->Intensity();
+}
+
+// =======================================================================
+// function : Smoothness
+// purpose :
+// =======================================================================
+Standard_Real V3d_Light::Smoothness() const
+{
+ return MyLight->Smoothness();
+}
Standard_Boolean V3d_Light::Headlight() const {
return MyLight->Headlight();
-- Warning: raises BadValue from V3d
-- if one of the attenuation coefficients is not between 0 et 1.
+ SetSmoothRadius ( me : mutable;
+ theValue : Real from Standard )
+ ---Level: Public
+ ---Purpose: Modifies the smoothing radius
+ is static;
+
---------------------------------------------------
---Category: Displaying methods
---------------------------------------------------
//-Methods, in order
+// =======================================================================
+// function : SetSmoothRadius
+// purpose :
+// =======================================================================
+void V3d_PositionalLight::SetSmoothRadius (const Standard_Real theValue)
+{
+ MyLight->SetSmoothRadius (theValue);
+}
+
void V3d_PositionalLight::SetPosition(const Standard_Real Xp, const Standard_Real Yp, const Standard_Real Zp) {
MyLight->SetPosition (Graphic3d_Vertex (Xp,Yp,Zp));
}
ViewerTest_ViewerCommands_1.mm
ViewerTest.hxx
ViewerTest.cxx
+ViewerTest_CmdParser.hxx
+ViewerTest_CmdParser.cxx
#include <Standard_Stream.hxx>
#include <ViewerTest.hxx>
+#include <ViewerTest_CmdParser.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_HArray1OfShape.hxx>
return 0;
}
+//===============================================================================================
+//function : VBsdf
+//purpose :
+//===============================================================================================
+static int VBsdf (Draw_Interpretor& theDi,
+ Standard_Integer theArgsNb,
+ const char** theArgVec)
+{
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
+ Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
+ if (aView.IsNull()
+ || aViewer.IsNull())
+ {
+ std::cerr << "No active viewer!\n";
+ return 1;
+ }
+
+ ViewerTest_CmdParser aCmd;
+
+ aCmd.AddDescription ("Adjusts parameters of material BSDF:");
+ aCmd.AddOption ("print|echo|p", "Print BSDF");
+
+ aCmd.AddOption ("kd", "Weight of the Lambertian BRDF");
+ aCmd.AddOption ("kr", "Weight of the reflection BRDF");
+ aCmd.AddOption ("kt", "Weight of the transmission BTDF");
+ aCmd.AddOption ("ks", "Weight of the glossy Blinn BRDF");
+ aCmd.AddOption ("le", "Self-emitted radiance");
+
+ aCmd.AddOption ("fresnel|f", "Fresnel coefficients; Allowed fresnel formats are: Constant x, Schlick x y z, Dielectric x, Conductor x y");
+
+ aCmd.AddOption ("roughness|r", "Roughness of material (Blinn's exponent)");
+ aCmd.AddOption ("absorpCoeff|af", "Absorption coeff (only for transparent material)");
+ aCmd.AddOption ("absorpColor|ac", "Absorption color (only for transparent material)");
+
+ aCmd.AddOption ("normalize|n", "Normalize BSDF coefficients");
+
+ aCmd.Parse (theArgsNb, theArgVec);
+
+ if (aCmd.HasOption ("help"))
+ {
+ theDi.PrintHelp (theArgVec[0]);
+ return 0;
+ }
+
+ TCollection_AsciiString aName (aCmd.Arg ("", 0).c_str());
+
+ // find object
+ ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
+ if (!aMap.IsBound2 (aName) )
+ {
+ std::cerr << "Use 'vdisplay' before" << "\n";
+ return 1;
+ }
+
+ Handle(AIS_InteractiveObject) anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
+ Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
+ Graphic3d_BSDF aBSDF = aMaterial.BSDF();
+
+ if (aCmd.HasOption ("print"))
+ {
+ Graphic3d_Vec4 aFresnel = aBSDF.Fresnel.Serialize();
+
+ std::cout << "\n"
+ << "Kd: " << aBSDF.Kd.r() << ", " << aBSDF.Kd.g() << ", " << aBSDF.Kd.b() << "\n"
+ << "Kr: " << aBSDF.Kr.r() << ", " << aBSDF.Kr.g() << ", " << aBSDF.Kr.b() << "\n"
+ << "Kt: " << aBSDF.Kt.r() << ", " << aBSDF.Kt.g() << ", " << aBSDF.Kt.b() << "\n"
+ << "Ks: " << aBSDF.Ks.r() << ", " << aBSDF.Ks.g() << ", " << aBSDF.Ks.b() << "\n"
+ << "Le: " << aBSDF.Le.r() << ", " << aBSDF.Le.g() << ", " << aBSDF.Le.b() << "\n"
+ << "Fresnel: ";
+
+ if (aFresnel.x() >= 0.f)
+ {
+ std::cout
+ << "|Schlick| " << aFresnel.x() << ", " << aFresnel.y() << ", " << aFresnel.z() << "\n";
+ }
+ else if (aFresnel.x() >= -1.5f)
+ {
+ std::cout
+ << "|Constant| " << aFresnel.z() << "\n";
+ }
+ else if (aFresnel.x() >= -2.5f)
+ {
+ std::cout
+ << "|Conductor| " << aFresnel.y() << ", " << aFresnel.z() << "\n";
+ }
+ else
+ {
+ std::cout
+ << "|Dielectric| " << aFresnel.y() << "\n";
+ }
+
+
+ std::cout
+ << "Roughness: " << aBSDF.Roughness << "\n"
+ << "Absorption coeff: " << aBSDF.AbsorptionCoeff << "\n"
+ << "Absorption color: " << aBSDF.AbsorptionColor.r() << ", "
+ << aBSDF.AbsorptionColor.g() << ", "
+ << aBSDF.AbsorptionColor.b() << "\n";
+
+ return 0;
+ }
+
+ if (aCmd.HasOption ("roughness", 1, Standard_True))
+ {
+ aCmd.Arg ("roughness", 0);
+ aBSDF.Roughness = aCmd.ArgFloat ("roughness");
+ }
+
+ if (aCmd.HasOption ("absorpCoeff", 1, Standard_True))
+ {
+ aBSDF.AbsorptionCoeff = aCmd.ArgFloat ("absorpCoeff");
+ }
+
+ if (aCmd.HasOption ("absorpColor", 3, Standard_True))
+ {
+ aBSDF.AbsorptionColor = aCmd.ArgVec3f ("absorpColor");
+ }
+
+ if (aCmd.HasOption ("kd", 3))
+ {
+ aBSDF.Kd = aCmd.ArgVec3f ("kd");
+ }
+ else if (aCmd.HasOption ("kd", 1, Standard_True))
+ {
+ aBSDF.Kd = Graphic3d_Vec3 (aCmd.ArgFloat ("kd"));
+ }
+
+ if (aCmd.HasOption ("kr", 3))
+ {
+ aBSDF.Kr = aCmd.ArgVec3f ("kr");
+ }
+ else if (aCmd.HasOption ("kr", 1, Standard_True))
+ {
+ aBSDF.Kr = Graphic3d_Vec3 (aCmd.ArgFloat ("kr"));
+ }
+
+ if (aCmd.HasOption ("kt", 3))
+ {
+ aBSDF.Kt = aCmd.ArgVec3f ("kt");
+ }
+ else if (aCmd.HasOption ("kt", 1, Standard_True))
+ {
+ aBSDF.Kt = Graphic3d_Vec3 (aCmd.ArgFloat ("kt"));
+ }
+
+ if (aCmd.HasOption ("ks", 3))
+ {
+ aBSDF.Ks = aCmd.ArgVec3f ("ks");
+ }
+ else if (aCmd.HasOption ("ks", 1, Standard_True))
+ {
+ aBSDF.Ks = Graphic3d_Vec3 (aCmd.ArgFloat ("ks"));
+ }
+
+ if (aCmd.HasOption ("le", 3))
+ {
+ aBSDF.Le = aCmd.ArgVec3f ("le");
+ }
+ else if (aCmd.HasOption ("le", 1, Standard_True))
+ {
+ aBSDF.Le = Graphic3d_Vec3 (aCmd.ArgFloat ("le"));
+ }
+
+ const std::string aFresnelErrorMessage =
+ "Error! Wrong Fresnel type. Allowed types are: Constant x, Schlick x y z, Dielectric x, Conductor x y.\n";
+
+ if (aCmd.HasOption ("fresnel", 4)) // Schlick: type, x, y ,z
+ {
+ std::string aFresnelType = aCmd.Arg ("fresnel", 0);
+ std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
+
+ if (aFresnelType == "schlick")
+ {
+ aBSDF.Fresnel = Graphic3d_Fresnel::CreateSchlick (
+ Graphic3d_Vec3 (static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
+ static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())),
+ static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 3).c_str()))));
+ }
+ else
+ {
+ std::cout << aFresnelErrorMessage;
+ }
+ }
+ else if (aCmd.HasOption ("fresnel", 3)) // Conductor: type, x, y
+ {
+ std::string aFresnelType = aCmd.Arg ("fresnel", 0);
+ std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
+
+ if (aFresnelType == "conductor")
+ {
+ aBSDF.Fresnel = Graphic3d_Fresnel::CreateConductor (
+ static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
+ static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())));
+ }
+ else
+ {
+ std::cout << aFresnelErrorMessage;
+ }
+ }
+ else if (aCmd.HasOption ("fresnel", 2)) // Dielectric, Constant: type, x
+ {
+ std::string aFresnelType = aCmd.Arg ("fresnel", 0);
+ std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
+
+ if (aFresnelType == "dielectric")
+ {
+ aBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (
+ static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
+ }
+ else if (aFresnelType == "constant")
+ {
+ aBSDF.Fresnel = Graphic3d_Fresnel::CreateConstant (
+ static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
+ }
+ else
+ {
+ std::cout << aFresnelErrorMessage;
+ }
+ }
+
+ if (aCmd.HasOption ("normalize"))
+ {
+ aBSDF.Normalize();
+ }
+
+ aMaterial.SetBSDF (aBSDF);
+ anIObj->SetMaterial (aMaterial);
+
+ aView->Redraw();
+
+ return 0;
+}
+
//==============================================================================
//function : VLoadSelection
//purpose : Adds given objects to map of AIS and loads selection primitives for them
"\n\t\t: [0|1] - turn off | on auto activation of selection",
__FILE__, VAutoActivateSelection, group);
+ theCommands.Add("vbsdf", "vbsdf [name] [options]"
+ "\nAdjusts parameters of material BSDF:"
+ "\n -help : Shows this message"
+ "\n -print : Print BSDF"
+ "\n -kd : Weight of the Lambertian BRDF"
+ "\n -kr : Weight of the reflection BRDF"
+ "\n -kt : Weight of the transmission BTDF"
+ "\n -ks : Weight of the glossy Blinn BRDF"
+ "\n -le : Self-emitted radiance"
+ "\n -fresnel : Fresnel coefficients; Allowed fresnel formats are: Constant x,"
+ "\n Schlick x y z, Dielectric x, Conductor x y"
+ "\n -roughness : Roughness of material (Blinn's exponent)"
+ "\n -absorpcoeff : Absorption coefficient (only for transparent material)"
+ "\n -absorpcolor : Absorption color (only for transparent material)"
+ "\n -normalize : Normalize BSDF coefficients",
+ __FILE__, VBsdf, group);
+
}
//=====================================================================
--- /dev/null
+// Created on: 2015-03-15
+// Created by: Danila ULYANOV
+// Copyright (c) 2014 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.
+
+#include <ViewerTest_CmdParser.hxx>
+
+#include <Draw.hxx>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+
+//===============================================================================================
+//function : ViewerTest_CmdParser
+//purpose :
+//===============================================================================================
+ViewerTest_CmdParser::ViewerTest_CmdParser()
+{
+ ViewerTest_CmdOption aDefaultOption;
+ myArgumentStorage.push_back (aDefaultOption);
+ myArgumentLists[""] = 0;
+ myArgumentLists["help"] = 0;
+}
+
+//===============================================================================================
+//function : AddOption
+//purpose :
+//===============================================================================================
+void ViewerTest_CmdParser::AddOption (const std::string& theOptionNames, const std::string& theOptionDescription)
+{
+ ViewerTest_CmdOption aNewOption;
+
+ // extract option names
+ std::vector<std::string> aNames;
+ std::stringstream aStream (theOptionNames);
+ std::string anItem;
+ while (std::getline (aStream, anItem, '|'))
+ {
+ std::transform (anItem.begin(), anItem.end(), anItem.begin(), ::tolower);
+ if (!anItem.empty())
+ {
+ aNames.push_back (anItem);
+ }
+ }
+
+ aNewOption.Name = aNames.front();
+ aNewOption.Description = theOptionDescription;
+ aNewOption.IsSet = Standard_False;
+
+ myArgumentStorage.push_back (aNewOption);
+
+ std::vector<std::string>::const_iterator anIt = aNames.begin();
+ for (; anIt != aNames.end(); ++anIt)
+ {
+ myArgumentLists[*anIt] = (Standard_Integer) myArgumentStorage.size() - 1;
+ }
+}
+
+//===============================================================================================
+//function : Help
+//purpose :
+//===============================================================================================
+void ViewerTest_CmdParser::Help()
+{
+ std::cout << myDescription << std::endl;
+
+ std::vector<ViewerTest_CmdOption>::const_iterator anIt = myArgumentStorage.begin();
+ for (++anIt; anIt != myArgumentStorage.end(); ++anIt)
+ {
+ std::cout << "\n -" << (*anIt).Name << " : " << (*anIt).Description;
+ }
+
+ std::cout << std::endl;
+}
+
+//===============================================================================================
+//function : Parse
+//purpose :
+//===============================================================================================
+void ViewerTest_CmdParser::Parse (Standard_Integer theArgsNb, const char** theArgVec)
+{
+ Standard_Integer aCurrentOption = 0;
+
+ for (Standard_Integer anIter = 1; anIter < theArgsNb; ++anIter)
+ {
+ if (theArgVec[anIter][0] == '-')
+ {
+ std::string anOptionName (&theArgVec[anIter][1]);
+ std::transform (anOptionName.begin(), anOptionName.end(), anOptionName.begin(), ::tolower);
+
+ std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (anOptionName);
+ if (aMapIter != myArgumentLists.end())
+ {
+ aCurrentOption = aMapIter->second;
+ myArgumentStorage[aCurrentOption].IsSet = true;
+ myArgumentStorage[aCurrentOption].Arguments.clear();
+ }
+ else
+ {
+ std::cerr << "Error: unknown argument '" << theArgVec[anIter] << "'\n";
+ }
+ }
+ else
+ {
+ myArgumentStorage[aCurrentOption].Arguments.push_back (theArgVec[anIter]);
+ }
+ }
+}
+
+//===============================================================================================
+//function : HasOption
+//purpose :
+//===============================================================================================
+Standard_Boolean ViewerTest_CmdParser::HasOption (const std::string& theOptionName, Standard_Integer theMandatoryArgsNb /*= 0*/, Standard_Boolean isFatal /*= Standard_False*/)
+{
+ std::string aLowerName = theOptionName;
+ std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::tolower);
+
+ Standard_Boolean aResult = Standard_False;
+ std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (aLowerName);
+ if (aMapIter != myArgumentLists.end())
+ {
+ Standard_Integer anOption = aMapIter->second;
+ aResult = myArgumentStorage[anOption].Arguments.size() >= static_cast<size_t> (theMandatoryArgsNb);
+ if (isFatal && !aResult && myArgumentStorage[anOption].IsSet)
+ {
+ std::cerr << "Error: wrong syntax at argument '" << theOptionName << "'\n";
+ }
+
+ aResult &= myArgumentStorage[anOption].IsSet;
+ }
+
+ return aResult;
+}
+
+//===============================================================================================
+//function : Arg
+//purpose :
+//===============================================================================================
+std::string ViewerTest_CmdParser::Arg (const std::string& theOptionName, Standard_Integer theArgumentIndex)
+{
+ std::string aLowerName = theOptionName;
+ std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::tolower);
+
+ std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (aLowerName);
+ if (aMapIter != myArgumentLists.end())
+ {
+ Standard_Integer anOption = aMapIter->second;
+ if (myArgumentStorage[anOption].Arguments.size() > static_cast<size_t> (theArgumentIndex))
+ {
+ return myArgumentStorage[anOption].Arguments[theArgumentIndex];
+ }
+ else
+ {
+ std::cerr << "Error: wrong syntax at argument '" << aLowerName << "'\n";
+ }
+ }
+
+ return "";
+}
+
+//===============================================================================================
+//function : ArgVec3f
+//purpose :
+//===============================================================================================
+Graphic3d_Vec3 ViewerTest_CmdParser::ArgVec3f (const std::string& theOptionName)
+{
+ return Graphic3d_Vec3 (static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 0).c_str())),
+ static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 1).c_str())),
+ static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 2).c_str())));
+}
+
+//===============================================================================================
+//function : ArgVec3d
+//purpose :
+//===============================================================================================
+Graphic3d_Vec3d ViewerTest_CmdParser::ArgVec3d (const std::string& theOptionName)
+{
+ return Graphic3d_Vec3d ( Draw::Atof (Arg (theOptionName, 0).c_str()),
+ Draw::Atof (Arg (theOptionName, 1).c_str()),
+ Draw::Atof (Arg (theOptionName, 2).c_str()));
+}
+
+//===============================================================================================
+//function : ArgDouble
+//purpose :
+//===============================================================================================
+Standard_Real ViewerTest_CmdParser::ArgDouble (const std::string& theOptionName)
+{
+ return Draw::Atof (Arg (theOptionName, 0).c_str());
+}
+
+//===============================================================================================
+//function : ArgFloat
+//purpose :
+//===============================================================================================
+Standard_ShortReal ViewerTest_CmdParser::ArgFloat (const std::string& theOptionName)
+{
+ return static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 0).c_str()));
+}
--- /dev/null
+// Created on: 2015-03-15
+// Created by: Danila ULYANOV
+// Copyright (c) 2014 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 _ViewerTest_CmdParser_HeaderFile
+#define _ViewerTest_CmdParser_HeaderFile
+
+#include <map>
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#include <Standard.hxx>
+#include <Graphic3d_Vec.hxx>
+
+//! Command parser.
+class ViewerTest_CmdParser
+{
+public:
+
+ //! Initializes default option.
+ ViewerTest_CmdParser();
+
+ //! Sets description for command.
+ void AddDescription (const std::string& theDescription)
+ {
+ myDescription = theDescription;
+ }
+
+ //! Adds option to available option list. Several names may be provided if separated with '|'.
+ void AddOption (const std::string& theOptionNames, const std::string& theOptionDescription);
+
+ //! Prints help message based on provided command and options descriptions.
+ void Help();
+
+ //! Parses argument list; assignes local arguments to each option.
+ void Parse (Standard_Integer theArgsNb,
+ const char** theArgVec);
+
+ //! Checks if option was set with given minimal argument number.
+ //! Prints error message if isFatal flag was set.
+ Standard_Boolean HasOption (const std::string& theOptionName,
+ Standard_Integer theMandatoryArgsNb = 0,
+ Standard_Boolean isFatal = Standard_False);
+
+ //! Accesses local argument of option 'theOptionName' with index 'theArgumentIndex'.
+ std::string Arg (const std::string& theOptionName, Standard_Integer theArgumentIndex);
+
+ // Interprets arguments of option 'theOptionName' as float vector.
+ Graphic3d_Vec3 ArgVec3f (const std::string& theOptionName);
+
+ // Interprets arguments of option 'theOptionName' as double vector.
+ Graphic3d_Vec3d ArgVec3d (const std::string& theOptionName);
+
+ // Interprets arguments of option 'theOptionName' as double.
+ Standard_Real ArgDouble (const std::string& theOptionName);
+
+ // Interprets arguments of option 'theOptionName' as float.
+ Standard_ShortReal ArgFloat (const std::string& theOptionName);
+
+private:
+
+ //! Object representing option state.
+ struct ViewerTest_CmdOption
+ {
+ ViewerTest_CmdOption() : IsSet (Standard_False) {}
+
+ std::string Name;
+ std::string Description;
+ Standard_Boolean IsSet;
+ std::vector<std::string> Arguments;
+ };
+
+ //! Description of command.
+ std::string myDescription;
+
+ //! Map from all possible option names to option object indexes in myArgumentStorage.
+ std::map<std::string, Standard_Integer> myArgumentLists;
+
+ //! Container which stores option objects.
+ std::vector<ViewerTest_CmdOption> myArgumentStorage;
+};
+
+#endif // _ViewerTest_CmdParser_HeaderFile
{
case V3d_AMBIENT:
{
- theDi << " Type: Ambient\n";
+ theDi << " Type: Ambient\n";
+ theDi << " Intensity: " << aLight->Intensity() << "\n";
break;
}
case V3d_DIRECTIONAL:
{
Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
- theDi << " Type: Directional\n";
- theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
+ theDi << " Type: Directional\n";
+ theDi << " Intensity: " << aLight->Intensity() << "\n";
+ theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
+ theDi << " Smoothness: " << aLight->Smoothness() << "\n";
if (!aLightDir.IsNull())
{
aLightDir->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
- theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+ theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
- theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+ theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
}
break;
}
case V3d_POSITIONAL:
{
Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
- theDi << " Type: Positional\n";
- theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
+ theDi << " Type: Positional\n";
+ theDi << " Intensity: " << aLight->Intensity() << "\n";
+ theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
+ theDi << " Smoothness: " << aLight->Smoothness() << "\n";
if (!aLightPos.IsNull())
{
aLightPos->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
- theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+ theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightPos->Attenuation (anAtten[0], anAtten[1]);
- theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
+ theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
}
break;
}
case V3d_SPOT:
{
Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
- theDi << " Type: Spot\n";
- theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
+ theDi << " Type: Spot\n";
+ theDi << " Intensity: " << aLight->Intensity() << "\n";
+ theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
if (!aLightSpot.IsNull())
{
aLightSpot->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
- theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+ theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
- theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+ theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightSpot->Attenuation (anAtten[0], anAtten[1]);
- theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
- theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
- theDi << " Exponent: " << aLightSpot->Concentration() << "\n";
+ theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
+ theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
+ theDi << " Exponent: " << aLightSpot->Concentration() << "\n";
}
break;
}
default:
{
- theDi << " Type: UNKNOWN\n";
+ theDi << " Type: UNKNOWN\n";
break;
}
}
return 1;
}
}
+ else if (anArgCase.IsEqual ("SM")
+ || anArgCase.IsEqual ("SMOOTHNESS"))
+ {
+ if (++anArgIt >= theArgsNb)
+ {
+ std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+ return 1;
+ }
+
+ Standard_Real aSmoothness = Atof (theArgVec[anArgIt]);
+
+ if (fabs (aSmoothness) < Precision::Confusion())
+ {
+ aLightCurr->SetIntensity (1.f);
+ }
+ else if (fabs (aLightCurr->Smoothness()) < Precision::Confusion())
+ {
+ aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
+ }
+ else
+ {
+ Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
+ aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
+ }
+
+ if (!aLightPos.IsNull())
+ {
+ aLightPos->SetSmoothRadius (aSmoothness);
+ }
+ else if (!aLightDir.IsNull())
+ {
+ aLightDir->SetSmoothAngle (aSmoothness);
+ }
+ }
+ else if (anArgCase.IsEqual ("INT")
+ || anArgCase.IsEqual ("INTENSITY"))
+ {
+ if (++anArgIt >= theArgsNb)
+ {
+ std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+ return 1;
+ }
+
+ Standard_Real aIntensity = Atof (theArgVec[anArgIt]);
+
+ if (!aLightCurr.IsNull())
+ {
+ aLightCurr->SetIntensity (aIntensity);
+ }
+ }
else if (anArgCase.IsEqual ("ANG")
|| anArgCase.IsEqual ("ANGLE"))
{
case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
}
theDI << "\n";
- theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
- theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
- theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
- theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
- theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
+ theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
+ theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
+ theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
+ theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
+ theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
+ theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
theDI << "shadingModel: ";
switch (aView->ShadingModel())
{
}
const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
- if (aDepth < 1 || aDepth > 10)
+
+ // We allow RaytracingDepth be more than 10 in case of GI enabled
+ if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
{
std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
return 1;
}
aParams.IsTransparentShadowEnabled = toEnable;
}
+ else if (aFlag == "-gi")
+ {
+ if (toPrint)
+ {
+ theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
+ continue;
+ }
+
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aParams.IsGlobalIlluminationEnabled = toEnable;
+ if (!toEnable)
+ {
+ aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
+ }
+ }
+ else if (aFlag == "-env")
+ {
+ if (toPrint)
+ {
+ theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
+ continue;
+ }
+
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aParams.UseEnvironmentMapBackground = toEnable;
+ }
else if (aFlag == "-shademodel"
|| aFlag == "-shadingmodel"
|| aFlag == "-shading")
return 1;
}
}
+
+ return 0;
+}
+
+//=======================================================================
+//function : VProgressiveMode
+//purpose :
+//=======================================================================
+#if defined(_WIN32)
+static Standard_Integer VProgressiveMode (Draw_Interpretor& /*theDI*/,
+ Standard_Integer /*theNbArgs*/,
+ const char** /*theArgs*/)
+{
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
+ if (aView.IsNull())
+ {
+ std::cerr << "Error: no active viewer!\n";
+ return 1;
+ }
+
+ std::cout << "Press Enter or Escape key to exit progressive rendering mode" << std::endl;
+
+ for (;;)
+ {
+ aView->Redraw();
+
+ Standard_Boolean toExit = Standard_False;
+
+ MSG aMsg;
+ while (PeekMessage (&aMsg, NULL, NULL, NULL, PM_REMOVE))
+ {
+ if (aMsg.message == WM_KEYDOWN && (aMsg.wParam == 0x0d || aMsg.wParam == 0x1b))
+ {
+ toExit = Standard_True;
+ }
+
+ TranslateMessage (&aMsg);
+ DispatchMessage (&aMsg);
+ }
+
+ if (toExit)
+ {
+ break;
+ }
+ }
+
return 0;
}
+#endif
//=======================================================================
//function : VFrustumCulling
"\n {dir}ection X Y Z (for directional light or for spotlight)"
"\n color colorName"
"\n {head}light 0|1"
+ "\n {sm}oothness value"
+ "\n {int}ensity value"
"\n {constAtten}uation value"
"\n {linearAtten}uation value"
"\n angle angleDeg"
__FILE__, VLight, group);
theCommands.Add("vraytrace",
"vraytrace [0|1]"
- "\n\t\t: Turn on/off raytracing renderer."
+ "\n\t\t: Turns on/off ray-tracing renderer."
"\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
"\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
__FILE__, VRenderParams, group);
"\n '-reflections on|off' Enables/disables specular reflections"
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
"\n '-gleam on|off' Enables/disables transparency shadow effects"
+ "\n '-gi on|off' Enables/disables global illumination effects"
+ "\n '-env on|off' Enables/disables environment map background"
"\n '-shadingModel model' Controls shading model from enumeration"
"\n color, flat, gouraud, phong"
"\n Unlike vcaps, these parameters dramatically change visual properties."
"vxrotate",
__FILE__,VXRotate,group);
+#if defined(_WIN32)
+ theCommands.Add("vprogressive",
+ "vprogressive",
+ __FILE__, VProgressiveMode, group);
+#endif
}
-- Light sources are created in a visualiser
-- and are activated in one of its views.
- Create ( Color : Color from Quantity;
- Direction : Vector from Graphic3d;
- Headlight : Boolean from Standard = Standard_False )
- returns Light from Visual3d
- ---Level: Public
- ---Purpose: Creates a DIRECTIONAL light source.
- -- Light sources are created in a visualiser
- -- and are activated in one of its views.
- -- Warning: Raises LightDefinitionError if <Direction> is null.
- raises LightDefinitionError;
-
- Create ( Color : Color from Quantity;
- Position : Vertex from Graphic3d;
- Fact1, Fact2 : Real from Standard )
- returns Light from Visual3d
- ---Level: Public
- ---Purpose: Creates a POSITIONAL light source.
- -- Light sources are created in a visualiser
- -- and are activated in one of its views.
- -- Warning: Raises LightDefinitionError
- -- if <Fact1> and <Fact2> are null.
- -- if <Fact1> is a negative value or greater than 1.0.
- -- if <Fact2> is a negative value or greater than 1.0.
- raises LightDefinitionError;
+ Create ( theColor : Color from Quantity;
+ theDirection : Vector from Graphic3d;
+ theHeadlight : Boolean from Standard = Standard_False;
+ theSmoothAngle : Real from Standard = 0.0;
+ theIntensity : Real from Standard = 1.0 )
+ returns Light from Visual3d
+ ---Level: Public
+ ---Purpose: Creates a DIRECTIONAL light source.
+ -- Light sources are created in a visualiser
+ -- and are activated in one of its views.
+ -- Warning: Raises LightDefinitionError if <Direction> is null.
+ raises LightDefinitionError;
+
+ Create ( theColor : Color from Quantity;
+ thePosition : Vertex from Graphic3d;
+ theFact1 : Real from Standard;
+ theFact2 : Real from Standard;
+ theSmoothRadius : Real from Standard = 0.0;
+ theIntensity : Real from Standard = 1.0 )
+ returns Light from Visual3d
+ ---Level: Public
+ ---Purpose: Creates a POSITIONAL light source.
+ -- Light sources are created in a visualiser
+ -- and are activated in one of its views.
+ -- Warning: Raises LightDefinitionError
+ -- if <Fact1> and <Fact2> are null.
+ -- if <Fact1> is a negative value or greater than 1.0.
+ -- if <Fact2> is a negative value or greater than 1.0.
+ raises LightDefinitionError;
Create ( Color : Color from Quantity;
Position : Vertex from Graphic3d;
-- if the type of the light is not TOLS_POSITIONAL or TOLS_SPOT.
raises LightDefinitionError is static;
+ SetSmoothAngle ( me : mutable;
+ theValue : Real from Standard )
+ ---Level: Public
+ ---Purpose: Modifies the smoothing angle (in radians) of
+ -- DIRECTIONAL light source.
+ -- Category: Methods to modify the class definition
+ -- Warning: Raises LightDefinitionError
+ -- if the type of the light is not TOLS_DIRECTIONAL
+ -- if <Value> is negative or greater than PI / 2.
+ raises LightDefinitionError is static;
+
+ SetSmoothRadius ( me : mutable;
+ theValue : Real from Standard )
+ ---Level: Public
+ ---Purpose: Modifies the smoothing radius of
+ -- POSITIONAL light source.
+ -- Category: Methods to modify the class definition
+ -- Warning: Raises LightDefinitionError
+ -- if the type of the light is not TOLS_POSITIONAL
+ -- if <Value> is negative.
+ raises LightDefinitionError is static;
+
+ SetIntensity ( me : mutable;
+ theValue : Real from Standard )
+ ---Level: Public
+ ---Purpose: Modifies the intensity of light source.
+ -- Category: Methods to modify the class definition
+ -- Warning: Raises LightDefinitionError
+ -- if <Value> is negative or equal to zero.
+ raises LightDefinitionError is static;
+
+ Intensity ( me ) returns Real from Standard is static;
+ ---Level: Public
+ ---Purpose: returns the intensity of light source
+
+ Smoothness ( me ) returns Real from Standard is static;
+ ---Level: Public
+ ---Purpose: returns the smoothness of light source
+
----------------------------
-- Category: Inquire methods
----------------------------
// purpose :
// =======================================================================
Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor,
- const Graphic3d_Vector& theDir,
- const Standard_Boolean theIsHeadlight)
+ const Graphic3d_Vector& theDirection,
+ const Standard_Boolean theIsHeadlight,
+ const Standard_Real theSmoothAngle,
+ const Standard_Real theIntensity)
{
- Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
+ Visual3d_LightDefinitionError_Raise_if (theDirection.LengthZero(),
"Bad value for LightDirection");
myCLight.Type = Visual3d_TOLS_DIRECTIONAL;
myCLight.IsHeadlight = theIsHeadlight;
myCLight.Color.b() = Standard_ShortReal (theColor.Blue());
Standard_Real X, Y, Z;
- theDir.Coord (X, Y, Z);
+ theDirection.Coord (X, Y, Z);
const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z);
myCLight.Direction.x() = Standard_ShortReal (X / aNorm);
myCLight.Direction.y() = Standard_ShortReal (Y / aNorm);
myCLight.Direction.z() = Standard_ShortReal (Z / aNorm);
+
+ myCLight.Smoothness = static_cast<Standard_ShortReal> (theSmoothAngle);
+ myCLight.Intensity = static_cast<Standard_ShortReal> (theIntensity);
}
// =======================================================================
// purpose :
// =======================================================================
Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor,
- const Graphic3d_Vertex& thePos,
+ const Graphic3d_Vertex& thePosition,
const Standard_Real theFact1,
- const Standard_Real theFact2)
+ const Standard_Real theFact2,
+ const Standard_Real theSmoothRadius,
+ const Standard_Real theIntensity)
{
Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0)
|| (theFact1 < 0.0 || theFact1 > 1.0)
myCLight.Color.r() = Standard_ShortReal (theColor.Red());
myCLight.Color.g() = Standard_ShortReal (theColor.Green());
myCLight.Color.b() = Standard_ShortReal (theColor.Blue());
- myCLight.Position.x() = Standard_ShortReal (thePos.X());
- myCLight.Position.y() = Standard_ShortReal (thePos.Y());
- myCLight.Position.z() = Standard_ShortReal (thePos.Z());
+ myCLight.Position.x() = Standard_ShortReal (thePosition.X());
+ myCLight.Position.y() = Standard_ShortReal (thePosition.Y());
+ myCLight.Position.z() = Standard_ShortReal (thePosition.Z());
myCLight.ChangeConstAttenuation() = Standard_ShortReal (theFact1);
myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
+ myCLight.Smoothness = static_cast<Standard_ShortReal> (theSmoothRadius);
+ myCLight.Intensity = static_cast<Standard_ShortReal> (theIntensity);
}
// =======================================================================
myCLight.Position.z() = float (thePos.Z());
}
+// =======================================================================
+// function : SetSmoothAngle
+// purpose :
+// =======================================================================
+void Visual3d_Light::SetSmoothAngle (const Standard_Real theValue)
+{
+ Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_DIRECTIONAL,
+ "Light Type != Visual3d_TOLS_DIRECTIONAL");
+
+ Visual3d_LightDefinitionError_Raise_if (theValue < 0.0 || theValue > M_PI / 2.0,
+ "Bad value for smoothing angle");
+
+ myCLight.Smoothness = static_cast<Standard_ShortReal> (theValue);
+}
+
+// =======================================================================
+// function : SetSmoothRadius
+// purpose :
+// =======================================================================
+void Visual3d_Light::SetSmoothRadius (const Standard_Real theValue)
+{
+ Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL,
+ "Light Type != Visual3d_TOLS_POSITIONAL");
+
+ Visual3d_LightDefinitionError_Raise_if (theValue < 0.0,
+ "Bad value for smoothing radius");
+
+ myCLight.Smoothness = static_cast<Standard_ShortReal> (theValue);
+}
+
+// =======================================================================
+// function : SetIntensity
+// purpose :
+// =======================================================================
+void Visual3d_Light::SetIntensity (const Standard_Real theValue)
+{
+ Visual3d_LightDefinitionError_Raise_if (theValue <= 0.0,
+ "Bad value for intensity");
+
+ myCLight.Intensity = static_cast<Standard_ShortReal> (theValue);
+}
+
+// =======================================================================
+// function : Intensity
+// purpose :
+// =======================================================================
+Standard_Real Visual3d_Light::Intensity() const
+{
+ return static_cast<Standard_Real> (myCLight.Intensity);
+}
+
+// =======================================================================
+// function : Smoothness
+// purpose :
+// =======================================================================
+Standard_Real Visual3d_Light::Smoothness() const
+{
+ return static_cast<Standard_Real> (myCLight.Smoothness);
+}
+
// =======================================================================
// function : IsValid
// purpose :
--- /dev/null
+puts "========"
+puts "OCC25201: Visualization - Implementing soft shadows and ambient occlusion in OCCT ray-tracing core"
+puts "========"
+
+# custom shapes
+set aShape1 [locate_data_file occ/Top.brep]
+set aShape2 [locate_data_file occ/Bottom.brep]
+
+# setup 3D viewer content
+vinit name=View1 w=512 h=512
+vglinfo
+
+vvbo 0
+vsetdispmode 1
+vsetgradientbg 180 200 255 180 180 180 2
+vtextureenv on 4
+restore $aShape1 s1
+restore $aShape2 s2
+vdisplay s1 s2
+vsetmaterial s1 Gold
+vsetmaterial s2 Silver
+vsetlocation s1 0.0 0.1 0.0
+vlight change 0 pos -1 1 0.5
+vturnview 3.0 -1.2 -0.1
+vfit
+
+# activate path tracing
+vrenderparams -raytrace
+vrenderparams -gi
+vrenderparams -rayDepth 12
+
+set aModeNum 0
+
+vlight change 0 sm 0.1
+vlight change 0 int 100
+vbsdf s1 roughness 6400
+
+vfps 200
+vdump $imagedir/${casename}_${aModeNum}.png
+incr aModeNum
+
+vsetmaterial s1 glass
+vbsdf s1 absorpcoeff 1.0
+
+vfps 200
+vdump $imagedir/${casename}_${aModeNum}.png
+incr aModeNum
+
+vsetmaterial s2 plaster
+
+vfps 200
+vdump $imagedir/${casename}_${aModeNum}.png
+incr aModeNum
\ No newline at end of file