847 shaderLibraryManager);
856 || keyProps.m_usesInstancing.getValue(inKey)
857 || keyProps.m_blendParticles.getValue(inKey);
860 bool isDoubleSided = keyProps.m_isDoubleSided.getValue(inKey);
861 bool hasImage = firstImage !=
nullptr;
863 bool hasIblProbe = keyProps.m_hasIbl.getValue(inKey);
864 bool specularLightingEnabled = metalnessEnabled || materialAdapter->
isSpecularEnabled() || hasIblProbe;
865 bool specularAAEnabled = keyProps.m_specularAAEnabled.getValue(inKey);
866 quint32 numMorphTargets = keyProps.m_targetCount.getValue(inKey);
894 QVector<QSSGRenderableImage *> identityImages;
895 char imageFragCoords[TEXCOORD_VAR_LEN];
899 switch (chProp.getTextureChannel(inKey)) {
916 auto maskVariableByVertexColorChannel = [&fragmentShader, materialAdapter](
const QByteArray &maskVariable
920 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.r;\n";
922 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.g;\n";
924 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.b;\n";
926 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.a;\n";
931 if (
img->m_imageNode.isImageTransformIdentity())
932 identityImages.push_back(
img);
933 if (
img->m_mapType == QSSGRenderableImage::Type::BaseColor ||
img->m_mapType == QSSGRenderableImage::Type::Diffuse) {
935 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Bump) {
937 }
else if (
img->m_mapType == QSSGRenderableImage::Type::SpecularAmountMap) {
938 specularAmountImage =
img;
939 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Roughness) {
940 roughnessImage =
img;
941 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Metalness) {
942 metalnessImage =
img;
943 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Occlusion) {
944 occlusionImage =
img;
945 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Normal) {
947 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Translucency) {
948 translucencyImage =
img;
949 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Opacity) {
951 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Height) {
953 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Clearcoat) {
954 clearcoatImage =
img;
955 }
else if (
img->m_mapType == QSSGRenderableImage::Type::ClearcoatRoughness) {
956 clearcoatRoughnessImage =
img;
957 }
else if (
img->m_mapType == QSSGRenderableImage::Type::ClearcoatNormal) {
958 clearcoatNormalImage =
img;
959 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Transmission) {
960 transmissionImage =
img;
961 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Thickness) {
962 thicknessImage =
img;
975 bool enableBumpNormal = normalImage || bumpImage;
976 bool genBumpNormalImageCoords =
false;
977 bool enableParallaxMapping = heightImage !=
nullptr;
983 specularLightingEnabled |= specularAmountImage !=
nullptr;
984 specularLightingEnabled |= hasReflectionProbe;
988 const bool enableFog = keyProps.m_fogEnabled.getValue(inKey);
991 ? 1 : keyProps.m_viewCount.getValue(inKey);
994 if (numMorphTargets > 0 || hasCustomVert) {
998 if ((
offset = keyProps.m_targetPositionOffset.getValue(inKey)) < UINT8_MAX) {
1002 if ((
offset = keyProps.m_targetNormalOffset.getValue(inKey)) < UINT8_MAX) {
1006 if ((
offset = keyProps.m_targetTangentOffset.getValue(inKey)) < UINT8_MAX) {
1010 if ((
offset = keyProps.m_targetBinormalOffset.getValue(inKey)) < UINT8_MAX) {
1014 if ((
offset = keyProps.m_targetTexCoord0Offset.getValue(inKey)) < UINT8_MAX) {
1018 if ((
offset = keyProps.m_targetTexCoord1Offset.getValue(inKey)) < UINT8_MAX) {
1022 if ((
offset = keyProps.m_targetColorOffset.getValue(inKey)) < UINT8_MAX) {
1028 bool includeCustomFragmentMain =
true;
1029 if (isDepthPass || isOrthoShadowPass || isCubeShadowPass) {
1030 hasLighting =
false;
1032 enableShadowMaps =
false;
1033 enableLightmap =
false;
1035 metalnessEnabled =
false;
1036 specularLightingEnabled =
false;
1038 if (!isOpaqueDepthPrePass) {
1039 vertexColorsEnabled =
false;
1040 baseImage =
nullptr;
1041 includeCustomFragmentMain =
false;
1045 bool includeSSAOVars = enableSSAO || enableShadowMaps;
1052 if (hasCustomFrag && materialAdapter->
isUnshaded())
1059 fragmentShader.
addUniform(
"qt_material_emissive_color",
"vec3");
1060 fragmentShader.
addUniform(
"qt_material_base_color",
"vec4");
1061 fragmentShader.
addUniform(
"qt_material_properties",
"vec4");
1062 fragmentShader.
addUniform(
"qt_material_properties2",
"vec4");
1063 fragmentShader.
addUniform(
"qt_material_properties3",
"vec4");
1064 if (enableParallaxMapping || enableTransmission)
1065 fragmentShader.
addUniform(
"qt_material_properties4",
"vec4");
1066 if (enableFresnelScaleBias || enableClearcoatFresnelScaleBias)
1067 fragmentShader.
addUniform(
"qt_material_properties5",
"vec4");
1068 if (enableTransmission) {
1069 fragmentShader.
addUniform(
"qt_material_attenuation",
"vec4");
1070 fragmentShader.
addUniform(
"qt_material_thickness",
"float");
1072 fragmentShader.
addUniform(
"qt_material_clearcoat_normal_strength",
"float");
1073 fragmentShader.
addUniform(
"qt_material_clearcoat_fresnel_power",
"float");
1075 if (vertexColorsEnabled) {
1078 fragmentShader.
append(
" vec4 qt_vertColorMask = vec4(1.0);");
1079 fragmentShader.
append(
" vec4 qt_vertColor = vec4(1.0);");
1082 if (hasImage && ((!isDepthPass && !isOrthoShadowPass && !isCubeShadowPass) || isOpaqueDepthPrePass)) {
1083 fragmentShader.
append(
" vec3 qt_uTransform;");
1084 fragmentShader.
append(
" vec3 qt_vTransform;");
1087 if (hasLighting || hasCustomFrag) {
1090 if (keyProps.m_usesProjectionMatrix.getValue(inKey)) {
1092 fragmentShader.
addUniformArray(
"qt_projectionMatrix",
"mat4", viewCount);
1094 fragmentShader.
addUniform(
"qt_projectionMatrix",
"mat4");
1096 if (keyProps.m_usesInverseProjectionMatrix.getValue(inKey)) {
1098 fragmentShader.
addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", viewCount);
1100 fragmentShader.
addUniform(
"qt_inverseProjectionMatrix",
"mat4");
1108 const bool needsTangentAndBinormal = hasCustomFrag || enableParallaxMapping || clearcoatNormalImage || enableBumpNormal || usingDefaultMaterialSpecularGGX || tangentOrBinormalDebugMode;
1111 if (needsTangentAndBinormal) {
1112 bool genTangent =
false;
1113 bool genBinormal =
false;
1116 if (enableBumpNormal && !genTangent) {
1120 auto *bumpNormalImage = bumpImage !=
nullptr ? bumpImage : normalImage;
1121 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *bumpNormalImage,
true, bumpNormalImage->m_imageNode.m_indexUV);
1122 genBumpNormalImageCoords =
true;
1124 int id = (bumpImage !=
nullptr) ?
int(QSSGRenderableImage::Type::Bump) : int(QSSGRenderableImage::Type::Normal);
1125 const auto &
names = imageStringTable[
id];
1126 fragmentShader <<
" vec2 dUVdx = dFdx(" <<
names.imageFragCoords <<
");\n"
1127 <<
" vec2 dUVdy = dFdy(" <<
names.imageFragCoords <<
");\n";
1128 fragmentShader <<
" qt_tangent = (dUVdy.y * dFdx(qt_varWorldPos) - dUVdx.y * dFdy(qt_varWorldPos)) / (dUVdx.x * dUVdy.y - dUVdx.y * dUVdy.x);\n"
1129 <<
" qt_tangent = qt_tangent - dot(qt_world_normal, qt_tangent) * qt_world_normal;\n"
1130 <<
" qt_tangent = normalize(qt_tangent);\n";
1133 fragmentShader <<
" qt_binormal = cross(qt_world_normal, qt_tangent);\n";
1136 if (isDoubleSided) {
1137 fragmentShader.
append(
"#if QSHADER_HLSL && QSHADER_VIEW_COUNT >= 2");
1138 fragmentShader.
append(
" const float qt_facing = 1.0;");
1139 fragmentShader.
append(
"#else");
1140 fragmentShader.
append(
" const float qt_facing = gl_FrontFacing ? 1.0 : -1.0;");
1141 fragmentShader.
append(
"#endif");
1142 fragmentShader.
append(
" qt_world_normal *= qt_facing;\n");
1143 if (needsTangentAndBinormal) {
1144 fragmentShader.
append(
" qt_tangent *= qt_facing;");
1145 fragmentShader.
append(
" qt_binormal *= qt_facing;");
1150 if (hasCustomFrag) {
1157 fragmentShader <<
" QT_SHARED_VARS qt_customShared;\n";
1159 fragmentShader <<
" float qt_customSpecularAmount = 0.5;\n";
1160 fragmentShader <<
" float qt_customSpecularRoughness = 0.0;\n";
1161 fragmentShader <<
" float qt_customMetalnessAmount = 0.0;\n";
1162 fragmentShader <<
" float qt_customFresnelPower = 5.0;\n";
1163 fragmentShader <<
" vec4 qt_customBaseColor = vec4(1.0);\n";
1164 fragmentShader <<
" vec3 qt_customEmissiveColor = vec3(0.0);\n";
1170 fragmentShader <<
" qt_customMain(qt_customBaseColor, qt_customEmissiveColor, qt_customMetalnessAmount, qt_customSpecularRoughness,"
1171 " qt_customSpecularAmount, qt_customFresnelPower, qt_world_normal, qt_tangent, qt_binormal,"
1172 " qt_texCoord0, qt_texCoord1, qt_view_vector";
1174 fragmentShader <<
", qt_customShared);\n";
1176 fragmentShader <<
");\n";
1178 fragmentShader <<
" vec4 qt_diffuseColor = qt_customBaseColor * qt_vertColor;\n";
1179 fragmentShader <<
" vec3 qt_global_emission = qt_customEmissiveColor;\n";
1181 fragmentShader <<
" vec4 qt_diffuseColor = qt_material_base_color * qt_vertColor;\n";
1182 fragmentShader <<
" vec3 qt_global_emission = qt_material_emissive_color;\n";
1187 fragmentShader <<
" vec4 fragOutput = vec4(0.0);\n";
1189 if (isOrthoShadowPass)
1192 if (isCubeShadowPass)
1199 if (includeSSAOVars)
1202 if (enableLightmap) {
1211 fragmentShader.
addFunction(
"diffuseReflectionBSDF");
1213 if (enableParallaxMapping) {
1216 const bool hasIdentityMap = identityImages.contains(heightImage);
1218 generateImageUVSampler(vertexShader, fragmentShader, inKey, *heightImage, imageFragCoords, heightImage->m_imageNode.m_indexUV);
1221 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Height)];
1222 fragmentShader.
addInclude(
"parallaxMapping.glsllib");
1223 fragmentShader <<
" float qt_heightAmount = qt_material_properties4.x;\n";
1225 if (viewCount < 2) {
1226 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
", " <<
names.imageSampler
1227 <<
", qt_tangent, qt_binormal, qt_world_normal, qt_varWorldPos, qt_cameraPosition, qt_heightAmount, qt_material_properties4.y, qt_material_properties4.z);\n";
1229 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
", " <<
names.imageSampler
1230 <<
", qt_tangent, qt_binormal, qt_world_normal, qt_varWorldPos, qt_cameraPosition[qt_viewIndex], qt_heightAmount, qt_material_properties4.y, qt_material_properties4.z);\n";
1235 if (enableClearcoat) {
1241 if (clearcoatNormalImage) {
1242 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *clearcoatNormalImage, enableParallaxMapping, clearcoatNormalImage->m_imageNode.m_indexUV);
1243 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::ClearcoatNormal)];
1244 fragmentShader.
addFunction(
"sampleNormalTexture");
1245 fragmentShader <<
" float qt_clearcoat_normal_strength = qt_material_clearcoat_normal_strength;\n";
1247 fragmentShader <<
" qt_clearcoatNormal = qt_sampleNormalTexture3(" <<
names.imageSampler <<
", qt_clearcoat_normal_strength, " <<
names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1251 fragmentShader <<
" qt_clearcoatNormal = qt_world_normal;\n";
1255 if (bumpImage !=
nullptr) {
1256 if (enableParallaxMapping || !genBumpNormalImageCoords) {
1258 *bumpImage, enableParallaxMapping,
1259 bumpImage->m_imageNode.m_indexUV,
1260 genBumpNormalImageCoords);
1262 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Bump)];
1264 fragmentShader.
append(
" float qt_bumpAmount = qt_material_properties2.y;\n");
1266 fragmentShader.
addInclude(
"defaultMaterialBumpNoLod.glsllib");
1267 fragmentShader <<
" qt_world_normal = qt_defaultMaterialBumpNoLod(" <<
names.imageSampler <<
", qt_bumpAmount, " <<
names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal, " <<
names.imageSamplerSize <<
");\n";
1268 }
else if (normalImage !=
nullptr) {
1269 if (enableParallaxMapping || !genBumpNormalImageCoords) {
1271 *normalImage, enableParallaxMapping,
1272 normalImage->m_imageNode.m_indexUV,
1273 genBumpNormalImageCoords);
1275 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Normal)];
1276 fragmentShader.
append(
" float qt_normalStrength = qt_material_properties2.y;\n");
1278 fragmentShader.
addFunction(
"sampleNormalTexture");
1279 fragmentShader <<
" qt_world_normal = qt_sampleNormalTexture3(" <<
names.imageSampler <<
", qt_normalStrength, " <<
names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1282 fragmentShader.
append(
" vec3 tmp_light_color;");
1285 if (specularLightingEnabled || hasImage) {
1286 fragmentShader.
append(
" vec3 qt_specularBase;");
1287 fragmentShader.
addUniform(
"qt_material_specular",
"vec4");
1289 fragmentShader.
append(
" vec3 qt_specularTint = vec3(1.0);");
1291 fragmentShader.
append(
" vec3 qt_specularTint = qt_material_specular.rgb;");
1295 const bool hasIdentityMap = identityImages.contains(baseImage);
1297 generateImageUVSampler(vertexShader, fragmentShader, inKey, *baseImage, imageFragCoords, baseImage->m_imageNode.m_indexUV);
1299 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *baseImage, enableParallaxMapping, baseImage->m_imageNode.m_indexUV);
1302 const auto &
names = imageStringTable[int(baseImage->m_mapType)];
1304 fragmentShader.
addInclude(
"tonemapping.glsllib");
1307 fragmentShader <<
" vec4 qt_base_texture_color = vec4(vec3(texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1309 fragmentShader <<
" vec4 qt_base_texture_color = texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
");\n";
1312 fragmentShader <<
" qt_base_texture_color = qt_sRGBToLinear(qt_base_texture_color);\n";
1313 fragmentShader <<
" qt_diffuseColor *= qt_base_texture_color;\n";
1321 fragmentShader <<
" if (qt_diffuseColor.a < qt_material_properties3.y) {\n"
1322 <<
" qt_diffuseColor = vec4(0.0);\n"
1325 <<
" qt_diffuseColor.a = 1.0;\n"
1328 fragmentShader <<
" qt_diffuseColor.a = 1.0;\n";
1332 const bool hasIdentityMap = identityImages.contains(opacityImage);
1334 generateImageUVSampler(vertexShader, fragmentShader, inKey, *opacityImage, imageFragCoords, opacityImage->m_imageNode.m_indexUV);
1336 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *opacityImage, enableParallaxMapping, opacityImage->m_imageNode.m_indexUV);
1338 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Opacity)];
1340 fragmentShader <<
" float qt_opacity_map_value = texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1342 fragmentShader <<
" qt_opacity_map_value = 1.0 - qt_opacity_map_value;\n";
1343 fragmentShader <<
" qt_objectOpacity *= qt_opacity_map_value;\n";
1347 if (specularLightingEnabled) {
1349 fragmentShader.
addUniform(
"qt_material_properties",
"vec4");
1352 fragmentShader <<
" qt_specularBase = vec3(1.0);\n";
1354 fragmentShader <<
" qt_specularBase = qt_diffuseColor.rgb;\n";
1356 fragmentShader <<
" float qt_specularFactor = qt_customSpecularAmount;\n";
1358 fragmentShader <<
" float qt_specularFactor = qt_material_properties.x;\n";
1365 fragmentShader <<
" float qt_metalnessAmount = qt_customMetalnessAmount;\n";
1367 fragmentShader <<
" float qt_metalnessAmount = qt_material_properties.z;\n";
1369 fragmentShader <<
" float qt_metalnessAmount = 0.0;\n";
1373 if (specularLightingEnabled && metalnessImage) {
1375 const bool hasIdentityMap = identityImages.contains(metalnessImage);
1377 generateImageUVSampler(vertexShader, fragmentShader, inKey, *metalnessImage, imageFragCoords, metalnessImage->m_imageNode.m_indexUV);
1379 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *metalnessImage, enableParallaxMapping, metalnessImage->m_imageNode.m_indexUV);
1381 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Metalness)];
1382 fragmentShader <<
" float qt_sampledMetalness = texture2D(" <<
names.imageSampler <<
", "
1383 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1384 fragmentShader <<
" qt_metalnessAmount = clamp(qt_metalnessAmount * qt_sampledMetalness, 0.0, 1.0);\n";
1387 fragmentShader.
addUniform(
"qt_light_ambient_total",
"vec3");
1389 fragmentShader.
append(
" vec4 global_diffuse_light = vec4(0.0);");
1391 if (enableLightmap) {
1392 fragmentShader <<
" global_diffuse_light.rgb = qt_lightmap_color(qt_texCoordLightmap) * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb;\n";
1396 fragmentShader.
append(
" qt_ambientLightProcessor(global_diffuse_light.rgb, qt_light_ambient_total.rgb * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb, qt_world_normal, qt_view_vector");
1398 fragmentShader <<
", qt_customShared);\n";
1400 fragmentShader <<
");\n";
1402 fragmentShader.
append(
" global_diffuse_light = vec4(qt_light_ambient_total.rgb * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb, 0.0);");
1406 fragmentShader.
append(
" vec3 global_specular_light = vec3(0.0);");
1408 if (!lights.
isEmpty() || hasCustomFrag) {
1409 fragmentShader.
append(
" float qt_shadow_map_occl = 1.0;");
1410 fragmentShader.
append(
" float qt_lightAttenuation = 1.0;");
1415 if (specularAmountImage) {
1416 const bool hasIdentityMap = identityImages.contains(specularAmountImage);
1418 generateImageUVSampler(vertexShader, fragmentShader, inKey, *specularAmountImage, imageFragCoords, specularAmountImage->m_imageNode.m_indexUV);
1420 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *specularAmountImage, enableParallaxMapping, specularAmountImage->m_imageNode.m_indexUV);
1422 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::SpecularAmountMap )];
1426 fragmentShader <<
" vec4 qt_specular_amount_map = vec4(vec3(texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1428 fragmentShader <<
" vec4 qt_specular_amount_map = texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
");\n";
1430 fragmentShader <<
" qt_specularBase *= qt_sRGBToLinear(qt_specular_amount_map).rgb;\n";
1433 if (specularLightingEnabled) {
1435 fragmentShader <<
" qt_specularTint *= qt_specularBase;\n";
1436 fragmentShader <<
" vec3 qt_specularAmount = vec3(1.0);\n";
1438 fragmentShader <<
" vec3 qt_specularAmount = qt_specularBase * vec3(qt_metalnessAmount + qt_specularFactor * (1.0 - qt_metalnessAmount));\n";
1442 if (translucencyImage !=
nullptr) {
1443 const bool hasIdentityMap = identityImages.contains(translucencyImage);
1449 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Translucency)];
1451 fragmentShader <<
" float qt_translucent_depth_range = texture2D(" <<
names.imageSampler
1452 <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1453 fragmentShader <<
" float qt_translucent_thickness = qt_translucent_depth_range * qt_translucent_depth_range;\n";
1454 fragmentShader <<
" float qt_translucent_thickness_exp = exp(qt_translucent_thickness * qt_material_properties2.z);\n";
1460 fragmentShader.
append(
" qt_aoFactor = qt_screenSpaceAmbientOcclusionFactor();");
1462 fragmentShader.
append(
" qt_aoFactor = 1.0;");
1465 fragmentShader <<
" float qt_roughnessAmount = qt_customSpecularRoughness;\n";
1467 fragmentShader <<
" float qt_roughnessAmount = qt_material_properties.y;\n";
1473 if (occlusionImage) {
1476 const bool hasIdentityMap = identityImages.contains(occlusionImage);
1478 generateImageUVSampler(vertexShader, fragmentShader, inKey, *occlusionImage, imageFragCoords, occlusionImage->m_imageNode.m_indexUV);
1480 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *occlusionImage, enableParallaxMapping, occlusionImage->m_imageNode.m_indexUV);
1481 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Occlusion)];
1482 fragmentShader <<
" qt_ao = texture2D(" <<
names.imageSampler <<
", "
1483 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1484 fragmentShader <<
" qt_aoFactor *= qt_ao * qt_material_properties3.x;\n";
1489 if (specularLightingEnabled && roughnessImage) {
1491 const bool hasIdentityMap = identityImages.contains(roughnessImage);
1493 generateImageUVSampler(vertexShader, fragmentShader, inKey, *roughnessImage, imageFragCoords, roughnessImage->m_imageNode.m_indexUV);
1495 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *roughnessImage, enableParallaxMapping, roughnessImage->m_imageNode.m_indexUV);
1497 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Roughness)];
1498 fragmentShader <<
" qt_roughnessAmount *= texture2D(" <<
names.imageSampler <<
", "
1499 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1504 fragmentShader <<
" qt_roughnessAmount = clamp(1.0 - qt_roughnessAmount, 0.0, 1.0);\n";
1506 if (enableClearcoat) {
1513 fragmentShader <<
" qt_clearcoatAmount = qt_material_properties3.z;\n";
1515 fragmentShader <<
" qt_clearcoatRoughness = qt_material_properties3.w;\n";
1517 fragmentShader <<
" qt_clearcoatF0 = vec3(((1.0-qt_material_specular.w) * (1.0-qt_material_specular.w)) / ((1.0+qt_material_specular.w) * (1.0+qt_material_specular.w)));\n";
1518 fragmentShader <<
" qt_clearcoatF90 = vec3(1.0);\n";
1519 fragmentShader <<
" qt_global_clearcoat = vec3(0.0);\n";
1521 if (clearcoatImage) {
1523 const bool hasIdentityMap = identityImages.contains(clearcoatImage);
1525 generateImageUVSampler(vertexShader, fragmentShader, inKey, *clearcoatImage, imageFragCoords, clearcoatImage->m_imageNode.m_indexUV);
1527 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *clearcoatImage, enableParallaxMapping, clearcoatImage->m_imageNode.m_indexUV);
1528 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Clearcoat)];
1529 fragmentShader <<
" qt_clearcoatAmount *= texture2D(" <<
names.imageSampler <<
", "
1530 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1533 if (clearcoatRoughnessImage) {
1535 const bool hasIdentityMap = identityImages.contains(clearcoatRoughnessImage);
1537 generateImageUVSampler(vertexShader, fragmentShader, inKey, *clearcoatRoughnessImage, imageFragCoords, clearcoatRoughnessImage->m_imageNode.m_indexUV);
1539 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *clearcoatRoughnessImage, enableParallaxMapping, clearcoatRoughnessImage->m_imageNode.m_indexUV);
1540 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::ClearcoatRoughness)];
1541 fragmentShader <<
" qt_clearcoatRoughness *= texture2D(" <<
names.imageSampler <<
", "
1542 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1543 fragmentShader <<
" qt_clearcoatRoughness = clamp(qt_clearcoatRoughness, 0.0, 1.0);\n";
1547 if (enableTransmission) {
1548 fragmentShader.
addInclude(
"transmission.glsllib");
1551 fragmentShader <<
" qt_transmissionFactor = qt_material_properties4.w;\n";
1553 fragmentShader <<
" qt_global_transmission = vec3(0.0);\n";
1555 if (transmissionImage) {
1557 const bool hasIdentityMap = identityImages.contains(transmissionImage);
1559 generateImageUVSampler(vertexShader, fragmentShader, inKey, *transmissionImage, imageFragCoords, transmissionImage->m_imageNode.m_indexUV);
1561 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *transmissionImage, enableParallaxMapping, transmissionImage->m_imageNode.m_indexUV);
1562 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Transmission)];
1563 fragmentShader <<
" qt_transmissionFactor *= texture2D(" <<
names.imageSampler <<
", "
1564 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1572 fragmentShader <<
" qt_thicknessFactor = qt_material_thickness;\n";
1574 fragmentShader <<
" qt_attenuationColor = qt_material_attenuation.xyz;\n";
1575 fragmentShader <<
" qt_attenuationDistance = qt_material_attenuation.w;\n";
1577 if (thicknessImage) {
1579 const bool hasIdentityMap = identityImages.contains(thicknessImage);
1581 generateImageUVSampler(vertexShader, fragmentShader, inKey, *thicknessImage, imageFragCoords, thicknessImage->m_imageNode.m_indexUV);
1583 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *thicknessImage, enableParallaxMapping, thicknessImage->m_imageNode.m_indexUV);
1584 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Thickness)];
1585 fragmentShader <<
" qt_thicknessFactor *= texture2D(" <<
names.imageSampler <<
", "
1586 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1590 if (specularLightingEnabled) {
1592 fragmentShader.
addInclude(
"principledMaterialFresnel.glsllib");
1593 const bool useF90 = !lights.
isEmpty() || enableTransmission;
1598 fragmentShader <<
" qt_f0 = qt_F0_ior(qt_material_specular.w, qt_metalnessAmount, qt_diffuseColor.rgb);\n";
1600 fragmentShader <<
" qt_f90 = vec3(1.0);\n";
1604 fragmentShader <<
" qt_reflectance = max(max(qt_specularTint.r, qt_specularTint.g), qt_specularTint.b);\n";
1605 fragmentShader <<
" qt_f0 = qt_specularTint;\n";
1606 fragmentShader <<
" qt_specularTint = vec3(1.0);\n";
1608 fragmentShader <<
" qt_f90 = vec3(clamp(qt_reflectance * 50.0, 0.0, 1.0));\n";
1609 fragmentShader <<
" qt_diffuseColor.rgb *= (1 - qt_reflectance);\n";
1612 if (specularAAEnabled) {
1613 fragmentShader.
append(
" vec3 vNormalWsDdx = dFdx(qt_world_normal.xyz);\n");
1614 fragmentShader.
append(
" vec3 vNormalWsDdy = dFdy(qt_world_normal.xyz);\n");
1615 fragmentShader.
append(
" float flGeometricRoughnessFactor = pow(clamp(max(dot(vNormalWsDdx, vNormalWsDdx), dot(vNormalWsDdy, vNormalWsDdy)), 0.0, 1.0), 0.333);\n");
1616 fragmentShader.
append(
" qt_roughnessAmount = max(flGeometricRoughnessFactor, qt_roughnessAmount);\n");
1620 fragmentShader <<
" float qt_fresnelPower = qt_customFresnelPower;\n";
1622 fragmentShader <<
" float qt_fresnelPower = qt_material_properties2.x;\n";
1625 fragmentShader <<
" vec3 qt_principledMaterialFresnelValue = qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, "
1626 <<
"qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1627 if (enableFresnelScaleBias) {
1628 fragmentShader <<
" float qt_fresnelScale = qt_material_properties5.x;\n";
1629 fragmentShader <<
" float qt_fresnelBias = qt_material_properties5.y;\n";
1630 fragmentShader <<
" qt_principledMaterialFresnelValue = clamp(vec3(qt_fresnelBias) + "
1631 <<
"qt_fresnelScale * qt_principledMaterialFresnelValue, 0.0, 1.0);\n";
1633 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnelValue;\n";
1637 fragmentShader <<
" qt_specularTint = mix(vec3(1.0), qt_specularTint, 1.0 - qt_metalnessAmount);\n";
1640 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, "
1641 <<
"qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1645 fragmentShader.
addInclude(
"defaultMaterialFresnel.glsllib");
1646 fragmentShader <<
" qt_diffuseColor.rgb *= (1.0 - qt_dielectricSpecular(qt_material_specular.w)) * (1.0 - qt_metalnessAmount);\n";
1657 shaderLibraryManager,
1663 specularLightingEnabled,
1665 enableTransmission);
1671 fragmentShader <<
" global_diffuse_light = vec4(global_diffuse_light.rgb * qt_aoFactor, qt_objectOpacity * qt_diffuseColor.a);\n";
1673 if (hasReflectionProbe) {
1675 fragmentShader.
addInclude(
"sampleReflectionProbe.glsllib");
1677 fragmentShader <<
" vec3 qt_reflectionDiffuse = vec3(0.0);\n";
1679 fragmentShader <<
" qt_reflectionDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1681 fragmentShader <<
" qt_reflectionDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1684 if (specularLightingEnabled) {
1685 fragmentShader <<
" vec3 qt_reflectionSpecular = vec3(0.0);\n";
1687 fragmentShader <<
" qt_reflectionSpecular = "
1688 <<
"qt_specularTint * qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1690 fragmentShader <<
" qt_reflectionSpecular = qt_specularAmount * "
1691 <<
"qt_specularTint * qt_sampleGlossyReflection(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1694 if (enableClearcoat) {
1695 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1698 fragmentShader <<
" global_diffuse_light.rgb += qt_reflectionDiffuse;\n";
1699 if (specularLightingEnabled)
1700 fragmentShader <<
" global_specular_light += qt_reflectionSpecular;\n";
1701 if (enableClearcoat)
1702 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat;\n";
1703 }
else if (hasIblProbe) {
1705 fragmentShader.
addInclude(
"sampleProbe.glsllib");
1706 if (hasCustomIblProbe) {
1708 fragmentShader <<
" vec3 qt_iblDiffuse = vec3(0.0);\n";
1709 fragmentShader <<
" vec3 qt_iblSpecular = vec3(0.0);\n";
1710 fragmentShader <<
" qt_iblProbeProcessor(qt_iblDiffuse, qt_iblSpecular, qt_customBaseColor, qt_aoFactor, qt_specularFactor, qt_roughnessAmount, qt_world_normal, qt_view_vector";
1711 if (hasIblOrientation)
1712 fragmentShader <<
", qt_lightProbeOrientation";
1714 fragmentShader <<
", mat3(1.0)";
1716 fragmentShader <<
", qt_customShared);\n";
1718 fragmentShader <<
");\n";
1721 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1723 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1725 if (specularLightingEnabled) {
1727 fragmentShader <<
" vec3 qt_iblSpecular = "
1728 <<
"qt_specularTint * qt_sampleGlossyPrincipled(qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1730 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularAmount * "
1731 <<
"qt_specularTint * qt_sampleGlossy(qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1734 if (enableClearcoat) {
1735 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyPrincipled(qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1739 fragmentShader <<
" global_diffuse_light.rgb += qt_iblDiffuse * qt_aoFactor;\n";
1740 if (specularLightingEnabled)
1741 fragmentShader <<
" global_specular_light += qt_iblSpecular * qt_aoFactor;\n";
1742 if (enableClearcoat)
1743 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat * qt_aoFactor;\n";
1744 }
else if (hasCustomIblProbe) {
1746 fragmentShader.
addUniform(
"qt_lightProbe",
"samplerCube");
1747 fragmentShader.
addUniform(
"qt_lightProbeProperties",
"vec4");
1751 if (enableTransmission) {
1752 fragmentShader <<
" qt_global_transmission += qt_transmissionFactor * qt_getIBLVolumeRefraction(qt_world_normal, qt_view_vector, qt_roughnessAmount, "
1753 "qt_diffuseColor.rgb, qt_specularAmount, qt_varWorldPos, qt_material_specular.w, qt_thicknessFactor, qt_attenuationColor, qt_attenuationDistance);\n";
1757 bool texColorDeclared =
false;
1760 if (
image->m_mapType != QSSGRenderableImage::Type::Specular
1761 &&
image->m_mapType != QSSGRenderableImage::Type::Emissive)
1766 if (!texColorDeclared) {
1767 fragmentShader.
append(
" vec4 qt_texture_color;");
1768 texColorDeclared =
true;
1771 const bool hasIdentityMap = identityImages.contains(
image);
1777 const auto &
names = imageStringTable[int(
image->m_mapType)];
1778 fragmentShader <<
" qt_texture_color = texture2D(" <<
names.imageSampler
1779 <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
");\n";
1781 switch (
image->m_mapType) {
1782 case QSSGRenderableImage::Type::Specular:
1783 fragmentShader.
addInclude(
"tonemapping.glsllib");
1784 fragmentShader.
append(
" global_specular_light += qt_sRGBToLinear(qt_texture_color.rgb) * qt_specularTint;");
1785 fragmentShader.
append(
" global_diffuse_light.a *= qt_texture_color.a;");
1787 case QSSGRenderableImage::Type::Emissive:
1788 fragmentShader.
addInclude(
"tonemapping.glsllib");
1791 fragmentShader <<
" qt_global_emission *= qt_sRGBToLinear(vec3(qt_texture_color" <<
1792 channelStr(channelProps, inKey) <<
"));\n";
1794 fragmentShader.
append(
" qt_global_emission *= qt_sRGBToLinear(qt_texture_color.rgb);");
1804 if (enableTransmission)
1805 fragmentShader <<
" global_diffuse_light.rgb = mix(global_diffuse_light.rgb, qt_global_transmission, qt_transmissionFactor);\n";
1808 fragmentShader <<
" global_diffuse_light.rgb *= 1.0 - qt_metalnessAmount;\n";
1813 fragmentShader <<
" calculateFog(qt_global_emission, global_specular_light, global_diffuse_light.rgb);\n";
1816 fragmentShader <<
" vec4 qt_color_sum = vec4(global_diffuse_light.rgb + global_specular_light + qt_global_emission, global_diffuse_light.a);\n";
1818 if (enableClearcoat) {
1820 fragmentShader <<
" vec3 qt_clearcoatFresnel = qt_schlick3(qt_clearcoatF0, qt_clearcoatF90, clamp(dot(qt_clearcoatNormal, qt_view_vector), 0.0, 1.0), qt_material_clearcoat_fresnel_power);\n";
1821 if (enableClearcoatFresnelScaleBias) {
1822 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_material_properties5.z;\n";
1823 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_material_properties5.w;\n";
1824 fragmentShader <<
" qt_clearcoatFresnel = clamp(vec3(qt_clearcoatFresnelBias) + qt_clearcoatFresnelScale * qt_clearcoatFresnel, 0.0, 1.0);\n";
1826 fragmentShader <<
" qt_global_clearcoat = qt_global_clearcoat * qt_clearcoatAmount;\n";
1827 fragmentShader <<
" qt_color_sum.rgb = qt_color_sum.rgb * (1.0 - qt_clearcoatAmount * qt_clearcoatFresnel) + qt_global_clearcoat;\n";
1832 fragmentShader <<
" qt_customPostProcessor(qt_color_sum, global_diffuse_light, global_specular_light, qt_global_emission, qt_texCoord0, qt_texCoord1";
1834 fragmentShader <<
", qt_customShared);\n";
1836 fragmentShader <<
");\n";
1839 Q_ASSERT(!isDepthPass && !isOrthoShadowPass && !isCubeShadowPass);
1840 fragmentShader.
addInclude(
"tonemapping.glsllib");
1841 fragmentShader.
append(
" fragOutput = vec4(qt_tonemap(qt_color_sum));");
1845 fragmentShader.
append(
" vec3 debugOutput = vec3(0.0);\n");
1846 switch (debugMode) {
1848 fragmentShader.
append(
" debugOutput += qt_tonemap(qt_diffuseColor.rgb);\n");
1851 fragmentShader.
append(
" debugOutput += vec3(qt_roughnessAmount);\n");
1854 fragmentShader.
append(
" debugOutput += vec3(qt_metalnessAmount);\n");
1857 fragmentShader.
append(
" debugOutput += qt_tonemap(global_diffuse_light.rgb);\n");
1860 fragmentShader.
append(
" debugOutput += qt_tonemap(global_specular_light);\n");
1863 fragmentShader.
append(
" debugOutput += vec3(qt_shadow_map_occl);\n");
1866 fragmentShader.
append(
" debugOutput += qt_tonemap(qt_global_emission);\n");
1869 fragmentShader.
append(
" debugOutput += vec3(qt_aoFactor);\n");
1872 fragmentShader.
append(
" debugOutput += qt_world_normal * 0.5 + 0.5;\n");
1875 fragmentShader.
append(
" debugOutput += qt_tangent * 0.5 + 0.5;\n");
1878 fragmentShader.
append(
" debugOutput += qt_binormal * 0.5 + 0.5;\n");
1882 fragmentShader.
append(
" debugOutput += qt_f0;");
1888 fragmentShader.
append(
" fragOutput = vec4(debugOutput, 1.0);\n");
1891 if ((isOrthoShadowPass || isCubeShadowPass || isDepthPass) && isOpaqueDepthPrePass) {
1892 fragmentShader <<
" if ((qt_diffuseColor.a * qt_objectOpacity) < 1.0)\n";
1893 fragmentShader <<
" discard;\n";
1896 if (isOrthoShadowPass) {
1898 fragmentShader.
addUniform(
"qt_shadowDepthAdjust",
"vec2");
1899 fragmentShader <<
" // directional shadow pass\n"
1900 <<
" float qt_shadowDepth = (qt_varDepth + qt_shadowDepthAdjust.x) * qt_shadowDepthAdjust.y;\n"
1901 <<
" fragOutput = vec4(qt_shadowDepth);\n";
1902 }
else if (isCubeShadowPass) {
1904 fragmentShader.
addUniform(
"qt_cameraPosition",
"vec3");
1905 fragmentShader.
addUniform(
"qt_cameraProperties",
"vec2");
1906 fragmentShader <<
" // omnidirectional shadow pass\n"
1907 <<
" vec3 qt_shadowCamPos = vec3(qt_cameraPosition.x, qt_cameraPosition.y, qt_cameraPosition.z);\n"
1908 <<
" float qt_shadowDist = length(qt_varShadowWorldPos - qt_shadowCamPos);\n"
1909 <<
" qt_shadowDist = (qt_shadowDist - qt_cameraProperties.x) / (qt_cameraProperties.y - qt_cameraProperties.x);\n"
1910 <<
" fragOutput = vec4(qt_shadowDist, qt_shadowDist, qt_shadowDist, 1.0);\n";
1912 fragmentShader.
addInclude(
"tonemapping.glsllib");
1913 fragmentShader.
append(
" fragOutput = vec4(qt_tonemap(qt_diffuseColor.rgb), qt_diffuseColor.a * qt_objectOpacity);");
1984 const QSSGDataView<float> &inMorphWeights,
1990 bool receivesShadows,
1991 bool receivesReflections,
2000 const QVector2D camProperties(inCameras[0]->clipNear, inCameras[0]->clipFar);
2001 shaders.setUniform(ubufData,
"qt_cameraProperties", &camProperties, 2 *
sizeof(
float), &cui.cameraPropertiesIdx);
2003 const int viewCount = inCameras.count();
2004 if (viewCount < 2) {
2005 const QVector3D camGlobalPos = inCameras[0]->getGlobalPos();
2006 shaders.setUniform(ubufData,
"qt_cameraPosition", &camGlobalPos, 3 *
sizeof(
float), &cui.cameraPositionIdx);
2007 const QVector3D camDirection =
QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2008 ? inRenderProperties.renderedCameraData.value()[0].direction
2010 shaders.setUniform(ubufData,
"qt_cameraDirection", &camDirection, 3 *
sizeof(
float), &cui.cameraDirectionIdx);
2012 QVarLengthArray<QVector3D, 2> camGlobalPos(viewCount);
2013 QVarLengthArray<QVector3D> camDirection(viewCount);
2014 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
2015 camGlobalPos[viewIndex] = inCameras[viewIndex]->getGlobalPos();
2016 camDirection[viewIndex] =
QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2017 ? inRenderProperties.renderedCameraData.value()[viewIndex].direction
2027 bool usesProjectionMatrix =
false;
2028 bool usesInvProjectionMatrix =
false;
2029 bool usesViewMatrix =
false;
2030 bool usesViewProjectionMatrix =
false;
2031 bool usesModelViewProjectionMatrix =
false;
2032 bool usesNormalMatrix =
false;
2033 bool usesParentMatrix =
false;
2035 if (inMaterial.type == QSSGRenderGraphObject::Type::CustomMaterial) {
2040 usesViewMatrix =
true;
2041 usesViewProjectionMatrix =
true;
2043 const bool usesInstancing = inProperties.m_usesInstancing.getValue(inKey);
2044 if (usesInstancing) {
2046 usesViewProjectionMatrix =
true;
2047 usesParentMatrix =
true;
2049 usesModelViewProjectionMatrix =
true;
2050 usesNormalMatrix =
true;
2054 usesViewProjectionMatrix =
true;
2057 if (usesProjectionMatrix || usesInvProjectionMatrix) {
2058 if (viewCount < 2) {
2059 const QMatrix4x4 projection = clipSpaceCorrMatrix * inCameras[0]->projection;
2060 if (usesProjectionMatrix)
2061 shaders.setUniform(ubufData,
"qt_projectionMatrix", projection.
constData(), 16 *
sizeof(float), &cui.projectionMatrixIdx);
2062 if (usesInvProjectionMatrix)
2063 shaders.setUniform(ubufData,
"qt_inverseProjectionMatrix", projection.
inverted().
constData(), 16 *
sizeof (float), &cui.inverseProjectionMatrixIdx);
2065 QVarLengthArray<QMatrix4x4, 2> projections(viewCount);
2066 QVarLengthArray<QMatrix4x4, 2> invertedProjections(viewCount);
2067 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
2068 projections[viewIndex] = clipSpaceCorrMatrix * inCameras[viewIndex]->projection;
2069 if (usesInvProjectionMatrix)
2070 invertedProjections[viewIndex] = projections[viewIndex].
inverted();
2072 if (usesProjectionMatrix)
2074 if (usesInvProjectionMatrix)
2078 if (usesViewMatrix) {
2079 if (viewCount < 2) {
2081 shaders.setUniform(ubufData,
"qt_viewMatrix", viewMatrix.constData(), 16 *
sizeof(
float), &cui.viewMatrixIdx);
2083 QVarLengthArray<QMatrix4x4, 2> viewMatrices(viewCount);
2084 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
2085 viewMatrices[viewIndex] = inCameras[viewIndex]->globalTransform.inverted();
2089 if (usesViewProjectionMatrix) {
2090 if (viewCount < 2) {
2092 inCameras[0]->calculateViewProjectionMatrix(viewProj);
2093 viewProj = clipSpaceCorrMatrix * viewProj;
2094 shaders.setUniform(ubufData,
"qt_viewProjectionMatrix", viewProj.constData(), 16 *
sizeof(
float), &cui.viewProjectionMatrixIdx);
2096 QVarLengthArray<QMatrix4x4, 2> viewProjections(viewCount);
2097 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
2098 inCameras[viewIndex]->calculateViewProjectionMatrix(viewProjections[viewIndex]);
2099 viewProjections[viewIndex] = clipSpaceCorrMatrix * viewProjections[viewIndex];
2107 shaders.setUniform(ubufData,
"qt_modelMatrix", localInstanceTransform.
constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2109 shaders.setUniform(ubufData,
"qt_modelMatrix", inGlobalTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2111 if (usesModelViewProjectionMatrix) {
2112 if (viewCount < 2) {
2114 mvp *= inModelViewProjections[0];
2115 shaders.setUniform(ubufData,
"qt_modelViewProjection", mvp.constData(), 16 *
sizeof(
float), &cui.modelViewProjectionIdx);
2117 QVarLengthArray<QMatrix4x4, 2> mvps(viewCount);
2118 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
2119 mvps[viewIndex] = clipSpaceCorrMatrix * inModelViewProjections[viewIndex];
2123 if (usesNormalMatrix)
2124 shaders.setUniform(ubufData,
"qt_normalMatrix", inNormalMatrix.constData(), 12 *
sizeof(
float), &cui.normalMatrixIdx,
2126 if (usesParentMatrix)
2127 shaders.setUniform(ubufData,
"qt_parentMatrix", globalInstanceTransform.
constData(), 16 *
sizeof(
float));
2130 const qsizetype morphSize = inProperties.m_targetCount.getValue(inKey);
2131 if (morphSize > 0) {
2132 if (inMorphWeights.mSize >= morphSize) {
2133 shaders.setUniformArray(ubufData,
"qt_morphWeights", inMorphWeights.mData, morphSize,
2136 const QList<float> zeroWeights(morphSize - inMorphWeights.mSize, 0.0f);
2137 QList<float> newWeights(inMorphWeights.mData, inMorphWeights.mData + inMorphWeights.mSize);
2138 newWeights.append(zeroWeights);
2139 shaders.setUniformArray(ubufData,
"qt_morphWeights", newWeights.constData(), morphSize,
2148 lightsUniformData.
count = 0;
2150 for (
quint32 lightIdx = 0, shadowMapCount = 0, lightEnd = inLights.size();
2154 const bool lightShadows = inLights[lightIdx].shadows;
2155 const float brightness = theLight->m_brightness;
2156 lightColor[lightIdx][0] = theLight->m_diffuseColor.x() * brightness;
2157 lightColor[lightIdx][1] = theLight->m_diffuseColor.y() * brightness;
2158 lightColor[lightIdx][2] = theLight->m_diffuseColor.z() * brightness;
2159 lightsUniformData.
count += 1;
2161 const QVector3D &lightSpecular(theLight->m_specularColor);
2162 lightData.
specular[0] = lightSpecular.x() * brightness;
2163 lightData.
specular[1] = lightSpecular.y() * brightness;
2164 lightData.
specular[2] = lightSpecular.z() * brightness;
2185 QSSGShadowMapEntry *pEntry = inRenderProperties.getShadowMapManager()->shadowMapEntry(lightIdx);
2190 if (theLight->type != QSSGRenderLight::Type::DirectionalLight) {
2191 theShadowMapProperties.shadowMapTexture = pEntry->m_rhiDepthCube;
2192 theShadowMapProperties.shadowMapTextureUniformName =
names.shadowCube;
2193 if (receivesShadows)
2194 shaders.setUniform(ubufData,
names.shadowMatrix, pEntry->m_lightView.constData(), 16 *
sizeof(
float));
2198 theShadowMapProperties.shadowMapTexture = pEntry->m_rhiDepthMap;
2199 theShadowMapProperties.shadowMapTextureUniformName =
names.shadowMap;
2200 if (receivesShadows) {
2206 0.0, 0.0, 0.0, 1.0 };
2208 shaders.setUniform(ubufData,
names.shadowMatrix,
m.constData(), 16 *
sizeof(
float));
2214 if (receivesShadows) {
2215 const QVector4D shadowControl(theLight->m_shadowBias,
2216 theLight->m_shadowFactor,
2217 theLight->m_shadowMapFar,
2218 globalRenderData.isYUpInFramebuffer ? 0.0f : 1.0f);
2219 shaders.setUniform(ubufData,
names.shadowControl, &shadowControl, 4 *
sizeof(
float));
2225 if (theLight->type == QSSGRenderLight::Type::PointLight
2226 || theLight->type == QSSGRenderLight::Type::SpotLight) {
2227 const QVector3D globalPos = theLight->getGlobalPos();
2236 if (theLight->type == QSSGRenderLight::Type::SpotLight) {
2237 const float coneAngle = theLight->m_coneAngle;
2238 const float innerConeAngle = (theLight->m_innerConeAngle > coneAngle) ?
2239 coneAngle : theLight->m_innerConeAngle;
2245 theLightAmbientTotal += theLight->m_ambientColor;
2255 shaders.setLightmapTexture(lightmapTexture);
2259 const auto &lightProbeData =
layer.lightProbeSettings;
2263 if (materialIblProbe)
2264 theLightProbe = materialIblProbe;
2268 if (theLightProbe && lightProbeTexture.
m_texture) {
2271 const int maxMipLevel = lightProbeTexture.
m_mipmapCount - 1;
2273 if (!materialIblProbe && !lightProbeData.probeOrientation.isIdentity()) {
2274 shaders.setUniform(ubufData,
"qt_lightProbeOrientation",
2275 lightProbeData.probeOrientation.constData(),
2276 12 *
sizeof(
float), &cui.lightProbeOrientationIdx,
2280 const float props[4] = { 0.0f, float(maxMipLevel), lightProbeData.probeHorizon, lightProbeData.probeExposure };
2281 shaders.setUniform(ubufData,
"qt_lightProbeProperties",
props, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2283 shaders.setLightProbeTexture(lightProbeTexture.
m_texture, theHorzLightProbeTilingMode, theVertLightProbeTilingMode);
2286 const float emptyProps[4] = { 0.0f, 0.0f, -1.0f, 0.0f };
2287 shaders.setUniform(ubufData,
"qt_lightProbeProperties", emptyProps, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2289 shaders.setLightProbeTexture(
nullptr);
2292 if (receivesReflections && reflectionProbe.
enabled) {
2293 shaders.setUniform(ubufData,
"qt_reflectionProbeCubeMapCenter", &reflectionProbe.
probeCubeMapCenter, 3 *
sizeof(
float), &cui.reflectionProbeCubeMapCenter);
2294 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMin", &reflectionProbe.
probeBoxMin, 3 *
sizeof(
float), &cui.reflectionProbeBoxMin);
2295 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMax", &reflectionProbe.
probeBoxMax, 3 *
sizeof(
float), &cui.reflectionProbeBoxMax);
2296 shaders.setUniform(ubufData,
"qt_reflectionProbeCorrection", &reflectionProbe.
parallaxCorrection,
sizeof(
int), &cui.reflectionProbeCorrection);
2300 shaders.setUniform(ubufData,
"qt_material_emissive_color", &emissiveColor, 3 *
sizeof(
float), &cui.material_emissiveColorIdx);
2302 const auto qMix = [](
float x,
float y,
float a) {
2303 return (
x * (1.0f -
a) + (
y *
a));
2307 return QVector3D{qMix(
x.x(),
y.x(),
a), qMix(
x.y(),
y.y(),
a), qMix(
x.z(),
y.z(),
a)};
2313 : materialSpecularTint;
2314 shaders.setUniform(ubufData,
"qt_material_base_color", &
color, 4 *
sizeof(
float), &cui.material_baseColorIdx);
2316 const float ior = materialAdapter->
ior();
2317 QVector4D specularColor(specularTint, ior);
2318 shaders.setUniform(ubufData,
"qt_material_specular", &specularColor, 4 *
sizeof(
float), &cui.material_specularIdx);
2321 const bool hasLighting = materialAdapter->
hasLighting();
2322 shaders.setLightsEnabled(hasLighting);
2324 for (
int lightIdx = 0; lightIdx < lightsUniformData.
count; ++lightIdx) {
2326 lightData.
diffuse[0] = lightColor[lightIdx][0];
2327 lightData.
diffuse[1] = lightColor[lightIdx][1];
2328 lightData.
diffuse[2] = lightColor[lightIdx][2];
2331 memcpy(ubufData +
shaders.ub0LightDataOffset(), &lightsUniformData,
shaders.ub0LightDataSize());
2334 shaders.setUniform(ubufData,
"qt_light_ambient_total", &theLightAmbientTotal, 3 *
sizeof(
float), &cui.light_ambient_totalIdx);
2336 const float materialProperties[4] = {
2342 shaders.setUniform(ubufData,
"qt_material_properties", materialProperties, 4 *
sizeof(
float), &cui.material_propertiesIdx);
2344 const float materialProperties2[4] = {
2350 shaders.setUniform(ubufData,
"qt_material_properties2", materialProperties2, 4 *
sizeof(
float), &cui.material_properties2Idx);
2352 const float materialProperties3[4] = {
2358 shaders.setUniform(ubufData,
"qt_material_properties3", materialProperties3, 4 *
sizeof(
float), &cui.material_properties3Idx);
2360 const float materialProperties4[4] = {
2366 shaders.setUniform(ubufData,
"qt_material_properties4", materialProperties4, 4 *
sizeof(
float), &cui.material_properties4Idx);
2368 if (inProperties.m_fresnelScaleBiasEnabled.getValue(inKey) || inProperties.m_clearcoatFresnelScaleBiasEnabled.getValue(inKey)) {
2369 const float materialProperties5[4] = {
2375 shaders.setUniform(ubufData,
"qt_material_properties5", materialProperties5, 4 *
sizeof(
float), &cui.material_properties5Idx);
2379 shaders.setUniform(ubufData,
"qt_material_clearcoat_normal_strength", &material_clearcoat_normal_strength,
sizeof(
float), &cui.clearcoatNormalStrengthIdx);
2382 shaders.setUniform(ubufData,
"qt_material_clearcoat_fresnel_power", &material_clearcoat_fresnel_power,
sizeof(
float), &cui.clearcoatFresnelPowerIdx);
2387 shaders.setUniform(ubufData,
"qt_material_attenuation", &attenuationProperties, 4 *
sizeof(
float), &cui.material_attenuationIdx);
2390 shaders.setUniform(ubufData,
"qt_material_thickness", &thickness,
sizeof(
float), &cui.thicknessFactorIdx);
2393 const float rhiProperties[4] = {
2394 globalRenderData.isYUpInFramebuffer ? 1.0f : -1.0f,
2395 globalRenderData.isYUpInNDC ? 1.0f : -1.0f,
2396 globalRenderData.isClipDepthZeroToOne ? 0.0f : -1.0f,
2399 shaders.setUniform(ubufData,
"qt_rhi_properties", rhiProperties, 4 *
sizeof(
float), &cui.rhiPropertiesIdx);
2404 const auto &
names = imageStringTable[int(theImage->m_mapType)];
2405 if (imageIdx == cui.imageIndices.size())
2407 auto &
indices = cui.imageIndices[imageIdx];
2409 const QMatrix4x4 &textureTransform = theImage->m_imageNode.m_textureTransform;
2412 const float *dataPtr(textureTransform.constData());
2416 const float offsets[3] = { dataPtr[12], dataPtr[13], 0.0f };
2419 const float rotations[4] = { dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5] };
2420 shaders.setUniform(ubufData,
names.imageRotations, rotations,
sizeof(rotations), &
indices.imageRotationsUniformIndex);
2423 if (shadowDepthAdjust)
2424 shaders.setUniform(ubufData,
"qt_shadowDepthAdjust", shadowDepthAdjust, 2 *
sizeof(
float), &cui.shadowDepthAdjustIdx);
2426 const bool usesPointsTopology = inProperties.m_usesPointsTopology.getValue(inKey);
2427 if (usesPointsTopology) {
2428 const float pointSize = materialAdapter->
pointSize();
2429 shaders.setUniform(ubufData,
"qt_materialPointSize", &pointSize,
sizeof(
float), &cui.pointSizeIdx);
2436 if (inRenderProperties.layer.fog.enabled) {
2437 const float fogColor[4] = {
2438 inRenderProperties.layer.fog.color.x(),
2439 inRenderProperties.layer.fog.color.y(),
2440 inRenderProperties.layer.fog.color.z(),
2441 inRenderProperties.layer.fog.density
2443 shaders.setUniform(ubufData,
"qt_fogColor", fogColor, 4 *
sizeof(
float), &cui.fogColorIdx);
2444 const float fogDepthProperties[4] = {
2445 inRenderProperties.layer.fog.depthBegin,
2446 inRenderProperties.layer.fog.depthEnd,
2447 inRenderProperties.layer.fog.depthCurve,
2448 inRenderProperties.layer.fog.depthEnabled ? 1.0f : 0.0f
2450 shaders.setUniform(ubufData,
"qt_fogDepthProperties", fogDepthProperties, 4 *
sizeof(
float), &cui.fogDepthPropertiesIdx);
2451 const float fogHeightProperties[4] = {
2452 inRenderProperties.layer.fog.heightMin,
2453 inRenderProperties.layer.fog.heightMax,
2454 inRenderProperties.layer.fog.heightCurve,
2455 inRenderProperties.layer.fog.heightEnabled ? 1.0f : 0.0f
2457 shaders.setUniform(ubufData,
"qt_fogHeightProperties", fogHeightProperties, 4 *
sizeof(
float), &cui.fogHeightPropertiesIdx);
2458 const float fogTransmitProperties[4] = {
2459 inRenderProperties.layer.fog.transmitCurve,
2462 inRenderProperties.layer.fog.transmitEnabled ? 1.0f : 0.0f
2464 shaders.setUniform(ubufData,
"qt_fogTransmitProperties", fogTransmitProperties, 4 *
sizeof(
float), &cui.fogTransmitPropertiesIdx);
2467 inPipelineState->lineWidth = materialAdapter->
lineWidth();