1010// -----------------------------------------------------------------------------
1111
1212layout (constant_id = 0 ) const int iMeshVariantFlags = 0 ;
13- layout (constant_id = 1 ) const int iDataStride = 0 ;
14- layout (constant_id = 2 ) const int iTextureMappingFlags = 0 ;
15- layout (constant_id = 3 ) const int iMaterialFlags = 0 ;
16- layout (constant_id = 4 ) const int iRenderingFlags = 0 ;
17- layout (constant_id = 5 ) const int iLightCount = 0 ;
18- layout (constant_id = 6 ) const int iProbeCount = 0 ;
13+ layout (constant_id = 1 ) const int iTextureMappingFlags = 0 ;
14+ layout (constant_id = 2 ) const int iMaterialFlags = 0 ;
15+ layout (constant_id = 3 ) const int iRenderingFlags = 0 ;
16+ layout (constant_id = 4 ) const int iLightCount = 0 ;
17+ layout (constant_id = 5 ) const int iProbeCount = 0 ;
1918
2019// -----------------------------------------------------------------------------
2120// [SECTION] dynamic bind group
@@ -41,9 +40,146 @@ layout(location = 0) in struct plShaderIn {
4140 mat3 tTBN;
4241} tShaderIn;
4342
44- #define PL_FRAGMENT
4543#include "math.glsl"
4644#include "lighting.glsl"
45+ #include "material_info.glsl"
46+
47+ struct NormalInfo {
48+ vec3 ng; // Geometry normal
49+ vec3 t; // Geometry tangent
50+ vec3 b; // Geometry bitangent
51+ vec3 n; // Shading normal
52+ vec3 ntex; // Normal from texture, scaling is accounted for.
53+ };
54+
55+ NormalInfo
56+ pl_get_normal_info(int iUVSet)
57+ {
58+ vec2 UV = tShaderIn.tUV[iUVSet];
59+ vec2 uv_dx = dFdx (UV);
60+ vec2 uv_dy = dFdy (UV);
61+
62+ // if (length(uv_dx) <= 1e-2) {
63+ // uv_dx = vec2(1.0, 0.0);
64+ // }
65+
66+ // if (length(uv_dy) <= 1e-2) {
67+ // uv_dy = vec2(0.0, 1.0);
68+ // }
69+
70+ vec3 t_ = (uv_dy.t * dFdx (tShaderIn.tWorldPosition) - uv_dx.t * dFdy (tShaderIn.tWorldPosition)) /
71+ (uv_dx.s * uv_dy.t - uv_dy.s * uv_dx.t);
72+
73+ vec3 n, t, b, ng;
74+
75+ // Compute geometrical TBN:
76+ if (bool (iMeshVariantFlags & PL_MESH_FORMAT_FLAG_HAS_NORMAL))
77+ {
78+
79+ if (bool (iMeshVariantFlags & PL_MESH_FORMAT_FLAG_HAS_TANGENT))
80+ {
81+ // Trivial TBN computation, present as vertex attribute.
82+ // Normalize eigenvectors as matrix is linearly interpolated.
83+ t = normalize (tShaderIn.tTBN[0 ]);
84+ b = normalize (tShaderIn.tTBN[1 ]);
85+ ng = normalize (tShaderIn.tTBN[2 ]);
86+ }
87+ else
88+ {
89+ // Normals are either present as vertex attributes or approximated.
90+ ng = normalize (tShaderIn.tWorldNormal);
91+ t = normalize (t_ - ng * dot (ng, t_));
92+ b = cross (ng, t);
93+ }
94+ }
95+ else
96+ {
97+ ng = normalize (cross (dFdx (tShaderIn.tWorldPosition), dFdy (tShaderIn.tWorldPosition)));
98+ t = normalize (t_ - ng * dot (ng, t_));
99+ b = cross (ng, t);
100+ }
101+
102+
103+ // For a back-facing surface, the tangential basis vectors are negated.
104+ if (gl_FrontFacing == false)
105+ {
106+ t *= - 1.0 ;
107+ b *= - 1.0 ;
108+ ng *= - 1.0 ;
109+ }
110+
111+ // Compute normals:
112+ NormalInfo info;
113+ info.ng = ng;
114+ if (bool (iTextureMappingFlags & PL_HAS_NORMAL_MAP))
115+ {
116+ plGpuMaterial material = tMaterialInfo.atMaterials[tObjectInfo.tData.iMaterialIndex];
117+ info.ntex = texture(sampler2D (at2DTextures[nonuniformEXT(material.iNormalTexIdx)], tSamplerLinearRepeat), UV).rgb * 2.0 - vec3 (1.0 );
118+ // info.ntex *= vec3(0.2, 0.2, 1.0);
119+ // info.ntex *= vec3(u_NormalScale, u_NormalScale, 1.0);
120+ info.ntex = normalize (info.ntex);
121+ info.n = normalize (mat3 (t, b, ng) * info.ntex);
122+ }
123+ else
124+ {
125+ info.n = ng;
126+ }
127+ info.t = t;
128+ info.b = b;
129+ return info;
130+ }
131+
132+ vec4
133+ getBaseColor(vec4 u_ColorFactor, int iUVSet)
134+ {
135+ vec4 baseColor = vec4 (1 );
136+
137+ // if(bool(MATERIAL_SPECULARGLOSSINESS))
138+ // {
139+ // baseColor = u_DiffuseFactor;
140+ // }
141+ // else if(bool(MATERIAL_METALLICROUGHNESS))
142+ if (bool (iMaterialFlags & PL_INFO_MATERIAL_METALLICROUGHNESS))
143+ {
144+ // baseColor = u_BaseColorFactor;
145+ baseColor = u_ColorFactor;
146+ }
147+
148+ // if(bool(MATERIAL_SPECULARGLOSSINESS) && bool(HAS_DIFFUSE_MAP))
149+ // {
150+ // // baseColor *= texture(u_DiffuseSampler, getDiffuseUV());
151+ // baseColor *= texture(u_DiffuseSampler, tShaderIn.tUV);
152+ // }
153+ // else if(bool(MATERIAL_METALLICROUGHNESS) && bool(HAS_BASE_COLOR_MAP))
154+ if (bool (iMaterialFlags & PL_INFO_MATERIAL_METALLICROUGHNESS) && bool (iTextureMappingFlags & PL_HAS_BASE_COLOR_MAP))
155+ {
156+ plGpuMaterial material = tMaterialInfo.atMaterials[tObjectInfo.tData.iMaterialIndex];
157+ baseColor *= pl_srgb_to_linear(texture(sampler2D (at2DTextures[nonuniformEXT(material.iBaseColorTexIdx)], tSamplerLinearRepeat), tShaderIn.tUV[iUVSet]));
158+ }
159+ return baseColor * tShaderIn.tColor;
160+ }
161+
162+ MaterialInfo
163+ getMetallicRoughnessInfo(MaterialInfo info, float u_MetallicFactor, float u_RoughnessFactor, int UVSet)
164+ {
165+ info.metallic = u_MetallicFactor;
166+ info.perceptualRoughness = u_RoughnessFactor;
167+
168+ if (bool (iTextureMappingFlags & PL_HAS_METALLIC_ROUGHNESS_MAP))
169+ {
170+ // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
171+ // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
172+ plGpuMaterial material = tMaterialInfo.atMaterials[tObjectInfo.tData.iMaterialIndex];
173+ vec4 mrSample = texture(sampler2D (at2DTextures[nonuniformEXT(material.iMetallicRoughnessTexIdx)], tSamplerLinearRepeat), tShaderIn.tUV[UVSet]);
174+ info.perceptualRoughness *= mrSample.g;
175+ info.metallic *= mrSample.b;
176+ }
177+
178+ // Achromatic f0 based on IOR.
179+ info.c_diff = mix (info.baseColor.rgb, vec3 (0 ), info.metallic);
180+ info.f0_dielectric = mix (info.f0_dielectric, info.baseColor.rgb, info.metallic);
181+ return info;
182+ }
47183
48184// -----------------------------------------------------------------------------
49185// [SECTION] entry
0 commit comments