0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Graphic3d / Graphic3d_BSDF.cxx
CommitLineData
189f85a3 1// Created on: 2015-01-19
2// Created by: Denis BOGOLEPOV
3// Copyright (c) 2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
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.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <Graphic3d_BSDF.hxx>
17
67312b79 18#include <Graphic3d_PBRMaterial.hxx>
19
189f85a3 20#include <algorithm>
21
22// =======================================================================
23// function : Serialize
24// purpose :
25// =======================================================================
26Graphic3d_Vec4 Graphic3d_Fresnel::Serialize() const
27{
28 Graphic3d_Vec4 aData = Graphic3d_Vec4 (myFresnelData, 0.f);
29
30 if (myFresnelType != Graphic3d_FM_SCHLICK)
31 {
05aa616d 32 aData.x() = -static_cast<float> (myFresnelType);
189f85a3 33 }
34
35 return aData;
36}
37
38// =======================================================================
39// function : fresnelNormal
40// purpose :
41// =======================================================================
05aa616d 42inline float fresnelNormal (float theN,
43 float theK)
189f85a3 44{
45 return ((theN - 1.f) * (theN - 1.f) + theK * theK) /
46 ((theN + 1.f) * (theN + 1.f) + theK * theK);
47}
48
49// =======================================================================
50// function : CreateConductor
51// purpose :
52// =======================================================================
53Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theRefractionIndex,
54 const Graphic3d_Vec3& theAbsorptionIndex)
55{
05aa616d 56 const Graphic3d_Vec3 aFresnel (fresnelNormal (theRefractionIndex.x(), theAbsorptionIndex.x()),
57 fresnelNormal (theRefractionIndex.y(), theAbsorptionIndex.y()),
58 fresnelNormal (theRefractionIndex.z(), theAbsorptionIndex.z()));
59
60 return Graphic3d_Fresnel (Graphic3d_FM_SCHLICK, aFresnel);
61}
62
bc73b006 63//=======================================================================
64//function : DumpJson
65//purpose :
66//=======================================================================
67void Graphic3d_Fresnel::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
68{
69 OCCT_DUMP_CLASS_BEGIN (theOStream, Graphic3d_Fresnel)
70
71 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myFresnelType)
72 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myFresnelData)
73}
74
05aa616d 75// =======================================================================
76// function : Graphic3d_BSDF
77// purpose :
78// =======================================================================
79Graphic3d_BSDF::Graphic3d_BSDF()
67312b79 80: Ks (Graphic3d_Vec3 (0.f), 1.f)
05aa616d 81{
82 FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
83 FresnelBase = Graphic3d_Fresnel::CreateConstant (1.f);
84}
85
86// =======================================================================
87// function : operator==
88// purpose :
89// =======================================================================
90bool Graphic3d_BSDF::operator== (const Graphic3d_BSDF& theOther) const
91{
92 return Kc == theOther.Kc
93 && Kd == theOther.Kd
94 && Kt == theOther.Kt
95 && Ks == theOther.Ks
96 && Le == theOther.Le
97 && Absorption == theOther.Absorption
98 && FresnelCoat == theOther.FresnelCoat
99 && FresnelBase == theOther.FresnelBase;
189f85a3 100}
101
102// =======================================================================
103// function : Normalize
104// purpose :
105// =======================================================================
106void Graphic3d_BSDF::Normalize()
107{
05aa616d 108 float aMax = 0.f;
109
110 for (int aChannelID = 0; aChannelID < 3; ++aChannelID)
111 {
112 aMax = std::max (aMax, Kd[aChannelID] + Ks[aChannelID] + Kt[aChannelID]);
113 }
189f85a3 114
115 if (aMax > 1.f)
116 {
05aa616d 117 for (int aChannelID = 0; aChannelID < 3; ++aChannelID)
118 {
119 Kd[aChannelID] /= aMax;
120 Ks[aChannelID] /= aMax;
121 Kt[aChannelID] /= aMax;
122 }
189f85a3 123 }
124}
125
126// =======================================================================
127// function : CreateDiffuse
128// purpose :
129// =======================================================================
130Graphic3d_BSDF Graphic3d_BSDF::CreateDiffuse (const Graphic3d_Vec3& theWeight)
131{
132 Graphic3d_BSDF aBSDF;
133
134 aBSDF.Kd = theWeight;
135
136 return aBSDF;
137}
138
139// =======================================================================
140// function : CreateMetallic
141// purpose :
142// =======================================================================
05aa616d 143Graphic3d_BSDF Graphic3d_BSDF::CreateMetallic (const Graphic3d_Vec3& theWeight, const Graphic3d_Fresnel& theFresnel, const float theRoughness)
189f85a3 144{
145 Graphic3d_BSDF aBSDF;
146
05aa616d 147 aBSDF.FresnelBase = theFresnel;
189f85a3 148
149 // Selecting between specular and glossy
150 // BRDF depending on the given roughness
05aa616d 151 aBSDF.Ks = Graphic3d_Vec4 (theWeight, theRoughness);
189f85a3 152
153 return aBSDF;
154}
155
156// =======================================================================
157// function : CreateTransparent
158// purpose :
159// =======================================================================
05aa616d 160Graphic3d_BSDF Graphic3d_BSDF::CreateTransparent (const Graphic3d_Vec3& theWeight,
161 const Graphic3d_Vec3& theAbsorptionColor,
162 const float theAbsorptionCoeff)
189f85a3 163{
164 Graphic3d_BSDF aBSDF;
165
05aa616d 166 // Create Fresnel parameters for the coat layer;
167 // set it to 0 value to simulate ideal refractor
168 aBSDF.FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
169
189f85a3 170 aBSDF.Kt = theWeight;
171
05aa616d 172 // Link reflection and transmission coefficients
173 aBSDF.Kc.r() = aBSDF.Kt.r();
174 aBSDF.Kc.g() = aBSDF.Kt.g();
175 aBSDF.Kc.b() = aBSDF.Kt.b();
189f85a3 176
05aa616d 177 aBSDF.Absorption = Graphic3d_Vec4 (theAbsorptionColor,
178 theAbsorptionCoeff);
189f85a3 179
180 return aBSDF;
181}
182
183// =======================================================================
184// function : CreateGlass
185// purpose :
186// =======================================================================
05aa616d 187Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
188 const Graphic3d_Vec3& theAbsorptionColor,
189 const float theAbsorptionCoeff,
190 const float theRefractionIndex)
189f85a3 191{
192 Graphic3d_BSDF aBSDF;
193
05aa616d 194 // Create Fresnel parameters for the coat layer
195 aBSDF.FresnelCoat = Graphic3d_Fresnel::CreateDielectric (theRefractionIndex);
196
189f85a3 197 aBSDF.Kt = theWeight;
198
05aa616d 199 aBSDF.Kc.r() = aBSDF.Kt.r();
200 aBSDF.Kc.g() = aBSDF.Kt.g();
201 aBSDF.Kc.b() = aBSDF.Kt.b();
189f85a3 202
05aa616d 203 aBSDF.Absorption = Graphic3d_Vec4 (theAbsorptionColor,
204 theAbsorptionCoeff);
189f85a3 205
206 return aBSDF;
67312b79 207}
208
209// =======================================================================
210// function : CreateMetallicRoughness
211// purpose :
212// =======================================================================
213Graphic3d_BSDF Graphic3d_BSDF::CreateMetallicRoughness (const Graphic3d_PBRMaterial& thePbr)
214{
215 const Graphic3d_Vec3 aDiff = (Graphic3d_Vec3 )thePbr.Color().GetRGB() * thePbr.Alpha();
216 const Standard_ShortReal aRougness2 = thePbr.NormalizedRoughness() * thePbr.NormalizedRoughness();
217
218 Graphic3d_BSDF aBsdf;
72f6dc61 219 aBsdf.Le = thePbr.Emission();
0858125f 220 if (thePbr.IOR() > 1.0f
221 && thePbr.Alpha() < 1.0f
222 && thePbr.Metallic() <= ShortRealEpsilon())
223 {
224 aBsdf.FresnelCoat = Graphic3d_Fresnel::CreateDielectric (thePbr.IOR());
225 aBsdf.Kt = Graphic3d_Vec3(1.0f);
226 aBsdf.Kc.r() = aBsdf.Kt.r();
227 aBsdf.Kc.g() = aBsdf.Kt.g();
228 aBsdf.Kc.b() = aBsdf.Kt.b();
229 aBsdf.Absorption.SetValues (thePbr.Color().GetRGB(), thePbr.Alpha() * 0.25f);
230 }
231 else
232 {
233 aBsdf.FresnelBase = Graphic3d_Fresnel::CreateSchlick (aDiff * thePbr.Metallic());
234 aBsdf.Ks.SetValues (Graphic3d_Vec3 (thePbr.Alpha()), aRougness2);
235 aBsdf.Kt = Graphic3d_Vec3 (1.0f - thePbr.Alpha());
236 aBsdf.Kd = aDiff * (1.0f - thePbr.Metallic());
237 }
238
67312b79 239 return aBsdf;
240}
bc73b006 241
242//=======================================================================
243//function : DumpJson
244//purpose :
245//=======================================================================
246void Graphic3d_BSDF::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
247{
248 OCCT_DUMP_CLASS_BEGIN (theOStream, Graphic3d_BSDF)
249
250 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Kc)
251 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Kd)
252 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Ks)
253 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Kt)
254 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Le)
255 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Absorption)
256
257 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &FresnelCoat)
258 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &FresnelBase)
259}