1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +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

@ -454,7 +454,7 @@ is
-- - Pewter
-- - Silver
-- - Stone.
SetMaterial(me:mutable;aName:NameOfMaterial from Graphic3d) is virtual;
---Purpose: Sets the name aName for material defining this
-- display attribute for the interactive object.

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 :
//purpose :
//function : UnsetMaterial
//purpose :
//=======================================================================
void AIS_InteractiveObject::UnsetMaterial()
{
if( !HasMaterial() ) return;
if (!HasMaterial())
{
return;
}
if (HasColor() || IsTransparent())
{
if(myDrawer->HasLink())
{
myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
}
if (HasColor()) SetColor (myOwnColor);
if (IsTransparent()) SetTransparency (myTransparency);
if (HasColor())
{
SetColor (myOwnColor);
}
if (IsTransparent())
{
SetTransparency (myTransparency);
}
}
else{
Handle(Prs3d_ShadingAspect) SA;
myDrawer->SetShadingAspect(SA);
else
{
Handle(Prs3d_ShadingAspect) anAspect;
myDrawer->SetShadingAspect (anAspect);
}
hasOwnMaterial = Standard_False;
}

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,14 +336,15 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
// Back Material
const Graphic3d_MaterialAspect& aBack = theAspFill->BackMaterial();
// Light specificity
ContextFillArea.Back.Shininess = float (aBack.Shininess());
ContextFillArea.Back.Ambient = float (aBack.Ambient());
ContextFillArea.Back.Diffuse = float (aBack.Diffuse());
ContextFillArea.Back.Specular = float (aBack.Specular());
ContextFillArea.Back.Transparency = float (aBack.Transparency());
ContextFillArea.Back.Emission = float (aBack.Emissive());
// Material properties
ContextFillArea.Back.Shininess = float (aBack.Shininess());
ContextFillArea.Back.Ambient = float (aBack.Ambient());
ContextFillArea.Back.Diffuse = float (aBack.Diffuse());
ContextFillArea.Back.Specular = float (aBack.Specular());
ContextFillArea.Back.Transparency = float (aBack.Transparency());
ContextFillArea.Back.Emission = float (aBack.Emissive());
ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
ContextFillArea.Back.BSDF = aBack.BSDF();
// Reflection mode
ContextFillArea.Back.IsAmbient = aBack.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
@ -378,14 +379,16 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
// Front Material
const Graphic3d_MaterialAspect& aFront = theAspFill->FrontMaterial();
// Light specificity
ContextFillArea.Front.Shininess = float (aFront.Shininess());
ContextFillArea.Front.Ambient = float (aFront.Ambient());
ContextFillArea.Front.Diffuse = float (aFront.Diffuse());
ContextFillArea.Front.Specular = float (aFront.Specular());
ContextFillArea.Front.Transparency = float (aFront.Transparency());
ContextFillArea.Front.Emission = float (aFront.Emissive());
// Material properties
ContextFillArea.Front.Shininess = float (aFront.Shininess());
ContextFillArea.Front.Ambient = float (aFront.Ambient());
ContextFillArea.Front.Diffuse = float (aFront.Diffuse());
ContextFillArea.Front.Specular = float (aFront.Specular());
ContextFillArea.Front.Transparency = float (aFront.Transparency());
ContextFillArea.Front.Emission = float (aFront.Emissive());
ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
ContextFillArea.Front.BSDF = aFront.BSDF();
// Reflection mode
ContextFillArea.Front.IsAmbient = aFront.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
@ -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

@ -34,12 +34,12 @@ class MaterialAspect from Graphic3d
uses
Color from Quantity,
NameOfMaterial from Graphic3d,
TypeOfReflection from Graphic3d,
TypeOfMaterial from Graphic3d,
AsciiString from TCollection
Color from Quantity,
NameOfMaterial from Graphic3d,
TypeOfReflection from Graphic3d,
TypeOfMaterial from Graphic3d,
BSDF from Graphic3d,
AsciiString from TCollection
raises
@ -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;
@ -501,4 +519,4 @@ fields
-- the string name of the material
myStringName : AsciiString from TCollection;
end MaterialAspect;
end MaterialAspect;

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;
@ -30,12 +33,15 @@ public:
//! Creates default rendering parameters.
Graphic3d_RenderingParams()
: Method (Graphic3d_RM_RASTERIZATION),
RaytracingDepth (THE_DEFAULT_DEPTH),
IsShadowEnabled (Standard_True),
IsReflectionEnabled (Standard_False),
IsAntialiasingEnabled (Standard_False),
IsTransparentShadowEnabled (Standard_False)
: Method (Graphic3d_RM_RASTERIZATION),
RaytracingDepth (THE_DEFAULT_DEPTH),
SamplesPerPixel (THE_DEFAULT_SPP),
IsShadowEnabled (Standard_True),
IsReflectionEnabled (Standard_False),
IsAntialiasingEnabled (Standard_False),
IsTransparentShadowEnabled (Standard_False),
IsGlobalIlluminationEnabled (Standard_False),
UseEnvironmentMapBackground (Standard_False)
{
//
}
@ -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,47 +44,52 @@ 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;
CALL_DEF_POINT Point;
Standard_Integer IsSet;
Standard_Integer IsDef;
Standard_Integer Flag;
CALL_DEF_POINT Point;
} CALL_DEF_TRANSFORM_PERSISTENCE;
/* USERDRAW DATA */
typedef struct {
void *Data;
Graphic3d_BndBox4f *Bounds;
void* Data;
Graphic3d_BndBox4f* Bounds;
} CALL_DEF_USERDRAW;

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,14 +92,19 @@ 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
//! Stores ray parameters.
struct SRay
{
vec3 Origin;
vec3 Direct;
};
@ -105,9 +112,9 @@ struct SRay
struct SIntersect
{
float Time;
vec2 UV;
vec3 Normal;
};
@ -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,18 +1,51 @@
out vec4 OutColor;
// Seed for random number generator
uniform int uFrameRndSeed;
// Weight of current frame related to accumulated frames.
uniform float uSampleWeight;
//! Input accumulated image.
uniform sampler2D uAccumTexture;
// =======================================================================
// function : main
// purpose :
// =======================================================================
void main (void)
{
#ifndef PATH_TRACING
SRay aRay = GenerateRay (vPixel);
#else
ivec2 aWinSize = textureSize (uAccumTexture, 0);
SeedRand (uFrameRndSeed, aWinSize.x);
SRay aRay = GenerateRay (vPixel +
vec2 (RandFloat() + 1.f, RandFloat() + 1.f) / vec2 (aWinSize));
#endif
vec3 aInvDirect = 1.f / max (abs (aRay.Direct), SMALL);
aInvDirect = vec3 (aRay.Direct.x < 0.f ? -aInvDirect.x : aInvDirect.x,
aRay.Direct.y < 0.f ? -aInvDirect.y : aInvDirect.y,
aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);
#ifdef PATH_TRACING
vec4 aColor = PathTrace (aRay, aInvDirect);
if (any (isnan (aColor.xyz)))
{
aColor.xyz = ZERO;
}
OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
#else
OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
#endif
}

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

@ -7502,58 +7502,64 @@ static int VLight (Draw_Interpretor& theDi,
{
case V3d_AMBIENT:
{
theDi << " Type: Ambient\n";
theDi << " Type: Ambient\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
break;
}
case V3d_DIRECTIONAL:
{
Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
theDi << " Type: Directional\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Type: Directional\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Smoothness: " << aLight->Smoothness() << "\n";
if (!aLightDir.IsNull())
{
aLightDir->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
}
break;
}
case V3d_POSITIONAL:
{
Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
theDi << " Type: Positional\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Type: Positional\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Smoothness: " << aLight->Smoothness() << "\n";
if (!aLightPos.IsNull())
{
aLightPos->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightPos->Attenuation (anAtten[0], anAtten[1]);
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
}
break;
}
case V3d_SPOT:
{
Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
theDi << " Type: Spot\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Type: Spot\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
if (!aLightSpot.IsNull())
{
aLightSpot->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightSpot->Attenuation (anAtten[0], anAtten[1]);
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
theDi << " Exponent: " << aLightSpot->Concentration() << "\n";
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
theDi << " Exponent: " << aLightSpot->Concentration() << "\n";
}
break;
}
default:
{
theDi << " Type: UNKNOWN\n";
theDi << " Type: UNKNOWN\n";
break;
}
}
@ -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"))
{
@ -7975,11 +8031,12 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
}
theDI << "\n";
theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
theDI << "shadingModel: ";
switch (aView->ShadingModel())
{
@ -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,30 +67,35 @@ 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 )
returns Light from Visual3d
---Level: Public
---Purpose: Creates a DIRECTIONAL light source.
-- Light sources are created in a visualiser
-- and are activated in one of its views.
-- Warning: Raises LightDefinitionError if <Direction> is null.
raises LightDefinitionError;
Create ( theColor : Color from Quantity;
theDirection : Vector from Graphic3d;
theHeadlight : Boolean from Standard = Standard_False;
theSmoothAngle : Real from Standard = 0.0;
theIntensity : Real from Standard = 1.0 )
returns Light from Visual3d
---Level: Public
---Purpose: Creates a DIRECTIONAL light source.
-- Light sources are created in a visualiser
-- and are activated in one of its views.
-- Warning: Raises LightDefinitionError if <Direction> is null.
raises LightDefinitionError;
Create ( Color : Color from Quantity;
Position : Vertex from Graphic3d;
Fact1, Fact2 : Real from Standard )
returns Light from Visual3d
---Level: Public
---Purpose: Creates a POSITIONAL light source.
-- Light sources are created in a visualiser
-- and are activated in one of its views.
-- Warning: Raises LightDefinitionError
-- if <Fact1> and <Fact2> are null.
-- if <Fact1> is a negative value or greater than 1.0.
-- if <Fact2> is a negative value or greater than 1.0.
raises LightDefinitionError;
Create ( theColor : Color from Quantity;
thePosition : Vertex from Graphic3d;
theFact1 : Real from Standard;
theFact2 : Real from Standard;
theSmoothRadius : Real from Standard = 0.0;
theIntensity : Real from Standard = 1.0 )
returns Light from Visual3d
---Level: Public
---Purpose: Creates a POSITIONAL light source.
-- Light sources are created in a visualiser
-- and are activated in one of its views.
-- Warning: Raises LightDefinitionError
-- if <Fact1> and <Fact2> are null.
-- if <Fact1> is a negative value or greater than 1.0.
-- if <Fact2> is a negative value or greater than 1.0.
raises LightDefinitionError;
Create ( Color : Color from Quantity;
Position : Vertex from Graphic3d;
@ -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