0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[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
18#include <algorithm>
19
20// =======================================================================
21// function : Serialize
22// purpose :
23// =======================================================================
24Graphic3d_Vec4 Graphic3d_Fresnel::Serialize() const
25{
26 Graphic3d_Vec4 aData = Graphic3d_Vec4 (myFresnelData, 0.f);
27
28 if (myFresnelType != Graphic3d_FM_SCHLICK)
29 {
05aa616d 30 aData.x() = -static_cast<float> (myFresnelType);
189f85a3 31 }
32
33 return aData;
34}
35
36// =======================================================================
37// function : fresnelNormal
38// purpose :
39// =======================================================================
05aa616d 40inline float fresnelNormal (float theN,
41 float theK)
189f85a3 42{
43 return ((theN - 1.f) * (theN - 1.f) + theK * theK) /
44 ((theN + 1.f) * (theN + 1.f) + theK * theK);
45}
46
47// =======================================================================
48// function : CreateConductor
49// purpose :
50// =======================================================================
51Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theRefractionIndex,
52 const Graphic3d_Vec3& theAbsorptionIndex)
53{
05aa616d 54 const Graphic3d_Vec3 aFresnel (fresnelNormal (theRefractionIndex.x(), theAbsorptionIndex.x()),
55 fresnelNormal (theRefractionIndex.y(), theAbsorptionIndex.y()),
56 fresnelNormal (theRefractionIndex.z(), theAbsorptionIndex.z()));
57
58 return Graphic3d_Fresnel (Graphic3d_FM_SCHLICK, aFresnel);
59}
60
61// =======================================================================
62// function : Graphic3d_BSDF
63// purpose :
64// =======================================================================
65Graphic3d_BSDF::Graphic3d_BSDF()
66{
67 FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
68 FresnelBase = Graphic3d_Fresnel::CreateConstant (1.f);
69}
70
71// =======================================================================
72// function : operator==
73// purpose :
74// =======================================================================
75bool Graphic3d_BSDF::operator== (const Graphic3d_BSDF& theOther) const
76{
77 return Kc == theOther.Kc
78 && Kd == theOther.Kd
79 && Kt == theOther.Kt
80 && Ks == theOther.Ks
81 && Le == theOther.Le
82 && Absorption == theOther.Absorption
83 && FresnelCoat == theOther.FresnelCoat
84 && FresnelBase == theOther.FresnelBase;
189f85a3 85}
86
87// =======================================================================
88// function : Normalize
89// purpose :
90// =======================================================================
91void Graphic3d_BSDF::Normalize()
92{
05aa616d 93 float aMax = 0.f;
94
95 for (int aChannelID = 0; aChannelID < 3; ++aChannelID)
96 {
97 aMax = std::max (aMax, Kd[aChannelID] + Ks[aChannelID] + Kt[aChannelID]);
98 }
189f85a3 99
100 if (aMax > 1.f)
101 {
05aa616d 102 for (int aChannelID = 0; aChannelID < 3; ++aChannelID)
103 {
104 Kd[aChannelID] /= aMax;
105 Ks[aChannelID] /= aMax;
106 Kt[aChannelID] /= aMax;
107 }
189f85a3 108 }
109}
110
111// =======================================================================
112// function : CreateDiffuse
113// purpose :
114// =======================================================================
115Graphic3d_BSDF Graphic3d_BSDF::CreateDiffuse (const Graphic3d_Vec3& theWeight)
116{
117 Graphic3d_BSDF aBSDF;
118
119 aBSDF.Kd = theWeight;
120
121 return aBSDF;
122}
123
124// =======================================================================
125// function : CreateMetallic
126// purpose :
127// =======================================================================
05aa616d 128Graphic3d_BSDF Graphic3d_BSDF::CreateMetallic (const Graphic3d_Vec3& theWeight, const Graphic3d_Fresnel& theFresnel, const float theRoughness)
189f85a3 129{
130 Graphic3d_BSDF aBSDF;
131
05aa616d 132 aBSDF.FresnelBase = theFresnel;
189f85a3 133
134 // Selecting between specular and glossy
135 // BRDF depending on the given roughness
05aa616d 136 aBSDF.Ks = Graphic3d_Vec4 (theWeight, theRoughness);
189f85a3 137
138 return aBSDF;
139}
140
141// =======================================================================
142// function : CreateTransparent
143// purpose :
144// =======================================================================
05aa616d 145Graphic3d_BSDF Graphic3d_BSDF::CreateTransparent (const Graphic3d_Vec3& theWeight,
146 const Graphic3d_Vec3& theAbsorptionColor,
147 const float theAbsorptionCoeff)
189f85a3 148{
149 Graphic3d_BSDF aBSDF;
150
05aa616d 151 // Create Fresnel parameters for the coat layer;
152 // set it to 0 value to simulate ideal refractor
153 aBSDF.FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
154
189f85a3 155 aBSDF.Kt = theWeight;
156
05aa616d 157 // Link reflection and transmission coefficients
158 aBSDF.Kc.r() = aBSDF.Kt.r();
159 aBSDF.Kc.g() = aBSDF.Kt.g();
160 aBSDF.Kc.b() = aBSDF.Kt.b();
189f85a3 161
05aa616d 162 aBSDF.Absorption = Graphic3d_Vec4 (theAbsorptionColor,
163 theAbsorptionCoeff);
189f85a3 164
165 return aBSDF;
166}
167
168// =======================================================================
169// function : CreateGlass
170// purpose :
171// =======================================================================
05aa616d 172Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
173 const Graphic3d_Vec3& theAbsorptionColor,
174 const float theAbsorptionCoeff,
175 const float theRefractionIndex)
189f85a3 176{
177 Graphic3d_BSDF aBSDF;
178
05aa616d 179 // Create Fresnel parameters for the coat layer
180 aBSDF.FresnelCoat = Graphic3d_Fresnel::CreateDielectric (theRefractionIndex);
181
189f85a3 182 aBSDF.Kt = theWeight;
183
05aa616d 184 aBSDF.Kc.r() = aBSDF.Kt.r();
185 aBSDF.Kc.g() = aBSDF.Kt.g();
186 aBSDF.Kc.b() = aBSDF.Kt.b();
189f85a3 187
05aa616d 188 aBSDF.Absorption = Graphic3d_Vec4 (theAbsorptionColor,
189 theAbsorptionCoeff);
189f85a3 190
191 return aBSDF;
192}