67312b79 |
1 | // Author: Ilya Khramov |
2 | // Copyright (c) 2019 OPEN CASCADE SAS |
3 | // |
4 | // This file is part of Open CASCADE Technology software library. |
5 | // |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
11 | // |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
14 | |
15 | #ifndef _Graphic3d_PBRMaterial_HeaderFile |
16 | #define _Graphic3d_PBRMaterial_HeaderFile |
17 | |
18 | #include <Image_PixMap.hxx> |
19 | #include <Graphic3d_BSDF.hxx> |
20 | #include <Graphic3d_Vec2.hxx> |
21 | #include <Graphic3d_Vec3.hxx> |
22 | #include <Graphic3d_Vec4.hxx> |
23 | #include <Quantity_Color.hxx> |
24 | |
25 | //! Class implementing Metallic-Roughness physically based material definition |
26 | class Graphic3d_PBRMaterial |
27 | { |
28 | public: |
29 | |
30 | //! Creates new physically based material in Metallic-Roughness system. |
31 | //! 'metallic' parameter is 0 by default. |
32 | //! 'roughness' parameter is 1 by default. |
33 | //! 'color' parameter is (0, 0, 0) by default. |
34 | //! 'alpha' parameter is 1 by default. |
35 | //! 'IOR' parameter is 1.5 by default. |
36 | //! 'emission' parameter is (0, 0, 0) by default. |
37 | Standard_EXPORT Graphic3d_PBRMaterial(); |
38 | |
39 | //! Creates new physically based material in Metallic-Roughness system from Graphic3d_BSDF. |
40 | Standard_EXPORT Graphic3d_PBRMaterial (const Graphic3d_BSDF& theBSDF); |
41 | |
42 | //! Returns material's metallic coefficient in [0, 1] range. |
43 | //! 1 for metals and 0 for dielectrics. |
44 | //! It is preferable to be exactly 0 or 1. Average values are needed for textures mixing in shader. |
45 | Standard_ShortReal Metallic() const { return myMetallic; } |
46 | |
47 | //! Modifies metallic coefficient of material in [0, 1] range. |
48 | Standard_EXPORT void SetMetallic (Standard_ShortReal theMetallic); |
49 | |
50 | //! Maps roughness from [0, 1] to [MinRoughness, 1] for calculations. |
51 | Standard_EXPORT static Standard_ShortReal Roughness(Standard_ShortReal theNormalizedRoughness); |
52 | |
53 | //! Returns real value of roughness in [MinRoughness, 1] range for calculations. |
54 | Standard_ShortReal Roughness() const { return Roughness(myRoughness); } |
55 | |
56 | //! Returns roughness mapping parameter in [0, 1] range. |
57 | //! Roughness is defined in [0, 1] for handful material settings |
58 | //! and is mapped to [MinRoughness, 1] for calculations. |
59 | Standard_ShortReal NormalizedRoughness() const { return myRoughness; } |
60 | |
61 | //! Modifies roughness coefficient of material in [0, 1] range. |
62 | Standard_EXPORT void SetRoughness (Standard_ShortReal theRoughness); |
63 | |
64 | //! Returns index of refraction in [1, 3] range. |
65 | Standard_ShortReal IOR() const { return myIOR; } |
66 | |
67 | //! Modifies index of refraction in [1, 3] range. |
68 | //! In practice affects only on non-metal materials reflection possibilities. |
69 | Standard_EXPORT void SetIOR (Standard_ShortReal theIOR); |
70 | |
71 | //! Returns albedo color with alpha component of material. |
72 | const Quantity_ColorRGBA& Color() const { return myColor; } |
73 | |
74 | //! Modifies albedo color with alpha component. |
75 | Standard_EXPORT void SetColor (const Quantity_ColorRGBA& theColor); |
76 | |
77 | //! Modifies only albedo color. |
78 | Standard_EXPORT void SetColor (const Quantity_Color& theColor); |
79 | |
80 | //! Returns alpha component in range [0, 1]. |
81 | Standard_ShortReal Alpha() const { return myColor.Alpha(); }; |
82 | |
83 | //! Modifies alpha component. |
84 | Standard_EXPORT void SetAlpha (Standard_ShortReal theAlpha); |
85 | |
86 | //! Returns light intensity emitted by material. |
87 | //! Values are greater or equal 0. |
88 | Graphic3d_Vec3 Emission() const { return myEmission; } |
89 | |
90 | //! Modifies light intensity emitted by material. |
91 | Standard_EXPORT void SetEmission (const Graphic3d_Vec3& theEmission); |
92 | |
93 | //! Generates material in Metallic-Roughness system from Graphic3d_BSDF. |
94 | Standard_EXPORT void SetBSDF (const Graphic3d_BSDF& theBSDF); |
95 | |
96 | public: |
97 | |
98 | //! PBR materials comparison operator. |
99 | Standard_Boolean operator== (const Graphic3d_PBRMaterial& theOther) const |
100 | { |
101 | return (myMetallic == theOther.myMetallic) |
102 | && (myRoughness == theOther.myRoughness) |
103 | && (myIOR == theOther.myIOR) |
104 | && (myColor == theOther.myColor) |
105 | && (myEmission == theOther.myEmission); |
106 | } |
107 | |
108 | public: |
109 | |
110 | //! Generates 2D look up table of scale and bias for fresnell zero coefficient. |
111 | //! It is needed for calculation reflectance part of environment lighting. |
112 | //! @param [out] theLUT table storage (must be Image_Format_RGF). |
113 | //! @param [in] theIntegralSamplesCount number of importance samples in hemisphere integral calculation for every table item. |
114 | Standard_EXPORT static void GenerateEnvLUT (const Handle(Image_PixMap)& theLUT, |
115 | unsigned int theNbIntegralSamples = 1024); |
116 | |
117 | //! Compute material roughness from common material (specular color + shininess). |
118 | //! @param theSpecular [in] specular color |
119 | //! @param theShiness [in] normalized shininess coefficient within [0..1] range |
120 | //! @return roughness within [0..1] range |
121 | Standard_EXPORT static Standard_ShortReal RoughnessFromSpecular (const Quantity_Color& theSpecular, |
122 | const Standard_Real theShiness); |
123 | |
124 | //! Compute material metallicity from common material (specular color). |
125 | //! @param theSpecular [in] specular color |
126 | //! @return metallicity within [0..1] range |
127 | static Standard_ShortReal MetallicFromSpecular (const Quantity_Color& theSpecular) |
128 | { |
129 | return ((Graphic3d_Vec3 )theSpecular).maxComp(); |
130 | } |
131 | |
132 | public: |
133 | |
134 | //! Roughness cannot be 0 in real calculations, so it returns minimal achievable level of roughness in practice |
135 | static Standard_ShortReal MinRoughness() { return 0.01f; } |
136 | |
137 | public: |
138 | |
139 | //! Shows how much times less samples can be used in certain roughness value specular IBL map generation |
140 | //! in compare with samples number for map with roughness of 1. |
141 | //! Specular IBL maps with less roughness values have higher resolution but require less samples for the same quality of baking. |
142 | //! So that reducing samples number is good strategy to improve performance of baking. |
143 | //! The samples number for specular IBL map with roughness of 1 (the maximum possible samples number) is expected to be defined as baking parameter. |
144 | //! Samples number for other roughness values can be calculated by multiplication origin samples number by this factor. |
145 | //! @param theProbability value from 0 to 1 controlling strength of samples reducing. |
146 | //! Bigger values result in slower reduction to provide better quality but worse performance. |
147 | //! Value of 1 doesn't affect at all so that 1 will be returned (it can be used to disable reduction strategy). |
148 | //! @param theRoughness roughness value of current generated specular IBL map (from 0 to 1). |
149 | //! @return factor to calculate number of samples for current specular IBL map baking. |
150 | //! Be aware! It has no obligation to return 1 in case of roughness of 1. |
151 | //! Be aware! It produces poor quality with small number of origin samples. In that case it is recommended to be disabled. |
152 | Standard_EXPORT static Standard_ShortReal SpecIBLMapSamplesFactor (Standard_ShortReal theProbability, |
153 | Standard_ShortReal theRoughness); |
154 | |
bc73b006 |
155 | //! Dumps the content of me into the stream |
156 | Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; |
157 | |
67312b79 |
158 | private: |
159 | |
160 | //! Calculates geometry factor of Cook-Torrance BRDF using Smith formula. |
161 | static Standard_ShortReal lutGenGeometryFactor (Standard_ShortReal theCosL, |
162 | Standard_ShortReal theCosV, |
163 | Standard_ShortReal theRoughness); |
164 | |
165 | //! Generates quasi-random point from Hammersley set. |
166 | //! @param theNumber number of point |
167 | //! @param theCount size of Hammersley set |
168 | static Graphic3d_Vec2 lutGenHammersley (unsigned int theNumber, unsigned int theCount); |
169 | |
170 | //! Generates only cosine theta of direction in spherical coordinates system |
171 | //! according to micro facet distribution function from Cook-Torrance BRDF. |
172 | static Standard_ShortReal lutGenImportanceSampleCosTheta (Standard_ShortReal theHammerslayPointComponent, |
173 | Standard_ShortReal theRoughness); |
174 | |
175 | //! Generates direction using point from Hammersley set |
176 | //! according to micro facet distribution function from Cook-Torrance BRDF. |
177 | static Graphic3d_Vec3 lutGenImportanceSample (const Graphic3d_Vec2 &theHammerslayPoint, |
178 | Standard_ShortReal theRoughness); |
179 | |
180 | //! Generates vector using cosine of angle between up vector (normal in hemisphere) |
181 | //! and desired vector. |
182 | //! x component for resulting vector will be zero. |
183 | static Graphic3d_Vec3 lutGenView (Standard_ShortReal theCosV); |
184 | |
185 | //! Returns reflected vector according axis. |
186 | //! @param theVector vector is needed to be reflected. |
187 | //! @param theAxis axis of reflection. |
188 | static Graphic3d_Vec3 lutGenReflect (const Graphic3d_Vec3 &theVector, |
189 | const Graphic3d_Vec3 &theAxis); |
190 | |
191 | private: |
192 | |
193 | Quantity_ColorRGBA myColor; //!< albedo color with alpha component [0, 1] |
194 | Standard_ShortReal myMetallic; //!< metallic coefficient of material [0, 1] |
195 | Standard_ShortReal myRoughness; //!< roughness coefficient of material [0, 1] |
196 | Graphic3d_Vec3 myEmission; //!< light intensity emitted by material [>= 0] |
197 | Standard_ShortReal myIOR; //!< index of refraction [1, 3] |
198 | |
199 | }; |
200 | |
201 | #endif // _Graphic3d_PBRMaterial_HeaderFile |