import common; import cooktorrance; struct SplatMaterialParameters { vec4 base_color; vec4 tint; vec4 emission; float metalness; float roughness; int base_color_layer; int normal_layer; int metalness_layer; int roughness_layer; int occlusion_layer; int emission_layer; }; const int max_materials = 128; layout(set=1) uniform SplatMaterial { SplatMaterialParameters splat_materials[max_materials]; }; layout(set=1) uniform sampler2DArray base_color_array; layout(set=1) uniform sampler2DArray normal_array; layout(set=1) uniform sampler2DArray metalness_array; layout(set=1) uniform sampler2DArray roughness_array; layout(set=1) uniform sampler2DArray occlusion_array; layout(set=1) uniform sampler2DArray emission_array; layout(constant_id=auto) const bool use_base_color_map = false; layout(constant_id=auto) const bool use_metalness_map = false; layout(constant_id=auto) const bool use_roughness_map = false; layout(constant_id=auto) const bool use_occlusion_map = false; layout(constant_id=auto) const bool use_emission = false; layout(constant_id=auto) const bool use_emission_map = false; #pragma MSP stage(fragment) void main() { vec2 uv = texcoord.xy; vec4 base_color = vec4(0.0); vec3 normal = vec3(0.0); float metalness = 0.0; float roughness = 0.0; float occlusion = (use_occlusion_map ? 0.0 : 1.0); vec3 emission = vec3(0.0); for(int i=0; i<3; ++i) { float w = weight[i]; if(w>0.0) { SplatMaterialParameters mat = splat_materials[group[i]]; if(use_base_color_map) { int layer = mat.base_color_layer; base_color += w*(layer>=0 ? texture(base_color_array, vec3(uv, layer)) : mat.base_color)*mat.tint; } else base_color += w*mat.base_color*mat.tint; if(use_normal_map) { int layer = mat.normal_layer; normal += w*(layer>=0 ? texture(normal_array, vec3(uv, layer)).xyz*2.0-1.0 : vec3(0.0, 0.0, 1.0)); } if(use_metalness_map) { int layer = mat.metalness_layer; metalness += w*(layer>=0 ? texture(metalness_array, vec3(uv, layer)).r : mat.metalness); } else metalness += w*mat.metalness; if(use_roughness_map) { int layer = mat.roughness_layer; roughness += w*(layer>=0 ? texture(roughness_array, vec3(uv, layer)).r : mat.roughness); } else roughness += w*mat.roughness; if(use_occlusion_map) { int layer = mat.occlusion_layer; occlusion += w*(layer>=0 ? texture(occlusion_array, vec3(uv, layer)).r : 1.0); } if(use_emission_map) { int layer = mat.emission_layer; emission += w*(layer>=0 ? texture(emission_array, vec3(uv, layer)).rgb : mat.emission.rgb); } else emission += w*mat.emission.rgb; } } if(use_normal_map) normal = world_tbn_matrix*normalize(normal); else normal = normalize(world_normal); vec3 look = normalize(world_look_dir); vec3 lit_color = cooktorrance_lighting(normal, look, base_color.rgb, metalness, roughness, occlusion); if(use_emission) lit_color += emission; frag_color = vec4(lit_color, base_color.a); }