]> git.tdb.fi Git - libs/gl.git/blob - shaderlib/splat.glsl
Implement a splat material type
[libs/gl.git] / shaderlib / splat.glsl
1 import common;
2 import cooktorrance;
3
4 struct SplatMaterialParameters
5 {
6         vec4 base_color;
7         vec4 tint;
8         vec4 emission;
9         float metalness;
10         float roughness;
11         int base_color_layer;
12         int normal_layer;
13         int metalness_layer;
14         int roughness_layer;
15         int occlusion_layer;
16         int emission_layer;
17 };
18
19 const int max_materials = 128;
20 layout(set=1) uniform SplatMaterial
21 {
22         SplatMaterialParameters splat_materials[max_materials];
23 };
24
25 layout(set=1) uniform sampler2DArray base_color_array;
26 layout(set=1) uniform sampler2DArray normal_array;
27 layout(set=1) uniform sampler2DArray metalness_array;
28 layout(set=1) uniform sampler2DArray roughness_array;
29 layout(set=1) uniform sampler2DArray occlusion_array;
30 layout(set=1) uniform sampler2DArray emission_array;
31
32 layout(constant_id=auto) const bool use_base_color_map = false;
33 layout(constant_id=auto) const bool use_metalness_map = false;
34 layout(constant_id=auto) const bool use_roughness_map = false;
35 layout(constant_id=auto) const bool use_occlusion_map = false;
36 layout(constant_id=auto) const bool use_emission = false;
37 layout(constant_id=auto) const bool use_emission_map = false;
38
39 #pragma MSP stage(fragment)
40 void main()
41 {
42         vec2 uv = texcoord.xy;
43         vec4 base_color = vec4(0.0);
44         vec3 normal = vec3(0.0);
45         float metalness = 0.0;
46         float roughness = 0.0;
47         float occlusion = (use_occlusion_map ? 0.0 : 1.0);
48         vec3 emission = vec3(0.0);
49
50         for(int i=0; i<3; ++i)
51         {
52                 float w = weight[i];
53                 if(w>0.0)
54                 {
55                         SplatMaterialParameters mat = splat_materials[group[i]];
56
57                         if(use_base_color_map)
58                         {
59                                 int layer = mat.base_color_layer;
60                                 base_color += w*(layer>=0 ? texture(base_color_array, vec3(uv, layer)) : mat.base_color)*mat.tint;
61                         }
62                         else
63                                 base_color += w*mat.base_color*mat.tint;
64
65                         if(use_normal_map)
66                         {
67                                 int layer = mat.normal_layer;
68                                 normal += w*(layer>=0 ? texture(normal_array, vec3(uv, layer)).xyz*2.0-1.0 : vec3(0.0, 0.0, 1.0));
69                         }
70
71                         if(use_metalness_map)
72                         {
73                                 int layer = mat.metalness_layer;
74                                 metalness += w*(layer>=0 ? texture(metalness_array, vec3(uv, layer)).r : mat.metalness);
75                         }
76                         else
77                                 metalness += w*mat.metalness;
78
79                         if(use_roughness_map)
80                         {
81                                 int layer = mat.roughness_layer;
82                                 roughness += w*(layer>=0 ? texture(roughness_array, vec3(uv, layer)).r : mat.roughness);
83                         }
84                         else
85                                 roughness += w*mat.roughness;
86
87                         if(use_occlusion_map)
88                         {
89                                 int layer = mat.occlusion_layer;
90                                 occlusion += w*(layer>=0 ? texture(occlusion_array, vec3(uv, layer)).r : 1.0);
91                         }
92
93                         if(use_emission_map)
94                         {
95                                 int layer = mat.emission_layer;
96                                 emission += w*(layer>=0 ? texture(emission_array, vec3(uv, layer)).rgb : mat.emission.rgb);
97                         }
98                         else
99                                 emission += w*mat.emission.rgb;
100                 }
101         }
102
103         if(use_normal_map)
104                 normal = world_tbn_matrix*normalize(normal);
105         else
106                 normal = normalize(world_normal);
107
108         vec3 look = normalize(world_look_dir);
109
110         vec3 lit_color = cooktorrance_lighting(normal, look, base_color.rgb, metalness, roughness, occlusion);
111         if(use_emission)
112                 lit_color += emission;
113
114         frag_color = vec4(lit_color, base_color.a);
115 }