forked from google/filament
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Materials.md.html
1519 lines (1176 loc) · 63.3 KB
/
Materials.md.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<meta charset="utf-8">
<style>img { max-width: 100%; }</style>
**Filament Materials**
Crafting physically-based materials
![](images/filament_logo.png)
# Overview
Filament is a physically based rendering (PBR) engine for Android. Filament offers a customizable
material system that you can use to create both simple and complex materials. This document
describes all the features available to materials and how to create your own material.
## Core concepts
Material
: A material defines the visual appearance of a surface. To completely describe and render a
surface, a material provides the following information:
- Material model
- Set of use-controllable named parameters
- Raster state (blending mode, backface culling, etc.)
- Vertex shader code
- Fragment shader code
Material model
: Also called _shading model_ or _lighting model_, the material model defines the intrinsic
properties of a surface. These properties have a direct influence on the way lighting is
computed and therefore on the appearance of a surface.
Material definition
: A text file that describes all the information required by a material. This is the file that you
will directly author to create new materials.
Material package
: At runtime, materials are loaded from _material packages_ compiled from material definitions
using the `matc` tool. A material package contains all the information required to describe a
material, and shaders generated for the target runtime platforms. This is necessary because
different platforms (Android, macOS, Linux, etc.) use different graphics APIs or different
variants of similar graphics APIs (OpenGL vs OpenGL ES for instance).
Material instance
: A material instance is a reference to a material and a set of values for the different values of
that material. Material instances are not covered in this document as they are created and
manipulated directly from code using Filament's APIs.
# Material models
Filament materials can use one of the following material models:
- Lit (or standard)
- Subsurface
- Cloth
- Unlit
## Lit model
The lit model is Filament's standard material model. This physically-based shading model was
designed after to offer good interoperability with other common tools and engines such as _Unity 5_,
_Unreal Engine 4_, _Substance Designer_ or _Marmoset Toolbag_.
This material model can be used to describe a large number of non-metallic surfaces (_dielectrics_)
or metallic surfaces (_conductors_).
The appearance of a material using the standard model is controlled using the properties described
in table [standardProperties].
Property | Definition
-----------------------:|:---------------------
**baseColor** | Diffuse albedo for non-metallic surfaces, and specular color for metallic surfaces
**metallic** | Whether a surface appears to be dielectric (0.0) or conductor (1.0). Often used as a binary value (0 or 1)
**roughness** | Perceived smoothness (1.0) or roughness (0.0) of a surface. Smooth surfaces exhibit sharp reflections
**reflectance** | Fresnel reflectance at normal incidence for dielectric surfaces. This directly controls the strength of the reflections
**clearCoat** | Strength of the clear coat layer
**clearCoatRoughness** | Perceived smoothness or roughness of the clear coat layer
**anisotropy** | Amount of anisotropy in either the tangent or bitangent direction
**anisotropyDirection** | Local surface direction
**ambientOcclusion** | Defines how much of the ambient light is accessible to a surface point. It is a per-pixel shadowing factor between 0.0 and 1.0
**normal** | A detail normal used to perturb the surface using _bump mapping_ (_normal mapping_)
**emissive** | Additional diffuse albedo to simulate emissive surfaces (such as neons, etc.) This property is mostly useful in an HDR pipeline with a bloom pass
[Table [standardProperties]: Properties of the standard model]
The type and range of each property is described in table [standardPropertiesTypes].
Property | Type | Range | Note
-----------------------:|:--------:|:------------------------:|:-------------------------
**baseColor** | float4 | [0..1] | Pre-multiplied linear RGB
**metallic** | float | [0..1] | Should be 0 or 1
**roughness** | float | [0..1] |
**reflectance** | float | [0..1] | Prefer values > 0.35
**clearCoat** | float | [0..1] | Should be 0 or 1
**clearCoatRoughness** | float | [0..1] | Remaps to [0..0.6]
**anisotropy** | float | [-1..1] | Anisotropy is in the tangent direction when this value is positive
**anisotropyDirection** | float3 | [0..1] | Linear RGB, encodes a direction vector in tangent space
**ambientOcclusion** | float | [0..1] |
**normal** | float3 | [0..1] | Linear RGB, encodes a direction vector in tangent space
**emissive** | float4 | rgb=[0..1], a=[-n..n] | Alpha is the exposure compensation
[Table [standardPropertiesTypes]: Range and type of the standard model's properties]
!!! Note: About linear RGB
Several material model properties expect RGB colors. Filament materials use RGB colors in linear
space and you must take proper care of supplying colors in that space. See the Linear colors
section for more information.
!!! Note: About pre-multiplied RGB
Filament materials expect colors to use pre-multiplied alpha. See the Pre-multiplied alpha
section for more information.
### Base color
The `baseColor` property defines the perceived color of an object (sometimes called albedo). The
effect of `baseColor` depends on the nature of the surface, controlled by the `metallic` property
explained in the Metallic section.
Non-metals (dielectrics)
: Defines the diffuse color of the surface. Real-world values are typically found in the range
$[10..240]$ if the value is encoded between 0 and 255, or in the range $[0.04..0.94]$ between 0
and 1. Several examples of base colors for non-metallic surfaces can be found in
table [baseColorsDielectrics].
Metal | sRGB | Hexadecimal | Color
----------:|:-------------------:|:------------:|-------------------------------------------------------
Coal | 0.19, 0.19, 0.19 | #323232 | <div style="background-color: #323232; width: 60px"> </div>
Rubber | 0.21, 0.21, 0.21 | #353535 | <div style="background-color: #353535; width: 60px"> </div>
Mud | 0.33, 0.24, 0.19 | #553d31 | <div style="background-color: #875c3c; width: 60px"> </div>
Wood | 0.53, 0.36, 0.24 | #875c3c | <div style="background-color: #c4c6c6; width: 60px"> </div>
Vegetation | 0.48, 0.51, 0.31 | #7b824e | <div style="background-color: #7b824e; width: 60px"> </div>
Brick | 0.58, 0.49, 0.46 | #947d75 | <div style="background-color: #947d75; width: 60px"> </div>
Sand | 0.69, 0.66, 0.52 | #b1a884 | <div style="background-color: #b1a884; width: 60px"> </div>
Concrete | 0.75, 0.75, 0.73 | #c0bfbb | <div style="background-color: #c0bfbb; width: 60px"> </div>
[Table [baseColorsDielectrics]: `baseColor` for common non-metals]
Metals (conductors)
: Defines the specular color of the surface. Real-world values are typically found in the range
$[170..255]$ if the value is encoded between 0 and 255, or in the range $[0.66..1.0]$ between 0 and
1. Several examples of base colors for metallic surfaces can be found in table [baseColorsConductors].
Metal | sRGB | Hexadecimal | Color
----------:|:-------------------:|:------------:|-------------------------------------------------------
Silver | 0.98, 0.98, 0.96 | #faf9f5 | <div style="background-color: #faf9f5; width: 60px"> </div>
Aluminum | 0.96, 0.96, 0.96 | #f4f5f5 | <div style="background-color: #f4f5f5; width: 60px"> </div>
Titanium | 0.81, 0.78, 0.76 | #cec8c2 | <div style="background-color: #cec8c2; width: 60px"> </div>
Iron | 0.76, 0.74, 0.73 | #c0bdba | <div style="background-color: #c0bdba; width: 60px"> </div>
Platinum | 0.84, 0.82, 0.79 | #d6d1c8 | <div style="background-color: #d6d1c8; width: 60px"> </div>
Gold | 1.00, 0.87, 0.62 | #fedc9d | <div style="background-color: #fedc9d; width: 60px"> </div>
Brass | 0.96, 0.89, 0.68 | #f4e4ad | <div style="background-color: #f4e4ad; width: 60px"> </div>
Copper | 0.98, 0.85, 0.72 | #fbd8b8 | <div style="background-color: #fbd8b8; width: 60px"> </div>
[Table [baseColorsConductors]: `baseColor` for common metals]
### Metallic
The `metallic` property defines whether the surface is a metallic (_conductor_) or a non-metallic
(_dielectric_) surface. This property should be used as a binary value, set to either 0 or 1.
Intermediate values are only truly useful to create transitions between different types of surfaces
when using textures.
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
(reflected light takes on the color of the surfaced as defined by `baseColor`).
The effect of `metallic` is shown in figure [metallicProperty] (click on the image to see a
larger version).
![Figure [metallicProperty]: `metallic` varying from 0.0
(left) to 1.0 (right)](images/materials/metallic.png)
### Roughness
The `roughness` property controls the perceived smoothness of the surface. When `roughness` is set
to 0, the surface is perfectly smooth and highly glossy. The rougher a surface is, the "blurrier"
the reflections are. This property is often called _glossiness_ in other engines and tools, and is
simply the opposite of the roughness (`roughness = 1 - glossiness`).
### Non-metals
The effect of `roughness` on non-metallic surfaces is shown in figure [roughnessProperty] (click
on the image to see a larger version).
![Figure [roughnessProperty]: Dielectric `roughness` varying from 0.0
(left) to 1.0 (right)](images/materials/dielectric_roughness.png)
### Metals
The effect of `roughness` on metallic surfaces is shown in figure [roughnessConductorProperty]
(click on the image to see a larger version).
![Figure [roughnessConductorProperty]: Conductor `roughness` varying from 0.0
(left) to 1.0 (right)](images/materials/conductor_roughness.png)
### Reflectance
The `reflectance` property only affects non-metallic surfaces. This property can be used to control
the specular intensity. This value is defined between 0 and 1 and represents a remapping of a
percentage of reflectance. For instance, the default value of 0.5 corresponds to a reflectance of
4%. Values below 0.35 (2% reflectance) should be avoided as no real-world materials have such
low reflectance.
The effect of `reflectance` on non-metallic surfaces is shown in figure [reflectanceProperty]
(click on the image to see a larger version).
![Figure [reflectanceProperty]: `reflectance` varying from 0.0 (left)
to 1.0 (right)](images/materials/reflectance.png)
Figure [reflectance] shows common values and how they relate to the mapping function.
![Figure [reflectance]: Common reflectance values](images/diagram_reflectance.png)
Table [commonMatReflectance] describes acceptable reflectance values for various types of materials
(no real world material has a value under 2%).
Material | Reflectance | Property value
--------------------------:|:---------------------:|:------------------
Glass | 3.5% | 0.46
Water | 2% | 0.35
Common liquids | 2% to 4% | 0.35 to 0.5
Common gemstones | 8% to 16% | 0.70 to 1.0
Other dielectric materials | 2% to 5% | 0.35 to 0.56
Default value | 4% | 0.50
[Table [commonMatReflectance]: Reflectance of common materials]
### Clear coat
Multi-layer materials are fairly common, particularly materials with a thin translucent
layer over a base layer. Real world examples of such materials include car paints, soda cans,
lacquered wood and acrylic.
The `clearCoat` property can be used to describe materials with two layers. The clear coat layer
will always be isotropic and dielectric.
![Figure [clearCoat]: Comparison of a carbon-fiber material under the standard material model
(left) and the clear coat model (right)](images/material_carbon_fiber.png)
The `clearCoat` property controls the strength of the clear coat layer. This should be treated as a
binary value, set to either 0 or 1. Intermediate values are useful to control transitions between
parts of the surface that have a clear coat layers and parts that don't.
The effect of `clearCoat` on a rough metal is shown in figure [clearCoatProperty]
(click on the image to see a larger version).
![Figure [clearCoatProperty]: `clearCoat` varying from 0.0
(left) to 1.0 (right)](images/materials/clear_coat.png)
!!! Warning
The clear coat layer effectively doubles the cost of specular computations. Do not assign a
value, even 0.0, to the clear coat property if you don't need this second layer.
### Clear coat roughness
The `clearCoatRoughness` property is similar to the `roughness` property but applies only to the
clear coat layer. In addition, since clear coat layers are never completely rough, the value between
0 and 1 is remapped internally to an actual roughness of 0 to 0.6.
The effect of `clearCoatRoughness` on a rough metal is shown in figure [clearCoatRoughnessProperty]
(click on the image to see a larger version).
![Figure [clearCoatRoughnessProperty]: `clearCoatRoughness` varying from 0.0
(left) to 1.0 (right)](images/materials/clear_coat_roughness.png)
### Anisotropy
Many real-world materials, such as brushed metal, can only be replicated using an anisotropic
reflectance model. A material can be changed from the default isotropic model to an anisotropic
model by using the `anisotropy` property.
![Figure [anisotropic]: Comparison of isotropic material
(left) and anistropic material (right)](images/material_anisotropic.png)
The effect of `anisotropy` on a rough metal is shown in figure [anisotropyProperty]
(click on the image to see a larger version).
![Figure [anisotropyProperty]: `anisotropy` varying from 0.0
(left) to 1.0 (right)](images/materials/anisotropy.png)
The figure [anisotropyDir] below shows how the direction of the anisotropic highlights can be
controlled by using either positive or negative values: positive values define anisotropy in the
tangent direction and negative values in the bitangent direction.
![Figure [anisotropyDir]: Positive (left) vs negative
(right) `anisotropy` values](images/screenshot_anisotropy_direction.png)
!!! Tip
The anisotropic material model is slightly more expensive than the standard material model. Do
not assign a value (even 0.0) to the `anisotropy` property if you don't need anisotropy.
### Anisotropy direction
The `anisotropyDirection` property defines the direction of the surface at a given point and thus
control the shape of the specular highlights. It is specified as vector of 3 values that usually
come from a texture, encoding the directions local to the surface.
The effect of `anisotropyDirection` on a metal is shown in figure [anisotropyDirectionProperty]
(click on the image to see a larger version).
![Figure [anisotropyDirectionProperty]: Anisotropic metal rendered
with a direction map](images/screenshot_anisotropy.png)
The result shown in figure [anisotropyDirectionProperty] was obtained using the direction map shown
in figure [anisotropyDirectionProperty].
![Figure [anisotropyDirectionProperty]: Example of a direction map](images/screenshot_anisotropy_map.jpg)
### Ambient occlusion
The `ambientOcclusion` property defines how much of the ambient light is accessible to a surface
point. It is a per-pixel shadowing factor between 0.0 (fully shadowed) and 1.0 (fully lit). This
property only affects diffuse indirect lighting (image-based lighting), not direct lights such as
directional, point and spot lights, nor specular lighting.
![Figure [aoExample]: Comparison of materials without diffuse ambient occlusion
(left) and with (right)](images/screenshot_ao.jpg)
### Normal
The `normal` property defines the normal of the surface at a given point. It usually comes from a
_normal map_ texture, which allows to vary the property per-pixel. The normal is supplied in tangent
space, which means that +Z points outside of the surface.
For example, let's imagine that we want to render a piece of furniture covered in tufted leather.
Modeling the geometry to accurately represent the tufted pattern would require too many triangles
so we instead bake a high-poly mesh into a normal map. Once the base map is applied to a simplified
mesh, we get the result in figure [normalMapped].
Note that the `normal` property affects the _base layer_ and not the clear coat layer.
![Figure [normalMapped]: Low-poly mesh without normal mapping (left)
and with (right)](images/screenshot_normal_mapping.jpg)
!!! Warning
Using a normal map increases the runtime cost of the material model.
### Emissive
The `emissive` property can be used to simulate additional light emitted by the surface. It is
defined as a `float4` value that contains an RGB color (in linear space) as well as an exposure
compensation value (in the alpha channel).
Even though an exposure value actually indicates combinations of camera settings, it is often used
by photographers to describe light intensity. This is why cameras let photographers apply an
exposure compensation to over or under-expose an image. This setting can be used for artistic
control but also to achieve proper exposure (snow for instance will be exposed for as
18% middle-grey).
The exposure compensation value of the emissive property can be used to force the emissive color
to be brighter (positive values) or darker (negative values) than the current exposure. If the bloom
effect is enabled, using a positive exposure compensation can force the surface to bloom.
## Subsurface model
### Thickness
### Subsurface color
### Subsurface power
## Cloth model
All the material models described previously are designed to simulate dense surfaces, both at a
macro and at a micro level. Clothes and fabrics are however often made of loosely connected threads
that absorb and scatter incident light. When compared to hard surfaces, cloth is characterized by
a softer specular lob with a large falloff and the presence of fuzz lighting, caused by
forward/backward scattering. Some fabrics also exhibit two-tone specular colors
(velvets for instance).
Figure [materialCloth] shows how the standard material model fails to capture the appearance of a
sample of denim fabric. The surface appears rigid (almost plastic-like), more similar to a tarp
than a piece of clothing. This figure also shows how important the softer specular lobe caused by
absorption and scattering is to the faithful recreation of the fabric.
![Figure [materialCloth]: Comparison of denim fabric rendered using the standard model
(left) and the cloth model (right)](images/screenshot_cloth.png)
Velvet is an interesting use case for a cloth material model. As shown in figure [materialVelvet]
this type of fabric exhibits strong rim lighting due to forward and backward scattering. These
scattering events are caused by fibers standing straight at the surface of the fabric. When the
incident light comes from the direction opposite to the view direction, the fibers will forward
scatter the light. Similarly, when the incident light from from the same direction as the view
direction, the fibers will scatter the light backward.
![Figure [materialVelvet]: Velvet fabric showcasing forward and
backward scattering](images/screenshot_cloth_velvet.png)
It is important to note that there are types of fabrics that are still best modeled by hard surface
material models. For instance, leather, silk and satin can be recreated using the standard or
anisotropic material models.
The cloth material model encompasses all the parameters previously defined for the standard
material mode except for _metallic_ and _reflectance_. Two extra parameters described in
table [clothProperties] are also available.
Parameter | Definition
---------------------:|:---------------------
**sheenColor** | Specular tint to create two-tone specular fabrics (defaults to $\sqrt{baseColor}$)
**subsurfaceColor** | Tint for the diffuse color after scattering and absorption through the material
[Table [clothProperties]: Cloth model parameters]
The type and range of each property is described in table [clothPropertiesTypes].
Property | Type | Range | Note
---------------------:|:--------:|:------------------------:|:-------------------------
**sheenColor** | float3 | [0..1] | Linear RGB
**subsurfaceColor** | float3 | [0..1] | Linear RGB
[Table [clothPropertiesTypes]: Range and type of the cloth model's properties]
To create a velvet-like material, the base color can be set to black (or a dark color).
Chromaticity information should instead be set on the sheen color. To create more common fabrics
such as denim, cotton, etc. use the base color for chromaticity and use the default sheen color
or set the sheen color to the luminance of the base color.
!!! Warning
The cloth material model is more expensive than the standard material model.
!!! Tip
To see the effect of the `roughness` parameter make sure the `sheenColor` is brighter than
`baseColor`. This can be used to create a fuzz effect. Taking the luminance of `baseColor`
as the `sheenColor` will produce a fairly natural effect that works for common cloth. A dark
`baseColor` combined with a bright/saturated `sheenColor` can be used to create velvet.
!!! Tip
The `subsurfaceColor` parameter should be used with care. High values can interfere with shadows
in some areas. It is best suited for subtle transmission effects through the material.
### Sheen color
The `sheenColor` property can be used to directly modify the specular reflectance. It offers
better control over the appearance of cloth and gives give the ability to create
two-tone specular materials.
The effect of `sheenColor` is shown in figure [materialClothSheen]
(click on the image to see a larger version).
![Figure [materialClothSheen]: Blue fabric without (left) and with (right) sheen](images/screenshot_cloth_sheen.png)
### Subsurface color
The `subsurfaceColor` property is not physically-based and can be used to simulate the scattering,
partial absorption and re-emission of light in certain types of fabrics. This is particularly
useful to create softer fabrics.
!!! Warning
The cloth material model is more expensive to compute when the `subsurfaceColor` property is used.
The effect of `subsurfaceColor` is shown in figure [materialClothSubsurface]
(click on the image to see a larger version).
![Figure [materialClothSubsurface]: White cloth (left column) vs white cloth with
brown subsurface scatting (right)](images/screenshot_cloth_subsurface.png)
## Unlit model
The unlit material model can be used to turn off all lighting computations. Its primary purpose is
to render pre-lit elements such as a cubemap, external content (such as a video or camera stream),
user interfaces, visualization/debugging etc. The unlit model exposes only two properties described
in table [unlitProperties].
Property | Definition
---------------------:|:---------------------
**baseColor** | Surface diffuse color
**emissive** | Additional diffuse color to simulate emissive surfaces. This property is mostly useful in an HDR pipeline with a bloom pass
[Table [unlitProperties]: Properties of the standard model]
The type and range of each property is described in table [unlitPropertiesTypes].
Property | Type | Range | Note
---------------------:|:--------:|:------------------------:|:-------------------------
**baseColor** | float4 | [0..1] | Pre-multiplied linear RGB
**emissive** | float4 | rgb=[0..1], a=N/A | Pre-multiplied linear RGB, alpha is ignored
[Table [unlitPropertiesTypes]: Range and type of the unlit model's properties]
The value of `emissive` is simply added to `baseColor` when present. The main use of `emissive`
is to force an unlit surface to bloom if the HDR pipeline is configured with a bloom pass.
Figure [materialUnlit] shows an example of the unlit material model
(click on the image to see a larger version).
![Figure [materialUnlit]: The unlit model is used to render debug information](images/screenshot_unlit.jpg)
# Material definitions
A material definition is a text file that describes all the information required by a material:
- Name
- User parameters
- Material model
- Required attributes
- Interpolants (called _variables_)
- Raster state (blending mode, etc.)
- Shader code (fragment shader, optionally vertex shader)
## Format
The material definition format is a format loosely based on [JSON](https://www.json.org/) that we
call _JSONish_. At the top level a material definition is composed of 3 different blocks that use
the JSON object notation:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
// material properties
}
vertex {
// vertex shader, optional
}
fragment {
// fragment shader
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A minimum viable material definition must contain a `material` section and a `fragment` block. The
`vertex` block is optional.
### Differences with JSON
In JSON, an object is made of key/value _pairs_. A JSON pair has the following syntax:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
"key" : value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Where value can be a string, number, object, array or a literal (`true`, `false` or `null`). While
this syntax is perfectly valid in a material definition, a variant without quotes around strings is
also accepted in JSONish:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
key : value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quotes remain mandatory when the string contains spaces.
The `vertex` and `fragment` blocks contain unescaped, unquoted GLSL code, which is not valid in JSON.
Single-line C++-style comments are allowed.
The key of a pair is case-sensitive.
The value of a pair is not case-sensitive.
### Example
The following code listing shows an example of a valid material definition. This definition uses
the _lit_ material model (see Lit model section), uses the default opaque blending mode, requires
that a set of UV coordinates be presented in the rendered mesh and defines 3 user parameters. The
following sections of this document describe the `material` and `fragment` blocks in detail.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
name : "Textured material",
parameters : [
{
type : sampler2d,
name : texture
},
{
type : float,
name : metallic
},
{
type : float,
name : roughness
}
],
requires : [
uv0
],
shadingModel : lit,
blending : opaque
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, getUV0());
material.metallic = materialParams.metallic;
material.roughness = materialParams.roughness;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Material block
The material block is mandatory block that contains a list of property pairs to describe all
non-shader data.
### name
Type
: `string`
Value
: Any string. Double quotes are required if the name contains spaces.
Description
: Sets the name of the material. The name is retained at runtime for debugging purpose.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
name : stone
}
material {
name : "Wet pavement"
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### shadingModel
Type
: `string`
Value
: Any of `lit`, `subsurface`, `cloth`, `unlit`. Defaults to `lit`.
Description
: Selects the material model as described in the Material models section.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
shadingModel : unlit
}
material {
shadingModel : "subsurface"
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### parameters
Type
: array of parameter objects
Value
: Each entry is an object with the properties `name` and `type`, both of `string` type. The
name must be a valid GLSL identifier. The type must be one of the types described in
table [materialParamsTypes].
Type | Description
:----------------------|:---------------------------------
bool | Single boolean
bool2 | Vector of 2 booleans
bool3 | Vector of 3 booleans
bool4 | Vector of 4 booleans
float | Single float
float2 | Vector of 2 floats
float3 | Vector of 3 floats
float4 | Vector of 4 floats
int | Single integer
int2 | Vector of 2 integers
int3 | Vector of 3 integers
int4 | Vector of 4 integers
uint | Single unsigned integer
uint2 | Vector of 2 unsigned integers
uint3 | Vector of 3 unsigned integers
uint4 | Vector of 4 unsigned integers
float3x3 | Matrix of 3x3 floats
float4x4 | Matrix of 4x4 floats
sampler2d | 2D texture
samplerExternal | External texture (platform-specific)
samplerCubemap | Cubemap texture
[Table [materialParamsTypes]: Material parameter types]
Samplers
: Sampler types can also specify a `format` (defaults to `float`) and a `precision` (defaults
to `default`). The format can be one of `int`, `float`. The precision can be one of `default`
(best precision for the platform, typically `high` on desktop, `medium` on mobile),
`low`, `medium`, `high`.
Arrays
: A parameter can define an array of values by appending `[size]` after the type name, where
`size` is a positive integer. For instance: `float[9]` declares an array of nine `float`
values. Arrays of samplers are _not_ supported at the moment.
Description
: Lists the parameters required by your material. These parameters can be set at runtime using
Filament's material API. Accessing parameters from the shaders varies depending on the type of
parameter:
- **Samplers types**: use the parameter name prefixed with `materialParams_`. For instance,
`materialParams_myTexture`.
- **Other types**: use the parameter name as the field of a structure called `materialParams`.
For instance, `materialParams.myColor`.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
parameters : [
{
type : float4,
name : albedo
},
{
type : sampler2d,
format : float,
precision : high,
name : roughness
},
{
type : float2,
name : metallicReflectance
}
],
requires : [
uv0
],
shadingModel : lit,
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = materialParams.albedo;
material.roughness = texture(materialParams_roughness, getUV0());
material.metallic = materialParams.metallicReflectance.x;
material.reflectance = materialParams.metallicReflectance.y;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### requires
Type
: array of `string`
Value
: Each entry must be any of `uv0`, `uv1`, `color`, `position`, `tangents`.
Description
: Lists the vertex attributes required by the material. The `position` attribute is always
required and does not need to be specified. The `tangents` attribute is automatically required
when selecting any shading model that is not `unlit`. See the shader sections of this document
for more information on how to access these attributes from the shaders.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
parameters : [
{
type : sampler2d,
name : texture
},
],
requires : [
uv0
],
shadingModel : lit,
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, getUV0());
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### variables
Type
: array of `string`
Value
: Up to 4 strings, each must be a valid GLSL identifier.
Description
: Defines custom interpolants (or variables) that are output by the material's vertex shader.
Each entry of the array defines the name of an interpolant. The full name in the fragment
shader is the name of the interpolant with the `variable_` prefix. For instance, if you
declare a variable called `eyeDirection` you can access it in the fragment shader using
`variable_eyeDirection`. In the vertex shader, the interpolant name is simply a member of
the `MaterialVertexInputs` structure (`material.eyeDirection` in your example). Each
interpolant is of type `float4` (`vec4`) in the shaders.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
name : Skybox,
parameters : [
{
type : samplerCubemap,
name : skybox
}
],
variables : [
eyeDirection
],
vertexDomain : device,
depthWrite : false,
shadingModel : unlit
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
float3 sky = texture(materialParams_skybox, variable_eyeDirection.xyz).rgb;
material.baseColor = vec4(sky, 1.0);
}
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
float3 p = getPosition().xyz;
float3 u = mulMat4x4Float3(getViewFromClipMatrix(), p).xyz;
material.eyeDirection.xyz = mulMat3x3Float3(getWorldFromViewMatrix(), u);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### blending
Type
: `string`
Value
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`. Defaults to `opaque`.
Description
: Defines how/if the rendered object is blended with the content of the render target.
The possible blending modes are:
- **Opaque**: blending is disabled, the alpha channel of the material's output is ignored.
- **Transparent**: blending is enabled. The material's output is alpha composited with the
render target, using Porter-Duff's `source over` rule. This blending mode assumes
pre-multiplied alpha.
- **Fade**: acts as `transparent` but transparency is also applied to specular lighting. In
`transparent` mode, the material's alpha values only applies to diffuse lighting. This
blending mode is useful to fade lit objects in and out.
- **Add**: blending is enabled. The material's output is added to the content of the
render target.
- **Masked**: blending is disabled. This blending mode enables alpha masking. The alpha channel
of the material's output defines whether a fragment is discarded or not. See the maskThreshold
section for more information.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
blending : transparent
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### vertexDomain
Type
: `string`
Value
: Any of `object`, `world`, `view`, `device`. Defaults to `object`.
Description
: Defines the domain (or coordinate space) of the rendered mesh. The domain influences how the
vertices are transformed in the vertex shader. The possible domains are:
- **Object**: the vertices are defined in the object (or model) coordinate space. The
vertices are transformed using the rendered object's transform matrix
- **World**: the vertices are defined in world coordinate space. The vertices are not
transformed using the rendered object's transform.
- **View**: the vertices are defined in view (or eye or camera) coordinate space. The
vertices are not transformed using the rendered object's transform.
- **Device**: the vertices are defined in normalized device (or clip) coordinate space.
The vertices are not transformed using the rendered object's transform.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
vertexDomain : device
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### interpolation
Type
: `string`
Value
: Any of `smooth`, `flat`. Defaults to `smooth`.
Description
: Defines how interpolants (or variables) are interpolated between vertices. When this property
is set to `smooth`, a perspective correct interpolation is performed on each interpolant.
When set to `flat`, no interpolation is performed and all the fragments within a given
triangle will be shaded the same.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
interpolation : flat
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### culling
Type
: `string`
Value
: Any of `none`, `front`, `back`, `frontAndBack`. Defaults to `back`.
Description
: Defines which triangles should be culled: none, front-facing triangles, back-facing
triangles or all.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
culling : none
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### colorWrite
Type
: `boolean`
Value
: `true` or `false`. Defaults to `true`.
Description
: Enables or disables writes to the color buffer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
colorWrite : false
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### depthWrite
Type
: `boolean`
Value
: `true` or `false`. Defaults to `true`.
Description
: Enables or disables writes to the depth buffer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
depthWrite : false
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### depthCulling
Type
: `boolean`
Value
: `true` or `false`. Defaults to `true`.
Description
: Enables or disables depth testing. When depth testing is disabled, an object rendered with
this material will always appear on top of other opaque objects.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
depthCulling : false
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### doubleSided
Type
: `boolean`
Value
: `true` or `false`. Defaults to `false`.
Description
: Enables or disables two-sided rendering. When set to `true`, `culling` is automatically set to
`none`; if the triangle is back-facing, the triangle's normal is automatically flipped to
become front-facing.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
doubleSided : true
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### transparency
Type
: `string`
Value
: Any of `default`, `twoPassesOneSide` or `twoPassesTwoSides`. Defaults to `default`.
Description
: Controls how transparent objects are rendered. It is only valid when the `blending` mode is
not `opaque`. None of these methods can accurately render concave geometry, but in practice
they are often good enough.
The three possible transparency modes are:
- `default`: the transparent object is rendered normally (as seen in figure [transparencyDefault]),
honoring the `culling` mode, etc.
- `twoPassesOneSide`: the transparent object is first rendered in the depth buffer, then again in
the color buffer, honoring the `cullling` mode. This effectively renders only half of the
transparent object as shown in figure [transparencyTwoPassesOneSide].
- `twoPassesTwoSides`: the transparent object is rendered twice in the color buffer: first with its
back faces, then with its front faces. This mode lets you render both set of faces while reducing
or eliminating sorting issues, as shown in figure [transparencyTwoPassesTwoSides].
`twoPassesTwoSides` can be combined with `doubleSided` for better effect.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {