1 // Created on: 2015-01-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Graphic3d_BSDF.hxx>
18 #include <Graphic3d_PBRMaterial.hxx>
22 // =======================================================================
23 // function : Serialize
25 // =======================================================================
26 Graphic3d_Vec4 Graphic3d_Fresnel::Serialize() const
28 Graphic3d_Vec4 aData = Graphic3d_Vec4 (myFresnelData, 0.f);
30 if (myFresnelType != Graphic3d_FM_SCHLICK)
32 aData.x() = -static_cast<float> (myFresnelType);
38 // =======================================================================
39 // function : fresnelNormal
41 // =======================================================================
42 inline float fresnelNormal (float theN,
45 return ((theN - 1.f) * (theN - 1.f) + theK * theK) /
46 ((theN + 1.f) * (theN + 1.f) + theK * theK);
49 // =======================================================================
50 // function : CreateConductor
52 // =======================================================================
53 Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theRefractionIndex,
54 const Graphic3d_Vec3& theAbsorptionIndex)
56 const Graphic3d_Vec3 aFresnel (fresnelNormal (theRefractionIndex.x(), theAbsorptionIndex.x()),
57 fresnelNormal (theRefractionIndex.y(), theAbsorptionIndex.y()),
58 fresnelNormal (theRefractionIndex.z(), theAbsorptionIndex.z()));
60 return Graphic3d_Fresnel (Graphic3d_FM_SCHLICK, aFresnel);
63 // =======================================================================
64 // function : Graphic3d_BSDF
66 // =======================================================================
67 Graphic3d_BSDF::Graphic3d_BSDF()
68 : Ks (Graphic3d_Vec3 (0.f), 1.f)
70 FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
71 FresnelBase = Graphic3d_Fresnel::CreateConstant (1.f);
74 // =======================================================================
75 // function : operator==
77 // =======================================================================
78 bool Graphic3d_BSDF::operator== (const Graphic3d_BSDF& theOther) const
80 return Kc == theOther.Kc
85 && Absorption == theOther.Absorption
86 && FresnelCoat == theOther.FresnelCoat
87 && FresnelBase == theOther.FresnelBase;
90 // =======================================================================
91 // function : Normalize
93 // =======================================================================
94 void Graphic3d_BSDF::Normalize()
98 for (int aChannelID = 0; aChannelID < 3; ++aChannelID)
100 aMax = std::max (aMax, Kd[aChannelID] + Ks[aChannelID] + Kt[aChannelID]);
105 for (int aChannelID = 0; aChannelID < 3; ++aChannelID)
107 Kd[aChannelID] /= aMax;
108 Ks[aChannelID] /= aMax;
109 Kt[aChannelID] /= aMax;
114 // =======================================================================
115 // function : CreateDiffuse
117 // =======================================================================
118 Graphic3d_BSDF Graphic3d_BSDF::CreateDiffuse (const Graphic3d_Vec3& theWeight)
120 Graphic3d_BSDF aBSDF;
122 aBSDF.Kd = theWeight;
127 // =======================================================================
128 // function : CreateMetallic
130 // =======================================================================
131 Graphic3d_BSDF Graphic3d_BSDF::CreateMetallic (const Graphic3d_Vec3& theWeight, const Graphic3d_Fresnel& theFresnel, const float theRoughness)
133 Graphic3d_BSDF aBSDF;
135 aBSDF.FresnelBase = theFresnel;
137 // Selecting between specular and glossy
138 // BRDF depending on the given roughness
139 aBSDF.Ks = Graphic3d_Vec4 (theWeight, theRoughness);
144 // =======================================================================
145 // function : CreateTransparent
147 // =======================================================================
148 Graphic3d_BSDF Graphic3d_BSDF::CreateTransparent (const Graphic3d_Vec3& theWeight,
149 const Graphic3d_Vec3& theAbsorptionColor,
150 const float theAbsorptionCoeff)
152 Graphic3d_BSDF aBSDF;
154 // Create Fresnel parameters for the coat layer;
155 // set it to 0 value to simulate ideal refractor
156 aBSDF.FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
158 aBSDF.Kt = theWeight;
160 // Link reflection and transmission coefficients
161 aBSDF.Kc.r() = aBSDF.Kt.r();
162 aBSDF.Kc.g() = aBSDF.Kt.g();
163 aBSDF.Kc.b() = aBSDF.Kt.b();
165 aBSDF.Absorption = Graphic3d_Vec4 (theAbsorptionColor,
171 // =======================================================================
172 // function : CreateGlass
174 // =======================================================================
175 Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
176 const Graphic3d_Vec3& theAbsorptionColor,
177 const float theAbsorptionCoeff,
178 const float theRefractionIndex)
180 Graphic3d_BSDF aBSDF;
182 // Create Fresnel parameters for the coat layer
183 aBSDF.FresnelCoat = Graphic3d_Fresnel::CreateDielectric (theRefractionIndex);
185 aBSDF.Kt = theWeight;
187 aBSDF.Kc.r() = aBSDF.Kt.r();
188 aBSDF.Kc.g() = aBSDF.Kt.g();
189 aBSDF.Kc.b() = aBSDF.Kt.b();
191 aBSDF.Absorption = Graphic3d_Vec4 (theAbsorptionColor,
197 // =======================================================================
198 // function : CreateMetallicRoughness
200 // =======================================================================
201 Graphic3d_BSDF Graphic3d_BSDF::CreateMetallicRoughness (const Graphic3d_PBRMaterial& thePbr)
203 const Graphic3d_Vec3 aDiff = (Graphic3d_Vec3 )thePbr.Color().GetRGB() * thePbr.Alpha();
204 const Standard_ShortReal aRougness2 = thePbr.NormalizedRoughness() * thePbr.NormalizedRoughness();
206 Graphic3d_BSDF aBsdf;
207 aBsdf.FresnelBase = Graphic3d_Fresnel::CreateSchlick (aDiff * thePbr.Metallic());
208 aBsdf.Ks.SetValues (Graphic3d_Vec3 (thePbr.Alpha()), aRougness2);
209 aBsdf.Kt = Graphic3d_Vec3 (1.0f - thePbr.Alpha());
210 aBsdf.Kd = aDiff * (1.0f - thePbr.Metallic());