1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-07-15 12:35:51 +03:00

0025201: Visualization - Implementing soft shadows and ambient occlusion in OCCT ray-tracing core

This commit is contained in:
dbp 2015-04-20 10:15:34 +03:00 committed by bugmaster
parent 283b833c8e
commit 189f85a3fd
41 changed files with 3109 additions and 418 deletions

View File

@ -276,9 +276,7 @@ void AIS_InteractiveObject::UnsetWidth()
//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() )
{
@ -292,44 +290,57 @@ void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
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 :
//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);
}
else{
Handle(Prs3d_ShadingAspect) SA;
myDrawer->SetShadingAspect(SA);
if (IsTransparent())
{
SetTransparency (myTransparency);
}
}
else
{
Handle(Prs3d_ShadingAspect) anAspect;
myDrawer->SetShadingAspect (anAspect);
}
hasOwnMaterial = Standard_False;
}

View File

@ -65,3 +65,5 @@ Graphic3d_Camera.cxx
Graphic3d_Camera.hxx
Graphic3d_RenderingParams.hxx
Graphic3d_NMapOfTransient.hxx
Graphic3d_BSDF.hxx
Graphic3d_BSDF.cxx

View File

@ -362,6 +362,8 @@ is
imported BndBox4d;
imported BufferType;
imported BSDF;
imported CBitFields20;
---Category: Imported types

View File

@ -0,0 +1,159 @@
// 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;
}

View File

@ -0,0 +1,203 @@
// 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

View File

@ -30,6 +30,8 @@ public:
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(); }
@ -61,7 +63,9 @@ public:
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)
{
//
}

View File

@ -336,7 +336,7 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
// Back Material
const Graphic3d_MaterialAspect& aBack = theAspFill->BackMaterial();
// Light specificity
// Material properties
ContextFillArea.Back.Shininess = float (aBack.Shininess());
ContextFillArea.Back.Ambient = float (aBack.Ambient());
ContextFillArea.Back.Diffuse = float (aBack.Diffuse());
@ -344,6 +344,7 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
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;
@ -378,7 +379,8 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
// Front Material
const Graphic3d_MaterialAspect& aFront = theAspFill->FrontMaterial();
// Light specificity
// Material properties
ContextFillArea.Front.Shininess = float (aFront.Shininess());
ContextFillArea.Front.Ambient = float (aFront.Ambient());
ContextFillArea.Front.Diffuse = float (aFront.Diffuse());
@ -386,6 +388,7 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
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;
@ -636,6 +639,9 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea
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
@ -677,6 +683,9 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea
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();
@ -892,6 +901,9 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
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));
@ -926,6 +938,9 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
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

View File

@ -35,10 +35,10 @@ class MaterialAspect from Graphic3d
uses
Color from Quantity,
NameOfMaterial from Graphic3d,
TypeOfReflection from Graphic3d,
TypeOfMaterial from Graphic3d,
BSDF from Graphic3d,
AsciiString from TCollection
raises
@ -148,6 +148,13 @@ is
-- 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;
@ -325,6 +332,14 @@ is
---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;
@ -485,6 +500,9 @@ fields
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;

View File

@ -62,6 +62,8 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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())
{
@ -70,23 +72,44 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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);
@ -96,6 +119,12 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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);
@ -104,10 +133,14 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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:
@ -118,6 +151,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -133,6 +169,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -148,6 +187,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -163,6 +205,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -178,6 +223,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -197,6 +245,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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;
@ -206,6 +257,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -221,6 +275,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -242,6 +299,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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:
@ -252,6 +313,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -267,6 +331,9 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -294,6 +361,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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;
@ -309,6 +380,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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;
@ -324,6 +399,11 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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;
@ -339,6 +419,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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;
@ -348,6 +432,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -365,6 +453,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -382,6 +474,10 @@ void Graphic3d_MaterialAspect::Init (const Graphic3d_NameOfMaterial theName)
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
@ -664,6 +760,15 @@ void Graphic3d_MaterialAspect::SetRefractionIndex (const Standard_Real theValue)
myRefractionIndex = static_cast<Standard_ShortReal> (theValue);
}
// =======================================================================
// function : SetBSDF
// purpose :
// =======================================================================
void Graphic3d_MaterialAspect::SetBSDF (const Graphic3d_BSDF& theBSDF)
{
myBSDF = theBSDF;
}
// =======================================================================
// function : Color
// purpose :
@ -790,6 +895,15 @@ Standard_Real Graphic3d_MaterialAspect::RefractionIndex() const
return myRefractionIndex;
}
// =======================================================================
// function : BSDF
// purpose :
// =======================================================================
const Graphic3d_BSDF& Graphic3d_MaterialAspect::BSDF() const
{
return myBSDF;
}
// =======================================================================
// function : Shininess
// purpose :
@ -863,6 +977,7 @@ Standard_Boolean Graphic3d_MaterialAspect::IsEqual (const Graphic3d_MaterialAspe
&& myEmissiveCoef == theOther.myEmissiveCoef
&& myTransparencyCoef == theOther.myTransparencyCoef
&& myRefractionIndex == theOther.myRefractionIndex
&& myBSDF == theOther.myBSDF
&& myShininess == theOther.myShininess
&& myEnvReflexion == theOther.myEnvReflexion
&& myAmbientColor == theOther.myAmbientColor

View File

@ -23,6 +23,9 @@ class Graphic3d_RenderingParams
{
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;
@ -32,10 +35,13 @@ public:
Graphic3d_RenderingParams()
: Method (Graphic3d_RM_RASTERIZATION),
RaytracingDepth (THE_DEFAULT_DEPTH),
SamplesPerPixel (THE_DEFAULT_SPP),
IsShadowEnabled (Standard_True),
IsReflectionEnabled (Standard_False),
IsAntialiasingEnabled (Standard_False),
IsTransparentShadowEnabled (Standard_False)
IsTransparentShadowEnabled (Standard_False),
IsGlobalIlluminationEnabled (Standard_False),
UseEnvironmentMapBackground (Standard_False)
{
//
}
@ -48,6 +54,9 @@ public:
//! Maximum ray-tracing depth.
Standard_Integer RaytracingDepth;
//! Number of samples per pixel (SPP).
Standard_Integer SamplesPerPixel;
//! Enables/disables shadows rendering.
Standard_Boolean IsShadowEnabled;
@ -60,6 +69,12 @@ public:
//! 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

View File

@ -807,6 +807,9 @@ Handle(Graphic3d_AspectFillArea3d) Graphic3d_Structure::FillArea3dAspect() const
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));
@ -855,6 +858,9 @@ Handle(Graphic3d_AspectFillArea3d) Graphic3d_Structure::FillArea3dAspect() const
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);
@ -1004,6 +1010,7 @@ void Graphic3d_Structure::SetPrimitivesAspect (const Handle(Graphic3d_AspectFill
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
@ -1048,6 +1055,7 @@ void Graphic3d_Structure::SetPrimitivesAspect (const Handle(Graphic3d_AspectFill
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

View File

@ -17,13 +17,16 @@
#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;
@ -31,7 +34,9 @@ typedef struct {
typedef struct {
float x, y, z;
Standard_ShortReal x;
Standard_ShortReal y;
Standard_ShortReal z;
} CALL_DEF_POINT;
@ -39,38 +44,43 @@ typedef struct {
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;
Standard_Integer IsSet;
Standard_Integer IsDef;
Standard_Integer Flag;
CALL_DEF_POINT Point;
} CALL_DEF_TRANSFORM_PERSISTENCE;
@ -78,8 +88,8 @@ typedef struct
typedef struct {
void *Data;
Graphic3d_BndBox4f *Bounds;
void* Data;
Graphic3d_BndBox4f* Bounds;
} CALL_DEF_USERDRAW;

View File

@ -111,6 +111,9 @@ void OpenGl_AspectFace::convertMaterial (const CALL_DEF_MATERIAL& theMat,
// 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;
}
// =======================================================================

View File

@ -31,6 +31,7 @@
#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)
@ -41,12 +42,28 @@ static const TEL_POFFSET_PARAM THE_DEFAULT_POFFSET = { Aspect_POM_Fill, 1.0F, 0.
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
};

View File

@ -53,6 +53,9 @@ public:
//! 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);

View File

@ -139,6 +139,7 @@ Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& the
{
if (myVPSizeX == theViewportSizeX
&& myVPSizeY == theViewportSizeY)
{
return IsValid();
}

View File

@ -72,6 +72,32 @@ public:
//! 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.

View File

@ -190,7 +190,7 @@ public:
//! 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)?

View File

@ -81,7 +81,7 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
myIsRaytraceDataValid (Standard_False),
myIsRaytraceWarnTextures (Standard_False),
myToUpdateEnvironmentMap (Standard_False),
myLayersModificationStatus (0)
myLayerListState (0)
{
myCurrLightSourceState = myStateCounter->Increment();
}

View File

@ -21,6 +21,7 @@
#include <TColStd_Array2OfReal.hxx>
#include <NCollection_List.hxx>
#include <math_BullardGenerator.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Aspect_FillMethod.hxx>
@ -318,6 +319,7 @@ protected: //! @name data types related to ray-tracing
{
OpenGl_RT_aPosition,
// camera position
OpenGl_RT_uOriginLT,
OpenGl_RT_uOriginLB,
OpenGl_RT_uOriginRT,
@ -328,22 +330,31 @@ protected: //! @name data types related to ray-tracing
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
};
@ -366,10 +377,11 @@ protected: //! @name data types related to ray-tracing
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.
@ -377,6 +389,9 @@ protected: //! @name data types related to ray-tracing
{
public:
//! Default shader prefix - empty string.
static const TCollection_AsciiString EMPTY_PREFIX;
//! Creates new uninitialized shader source.
ShaderSource()
{
@ -384,9 +399,11 @@ protected: //! @name data types related to ray-tracing
}
//! 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:
@ -407,7 +424,7 @@ protected: //! @name data types related to ray-tracing
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:
@ -434,6 +451,9 @@ protected: //! @name data types related to ray-tracing
//! 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;
@ -442,6 +462,7 @@ protected: //! @name data types related to ray-tracing
: StackSize (THE_DEFAULT_STACK_SIZE),
NbBounces (THE_DEFAULT_NB_BOUNCES),
TransparentShadows (Standard_False),
GlobalIllumination (Standard_False),
UseBindlessTextures (Standard_False)
{
//
@ -572,6 +593,11 @@ protected: //! @name methods related to ray-tracing
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);
@ -658,6 +684,8 @@ protected: //! @name fields related to ray-tracing
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;
@ -701,14 +729,26 @@ protected: //! @name fields related to ray-tracing
//! 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:

File diff suppressed because it is too large Load Diff

13
src/Shaders/Display.fs Normal file
View File

@ -0,0 +1,13 @@
//! 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);
}

View File

@ -0,0 +1,830 @@
#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

View File

@ -73,12 +73,14 @@ uniform int uLightCount;
//! 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;
@ -90,6 +92,11 @@ uniform float uSceneEpsilon;
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
@ -125,6 +132,24 @@ struct SIntersect
#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;
@ -133,9 +158,9 @@ 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);
@ -196,6 +221,26 @@ vec3 MatrixColMultiplyDir (in vec3 v,
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
@ -239,7 +284,7 @@ float ComputeOpenGlDepth (in SRay theRay)
// 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)
@ -421,16 +466,16 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
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
@ -850,10 +895,21 @@ vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle)
}
#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,
@ -877,6 +933,7 @@ vec3 Refract (in vec3 theInput,
return normalize (anIndex * theInput -
(anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
}
#endif
#define MIN_SLOPE 0.0001f
#define EPS_SCALE 8.0000f
@ -892,6 +949,7 @@ vec3 Refract (in vec3 theInput,
// 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);
@ -909,19 +967,19 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
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);
@ -944,7 +1002,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
if (anOpenGlDepth < aHit.Time + aPolygonOffset)
{
vec4 aGlColor = ComputeOpenGlColor (theRay);
vec4 aGlColor = ComputeOpenGlColor();
aResult += aWeight.xyz * aGlColor.xyz;
aWeight *= aGlColor.w;
@ -1018,7 +1076,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
{
float aVisibility = 1.0f;
if (bool(uShadowsEnable))
if (bool(uShadowsEnabled))
{
SRay aShadow = SRay (theRay.Origin, aLight.xyz);
@ -1059,7 +1117,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
}
else
{
aWeight *= bool(uReflectionsEnable) ?
aWeight *= bool(uReflectEnabled) ?
texelFetch (uRaytraceMaterialTexture, MATERIAL_REFL (aTriIndex.w)) : vec4 (0.0f);
vec3 aReflect = reflect (theRay.Direct, aNormal);
@ -1096,3 +1154,4 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
aResult.z,
aWeight.w);
}
#endif

View File

@ -1,12 +1,30 @@
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);
@ -14,5 +32,20 @@ void main (void)
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
}

View File

@ -9,14 +9,14 @@ out vec4 OutColor;
#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);
@ -75,4 +75,6 @@ void main (void)
}
OutColor = aColor;
#endif
}

View File

@ -86,6 +86,12 @@ is
---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
---------------------------------------------------

View File

@ -90,6 +90,15 @@ V3d_DirectionalLight::V3d_DirectionalLight(const Handle(V3d_Viewer)& VM,const St
//-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) ;

View File

@ -105,6 +105,20 @@ is
---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

View File

@ -102,6 +102,32 @@ V3d_TypeOfLight V3d_Light::Type() const {
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();

View File

@ -108,6 +108,12 @@ is
-- 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
---------------------------------------------------

View File

@ -94,6 +94,15 @@ V3d_PositionalLight::V3d_PositionalLight(const Handle(V3d_Viewer)& VM, const Sta
//-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));
}

View File

@ -12,3 +12,5 @@ ViewerTest_OpenGlCommands.cxx
ViewerTest_ViewerCommands_1.mm
ViewerTest.hxx
ViewerTest.cxx
ViewerTest_CmdParser.hxx
ViewerTest_CmdParser.cxx

View File

@ -25,6 +25,7 @@
#include <Standard_Stream.hxx>
#include <ViewerTest.hxx>
#include <ViewerTest_CmdParser.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_HArray1OfShape.hxx>
@ -4804,6 +4805,239 @@ static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a
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
@ -5250,6 +5484,23 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
"\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);
}
//=====================================================================

View File

@ -0,0 +1,212 @@
// 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()));
}

View File

@ -0,0 +1,95 @@
// 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

View File

@ -7503,13 +7503,16 @@ static int VLight (Draw_Interpretor& theDi,
case V3d_AMBIENT:
{
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 << " 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]);
@ -7523,7 +7526,9 @@ static int VLight (Draw_Interpretor& theDi,
{
Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
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]);
@ -7537,6 +7542,7 @@ static int VLight (Draw_Interpretor& theDi,
{
Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
theDi << " Type: Spot\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
if (!aLightSpot.IsNull())
{
@ -7785,6 +7791,56 @@ static int VLight (Draw_Interpretor& theDi,
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"))
{
@ -7980,6 +8036,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
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())
{
@ -8066,7 +8123,9 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
}
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;
@ -8142,6 +8201,42 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
}
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")
@ -8200,9 +8295,56 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
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
//purpose : enables/disables view volume's culling.
@ -8817,6 +8959,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\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"
@ -8827,7 +8971,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
__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);
@ -8840,6 +8984,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\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."
@ -8861,4 +9007,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"vxrotate",
__FILE__,VXRotate,group);
#if defined(_WIN32)
theCommands.Add("vprogressive",
"vprogressive",
__FILE__, VProgressiveMode, group);
#endif
}

View File

@ -67,9 +67,11 @@ is
-- 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 )
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.
@ -78,9 +80,12 @@ is
-- Warning: Raises LightDefinitionError if <Direction> is null.
raises LightDefinitionError;
Create ( Color : Color from Quantity;
Position : Vertex from Graphic3d;
Fact1, Fact2 : Real from Standard )
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.
@ -196,6 +201,45 @@ is
-- 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
----------------------------

View File

@ -42,10 +42,12 @@ Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor)
// 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;
@ -54,11 +56,14 @@ Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor,
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);
}
// =======================================================================
@ -66,9 +71,11 @@ Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor,
// 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)
@ -79,11 +86,13 @@ Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor,
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);
}
// =======================================================================
@ -350,6 +359,66 @@ void Visual3d_Light::SetPosition (const Graphic3d_Vertex& thePos)
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 :

View File

@ -0,0 +1,53 @@
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