VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
standardMaterial.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis Lektauers on 11.10.2025.
5//
6#pragma once
7#include "material.h"
8
9namespace visutwin::canvas
10{
11 class Texture;
12
24 {
25 public:
27
28 void reset();
29
30 void updateUniforms(MaterialUniforms& uniforms) const override;
31 void getTextureSlots(std::vector<TextureSlot>& slots) const override;
32
33 // --- Diffuse ---
34 const Color& diffuse() const { return _diffuse; }
35 void setDiffuse(const Color& value) { _diffuse = value; }
36 Texture* diffuseMap() const { return _diffuseMap; }
37 void setDiffuseMap(Texture* texture) { _diffuseMap = texture; _dirtyShader = true; }
38
39 // --- Specular ---
40 const Color& specular() const { return _specular; }
41 void setSpecular(const Color& value) { _specular = value; }
42
43 // --- Metalness ---
44 float metalness() const { return _metalness; }
45 void setMetalness(const float value) { _metalness = value; }
46 bool useMetalness() const { return _useMetalness; }
47 void setUseMetalness(const bool value) { _useMetalness = value; _dirtyShader = true; }
48 Texture* metalnessMap() const { return _metalnessMap; }
49 void setMetalnessMap(Texture* texture) { _metalnessMap = texture; _dirtyShader = true; }
50
51 // --- Gloss / Roughness ---
52 float gloss() const { return _gloss; }
53 void setGloss(const float value) { _gloss = value; }
54 bool glossInvert() const { return _glossInvert; }
55 void setGlossInvert(const bool value) { _glossInvert = value; }
56 Texture* glossMap() const { return _glossMap; }
57 void setGlossMap(Texture* texture) { _glossMap = texture; _dirtyShader = true; }
58
59 // --- Emissive ---
60 const Color& emissive() const { return _emissive; }
61 void setEmissive(const Color& value) { _emissive = value; }
62 float emissiveIntensity() const { return _emissiveIntensity; }
63 void setEmissiveIntensity(const float value) { _emissiveIntensity = value; }
64 Texture* emissiveMap() const { return _emissiveMap; }
65 void setEmissiveMap(Texture* texture) { _emissiveMap = texture; _dirtyShader = true; }
66
67 // --- Normal ---
68 Texture* normalMap() const { return _normalMap; }
69 void setNormalMap(Texture* texture) { _normalMap = texture; _dirtyShader = true; }
70 float bumpiness() const { return _bumpiness; }
71 void setBumpiness(const float value) { _bumpiness = value; }
72
73 // --- Opacity ---
74 float opacity() const { return _opacity; }
75 void setOpacity(const float value) { _opacity = value; }
76 Texture* opacityMap() const { return _opacityMap; }
77 void setOpacityMap(Texture* texture) { _opacityMap = texture; _dirtyShader = true; }
78
79 // --- Height / Parallax ---
80 Texture* heightMap() const { return _heightMap; }
81 void setHeightMap(Texture* texture) { _heightMap = texture; _dirtyShader = true; }
82 float heightMapFactor() const { return _heightMapFactor; }
83 void setHeightMapFactor(const float value) { _heightMapFactor = value; }
84
85 // --- Anisotropy ---
86 float anisotropy() const { return _anisotropy; }
87 void setAnisotropy(const float value) { _anisotropy = value; _dirtyShader = true; }
88
89 // --- Transmission / Refraction ---
90 float transmissionFactor() const { return _transmissionFactor; }
91 void setTransmissionFactor(const float value) { _transmissionFactor = value; _dirtyShader = true; }
92 float refractionIndex() const { return _refractionIndex; }
93 void setRefractionIndex(const float value) { _refractionIndex = value; }
94 float thickness() const { return _thickness; }
95 void setThickness(const float value) { _thickness = value; }
96
97 // --- Ambient Occlusion ---
98 Texture* aoMap() const { return _aoMap; }
99 void setAoMap(Texture* texture) { _aoMap = texture; _dirtyShader = true; }
100
101 // --- Texture Transforms ---
102 const Vector2& diffuseMapTiling() const { return _diffuseMapTiling; }
103 void setDiffuseMapTiling(const Vector2& v) { _diffuseMapTiling = v; }
104 const Vector2& diffuseMapOffset() const { return _diffuseMapOffset; }
105 void setDiffuseMapOffset(const Vector2& v) { _diffuseMapOffset = v; }
106 float diffuseMapRotation() const { return _diffuseMapRotation; }
107 void setDiffuseMapRotation(float deg) { _diffuseMapRotation = deg; }
108
109 const Vector2& normalMapTiling() const { return _normalMapTiling; }
110 void setNormalMapTiling(const Vector2& v) { _normalMapTiling = v; }
111 const Vector2& normalMapOffset() const { return _normalMapOffset; }
112 void setNormalMapOffset(const Vector2& v) { _normalMapOffset = v; }
113 float normalMapRotation() const { return _normalMapRotation; }
114 void setNormalMapRotation(float deg) { _normalMapRotation = deg; }
115
116 const Vector2& metalnessMapTiling() const { return _metalnessMapTiling; }
117 void setMetalnessMapTiling(const Vector2& v) { _metalnessMapTiling = v; }
118 const Vector2& metalnessMapOffset() const { return _metalnessMapOffset; }
119 void setMetalnessMapOffset(const Vector2& v) { _metalnessMapOffset = v; }
120 float metalnessMapRotation() const { return _metalnessMapRotation; }
121 void setMetalnessMapRotation(float deg) { _metalnessMapRotation = deg; }
122
123 const Vector2& aoMapTiling() const { return _aoMapTiling; }
124 void setAoMapTiling(const Vector2& v) { _aoMapTiling = v; }
125 const Vector2& aoMapOffset() const { return _aoMapOffset; }
126 void setAoMapOffset(const Vector2& v) { _aoMapOffset = v; }
127 float aoMapRotation() const { return _aoMapRotation; }
128 void setAoMapRotation(float deg) { _aoMapRotation = deg; }
129
130 const Vector2& emissiveMapTiling() const { return _emissiveMapTiling; }
131 void setEmissiveMapTiling(const Vector2& v) { _emissiveMapTiling = v; }
132 const Vector2& emissiveMapOffset() const { return _emissiveMapOffset; }
133 void setEmissiveMapOffset(const Vector2& v) { _emissiveMapOffset = v; }
134 float emissiveMapRotation() const { return _emissiveMapRotation; }
135 void setEmissiveMapRotation(float deg) { _emissiveMapRotation = deg; }
136
137 // --- Rendering flags ---
138 bool useFog() const { return _useFog; }
139 void setUseFog(const bool value) { _useFog = value; _dirtyShader = true; }
140 bool useLighting() const { return _useLighting; }
141 void setUseLighting(const bool value) { _useLighting = value; _dirtyShader = true; }
142 bool useSkybox() const { return _useSkybox; }
143 void setUseSkybox(const bool value) { _useSkybox = value; _dirtyShader = true; }
144 bool twoSidedLighting() const { return _twoSidedLighting; }
145 void setTwoSidedLighting(const bool value) { _twoSidedLighting = value; _dirtyShader = true; }
146
147 // --- Planar Reflection ---
148 // DEVIATION: planar reflection is handled at the application level as a script.
149 // We promote it to a material property for simpler integration with the shader variant system.
150 Texture* reflectionMap() const { return _reflectionMap; }
151 void setReflectionMap(Texture* texture) { _reflectionMap = texture; _dirtyShader = true; }
152
153 // --- Clearcoat ---
154 // dual-layer clearcoat material (KHR_materials_clearcoat).
155 // A thin dielectric coat (IOR 1.5, F0=0.04) over the standard PBR base.
156 float clearCoat() const { return _clearCoat; }
157 void setClearCoat(const float value) { _clearCoat = value; _dirtyShader = true; }
158 float clearCoatGloss() const { return _clearCoatGloss; }
159 void setClearCoatGloss(const float value) { _clearCoatGloss = value; }
160 bool clearCoatGlossInvert() const { return _clearCoatGlossInvert; }
161 void setClearCoatGlossInvert(const bool value) { _clearCoatGlossInvert = value; }
162 float clearCoatBumpiness() const { return _clearCoatBumpiness; }
163 void setClearCoatBumpiness(const float value) { _clearCoatBumpiness = value; }
164 Texture* clearCoatMap() const { return _clearCoatMap; }
165 void setClearCoatMap(Texture* texture) { _clearCoatMap = texture; _dirtyShader = true; }
166 Texture* clearCoatGlossMap() const { return _clearCoatGlossMap; }
167 void setClearCoatGlossMap(Texture* texture) { _clearCoatGlossMap = texture; _dirtyShader = true; }
168 Texture* clearCoatNormalMap() const { return _clearCoatNormalMap; }
169 void setClearCoatNormalMap(Texture* texture) { _clearCoatNormalMap = texture; _dirtyShader = true; }
170
171 // --- Sheen (KHR_materials_sheen) ---
172 // fabric/velvet sheen layer (Charlie sheen BRDF).
173 const Color& sheenColor() const { return _sheenColor; }
174 void setSheenColor(const Color& value) { _sheenColor = value; _dirtyShader = true; }
175 float sheenRoughness() const { return _sheenRoughness; }
176 void setSheenRoughness(const float value) { _sheenRoughness = value; }
177 Texture* sheenMap() const { return _sheenMap; }
178 void setSheenMap(Texture* texture) { _sheenMap = texture; _dirtyShader = true; }
179
180 // --- Iridescence (KHR_materials_iridescence) ---
181 // thin-film interference layer.
182 float iridescenceIntensity() const { return _iridescenceIntensity; }
183 void setIridescenceIntensity(const float value) { _iridescenceIntensity = value; _dirtyShader = true; }
184 float iridescenceIOR() const { return _iridescenceIOR; }
185 void setIridescenceIOR(const float value) { _iridescenceIOR = value; }
186 float iridescenceThicknessMin() const { return _iridescenceThicknessMin; }
187 void setIridescenceThicknessMin(const float value) { _iridescenceThicknessMin = value; }
188 float iridescenceThicknessMax() const { return _iridescenceThicknessMax; }
189 void setIridescenceThicknessMax(const float value) { _iridescenceThicknessMax = value; }
190 Texture* iridescenceMap() const { return _iridescenceMap; }
191 void setIridescenceMap(Texture* texture) { _iridescenceMap = texture; _dirtyShader = true; }
192 Texture* iridescenceThicknessMap() const { return _iridescenceThicknessMap; }
193 void setIridescenceThicknessMap(Texture* texture) { _iridescenceThicknessMap = texture; _dirtyShader = true; }
194
195 // --- Spec-Gloss (KHR_materials_pbrSpecularGlossiness) ---
196 // alternative PBR parameterization (specular + glossiness).
197 const Color& specularColor() const { return _specularColor; }
198 void setSpecularColor(const Color& value) { _specularColor = value; }
199 float glossiness() const { return _glossiness; }
200 void setGlossiness(const float value) { _glossiness = value; }
201 Texture* specGlossMap() const { return _specGlossMap; }
202 void setSpecGlossMap(Texture* texture) { _specGlossMap = texture; _dirtyShader = true; }
203
204 // --- Detail Normals ---
205 // detail normal map overlay blended with primary normal.
206 float detailNormalScale() const { return _detailNormalScale; }
207 void setDetailNormalScale(const float value) { _detailNormalScale = value; }
208 Texture* detailNormalMap() const { return _detailNormalMap; }
209 void setDetailNormalMap(Texture* texture) { _detailNormalMap = texture; _dirtyShader = true; }
210 const TextureTransform& detailNormalTransform() const { return _detailNormalTransform; }
211 void setDetailNormalTransform(const TextureTransform& t) { _detailNormalTransform = t; }
212
213 // --- Displacement ---
214 // vertex displacement along normals.
215 float displacementScale() const { return _displacementScale; }
216 void setDisplacementScale(const float value) { _displacementScale = value; _dirtyShader = true; }
217 float displacementBias() const { return _displacementBias; }
218 void setDisplacementBias(const float value) { _displacementBias = value; }
219 Texture* displacementMap() const { return _displacementMap; }
220 void setDisplacementMap(Texture* texture) { _displacementMap = texture; _dirtyShader = true; }
221
222 // --- Oren-Nayar ---
223 // roughness-dependent diffuse model (alternative to Lambertian).
224 bool useOrenNayar() const { return _useOrenNayar; }
225 void setUseOrenNayar(const bool value) { _useOrenNayar = value; _dirtyShader = true; }
226
227 // when true, the material accumulates shadow factors and outputs
228 // them via multiplicative blending (LIT_SHADOW_CATCHER shader path).
229 bool shadowCatcher() const { return _shadowCatcher; }
230 void setShadowCatcher(const bool value) { _shadowCatcher = value; _dirtyShader = true; }
231
232 bool dirtyShader() const { return _dirtyShader; }
233 void clearDirtyShader() { _dirtyShader = false; }
234
235 private:
236 Color _diffuse = Color(1.0f, 1.0f, 1.0f, 1.0f);
237 Texture* _diffuseMap = nullptr;
238
239 Color _specular = Color(0.0f, 0.0f, 0.0f, 1.0f);
240
241 float _metalness = 0.0f;
242 bool _useMetalness = true;
243 Texture* _metalnessMap = nullptr;
244
245 float _gloss = 0.25f;
246 bool _glossInvert = false;
247 Texture* _glossMap = nullptr;
248
249 Color _emissive = Color(0.0f, 0.0f, 0.0f, 1.0f);
250 float _emissiveIntensity = 1.0f;
251 Texture* _emissiveMap = nullptr;
252
253 Texture* _normalMap = nullptr;
254 float _bumpiness = 1.0f;
255
256 float _opacity = 1.0f;
257 Texture* _opacityMap = nullptr;
258
259 Texture* _heightMap = nullptr;
260 float _heightMapFactor = 0.05f;
261
262 float _anisotropy = 0.0f;
263
264 float _transmissionFactor = 0.0f;
265 float _refractionIndex = 1.5f;
266 float _thickness = 0.0f;
267
268 Texture* _aoMap = nullptr;
269
270 // Per-map texture transforms.
271 Vector2 _diffuseMapTiling{1.0f, 1.0f};
272 Vector2 _diffuseMapOffset{0.0f, 0.0f};
273 float _diffuseMapRotation = 0.0f;
274
275 Vector2 _normalMapTiling{1.0f, 1.0f};
276 Vector2 _normalMapOffset{0.0f, 0.0f};
277 float _normalMapRotation = 0.0f;
278
279 Vector2 _metalnessMapTiling{1.0f, 1.0f};
280 Vector2 _metalnessMapOffset{0.0f, 0.0f};
281 float _metalnessMapRotation = 0.0f;
282
283 Vector2 _aoMapTiling{1.0f, 1.0f};
284 Vector2 _aoMapOffset{0.0f, 0.0f};
285 float _aoMapRotation = 0.0f;
286
287 Vector2 _emissiveMapTiling{1.0f, 1.0f};
288 Vector2 _emissiveMapOffset{0.0f, 0.0f};
289 float _emissiveMapRotation = 0.0f;
290
291 Texture* _reflectionMap = nullptr;
292
293 // clearcoat properties.
294 float _clearCoat = 0.0f;
295 float _clearCoatGloss = 1.0f;
296 bool _clearCoatGlossInvert = false;
297 float _clearCoatBumpiness = 1.0f;
298 Texture* _clearCoatMap = nullptr;
299 Texture* _clearCoatGlossMap = nullptr;
300 Texture* _clearCoatNormalMap = nullptr;
301
302 // sheen properties (KHR_materials_sheen).
303 Color _sheenColor = Color(0.0f, 0.0f, 0.0f, 1.0f);
304 float _sheenRoughness = 0.0f;
305 Texture* _sheenMap = nullptr;
306
307 // iridescence properties (KHR_materials_iridescence).
308 float _iridescenceIntensity = 0.0f;
309 float _iridescenceIOR = 1.3f;
310 float _iridescenceThicknessMin = 100.0f;
311 float _iridescenceThicknessMax = 400.0f;
312 Texture* _iridescenceMap = nullptr;
313 Texture* _iridescenceThicknessMap = nullptr;
314
315 // spec-gloss properties (KHR_materials_pbrSpecularGlossiness).
316 Color _specularColor = Color(1.0f, 1.0f, 1.0f, 1.0f);
317 float _glossiness = 1.0f;
318 Texture* _specGlossMap = nullptr;
319
320 // detail normal map properties.
321 float _detailNormalScale = 1.0f;
322 Texture* _detailNormalMap = nullptr;
323 TextureTransform _detailNormalTransform;
324
325 // displacement properties.
326 float _displacementScale = 0.0f;
327 float _displacementBias = 0.5f;
328 Texture* _displacementMap = nullptr;
329
330 // Oren-Nayar diffuse model toggle.
331 bool _useOrenNayar = false;
332
333 bool _useFog = true;
334 bool _useLighting = true;
335 bool _useSkybox = true;
336 bool _twoSidedLighting = false;
337 bool _shadowCatcher = false;
338
339 mutable bool _dirtyShader = true;
340 };
341}
void setDiffuseMap(Texture *texture)
void setDetailNormalTransform(const TextureTransform &t)
void setEmissive(const Color &value)
void getTextureSlots(std::vector< TextureSlot > &slots) const override
void setSheenRoughness(const float value)
const TextureTransform & detailNormalTransform() const
void setEmissiveMapTiling(const Vector2 &v)
void setShadowCatcher(const bool value)
void setEmissiveMap(Texture *texture)
void setOpacity(const float value)
void setDiffuseMapOffset(const Vector2 &v)
void setMetalnessMapTiling(const Vector2 &v)
void setAnisotropy(const float value)
void updateUniforms(MaterialUniforms &uniforms) const override
void setClearCoatMap(Texture *texture)
void setGlossInvert(const bool value)
void setIridescenceIOR(const float value)
void setSheenColor(const Color &value)
void setIridescenceThicknessMax(const float value)
void setHeightMap(Texture *texture)
void setDiffuseMapTiling(const Vector2 &v)
const Vector2 & aoMapTiling() const
void setClearCoatGloss(const float value)
void setClearCoatBumpiness(const float value)
void setNormalMapOffset(const Vector2 &v)
void setIridescenceMap(Texture *texture)
void setTwoSidedLighting(const bool value)
void setMetalnessMap(Texture *texture)
const Vector2 & metalnessMapOffset() const
void setThickness(const float value)
const Vector2 & aoMapOffset() const
void setUseLighting(const bool value)
void setDetailNormalMap(Texture *texture)
void setSpecGlossMap(Texture *texture)
void setSpecular(const Color &value)
void setEmissiveIntensity(const float value)
void setTransmissionFactor(const float value)
void setNormalMap(Texture *texture)
void setBumpiness(const float value)
void setGlossiness(const float value)
void setHeightMapFactor(const float value)
void setAoMapTiling(const Vector2 &v)
const Vector2 & emissiveMapOffset() const
void setClearCoatGlossInvert(const bool value)
const Vector2 & diffuseMapOffset() const
void setRefractionIndex(const float value)
const Vector2 & emissiveMapTiling() const
void setReflectionMap(Texture *texture)
void setSpecularColor(const Color &value)
void setClearCoatGlossMap(Texture *texture)
void setIridescenceIntensity(const float value)
void setOpacityMap(Texture *texture)
void setEmissiveMapOffset(const Vector2 &v)
void setUseMetalness(const bool value)
void setDetailNormalScale(const float value)
const Vector2 & metalnessMapTiling() const
void setDiffuse(const Color &value)
const Vector2 & normalMapOffset() const
void setMetalness(const float value)
void setAoMapOffset(const Vector2 &v)
void setClearCoatNormalMap(Texture *texture)
void setDisplacementScale(const float value)
const Vector2 & diffuseMapTiling() const
void setNormalMapTiling(const Vector2 &v)
void setUseOrenNayar(const bool value)
void setDisplacementMap(Texture *texture)
void setIridescenceThicknessMap(Texture *texture)
void setMetalnessMapOffset(const Vector2 &v)
const Vector2 & normalMapTiling() const
void setClearCoat(const float value)
void setIridescenceThicknessMin(const float value)
void setDisplacementBias(const float value)
GPU texture resource supporting 2D, cubemap, volume, and array formats with mipmap management.
Definition texture.h:57
RGBA color with floating-point components in [0, 1].
Definition color.h:18
2D vector for UV coordinates, screen positions, and 2D math.
Definition vector2.h:18