888 QSSGMaterialVertexPipeline &vertexShader,
889 const QSSGShaderDefaultMaterialKey &inKey,
890 const QSSGShaderDefaultMaterialKeyProperties &keyProps,
891 const QSSGShaderFeatures &featureSet,
892 const QSSGRenderGraphObject &inMaterial,
893 const QSSGShaderLightListView &lights,
894 QSSGRenderableImage *firstImage,
895 QSSGShaderLibraryManager &shaderLibraryManager)
897 QSSGShaderMaterialAdapter *materialAdapter = getMaterialAdapter(inMaterial);
898 auto hasCustomFunction = [&shaderLibraryManager, materialAdapter](
const QByteArray &funcName) {
899 return materialAdapter->hasCustomShaderFunction(QSSGShaderCache::ShaderType::Fragment,
901 shaderLibraryManager);
904 bool metalnessEnabled = materialAdapter->isMetalnessEnabled();
908 bool vertexColorsEnabled = materialAdapter->isVertexColorsEnabled()
909 || materialAdapter->isVertexColorsMaskEnabled()
910 || keyProps.m_usesInstancing.getValue(inKey)
911 || keyProps.m_blendParticles.getValue(inKey);
913 bool hasLighting = materialAdapter->hasLighting();
914 bool isDoubleSided = keyProps.m_isDoubleSided.getValue(inKey);
915 bool hasImage = firstImage !=
nullptr;
917 bool hasIblProbe = keyProps.m_hasIbl.getValue(inKey);
918 bool specularLightingEnabled = metalnessEnabled || materialAdapter->isSpecularEnabled() || hasIblProbe;
919 bool specularAAEnabled = keyProps.m_specularAAEnabled.getValue(inKey);
920 quint32 numMorphTargets = keyProps.m_targetCount.getValue(inKey);
922 QSSGRenderableImage *bumpImage =
nullptr;
923 quint32 imageIdx = 0;
924 QSSGRenderableImage *specularAmountImage =
nullptr;
925 QSSGRenderableImage *roughnessImage =
nullptr;
926 QSSGRenderableImage *metalnessImage =
nullptr;
927 QSSGRenderableImage *occlusionImage =
nullptr;
929 QSSGRenderableImage *normalImage =
nullptr;
931 QSSGRenderableImage *translucencyImage =
nullptr;
933 QSSGRenderableImage *opacityImage =
nullptr;
935 QSSGRenderableImage *heightImage =
nullptr;
937 QSSGRenderableImage *clearcoatImage =
nullptr;
938 QSSGRenderableImage *clearcoatRoughnessImage =
nullptr;
939 QSSGRenderableImage *clearcoatNormalImage =
nullptr;
941 QSSGRenderableImage *transmissionImage =
nullptr;
943 QSSGRenderableImage *thicknessImage =
nullptr;
945 QSSGRenderableImage *baseImage =
nullptr;
948 QVector<QSSGRenderableImage *> identityImages;
951 auto channelStr = [](
const QSSGShaderKeyTextureChannel &chProp,
const QSSGShaderDefaultMaterialKey &inKey) -> QByteArray {
953 switch (chProp.getTextureChannel(inKey)) {
954 case QSSGShaderKeyTextureChannel::R:
957 case QSSGShaderKeyTextureChannel::G:
960 case QSSGShaderKeyTextureChannel::B:
963 case QSSGShaderKeyTextureChannel::A:
970 auto maskVariableByVertexColorChannel = [&fragmentShader, materialAdapter](
const QByteArray &maskVariable
971 ,
const QSSGRenderDefaultMaterial::VertexColorMask &maskEnum ){
972 if (materialAdapter->isVertexColorsMaskEnabled()) {
973 if ( materialAdapter->vertexColorRedMask() & maskEnum )
974 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.r;\n";
975 else if ( materialAdapter->vertexColorGreenMask() & maskEnum )
976 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.g;\n";
977 else if ( materialAdapter->vertexColorBlueMask() & maskEnum )
978 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.b;\n";
979 else if ( materialAdapter->vertexColorAlphaMask() & maskEnum )
980 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.a;\n";
984 for (QSSGRenderableImage *img = firstImage; img !=
nullptr; img = img->m_nextImage, ++imageIdx) {
985 if (img->m_imageNode.isImageTransformIdentity())
986 identityImages.push_back(img);
987 if (img->m_mapType == QSSGRenderableImage::Type::BaseColor || img->m_mapType == QSSGRenderableImage::Type::Diffuse) {
989 }
else if (img->m_mapType == QSSGRenderableImage::Type::Bump) {
991 }
else if (img->m_mapType == QSSGRenderableImage::Type::SpecularAmountMap) {
992 specularAmountImage = img;
993 }
else if (img->m_mapType == QSSGRenderableImage::Type::Roughness) {
994 roughnessImage = img;
995 }
else if (img->m_mapType == QSSGRenderableImage::Type::Metalness) {
996 metalnessImage = img;
997 }
else if (img->m_mapType == QSSGRenderableImage::Type::Occlusion) {
998 occlusionImage = img;
999 }
else if (img->m_mapType == QSSGRenderableImage::Type::Normal) {
1001 }
else if (img->m_mapType == QSSGRenderableImage::Type::Translucency) {
1002 translucencyImage = img;
1003 }
else if (img->m_mapType == QSSGRenderableImage::Type::Opacity) {
1005 }
else if (img->m_mapType == QSSGRenderableImage::Type::Height) {
1007 }
else if (img->m_mapType == QSSGRenderableImage::Type::Clearcoat) {
1008 clearcoatImage = img;
1009 }
else if (img->m_mapType == QSSGRenderableImage::Type::ClearcoatRoughness) {
1010 clearcoatRoughnessImage = img;
1011 }
else if (img->m_mapType == QSSGRenderableImage::Type::ClearcoatNormal) {
1012 clearcoatNormalImage = img;
1013 }
else if (img->m_mapType == QSSGRenderableImage::Type::Transmission) {
1014 transmissionImage = img;
1015 }
else if (img->m_mapType == QSSGRenderableImage::Type::Thickness) {
1016 thicknessImage = img;
1020 const bool isDepthPass = featureSet.isSet(QSSGShaderFeatures::Feature::DepthPass);
1021 const bool isOrthoShadowPass = featureSet.isSet(QSSGShaderFeatures::Feature::OrthoShadowPass);
1022 const bool isPerspectiveShadowPass = featureSet.isSet(QSSGShaderFeatures::Feature::PerspectiveShadowPass);
1023 const bool isOpaqueDepthPrePass = featureSet.isSet(QSSGShaderFeatures::Feature::OpaqueDepthPrePass);
1024 const bool hasIblOrientation = featureSet.isSet(QSSGShaderFeatures::Feature::IblOrientation);
1025 bool enableShadowMaps = featureSet.isSet(QSSGShaderFeatures::Feature::Ssm);
1026 bool enableSSAO = featureSet.isSet(QSSGShaderFeatures::Feature::Ssao);
1027 bool enableLightmap = featureSet.isSet(QSSGShaderFeatures::Feature::Lightmap);
1028 bool hasReflectionProbe = featureSet.isSet(QSSGShaderFeatures::Feature::ReflectionProbe);
1029 bool enableBumpNormal = normalImage || bumpImage;
1030 bool genBumpNormalImageCoords =
false;
1031 bool enableParallaxMapping = heightImage !=
nullptr;
1032 const bool enableClearcoat = materialAdapter->isClearcoatEnabled();
1033 const bool enableTransmission = materialAdapter->isTransmissionEnabled();
1034 const bool enableFresnelScaleBias = materialAdapter->isFresnelScaleBiasEnabled();
1035 const bool enableClearcoatFresnelScaleBias = materialAdapter->isClearcoatFresnelScaleBiasEnabled();
1037 specularLightingEnabled |= specularAmountImage !=
nullptr;
1038 specularLightingEnabled |= hasReflectionProbe;
1040 const bool hasCustomVert = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Vertex);
1041 auto debugMode = QSSGRenderLayer::MaterialDebugMode(keyProps.m_debugMode.getValue(inKey));
1042 const bool enableFog = keyProps.m_fogEnabled.getValue(inKey);
1044 const int viewCount = featureSet.isSet(QSSGShaderFeatures::Feature::DisableMultiView)
1045 ? 1 : keyProps.m_viewCount.getValue(inKey);
1048 if (numMorphTargets > 0 || hasCustomVert) {
1049 vertexShader.addDefinition(QByteArrayLiteral(
"QT_MORPH_MAX_COUNT"),
1050 QByteArray::number(numMorphTargets));
1052 if ((offset = keyProps.m_targetPositionOffset.getValue(inKey)) < UINT8_MAX) {
1053 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_POSITION_OFFSET"),
1054 QByteArray::number(offset));
1056 if ((offset = keyProps.m_targetNormalOffset.getValue(inKey)) < UINT8_MAX) {
1057 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_NORMAL_OFFSET"),
1058 QByteArray::number(offset));
1060 if ((offset = keyProps.m_targetTangentOffset.getValue(inKey)) < UINT8_MAX) {
1061 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TANGENT_OFFSET"),
1062 QByteArray::number(offset));
1064 if ((offset = keyProps.m_targetBinormalOffset.getValue(inKey)) < UINT8_MAX) {
1065 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_BINORMAL_OFFSET"),
1066 QByteArray::number(offset));
1068 if ((offset = keyProps.m_targetTexCoord0Offset.getValue(inKey)) < UINT8_MAX) {
1069 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TEX0_OFFSET"),
1070 QByteArray::number(offset));
1072 if ((offset = keyProps.m_targetTexCoord1Offset.getValue(inKey)) < UINT8_MAX) {
1073 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TEX1_OFFSET"),
1074 QByteArray::number(offset));
1076 if ((offset = keyProps.m_targetColorOffset.getValue(inKey)) < UINT8_MAX) {
1077 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_COLOR_OFFSET"),
1078 QByteArray::number(offset));
1082 bool includeCustomFragmentMain =
true;
1083 if (isDepthPass || isOrthoShadowPass || isPerspectiveShadowPass) {
1084 hasLighting =
false;
1086 enableShadowMaps =
false;
1087 enableLightmap =
false;
1089 metalnessEnabled =
false;
1090 specularLightingEnabled =
false;
1092 if (!isOpaqueDepthPrePass) {
1093 vertexColorsEnabled =
false;
1094 baseImage =
nullptr;
1095 includeCustomFragmentMain =
false;
1099 bool includeSSAOVars = enableSSAO || enableShadowMaps;
1101 vertexShader.beginFragmentGeneration(shaderLibraryManager);
1104 const bool hasCustomFrag = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
1105 const bool usesSharedVar = materialAdapter->usesSharedVariables();
1106 if (hasCustomFrag && materialAdapter->isUnshaded())
1113 fragmentShader.addUniform(
"qt_material_emissive_color",
"vec3");
1114 fragmentShader.addUniform(
"qt_material_base_color",
"vec4");
1115 fragmentShader.addUniform(
"qt_material_properties",
"vec4");
1116 fragmentShader.addUniform(
"qt_material_properties2",
"vec4");
1117 fragmentShader.addUniform(
"qt_material_properties3",
"vec4");
1118 if (enableParallaxMapping || enableTransmission)
1119 fragmentShader.addUniform(
"qt_material_properties4",
"vec4");
1120 if (!hasCustomFrag) {
1121 if (enableTransmission) {
1122 fragmentShader.addUniform(
"qt_material_attenuation",
"vec4");
1123 fragmentShader.addUniform(
"qt_material_thickness",
"float");
1125 if (enableFresnelScaleBias || enableClearcoatFresnelScaleBias)
1126 fragmentShader.addUniform(
"qt_material_properties5",
"vec4");
1127 fragmentShader.addUniform(
"qt_material_clearcoat_normal_strength",
"float");
1128 fragmentShader.addUniform(
"qt_material_clearcoat_fresnel_power",
"float");
1131 if (vertexColorsEnabled) {
1132 vertexShader.generateVertexColor(inKey);
1134 fragmentShader.append(
" vec4 qt_vertColorMask = vec4(1.0);");
1135 fragmentShader.append(
" vec4 qt_vertColor = vec4(1.0);");
1138 if (hasImage && ((!isDepthPass && !isOrthoShadowPass && !isPerspectiveShadowPass) || isOpaqueDepthPrePass)) {
1139 fragmentShader.append(
" vec3 qt_uTransform;");
1140 fragmentShader.append(
" vec3 qt_vTransform;");
1143 if (hasLighting || hasCustomFrag) {
1145 vertexShader.generateViewVector(inKey);
1146 if (keyProps.m_usesProjectionMatrix.getValue(inKey)) {
1148 fragmentShader.addUniformArray(
"qt_projectionMatrix",
"mat4", viewCount);
1150 fragmentShader.addUniform(
"qt_projectionMatrix",
"mat4");
1152 if (keyProps.m_usesInverseProjectionMatrix.getValue(inKey)) {
1154 fragmentShader.addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", viewCount);
1156 fragmentShader.addUniform(
"qt_inverseProjectionMatrix",
"mat4");
1158 vertexShader.generateWorldNormal(inKey);
1159 vertexShader.generateWorldPosition(inKey);
1161 const bool usingDefaultMaterialSpecularGGX = !(materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy()) && materialAdapter->specularModel() == QSSGRenderDefaultMaterial::MaterialSpecularModel::KGGX;
1163 const bool tangentOrBinormalDebugMode = (debugMode == QSSGRenderLayer::MaterialDebugMode::Tangent) || (debugMode == QSSGRenderLayer::MaterialDebugMode::Binormal);
1164 const bool needsTangentAndBinormal = hasCustomFrag || enableParallaxMapping || clearcoatNormalImage || enableBumpNormal || usingDefaultMaterialSpecularGGX || tangentOrBinormalDebugMode;
1167 if (needsTangentAndBinormal) {
1168 bool genTangent =
false;
1169 bool genBinormal =
false;
1170 vertexShader.generateVarTangentAndBinormal(inKey, genTangent, genBinormal);
1172 if (enableBumpNormal && !genTangent) {
1176 auto *bumpNormalImage = bumpImage !=
nullptr ? bumpImage : normalImage;
1177 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *bumpNormalImage,
true, bumpNormalImage->m_imageNode.m_indexUV);
1178 genBumpNormalImageCoords =
true;
1180 int id = (bumpImage !=
nullptr) ?
int(QSSGRenderableImage::Type::Bump) :
int(QSSGRenderableImage::Type::Normal);
1184 fragmentShader <<
" qt_tangent = (dUVdy.y * dFdx(qt_varWorldPos) - dUVdx.y * dFdy(qt_varWorldPos)) / (dUVdx.x * dUVdy.y - dUVdx.y * dUVdy.x);\n"
1185 <<
" qt_tangent = qt_tangent - dot(qt_world_normal, qt_tangent) * qt_world_normal;\n"
1186 <<
" qt_tangent = normalize(qt_tangent);\n";
1189 fragmentShader <<
" qt_binormal = cross(qt_world_normal, qt_tangent);\n";
1192 if (isDoubleSided) {
1193 fragmentShader.append(
"#if QSHADER_HLSL && QSHADER_VIEW_COUNT >= 2");
1194 fragmentShader.append(
" const float qt_facing = 1.0;");
1195 fragmentShader.append(
"#else");
1196 fragmentShader.append(
" const float qt_facing = gl_FrontFacing ? 1.0 : -1.0;");
1197 fragmentShader.append(
"#endif");
1198 fragmentShader.append(
" qt_world_normal *= qt_facing;\n");
1199 if (needsTangentAndBinormal) {
1200 fragmentShader.append(
" qt_tangent *= qt_facing;");
1201 fragmentShader.append(
" qt_binormal *= qt_facing;");
1206 if (hasCustomFrag) {
1212 fragmentShader <<
" float qt_customOcclusionAmount = 1.0;\n";
1213 fragmentShader <<
" float qt_customIOR = 1.5;\n";
1214 fragmentShader <<
" float qt_customSpecularAmount = 0.5;\n";
1215 fragmentShader <<
" float qt_customSpecularRoughness = 0.0;\n";
1216 fragmentShader <<
" float qt_customMetalnessAmount = 0.0;\n";
1217 fragmentShader <<
" float qt_customFresnelPower = 5.0;\n";
1218 fragmentShader <<
" vec4 qt_customBaseColor = vec4(1.0);\n";
1219 fragmentShader <<
" vec3 qt_customEmissiveColor = vec3(0.0);\n";
1220 if (enableClearcoat) {
1221 fragmentShader <<
" float qt_customClearcoatAmount = 0.0;\n";
1222 fragmentShader <<
" float qt_customClearcoatFresnelPower = 5.0;\n";
1223 fragmentShader <<
" float qt_customClearcoatRoughness = 0.0;\n";
1224 fragmentShader <<
" vec3 qt_customClearcoatNormal = qt_world_normal;\n";
1225 if (enableClearcoatFresnelScaleBias) {
1226 fragmentShader <<
" float qt_customClearcoatFresnelScale = 1.0;\n";
1227 fragmentShader <<
" float qt_customClearcoatFresnelBias = 0.0;\n";
1230 if (enableFresnelScaleBias) {
1231 fragmentShader <<
" float qt_customFresnelScale = 1.0;\n";
1232 fragmentShader <<
" float qt_customFresnelBias = 0.0;\n";
1235 if (enableTransmission) {
1236 fragmentShader <<
" float qt_customTransmissionFactor = 0.0;\n";
1237 fragmentShader <<
" float qt_customThicknessFactor = 0.0;\n";
1238 fragmentShader <<
" vec3 qt_customAttenuationColor = vec3(1.0);\n";
1239 fragmentShader <<
" float qt_customAttenuationDistance = 0.0;\n";
1242 fragmentShader <<
" QT_SHARED_VARS qt_customShared;\n";
1245 vertexShader.generateUVCoords(0, inKey);
1246 vertexShader.generateUVCoords(1, inKey);
1247 if (includeCustomFragmentMain && hasCustomFunction(QByteArrayLiteral(
"qt_customMain"))) {
1248 fragmentShader <<
" qt_customMain(qt_customBaseColor, qt_customEmissiveColor, qt_customMetalnessAmount, qt_customSpecularRoughness,"
1249 " qt_customSpecularAmount, qt_customFresnelPower, qt_world_normal, qt_tangent, qt_binormal,"
1250 " qt_texCoord0, qt_texCoord1, qt_view_vector, qt_customIOR, qt_customOcclusionAmount";
1251 if (enableClearcoat) {
1252 fragmentShader <<
", qt_customClearcoatAmount, qt_customClearcoatFresnelPower, qt_customClearcoatRoughness, qt_customClearcoatNormal";
1253 if (enableClearcoatFresnelScaleBias) {
1254 fragmentShader <<
", qt_customClearcoatFresnelScale, qt_customClearcoatFresnelBias";
1257 if (enableFresnelScaleBias) {
1258 fragmentShader <<
", qt_customFresnelScale, qt_customFresnelBias";
1260 if (enableTransmission) {
1261 fragmentShader <<
", qt_customTransmissionFactor, qt_customThicknessFactor, qt_customAttenuationColor, qt_customAttenuationDistance";
1264 fragmentShader <<
", qt_customShared);\n";
1266 fragmentShader <<
");\n";
1268 fragmentShader <<
" vec4 qt_diffuseColor = qt_customBaseColor * qt_vertColor;\n";
1269 fragmentShader <<
" vec3 qt_global_emission = qt_customEmissiveColor;\n";
1270 fragmentShader <<
" float qt_iOR = qt_customIOR;\n";
1272 fragmentShader <<
" vec4 qt_diffuseColor = qt_material_base_color * qt_vertColor;\n";
1273 fragmentShader <<
" vec3 qt_global_emission = qt_material_emissive_color;\n";
1274 if (specularLightingEnabled || hasImage)
1275 fragmentShader <<
" float qt_iOR = qt_material_specular.w;\n";
1278 const bool hasCustomIblProbe = hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_iblProbeProcessor"));
1281 fragmentShader <<
" vec4 fragOutput = vec4(0.0);\n";
1283 if (isOrthoShadowPass)
1284 vertexShader.generateDepth();
1286 if (isPerspectiveShadowPass)
1287 vertexShader.generateShadowWorldPosition(inKey);
1293 if (includeSSAOVars)
1294 fragmentShader.addInclude(
"ssao.glsllib");
1296 if (enableLightmap) {
1297 vertexShader.generateLightmapUVCoords(inKey);
1298 fragmentShader.addFunction(
"lightmap");
1301 fragmentShader.addFunction(
"sampleLightVars");
1302 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy())
1303 fragmentShader.addFunction(
"diffuseBurleyBSDF");
1305 fragmentShader.addFunction(
"diffuseReflectionBSDF");
1307 if (enableParallaxMapping) {
1310 const bool hasIdentityMap = identityImages.contains(heightImage);
1312 generateImageUVSampler(vertexShader, fragmentShader, inKey, *heightImage, imageFragCoords, heightImage->m_imageNode.m_indexUV);
1314 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *heightImage,
true, heightImage->m_imageNode.m_indexUV);
1315 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Height)];
1316 fragmentShader.addInclude(
"parallaxMapping.glsllib");
1317 fragmentShader <<
" float qt_heightAmount = qt_material_properties4.x;\n";
1318 maskVariableByVertexColorChannel(
"qt_heightAmount", QSSGRenderDefaultMaterial::HeightAmountMask );
1319 if (viewCount < 2) {
1320 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
", " << names.imageSampler
1321 <<
", qt_tangent, qt_binormal, qt_world_normal, qt_varWorldPos, qt_cameraPosition, qt_heightAmount, qt_material_properties4.y, qt_material_properties4.z);\n";
1323 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
", " << names.imageSampler
1324 <<
", qt_tangent, qt_binormal, qt_world_normal, qt_varWorldPos, qt_cameraPosition[qt_viewIndex], qt_heightAmount, qt_material_properties4.y, qt_material_properties4.z);\n";
1329 if (enableClearcoat) {
1330 addLocalVariable(fragmentShader,
"qt_clearcoatNormal",
"vec3");
1335 if (hasCustomFrag) {
1336 fragmentShader <<
" qt_clearcoatNormal = qt_customClearcoatNormal;\n";
1338 if (clearcoatNormalImage) {
1339 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *clearcoatNormalImage, enableParallaxMapping, clearcoatNormalImage->m_imageNode.m_indexUV);
1340 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::ClearcoatNormal)];
1341 fragmentShader.addFunction(
"sampleNormalTexture");
1342 fragmentShader <<
" float qt_clearcoat_normal_strength = qt_material_clearcoat_normal_strength;\n";
1343 maskVariableByVertexColorChannel(
"qt_clearcoat_normal_strength", QSSGRenderDefaultMaterial::ClearcoatNormalStrengthMask );
1344 fragmentShader <<
" qt_clearcoatNormal = qt_sampleNormalTexture3(" << names.imageSampler <<
", qt_clearcoat_normal_strength, " << names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1348 fragmentShader <<
" qt_clearcoatNormal = qt_world_normal;\n";
1353 if (bumpImage !=
nullptr) {
1354 if (enableParallaxMapping || !genBumpNormalImageCoords) {
1355 generateImageUVCoordinates(vertexShader, fragmentShader, inKey,
1356 *bumpImage, enableParallaxMapping,
1357 bumpImage->m_imageNode.m_indexUV,
1358 genBumpNormalImageCoords);
1360 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Bump)];
1361 fragmentShader.addUniform(names.imageSamplerSize,
"vec2");
1362 fragmentShader.append(
" float qt_bumpAmount = qt_material_properties2.y;\n");
1363 maskVariableByVertexColorChannel(
"qt_bumpAmount", QSSGRenderDefaultMaterial::NormalStrengthMask );
1364 fragmentShader.addInclude(
"defaultMaterialBumpNoLod.glsllib");
1365 fragmentShader <<
" qt_world_normal = qt_defaultMaterialBumpNoLod(" << names.imageSampler <<
", qt_bumpAmount, " << names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal, " << names.imageSamplerSize <<
");\n";
1366 }
else if (normalImage !=
nullptr) {
1367 if (enableParallaxMapping || !genBumpNormalImageCoords) {
1368 generateImageUVCoordinates(vertexShader, fragmentShader, inKey,
1369 *normalImage, enableParallaxMapping,
1370 normalImage->m_imageNode.m_indexUV,
1371 genBumpNormalImageCoords);
1373 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Normal)];
1374 fragmentShader.append(
" float qt_normalStrength = qt_material_properties2.y;\n");
1375 maskVariableByVertexColorChannel(
"qt_normalStrength", QSSGRenderDefaultMaterial::NormalStrengthMask );
1376 fragmentShader.addFunction(
"sampleNormalTexture");
1377 fragmentShader <<
" qt_world_normal = qt_sampleNormalTexture3(" << names.imageSampler <<
", qt_normalStrength, " << names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1380 fragmentShader.append(
" vec3 tmp_light_color;");
1383 if (specularLightingEnabled || hasImage) {
1384 fragmentShader.append(
" vec3 qt_specularBase;");
1385 fragmentShader.addUniform(
"qt_material_specular",
"vec4");
1387 fragmentShader.append(
" vec3 qt_specularTint = vec3(1.0);");
1389 fragmentShader.append(
" vec3 qt_specularTint = qt_material_specular.rgb;");
1393 const bool hasIdentityMap = identityImages.contains(baseImage);
1395 generateImageUVSampler(vertexShader, fragmentShader, inKey, *baseImage, imageFragCoords, baseImage->m_imageNode.m_indexUV);
1397 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *baseImage, enableParallaxMapping, baseImage->m_imageNode.m_indexUV);
1402 fragmentShader.addInclude(
"tonemapping.glsllib");
1403 if (materialAdapter->isBaseColorSingleChannelEnabled()) {
1404 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::BaseColorChannel];
1405 fragmentShader <<
" vec4 qt_base_texture_color = vec4(vec3(texture2D(" << names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1407 fragmentShader <<
" vec4 qt_base_texture_color = texture2D(" << names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
");\n";
1409 if (!keyProps.m_imageMaps[QSSGShaderDefaultMaterialKeyProperties::BaseColorMap].isLinear(inKey))
1410 fragmentShader <<
" qt_base_texture_color = qt_sRGBToLinear(qt_base_texture_color);\n";
1411 fragmentShader <<
" qt_diffuseColor *= qt_base_texture_color;\n";
1415 if (materialAdapter->alphaMode() == QSSGRenderDefaultMaterial::MaterialAlphaMode::Mask) {
1419 fragmentShader <<
" if (qt_diffuseColor.a < qt_material_properties3.y) {\n"
1420 <<
" qt_diffuseColor = vec4(0.0);\n"
1423 <<
" qt_diffuseColor.a = 1.0;\n"
1425 }
else if (materialAdapter->alphaMode() == QSSGRenderDefaultMaterial::MaterialAlphaMode::Opaque) {
1426 fragmentShader <<
" qt_diffuseColor.a = 1.0;\n";
1430 const bool hasIdentityMap = identityImages.contains(opacityImage);
1432 generateImageUVSampler(vertexShader, fragmentShader, inKey, *opacityImage, imageFragCoords, opacityImage->m_imageNode.m_indexUV);
1434 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *opacityImage, enableParallaxMapping, opacityImage->m_imageNode.m_indexUV);
1436 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Opacity)];
1437 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::OpacityChannel];
1438 fragmentShader <<
" float qt_opacity_map_value = texture2D(" << names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1439 if ( materialAdapter->isInvertOpacityMapValue() )
1440 fragmentShader <<
" qt_opacity_map_value = 1.0 - qt_opacity_map_value;\n";
1441 fragmentShader <<
" qt_objectOpacity *= qt_opacity_map_value;\n";
1445 if (specularLightingEnabled) {
1446 vertexShader.generateViewVector(inKey);
1447 fragmentShader.addUniform(
"qt_material_properties",
"vec4");
1449 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy())
1450 fragmentShader <<
" qt_specularBase = vec3(1.0);\n";
1452 fragmentShader <<
" qt_specularBase = qt_diffuseColor.rgb;\n";
1454 fragmentShader <<
" float qt_specularFactor = qt_customSpecularAmount;\n";
1456 fragmentShader <<
" float qt_specularFactor = qt_material_properties.x;\n";
1458 maskVariableByVertexColorChannel(
"qt_specularFactor", QSSGRenderDefaultMaterial::SpecularAmountMask );
1463 fragmentShader <<
" float qt_metalnessAmount = qt_customMetalnessAmount;\n";
1464 else if (!materialAdapter->isSpecularGlossy())
1465 fragmentShader <<
" float qt_metalnessAmount = qt_material_properties.z;\n";
1467 fragmentShader <<
" float qt_metalnessAmount = 0.0;\n";
1469 maskVariableByVertexColorChannel(
"qt_metalnessAmount", QSSGRenderDefaultMaterial::MetalnessMask );
1471 if (specularLightingEnabled && metalnessImage) {
1472 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::MetalnessChannel];
1473 const bool hasIdentityMap = identityImages.contains(metalnessImage);
1475 generateImageUVSampler(vertexShader, fragmentShader, inKey, *metalnessImage, imageFragCoords, metalnessImage->m_imageNode.m_indexUV);
1477 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *metalnessImage, enableParallaxMapping, metalnessImage->m_imageNode.m_indexUV);
1479 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Metalness)];
1480 fragmentShader <<
" float qt_sampledMetalness = texture2D(" << names.imageSampler <<
", "
1481 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1482 fragmentShader <<
" qt_metalnessAmount = clamp(qt_metalnessAmount * qt_sampledMetalness, 0.0, 1.0);\n";
1485 fragmentShader.addUniform(
"qt_light_ambient_total",
"vec3");
1487 fragmentShader.append(
" vec4 global_diffuse_light = vec4(0.0);");
1489 if (enableLightmap) {
1490 fragmentShader <<
" global_diffuse_light.rgb = qt_lightmap_color(qt_texCoordLightmap) * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb;\n";
1492 if (hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_ambientLightProcessor"))) {
1494 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");
1496 fragmentShader <<
", qt_customShared);\n";
1498 fragmentShader <<
");\n";
1500 fragmentShader.append(
" global_diffuse_light = vec4(qt_light_ambient_total.rgb * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb, 0.0);");
1504 fragmentShader.append(
" vec3 global_specular_light = vec3(0.0);");
1506 if (!lights.isEmpty() || hasCustomFrag) {
1507 fragmentShader.append(
" float qt_shadow_map_occl = 1.0;");
1508 fragmentShader.append(
" float qt_lightAttenuation = 1.0;");
1513 if (specularAmountImage) {
1514 const bool hasIdentityMap = identityImages.contains(specularAmountImage);
1516 generateImageUVSampler(vertexShader, fragmentShader, inKey, *specularAmountImage, imageFragCoords, specularAmountImage->m_imageNode.m_indexUV);
1518 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *specularAmountImage, enableParallaxMapping, specularAmountImage->m_imageNode.m_indexUV);
1520 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::SpecularAmountMap )];
1522 if (materialAdapter->isSpecularAmountSingleChannelEnabled()) {
1523 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::SpecularAmountChannel];
1524 fragmentShader <<
" vec4 qt_specular_amount_map = vec4(vec3(texture2D(" << names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1526 fragmentShader <<
" vec4 qt_specular_amount_map = texture2D(" << names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
");\n";
1528 fragmentShader <<
" qt_specularBase *= qt_sRGBToLinear(qt_specular_amount_map).rgb;\n";
1531 if (specularLightingEnabled) {
1532 if (materialAdapter->isSpecularGlossy()) {
1533 fragmentShader <<
" qt_specularTint *= qt_specularBase;\n";
1534 fragmentShader <<
" vec3 qt_specularAmount = vec3(1.0);\n";
1536 fragmentShader <<
" vec3 qt_specularAmount = qt_specularBase * vec3(qt_metalnessAmount + qt_specularFactor * (1.0 - qt_metalnessAmount));\n";
1540 if (translucencyImage !=
nullptr) {
1541 const bool hasIdentityMap = identityImages.contains(translucencyImage);
1543 generateImageUVSampler(vertexShader, fragmentShader, inKey, *translucencyImage, imageFragCoords);
1545 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *translucencyImage, enableParallaxMapping);
1547 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Translucency)];
1548 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::TranslucencyChannel];
1549 fragmentShader <<
" float qt_translucent_depth_range = texture2D(" << names.imageSampler
1550 <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1551 fragmentShader <<
" float qt_translucent_thickness = qt_translucent_depth_range * qt_translucent_depth_range;\n";
1552 fragmentShader <<
" float qt_translucent_thickness_exp = exp(qt_translucent_thickness * qt_material_properties2.z);\n";
1555 addLocalVariable(fragmentShader,
"qt_aoFactor",
"float");
1558 fragmentShader.append(
" qt_aoFactor = qt_screenSpaceAmbientOcclusionFactor();");
1560 fragmentShader.append(
" qt_aoFactor = 1.0;");
1562 if (hasCustomFrag) {
1563 fragmentShader <<
" float qt_roughnessAmount = qt_customSpecularRoughness;\n";
1564 fragmentShader <<
" qt_aoFactor *= qt_customOcclusionAmount;\n";
1567 fragmentShader <<
" float qt_roughnessAmount = qt_material_properties.y;\n";
1570 maskVariableByVertexColorChannel(
"qt_roughnessAmount", QSSGRenderDefaultMaterial::RoughnessMask );
1574 if (occlusionImage) {
1575 addLocalVariable(fragmentShader,
"qt_ao",
"float");
1576 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::OcclusionChannel];
1577 const bool hasIdentityMap = identityImages.contains(occlusionImage);
1579 generateImageUVSampler(vertexShader, fragmentShader, inKey, *occlusionImage, imageFragCoords, occlusionImage->m_imageNode.m_indexUV);
1581 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *occlusionImage, enableParallaxMapping, occlusionImage->m_imageNode.m_indexUV);
1582 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Occlusion)];
1583 fragmentShader <<
" qt_ao = texture2D(" << names.imageSampler <<
", "
1584 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1585 fragmentShader <<
" qt_aoFactor *= qt_ao * qt_material_properties3.x;\n";
1587 maskVariableByVertexColorChannel(
"qt_aoFactor", QSSGRenderDefaultMaterial::OcclusionAmountMask );
1590 if (specularLightingEnabled && roughnessImage) {
1591 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::RoughnessChannel];
1592 const bool hasIdentityMap = identityImages.contains(roughnessImage);
1594 generateImageUVSampler(vertexShader, fragmentShader, inKey, *roughnessImage, imageFragCoords, roughnessImage->m_imageNode.m_indexUV);
1596 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *roughnessImage, enableParallaxMapping, roughnessImage->m_imageNode.m_indexUV);
1598 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Roughness)];
1599 fragmentShader <<
" qt_roughnessAmount *= texture2D(" << names.imageSampler <<
", "
1600 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1604 if (materialAdapter->isSpecularGlossy())
1605 fragmentShader <<
" qt_roughnessAmount = clamp(1.0 - qt_roughnessAmount, 0.0, 1.0);\n";
1607 if (enableClearcoat) {
1608 addLocalVariable(fragmentShader,
"qt_clearcoatAmount",
"float");
1609 addLocalVariable(fragmentShader,
"qt_clearcoatRoughness",
"float");
1610 addLocalVariable(fragmentShader,
"qt_clearcoatF0",
"vec3");
1611 addLocalVariable(fragmentShader,
"qt_clearcoatF90",
"vec3");
1612 addLocalVariable(fragmentShader,
"qt_global_clearcoat",
"vec3");
1615 fragmentShader <<
" qt_clearcoatAmount = qt_customClearcoatAmount;\n";
1617 fragmentShader <<
" qt_clearcoatAmount = qt_material_properties3.z;\n";
1618 maskVariableByVertexColorChannel(
"qt_clearcoatAmount", QSSGRenderDefaultMaterial::ClearcoatAmountMask );
1620 fragmentShader <<
" qt_clearcoatRoughness = qt_customClearcoatRoughness;\n";
1622 fragmentShader <<
" qt_clearcoatRoughness = qt_material_properties3.w;\n";
1623 maskVariableByVertexColorChannel(
"qt_clearcoatRoughness", QSSGRenderDefaultMaterial::ClearcoatRoughnessAmountMask );
1624 fragmentShader <<
" qt_clearcoatF0 = vec3(((1.0-qt_iOR) * (1.0-qt_iOR)) / ((1.0+qt_iOR) * (1.0+qt_iOR)));\n";
1625 fragmentShader <<
" qt_clearcoatF90 = vec3(1.0);\n";
1626 fragmentShader <<
" qt_global_clearcoat = vec3(0.0);\n";
1628 if (clearcoatImage) {
1629 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ClearcoatChannel];
1630 const bool hasIdentityMap = identityImages.contains(clearcoatImage);
1632 generateImageUVSampler(vertexShader, fragmentShader, inKey, *clearcoatImage, imageFragCoords, clearcoatImage->m_imageNode.m_indexUV);
1634 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *clearcoatImage, enableParallaxMapping, clearcoatImage->m_imageNode.m_indexUV);
1635 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Clearcoat)];
1636 fragmentShader <<
" qt_clearcoatAmount *= texture2D(" << names.imageSampler <<
", "
1637 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1640 if (clearcoatRoughnessImage) {
1641 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ClearcoatRoughnessChannel];
1642 const bool hasIdentityMap = identityImages.contains(clearcoatRoughnessImage);
1644 generateImageUVSampler(vertexShader, fragmentShader, inKey, *clearcoatRoughnessImage, imageFragCoords, clearcoatRoughnessImage->m_imageNode.m_indexUV);
1646 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *clearcoatRoughnessImage, enableParallaxMapping, clearcoatRoughnessImage->m_imageNode.m_indexUV);
1647 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::ClearcoatRoughness)];
1648 fragmentShader <<
" qt_clearcoatRoughness *= texture2D(" << names.imageSampler <<
", "
1649 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1650 fragmentShader <<
" qt_clearcoatRoughness = clamp(qt_clearcoatRoughness, 0.0, 1.0);\n";
1654 if (enableTransmission) {
1655 fragmentShader.addInclude(
"transmission.glsllib");
1656 addLocalVariable(fragmentShader,
"qt_transmissionFactor",
"float");
1657 addLocalVariable(fragmentShader,
"qt_global_transmission",
"vec3");
1659 addLocalVariable(fragmentShader,
"qt_thicknessFactor",
"float");
1660 addLocalVariable(fragmentShader,
"qt_attenuationColor",
"vec3");
1661 addLocalVariable(fragmentShader,
"qt_attenuationDistance",
"float");
1662 fragmentShader <<
" qt_global_transmission = vec3(0.0);\n";
1664 if (hasCustomFrag) {
1665 fragmentShader <<
" qt_transmissionFactor = qt_customTransmissionFactor;\n";
1666 fragmentShader <<
" qt_thicknessFactor = qt_customThicknessFactor;\n";
1667 fragmentShader <<
" qt_attenuationColor = qt_customAttenuationColor;\n";
1668 fragmentShader <<
" qt_attenuationDistance = qt_customAttenuationDistance;\n";
1670 fragmentShader <<
" qt_transmissionFactor = qt_material_properties4.w;\n";
1671 maskVariableByVertexColorChannel(
"qt_transmissionFactor", QSSGRenderDefaultMaterial::TransmissionFactorMask );
1673 if (transmissionImage) {
1674 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::TransmissionChannel];
1675 const bool hasIdentityMap = identityImages.contains(transmissionImage);
1677 generateImageUVSampler(vertexShader, fragmentShader, inKey, *transmissionImage, imageFragCoords, transmissionImage->m_imageNode.m_indexUV);
1679 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *transmissionImage, enableParallaxMapping, transmissionImage->m_imageNode.m_indexUV);
1680 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Transmission)];
1681 fragmentShader <<
" qt_transmissionFactor *= texture2D(" << names.imageSampler <<
", "
1682 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1685 fragmentShader <<
" qt_thicknessFactor = qt_material_thickness;\n";
1686 maskVariableByVertexColorChannel(
"qt_thicknessFactor", QSSGRenderDefaultMaterial::ThicknessFactorMask );
1687 fragmentShader <<
" qt_attenuationColor = qt_material_attenuation.xyz;\n";
1688 fragmentShader <<
" qt_attenuationDistance = qt_material_attenuation.w;\n";
1690 if (thicknessImage) {
1691 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ThicknessChannel];
1692 const bool hasIdentityMap = identityImages.contains(thicknessImage);
1694 generateImageUVSampler(vertexShader, fragmentShader, inKey, *thicknessImage, imageFragCoords, thicknessImage->m_imageNode.m_indexUV);
1696 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *thicknessImage, enableParallaxMapping, thicknessImage->m_imageNode.m_indexUV);
1697 const auto &names = imageStringTable[
int(QSSGRenderableImage::Type::Thickness)];
1698 fragmentShader <<
" qt_thicknessFactor *= texture2D(" << names.imageSampler <<
", "
1699 << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1704 if (specularLightingEnabled) {
1705 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy()) {
1706 fragmentShader.addInclude(
"principledMaterialFresnel.glsllib");
1707 const bool useF90 = !lights.isEmpty() || enableTransmission;
1708 addLocalVariable(fragmentShader,
"qt_f0",
"vec3");
1710 addLocalVariable(fragmentShader,
"qt_f90",
"vec3");
1711 if (materialAdapter->isPrincipled()) {
1712 fragmentShader <<
" qt_f0 = qt_F0_ior(qt_iOR, qt_metalnessAmount, qt_diffuseColor.rgb);\n";
1714 fragmentShader <<
" qt_f90 = vec3(1.0);\n";
1716 addLocalVariable(fragmentShader,
"qt_reflectance",
"float");
1718 fragmentShader <<
" qt_reflectance = max(max(qt_specularTint.r, qt_specularTint.g), qt_specularTint.b);\n";
1719 fragmentShader <<
" qt_f0 = qt_specularTint;\n";
1720 fragmentShader <<
" qt_specularTint = vec3(1.0);\n";
1722 fragmentShader <<
" qt_f90 = vec3(clamp(qt_reflectance * 50.0, 0.0, 1.0));\n";
1723 fragmentShader <<
" qt_diffuseColor.rgb *= (1 - qt_reflectance);\n";
1726 if (specularAAEnabled) {
1727 fragmentShader.append(
" vec3 vNormalWsDdx = dFdx(qt_world_normal.xyz);\n");
1728 fragmentShader.append(
" vec3 vNormalWsDdy = dFdy(qt_world_normal.xyz);\n");
1729 fragmentShader.append(
" float flGeometricRoughnessFactor = pow(clamp(max(dot(vNormalWsDdx, vNormalWsDdx), dot(vNormalWsDdy, vNormalWsDdy)), 0.0, 1.0), 0.333);\n");
1730 fragmentShader.append(
" qt_roughnessAmount = max(flGeometricRoughnessFactor, qt_roughnessAmount);\n");
1734 fragmentShader <<
" float qt_fresnelPower = qt_customFresnelPower;\n";
1736 fragmentShader <<
" float qt_fresnelPower = qt_material_properties2.x;\n";
1738 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy()) {
1739 fragmentShader <<
" vec3 qt_principledMaterialFresnelValue = qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, "
1740 <<
"qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1741 if (enableFresnelScaleBias) {
1742 if (hasCustomFrag) {
1743 fragmentShader <<
" float qt_fresnelScale = qt_customFresnelScale;\n";
1744 fragmentShader <<
" float qt_fresnelBias = qt_customFresnelBias;\n";
1746 fragmentShader <<
" float qt_fresnelScale = qt_material_properties5.x;\n";
1747 fragmentShader <<
" float qt_fresnelBias = qt_material_properties5.y;\n";
1749 fragmentShader <<
" qt_principledMaterialFresnelValue = clamp(vec3(qt_fresnelBias) + "
1750 <<
"qt_fresnelScale * qt_principledMaterialFresnelValue, 0.0, 1.0);\n";
1752 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnelValue;\n";
1753 if (materialAdapter->isPrincipled()) {
1756 fragmentShader <<
" qt_specularTint = mix(vec3(1.0), qt_specularTint, 1.0 - qt_metalnessAmount);\n";
1759 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, "
1760 <<
"qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1763 Q_ASSERT(!hasCustomFrag);
1764 fragmentShader.addInclude(
"defaultMaterialFresnel.glsllib");
1765 fragmentShader <<
" qt_diffuseColor.rgb *= (1.0 - qt_dielectricSpecular(qt_iOR)) * (1.0 - qt_metalnessAmount);\n";
1766 maybeAddMaterialFresnel(fragmentShader, keyProps, inKey, metalnessEnabled);
1770 if (!lights.isEmpty()) {
1771 generateMainLightCalculation(fragmentShader,
1776 shaderLibraryManager,
1782 specularLightingEnabled,
1784 enableTransmission);
1790 fragmentShader <<
" global_diffuse_light = vec4(global_diffuse_light.rgb * qt_aoFactor, qt_objectOpacity * qt_diffuseColor.a);\n";
1792 if (hasReflectionProbe) {
1793 vertexShader.generateWorldNormal(inKey);
1794 fragmentShader.addInclude(
"sampleReflectionProbe.glsllib");
1796 fragmentShader <<
" vec3 qt_reflectionDiffuse = vec3(0.0);\n";
1797 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy()) {
1798 fragmentShader <<
" qt_reflectionDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1800 fragmentShader <<
" qt_reflectionDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1803 if (specularLightingEnabled) {
1804 fragmentShader <<
" vec3 qt_reflectionSpecular = vec3(0.0);\n";
1805 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy()) {
1806 fragmentShader <<
" qt_reflectionSpecular = "
1807 <<
"qt_specularTint * qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1809 fragmentShader <<
" qt_reflectionSpecular = qt_specularAmount * "
1810 <<
"qt_specularTint * qt_sampleGlossyReflection(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1813 if (enableClearcoat) {
1814 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1817 fragmentShader <<
" global_diffuse_light.rgb += qt_reflectionDiffuse;\n";
1818 if (specularLightingEnabled)
1819 fragmentShader <<
" global_specular_light += qt_reflectionSpecular;\n";
1820 if (enableClearcoat)
1821 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat;\n";
1822 }
else if (hasIblProbe) {
1823 vertexShader.generateWorldNormal(inKey);
1824 fragmentShader.addInclude(
"sampleProbe.glsllib");
1825 if (hasCustomIblProbe) {
1827 fragmentShader <<
" vec3 qt_iblDiffuse = vec3(0.0);\n";
1828 fragmentShader <<
" vec3 qt_iblSpecular = vec3(0.0);\n";
1829 fragmentShader <<
" qt_iblProbeProcessor(qt_iblDiffuse, qt_iblSpecular, qt_customBaseColor, qt_aoFactor, qt_specularFactor, qt_roughnessAmount, qt_world_normal, qt_view_vector";
1830 if (hasIblOrientation)
1831 fragmentShader <<
", qt_lightProbeOrientation";
1833 fragmentShader <<
", mat3(1.0)";
1835 fragmentShader <<
", qt_customShared);\n";
1837 fragmentShader <<
");\n";
1839 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy()) {
1840 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1842 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1844 if (specularLightingEnabled) {
1845 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularEnabled()) {
1846 fragmentShader <<
" vec3 qt_iblSpecular = "
1847 <<
"qt_specularTint * qt_sampleGlossyPrincipled(qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1849 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularAmount * "
1850 <<
"qt_specularTint * qt_sampleGlossy(qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1853 if (enableClearcoat) {
1854 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyPrincipled(qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1858 fragmentShader <<
" global_diffuse_light.rgb += qt_iblDiffuse * qt_aoFactor;\n";
1859 if (specularLightingEnabled)
1860 fragmentShader <<
" global_specular_light += qt_iblSpecular * qt_aoFactor;\n";
1861 if (enableClearcoat)
1862 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat * qt_aoFactor;\n";
1863 }
else if (hasCustomIblProbe) {
1865 fragmentShader.addUniform(
"qt_lightProbe",
"samplerCube");
1866 fragmentShader.addUniform(
"qt_lightProbeProperties",
"vec4");
1870 if (enableTransmission) {
1871 fragmentShader <<
" qt_global_transmission += qt_transmissionFactor * qt_getIBLVolumeRefraction(qt_world_normal, qt_view_vector, qt_roughnessAmount, "
1872 "qt_diffuseColor.rgb, qt_specularAmount, qt_varWorldPos, qt_iOR, qt_thicknessFactor, qt_attenuationColor, qt_attenuationDistance);\n";
1876 bool texColorDeclared =
false;
1877 for (QSSGRenderableImage *image = firstImage; image; image = image->m_nextImage) {
1879 if (image->m_mapType != QSSGRenderableImage::Type::Specular
1880 && image->m_mapType != QSSGRenderableImage::Type::Emissive)
1885 if (!texColorDeclared) {
1886 fragmentShader.append(
" vec4 qt_texture_color;");
1887 texColorDeclared =
true;
1890 const bool hasIdentityMap = identityImages.contains(image);
1892 generateImageUVSampler(vertexShader, fragmentShader, inKey, *image, imageFragCoords, image->m_imageNode.m_indexUV);
1894 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *image, enableParallaxMapping, image->m_imageNode.m_indexUV);
1897 fragmentShader <<
" qt_texture_color = texture2D(" << names.imageSampler
1898 <<
", " << (hasIdentityMap ? imageFragCoords : names.imageFragCoords) <<
");\n";
1900 switch (image->m_mapType) {
1901 case QSSGRenderableImage::Type::Specular:
1902 fragmentShader.addInclude(
"tonemapping.glsllib");
1903 fragmentShader.append(
" global_specular_light += qt_sRGBToLinear(qt_texture_color.rgb) * qt_specularTint;");
1904 fragmentShader.append(
" global_diffuse_light.a *= qt_texture_color.a;");
1906 case QSSGRenderableImage::Type::Emissive:
1907 fragmentShader.addInclude(
"tonemapping.glsllib");
1908 if (materialAdapter->isEmissiveSingleChannelEnabled()) {
1909 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::EmissiveChannel];
1910 fragmentShader <<
" qt_global_emission *= qt_sRGBToLinear(vec3(qt_texture_color" <<
1911 channelStr(channelProps, inKey) <<
"));\n";
1913 fragmentShader.append(
" qt_global_emission *= qt_sRGBToLinear(qt_texture_color.rgb);");
1923 if (enableTransmission)
1924 fragmentShader <<
" global_diffuse_light.rgb = mix(global_diffuse_light.rgb, qt_global_transmission, qt_transmissionFactor);\n";
1926 if (materialAdapter->isPrincipled()) {
1927 fragmentShader <<
" global_diffuse_light.rgb *= 1.0 - qt_metalnessAmount;\n";
1931 fragmentShader.addInclude(
"fog.glsllib");
1932 fragmentShader <<
" calculateFog(qt_global_emission, global_specular_light, global_diffuse_light.rgb);\n";
1935 fragmentShader <<
" vec4 qt_color_sum = vec4(global_diffuse_light.rgb + global_specular_light + qt_global_emission, global_diffuse_light.a);\n";
1937 if (enableClearcoat) {
1938 fragmentShader.addInclude(
"bsdf.glsllib");
1940 fragmentShader <<
" float qt_clearcoatFresnelPower = qt_customClearcoatFresnelPower;\n";
1942 fragmentShader <<
" float qt_clearcoatFresnelPower = qt_material_clearcoat_fresnel_power;\n";
1943 fragmentShader <<
" vec3 qt_clearcoatFresnel = qt_schlick3(qt_clearcoatF0, qt_clearcoatF90, clamp(dot(qt_clearcoatNormal, qt_view_vector), 0.0, 1.0), qt_clearcoatFresnelPower);\n";
1944 if (enableClearcoatFresnelScaleBias) {
1945 if (hasCustomFrag) {
1946 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_customClearcoatFresnelScale;\n";
1947 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_customClearcoatFresnelBias;\n";
1949 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_material_properties5.z;\n";
1950 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_material_properties5.w;\n";
1952 fragmentShader <<
" qt_clearcoatFresnel = clamp(vec3(qt_clearcoatFresnelBias) + qt_clearcoatFresnelScale * qt_clearcoatFresnel, 0.0, 1.0);\n";
1954 fragmentShader <<
" qt_global_clearcoat = qt_global_clearcoat * qt_clearcoatAmount;\n";
1955 fragmentShader <<
" qt_color_sum.rgb = qt_color_sum.rgb * (1.0 - qt_clearcoatAmount * qt_clearcoatFresnel) + qt_global_clearcoat;\n";
1958 if (hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_customPostProcessor"))) {
1960 fragmentShader <<
" qt_customPostProcessor(qt_color_sum, global_diffuse_light, global_specular_light, qt_global_emission, qt_texCoord0, qt_texCoord1";
1962 fragmentShader <<
", qt_customShared);\n";
1964 fragmentShader <<
");\n";
1967 Q_ASSERT(!isDepthPass && !isOrthoShadowPass && !isPerspectiveShadowPass);
1968 fragmentShader.addInclude(
"tonemapping.glsllib");
1969 fragmentShader.append(
" fragOutput = vec4(qt_tonemap(qt_color_sum));");
1972 if (Q_UNLIKELY(debugMode != QSSGRenderLayer::MaterialDebugMode::None)) {
1973 fragmentShader.append(
" vec3 debugOutput = vec3(0.0);\n");
1974 switch (debugMode) {
1975 case QSSGRenderLayer::MaterialDebugMode::BaseColor:
1976 fragmentShader.append(
" debugOutput += qt_tonemap(qt_diffuseColor.rgb);\n");
1978 case QSSGRenderLayer::MaterialDebugMode::Roughness:
1979 fragmentShader.append(
" debugOutput += vec3(qt_roughnessAmount);\n");
1981 case QSSGRenderLayer::MaterialDebugMode::Metalness:
1982 fragmentShader.append(
" debugOutput += vec3(qt_metalnessAmount);\n");
1984 case QSSGRenderLayer::MaterialDebugMode::Diffuse:
1985 fragmentShader.append(
" debugOutput += qt_tonemap(global_diffuse_light.rgb);\n");
1987 case QSSGRenderLayer::MaterialDebugMode::Specular:
1988 fragmentShader.append(
" debugOutput += qt_tonemap(global_specular_light);\n");
1990 case QSSGRenderLayer::MaterialDebugMode::ShadowOcclusion:
1991 fragmentShader.append(
" debugOutput += vec3(qt_shadow_map_occl);\n");
1993 case QSSGRenderLayer::MaterialDebugMode::Emission:
1994 fragmentShader.append(
" debugOutput += qt_tonemap(qt_global_emission);\n");
1996 case QSSGRenderLayer::MaterialDebugMode::AmbientOcclusion:
1997 fragmentShader.append(
" debugOutput += vec3(qt_aoFactor);\n");
1999 case QSSGRenderLayer::MaterialDebugMode::Normal:
2000 fragmentShader.append(
" debugOutput += qt_world_normal * 0.5 + 0.5;\n");
2002 case QSSGRenderLayer::MaterialDebugMode::Tangent:
2003 fragmentShader.append(
" debugOutput += qt_tangent * 0.5 + 0.5;\n");
2005 case QSSGRenderLayer::MaterialDebugMode::Binormal:
2006 fragmentShader.append(
" debugOutput += qt_binormal * 0.5 + 0.5;\n");
2008 case QSSGRenderLayer::MaterialDebugMode::F0:
2009 if (materialAdapter->isPrincipled() || materialAdapter->isSpecularGlossy())
2010 fragmentShader.append(
" debugOutput += qt_f0;");
2012 case QSSGRenderLayer::MaterialDebugMode::None:
2016 fragmentShader.append(
" fragOutput = vec4(debugOutput, 1.0);\n");
2019 if ((isOrthoShadowPass || isPerspectiveShadowPass || isDepthPass) && isOpaqueDepthPrePass) {
2020 fragmentShader <<
" if ((qt_diffuseColor.a * qt_objectOpacity) < 1.0)\n";
2021 fragmentShader <<
" discard;\n";
2024 if (isOrthoShadowPass) {
2025 Q_ASSERT(viewCount == 1);
2026 fragmentShader.addUniform(
"qt_shadowDepthAdjust",
"vec2");
2027 fragmentShader <<
" // directional shadow pass\n"
2028 <<
" float qt_shadowDepth = (qt_varDepth + qt_shadowDepthAdjust.x) * qt_shadowDepthAdjust.y;\n"
2029 <<
" fragOutput = vec4(qt_shadowDepth);\n";
2030 }
else if (isPerspectiveShadowPass) {
2031 Q_ASSERT(viewCount == 1);
2032 fragmentShader.addUniform(
"qt_cameraPosition",
"vec3");
2033 fragmentShader.addUniform(
"qt_cameraProperties",
"vec2");
2034 fragmentShader <<
" // omnidirectional shadow pass\n"
2035 <<
" vec3 qt_shadowCamPos = vec3(qt_cameraPosition.x, qt_cameraPosition.y, qt_cameraPosition.z);\n"
2036 <<
" float qt_shadowDist = length(qt_varShadowWorldPos - qt_shadowCamPos);\n"
2037 <<
" qt_shadowDist = (qt_shadowDist - qt_cameraProperties.x) / (qt_cameraProperties.y - qt_cameraProperties.x);\n"
2038 <<
" fragOutput = vec4(qt_shadowDist, qt_shadowDist, qt_shadowDist, 1.0);\n";
2040 fragmentShader.addInclude(
"tonemapping.glsllib");
2041 fragmentShader.append(
" fragOutput = vec4(qt_tonemap(qt_diffuseColor.rgb), qt_diffuseColor.a * qt_objectOpacity);");
2096void QSSGMaterialShaderGenerator::setRhiMaterialProperties(
const QSSGRenderContextInterface &renderContext,
2097 QSSGRhiShaderPipeline &shaders,
2099 QSSGRhiGraphicsPipelineState *inPipelineState,
2100 const QSSGRenderGraphObject &inMaterial,
2101 const QSSGShaderDefaultMaterialKey &inKey,
2102 const QSSGShaderDefaultMaterialKeyProperties &inProperties,
2103 const QSSGRenderCameraList &inCameras,
2104 const QSSGRenderMvpArray &inModelViewProjections,
2105 const QMatrix3x3 &inNormalMatrix,
2106 const QMatrix4x4 &inGlobalTransform,
2107 const QMatrix4x4 &clipSpaceCorrMatrix,
2108 const QMatrix4x4 &localInstanceTransform,
2109 const QMatrix4x4 &globalInstanceTransform,
2110 const QSSGDataView<
float> &inMorphWeights,
2111 QSSGRenderableImage *inFirstImage,
2113 const QSSGLayerRenderData &inRenderProperties,
2114 const QSSGShaderLightListView &inLights,
2115 const QSSGShaderReflectionProbe &reflectionProbe,
2116 bool receivesShadows,
2117 bool receivesReflections,
2118 const QVector2D *shadowDepthAdjust,
2119 QRhiTexture *lightmapTexture)
2121 QSSGShaderMaterialAdapter *materialAdapter = getMaterialAdapter(inMaterial);
2122 QSSGRhiShaderPipeline::CommonUniformIndices &cui = shaders.commonUniformIndices;
2124 materialAdapter->setCustomPropertyUniforms(ubufData, shaders, renderContext);
2126 const QVector2D camProperties(inCameras[0]->clipNear, inCameras[0]->clipFar);
2127 shaders.setUniform(ubufData,
"qt_cameraProperties", &camProperties, 2 *
sizeof(
float), &cui.cameraPropertiesIdx);
2129 const int viewCount = inCameras.count();
2130 if (viewCount < 2) {
2131 const QVector3D camGlobalPos = inCameras[0]->getGlobalPos();
2132 shaders.setUniform(ubufData,
"qt_cameraPosition", &camGlobalPos, 3 *
sizeof(
float), &cui.cameraPositionIdx);
2133 const QVector3D camDirection = QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2134 ? inRenderProperties.renderedCameraData.value()[0].direction
2135 : QVector3D{ 0.0f, 0.0f, -1.0f };
2136 shaders.setUniform(ubufData,
"qt_cameraDirection", &camDirection, 3 *
sizeof(
float), &cui.cameraDirectionIdx);
2138 QVarLengthArray<QVector3D, 2> camGlobalPos(viewCount);
2139 QVarLengthArray<QVector3D> camDirection(viewCount);
2140 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
2141 camGlobalPos[viewIndex] = inCameras[viewIndex]->getGlobalPos();
2142 camDirection[viewIndex] = QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2143 ? inRenderProperties.renderedCameraData.value()[viewIndex].direction
2144 : QVector3D{ 0.0f, 0.0f, -1.0f };
2146 shaders.setUniformArray(ubufData,
"qt_cameraPosition", camGlobalPos.constData(), viewCount, QSSGRenderShaderValue::Vec3, &cui.cameraPositionIdx);
2147 shaders.setUniformArray(ubufData,
"qt_cameraDirection", camDirection.constData(), viewCount, QSSGRenderShaderValue::Vec3, &cui.cameraDirectionIdx);
2150 const auto globalRenderData = QSSGLayerRenderData::globalRenderProperties(renderContext);
2153 bool usesProjectionMatrix =
false;
2154 bool usesInvProjectionMatrix =
false;
2155 bool usesViewProjectionMatrix =
false;
2156 bool usesModelViewProjectionMatrix =
false;
2157 bool usesNormalMatrix =
false;
2158 bool usesParentMatrix =
false;
2160 if (inMaterial.type == QSSGRenderGraphObject::Type::CustomMaterial) {
2161 const auto *customMaterial =
static_cast<
const QSSGRenderCustomMaterial *>(&inMaterial);
2162 usesProjectionMatrix = customMaterial->m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::ProjectionMatrix);
2163 usesInvProjectionMatrix = customMaterial->m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::InverseProjectionMatrix);
2165 usesViewProjectionMatrix =
true;
2168 const bool usesInstancing = inProperties.m_usesInstancing.getValue(inKey);
2169 if (usesInstancing) {
2171 usesViewProjectionMatrix =
true;
2172 usesParentMatrix =
true;
2174 usesModelViewProjectionMatrix =
true;
2175 usesNormalMatrix =
true;
2178 if (materialAdapter->isTransmissionEnabled())
2179 usesViewProjectionMatrix =
true;
2182 if (usesProjectionMatrix || usesInvProjectionMatrix) {
2183 if (viewCount < 2) {
2184 const QMatrix4x4 projection = clipSpaceCorrMatrix * inCameras[0]->projection;
2185 if (usesProjectionMatrix)
2186 shaders.setUniform(ubufData,
"qt_projectionMatrix", projection.constData(), 16 *
sizeof(
float), &cui.projectionMatrixIdx);
2187 if (usesInvProjectionMatrix)
2188 shaders.setUniform(ubufData,
"qt_inverseProjectionMatrix", projection.inverted().constData(), 16 *
sizeof (
float), &cui.inverseProjectionMatrixIdx);
2190 QVarLengthArray<QMatrix4x4, 2> projections(viewCount);
2191 QVarLengthArray<QMatrix4x4, 2> invertedProjections(viewCount);
2192 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
2193 projections[viewIndex] = clipSpaceCorrMatrix * inCameras[viewIndex]->projection;
2194 if (usesInvProjectionMatrix)
2195 invertedProjections[viewIndex] = projections[viewIndex].inverted();
2197 if (usesProjectionMatrix)
2198 shaders.setUniformArray(ubufData,
"qt_projectionMatrix", projections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.projectionMatrixIdx);
2199 if (usesInvProjectionMatrix)
2200 shaders.setUniformArray(ubufData,
"qt_inverseProjectionMatrix", invertedProjections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.inverseProjectionMatrixIdx);
2204 if (viewCount < 2) {
2205 const QMatrix4x4 viewMatrix = inCameras[0]->globalTransform.inverted();
2206 shaders.setUniform(ubufData,
"qt_viewMatrix", viewMatrix.constData(), 16 *
sizeof(
float), &cui.viewMatrixIdx);
2208 QVarLengthArray<QMatrix4x4, 2> viewMatrices(viewCount);
2209 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
2210 viewMatrices[viewIndex] = inCameras[viewIndex]->globalTransform.inverted();
2211 shaders.setUniformArray(ubufData,
"qt_viewMatrix", viewMatrices.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.viewMatrixIdx);
2214 if (usesViewProjectionMatrix) {
2215 if (viewCount < 2) {
2216 QMatrix4x4 viewProj(Qt::Uninitialized);
2217 inCameras[0]->calculateViewProjectionMatrix(viewProj);
2218 viewProj = clipSpaceCorrMatrix * viewProj;
2219 shaders.setUniform(ubufData,
"qt_viewProjectionMatrix", viewProj.constData(), 16 *
sizeof(
float), &cui.viewProjectionMatrixIdx);
2221 QVarLengthArray<QMatrix4x4, 2> viewProjections(viewCount);
2222 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
2223 inCameras[viewIndex]->calculateViewProjectionMatrix(viewProjections[viewIndex]);
2224 viewProjections[viewIndex] = clipSpaceCorrMatrix * viewProjections[viewIndex];
2226 shaders.setUniformArray(ubufData,
"qt_viewProjectionMatrix", viewProjections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.viewProjectionMatrixIdx);
2232 shaders.setUniform(ubufData,
"qt_modelMatrix", localInstanceTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2234 shaders.setUniform(ubufData,
"qt_modelMatrix", inGlobalTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2236 if (usesModelViewProjectionMatrix) {
2237 if (viewCount < 2) {
2238 QMatrix4x4 mvp { clipSpaceCorrMatrix };
2239 mvp *= inModelViewProjections[0];
2240 shaders.setUniform(ubufData,
"qt_modelViewProjection", mvp.constData(), 16 *
sizeof(
float), &cui.modelViewProjectionIdx);
2242 QVarLengthArray<QMatrix4x4, 2> mvps(viewCount);
2243 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
2244 mvps[viewIndex] = clipSpaceCorrMatrix * inModelViewProjections[viewIndex];
2245 shaders.setUniformArray(ubufData,
"qt_modelViewProjection", mvps.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.modelViewProjectionIdx);
2248 if (usesNormalMatrix)
2249 shaders.setUniform(ubufData,
"qt_normalMatrix", inNormalMatrix.constData(), 12 *
sizeof(
float), &cui.normalMatrixIdx,
2250 QSSGRhiShaderPipeline::UniformFlag::Mat3);
2251 if (usesParentMatrix)
2252 shaders.setUniform(ubufData,
"qt_parentMatrix", globalInstanceTransform.constData(), 16 *
sizeof(
float));
2255 const qsizetype morphSize = inProperties.m_targetCount.getValue(inKey);
2256 if (morphSize > 0) {
2257 if (inMorphWeights.mSize >= morphSize) {
2258 shaders.setUniformArray(ubufData,
"qt_morphWeights", inMorphWeights.mData, morphSize,
2259 QSSGRenderShaderValue::Float, &cui.morphWeightsIdx);
2261 const QList<
float> zeroWeights(morphSize - inMorphWeights.mSize, 0.0f);
2262 QList<
float> newWeights(inMorphWeights.mData, inMorphWeights.mData + inMorphWeights.mSize);
2263 newWeights.append(zeroWeights);
2264 shaders.setUniformArray(ubufData,
"qt_morphWeights", newWeights.constData(), morphSize,
2265 QSSGRenderShaderValue::Float, &cui.morphWeightsIdx);
2269 QVector3D theLightAmbientTotal;
2270 shaders.resetShadowMaps();
2271 float lightColor[QSSG_MAX_NUM_LIGHTS][3];
2272 QSSGShaderLightsUniformData &lightsUniformData(shaders.lightsUniformData());
2273 lightsUniformData.count = 0;
2274 QSSGShaderShadowsUniformData &shadowsUniformData(shaders.shadowsUniformData());
2275 shadowsUniformData.count = 0;
2277 for (quint32 lightIdx = 0, lightEnd = inLights.size();
2278 lightIdx < lightEnd && lightIdx < QSSG_MAX_NUM_LIGHTS; ++lightIdx)
2280 QSSGRenderLight *theLight(inLights[lightIdx].light);
2281 const bool lightShadows = inLights[lightIdx].shadows;
2282 const float brightness = theLight->m_brightness;
2283 lightColor[lightIdx][0] = theLight->m_diffuseColor.x() * brightness;
2284 lightColor[lightIdx][1] = theLight->m_diffuseColor.y() * brightness;
2285 lightColor[lightIdx][2] = theLight->m_diffuseColor.z() * brightness;
2286 lightsUniformData.count += 1;
2287 QSSGShaderLightData &lightData(lightsUniformData.lightData[lightIdx]);
2288 const QVector3D &lightSpecular(theLight->m_specularColor);
2289 lightData.specular[0] = lightSpecular.x() * brightness;
2290 lightData.specular[1] = lightSpecular.y() * brightness;
2291 lightData.specular[2] = lightSpecular.z() * brightness;
2292 lightData.specular[3] = 1.0f;
2293 const QVector3D &lightDirection(inLights[lightIdx].direction);
2294 lightData.direction[0] = lightDirection.x();
2295 lightData.direction[1] = lightDirection.y();
2296 lightData.direction[2] = lightDirection.z();
2297 lightData.direction[3] = 1.0f;
2308 if (lightShadows && shadowsUniformData.count < QSSG_MAX_NUM_SHADOW_MAPS) {
2309 QSSGRhiShadowMapProperties &theShadowMapProperties(shaders.addShadowMap());
2310 ++shadowsUniformData.count;
2312 QSSGShadowMapEntry *pEntry = inRenderProperties.getShadowMapManager()->shadowMapEntry(lightIdx);
2315 const auto& names = setupShadowMapVariableNames(lightIdx, theLight->m_shadowMapRes);
2317 QSSGShaderShadowData &shadowData(shadowsUniformData.shadowData[lightIdx]);
2319 if (theLight->type == QSSGRenderLight::Type::DirectionalLight ||
2320 theLight->type == QSSGRenderLight::Type::SpotLight) {
2321 theShadowMapProperties.shadowMapTexture = pEntry->m_rhiDepthTextureArray;
2322 theShadowMapProperties.shadowMapTextureUniformName = names.shadowMapTexture;
2323 }
else if (theLight->type == QSSGRenderLight::Type::PointLight) {
2324 theShadowMapProperties.shadowMapTexture = pEntry->m_rhiDepthCube;
2325 theShadowMapProperties.shadowMapTextureUniformName = names.shadowCube;
2330 if (receivesShadows) {
2331 if (theLight->type == QSSGRenderLight::Type::DirectionalLight ||
2332 theLight->type == QSSGRenderLight::Type::SpotLight) {
2334 static const QMatrix4x4 bias = {
2338 0.0, 0.0, 0.0, 1.0 };
2339 for (
int i = 0; i < 4; i++) {
2340 const QMatrix4x4 m = bias * pEntry->m_lightViewProjection[i];
2341 memcpy(shadowData.matrices[i], m.constData(), 16 *
sizeof(
float));
2344 Q_ASSERT(theLight->type == QSSGRenderLight::Type::PointLight);
2345 memcpy(&shadowData.matrices[0], pEntry->m_lightView.constData(), 16 *
sizeof(
float));
2348 shadowData.bias = theLight->m_shadowBias;
2350 const bool noCascades = !(pEntry->m_csmActive[0] || pEntry->m_csmActive[1] || pEntry->m_csmActive[2] || pEntry->m_csmActive[3]);
2351 shadowData.factor = theLight->type == QSSGRenderLight::Type::DirectionalLight && noCascades ? 0.0f : theLight->m_shadowFactor;
2352 shadowData.clipNear = 1.0f;
2353 shadowData.shadowMapFar = pEntry->m_shadowMapFar;
2354 shadowData.isYUp = globalRenderData.isYUpInFramebuffer ? 0.0f : 1.0f;
2355 shadowData.layerIndex = pEntry->m_depthArrayIndex;
2356 shadowData.csmNumSplits = pEntry->m_csmNumSplits;
2357 memcpy(shadowData.csmSplits, pEntry->m_csmSplits, 4 *
sizeof(
float));
2358 memcpy(shadowData.csmActive, pEntry->m_csmActive, 4 *
sizeof(
float));
2359 shadowData.csmBlendRatio = theLight->m_csmBlendRatio;
2360 for (
int i = 0; i < 4; i++) {
2361 QMatrix4x4 inv = pEntry->m_lightViewProjection[i].inverted();
2362 const float x = 0.5f / (inv * QVector4D(1, 0, 0, 0)).length();
2363 const float y = 0.5f / (inv * QVector4D(0, 1, 0, 0)).length();
2364 const float z = 0.5f / (inv * QVector4D(0, 0, 1, 0)).length();
2365 QVector4D dimensionsInverted = QVector4D(x, y, z, 0);
2366 memcpy(shadowData.dimensionsInverted[i], &dimensionsInverted, 4 *
sizeof(
float));
2368 shadowData.pcfFactor = theLight->m_pcfFactor;
2370 memset(&shadowData,
'\0',
sizeof(shadowData));
2374 if (theLight->type == QSSGRenderLight::Type::PointLight
2375 || theLight->type == QSSGRenderLight::Type::SpotLight) {
2376 const QVector3D globalPos = theLight->getGlobalPos();
2377 lightData.position[0] = globalPos.x();
2378 lightData.position[1] = globalPos.y();
2379 lightData.position[2] = globalPos.z();
2380 lightData.position[3] = 1.0f;
2381 lightData.constantAttenuation = QSSGUtils::aux::translateConstantAttenuation(theLight->m_constantFade);
2382 lightData.linearAttenuation = QSSGUtils::aux::translateLinearAttenuation(theLight->m_linearFade);
2383 lightData.quadraticAttenuation = QSSGUtils::aux::translateQuadraticAttenuation(theLight->m_quadraticFade);
2384 lightData.coneAngle = 180.0f;
2385 if (theLight->type == QSSGRenderLight::Type::SpotLight) {
2386 const float coneAngle = theLight->m_coneAngle;
2387 const float innerConeAngle = (theLight->m_innerConeAngle > coneAngle) ?
2388 coneAngle : theLight->m_innerConeAngle;
2389 lightData.coneAngle = qCos(qDegreesToRadians(coneAngle));
2390 lightData.innerConeAngle = qCos(qDegreesToRadians(innerConeAngle));
2394 theLightAmbientTotal += theLight->m_ambientColor;
2397 const QSSGRhiRenderableTexture *depthTexture = inRenderProperties.getRenderResult(QSSGFrameData::RenderResult::DepthTexture);
2398 const QSSGRhiRenderableTexture *ssaoTexture = inRenderProperties.getRenderResult(QSSGFrameData::RenderResult::AoTexture);
2399 const QSSGRhiRenderableTexture *screenTexture = inRenderProperties.getRenderResult(QSSGFrameData::RenderResult::ScreenTexture);
2401 shaders.setDepthTexture(depthTexture->texture);
2402 shaders.setSsaoTexture(ssaoTexture->texture);
2403 shaders.setScreenTexture(screenTexture->texture);
2404 shaders.setLightmapTexture(lightmapTexture);
2406 const QSSGRenderLayer &layer = QSSGLayerRenderData::getCurrent(*renderContext.renderer())->layer;
2407 QSSGRenderImage *theLightProbe = layer.lightProbe;
2408 const auto &lightProbeData = layer.lightProbeSettings;
2411 QSSGRenderImage *materialIblProbe = materialAdapter->iblProbe();
2412 if (materialIblProbe)
2413 theLightProbe = materialIblProbe;
2414 QSSGRenderImageTexture lightProbeTexture;
2416 lightProbeTexture = renderContext.bufferManager()->loadRenderImage(theLightProbe, QSSGBufferManager::MipModeBsdf);
2417 if (theLightProbe && lightProbeTexture.m_texture) {
2418 QSSGRenderTextureCoordOp theHorzLightProbeTilingMode = theLightProbe->m_horizontalTilingMode;
2419 QSSGRenderTextureCoordOp theVertLightProbeTilingMode = theLightProbe->m_verticalTilingMode;
2420 const int maxMipLevel = lightProbeTexture.m_mipmapCount - 1;
2422 if (!materialIblProbe && !lightProbeData.probeOrientation.isIdentity()) {
2423 shaders.setUniform(ubufData,
"qt_lightProbeOrientation",
2424 lightProbeData.probeOrientation.constData(),
2425 12 *
sizeof(
float), &cui.lightProbeOrientationIdx,
2426 QSSGRhiShaderPipeline::UniformFlag::Mat3);
2429 const float props[4] = { 0.0f,
float(maxMipLevel), lightProbeData.probeHorizon, lightProbeData.probeExposure };
2430 shaders.setUniform(ubufData,
"qt_lightProbeProperties", props, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2432 shaders.setLightProbeTexture(lightProbeTexture.m_texture, theHorzLightProbeTilingMode, theVertLightProbeTilingMode);
2435 const float emptyProps[4] = { 0.0f, 0.0f, -1.0f, 0.0f };
2436 shaders.setUniform(ubufData,
"qt_lightProbeProperties", emptyProps, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2438 shaders.setLightProbeTexture(
nullptr);
2441 if (receivesReflections && reflectionProbe.enabled) {
2442 shaders.setUniform(ubufData,
"qt_reflectionProbeCubeMapCenter", &reflectionProbe.probeCubeMapCenter, 3 *
sizeof(
float), &cui.reflectionProbeCubeMapCenter);
2443 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMin", &reflectionProbe.probeBoxMin, 3 *
sizeof(
float), &cui.reflectionProbeBoxMin);
2444 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMax", &reflectionProbe.probeBoxMax, 3 *
sizeof(
float), &cui.reflectionProbeBoxMax);
2445 shaders.setUniform(ubufData,
"qt_reflectionProbeCorrection", &reflectionProbe.parallaxCorrection,
sizeof(
int), &cui.reflectionProbeCorrection);
2448 const QVector3D emissiveColor = materialAdapter->emissiveColor();
2449 shaders.setUniform(ubufData,
"qt_material_emissive_color", &emissiveColor, 3 *
sizeof(
float), &cui.material_emissiveColorIdx);
2451 const auto qMix = [](
float x,
float y,
float a) {
2452 return (x * (1.0f - a) + (y * a));
2455 const auto qMix3 = [&qMix](
const QVector3D &x,
const QVector3D &y,
float a) {
2456 return QVector3D{qMix(x.x(), y.x(), a), qMix(x.y(), y.y(), a), qMix(x.z(), y.z(), a)};
2459 const QVector4D color = materialAdapter->color();
2460 const QVector3D materialSpecularTint = materialAdapter->specularTint();
2461 const QVector3D specularTint = materialAdapter->isPrincipled() ? qMix3(QVector3D(1.0f, 1.0f, 1.0f), color.toVector3D(), materialSpecularTint.x())
2462 : materialSpecularTint;
2463 shaders.setUniform(ubufData,
"qt_material_base_color", &color, 4 *
sizeof(
float), &cui.material_baseColorIdx);
2465 const float ior = materialAdapter->ior();
2466 QVector4D specularColor(specularTint, ior);
2467 shaders.setUniform(ubufData,
"qt_material_specular", &specularColor, 4 *
sizeof(
float), &cui.material_specularIdx);
2470 const bool hasLighting = materialAdapter->hasLighting();
2471 shaders.setLightsEnabled(hasLighting);
2473 for (
int lightIdx = 0; lightIdx < lightsUniformData.count; ++lightIdx) {
2474 QSSGShaderLightData &lightData(lightsUniformData.lightData[lightIdx]);
2475 lightData.diffuse[0] = lightColor[lightIdx][0];
2476 lightData.diffuse[1] = lightColor[lightIdx][1];
2477 lightData.diffuse[2] = lightColor[lightIdx][2];
2478 lightData.diffuse[3] = 1.0f;
2480 memcpy(ubufData + shaders.ub0LightDataOffset(), &lightsUniformData, shaders.ub0LightDataSize());
2482 if (shadowsUniformData.count)
2483 memcpy(ubufData + shaders.ub0ShadowDataOffset(), &shadowsUniformData, shaders.ub0ShadowDataSize());
2486 shaders.setUniform(ubufData,
"qt_light_ambient_total", &theLightAmbientTotal, 3 *
sizeof(
float), &cui.light_ambient_totalIdx);
2488 const float materialProperties[4] = {
2489 materialAdapter->specularAmount(),
2490 materialAdapter->specularRoughness(),
2491 materialAdapter->metalnessAmount(),
2494 shaders.setUniform(ubufData,
"qt_material_properties", materialProperties, 4 *
sizeof(
float), &cui.material_propertiesIdx);
2496 const float materialProperties2[4] = {
2497 materialAdapter->fresnelPower(),
2498 materialAdapter->bumpAmount(),
2499 materialAdapter->translucentFallOff(),
2500 materialAdapter->diffuseLightWrap()
2502 shaders.setUniform(ubufData,
"qt_material_properties2", materialProperties2, 4 *
sizeof(
float), &cui.material_properties2Idx);
2504 const float materialProperties3[4] = {
2505 materialAdapter->occlusionAmount(),
2506 materialAdapter->alphaCutOff(),
2507 materialAdapter->clearcoatAmount(),
2508 materialAdapter->clearcoatRoughnessAmount()
2510 shaders.setUniform(ubufData,
"qt_material_properties3", materialProperties3, 4 *
sizeof(
float), &cui.material_properties3Idx);
2512 const float materialProperties4[4] = {
2513 materialAdapter->heightAmount(),
2514 materialAdapter->minHeightSamples(),
2515 materialAdapter->maxHeightSamples(),
2516 materialAdapter->transmissionFactor()
2518 shaders.setUniform(ubufData,
"qt_material_properties4", materialProperties4, 4 *
sizeof(
float), &cui.material_properties4Idx);
2520 const bool hasCustomFrag = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
2521 if (!hasCustomFrag) {
2522 if (inProperties.m_fresnelScaleBiasEnabled.getValue(inKey) || inProperties.m_clearcoatFresnelScaleBiasEnabled.getValue(inKey)) {
2523 const float materialProperties5[4] = {
2524 materialAdapter->fresnelScale(),
2525 materialAdapter->fresnelBias(),
2526 materialAdapter->clearcoatFresnelScale(),
2527 materialAdapter->clearcoatFresnelBias()
2529 shaders.setUniform(ubufData,
"qt_material_properties5", materialProperties5, 4 *
sizeof(
float), &cui.material_properties5Idx);
2532 const float material_clearcoat_normal_strength = materialAdapter->clearcoatNormalStrength();
2533 shaders.setUniform(ubufData,
"qt_material_clearcoat_normal_strength", &material_clearcoat_normal_strength,
sizeof(
float), &cui.clearcoatNormalStrengthIdx);
2535 const float material_clearcoat_fresnel_power = materialAdapter->clearcoatFresnelPower();
2536 shaders.setUniform(ubufData,
"qt_material_clearcoat_fresnel_power", &material_clearcoat_fresnel_power,
sizeof(
float), &cui.clearcoatFresnelPowerIdx);
2538 if (materialAdapter->isTransmissionEnabled()) {
2539 const QVector4D attenuationProperties(materialAdapter->attenuationColor(), materialAdapter->attenuationDistance());
2540 shaders.setUniform(ubufData,
"qt_material_attenuation", &attenuationProperties, 4 *
sizeof(
float), &cui.material_attenuationIdx);
2542 const float thickness = materialAdapter->thicknessFactor();
2543 shaders.setUniform(ubufData,
"qt_material_thickness", &thickness,
sizeof(
float), &cui.thicknessFactorIdx);
2547 const float rhiProperties[4] = {
2548 globalRenderData.isYUpInFramebuffer ? 1.0f : -1.0f,
2549 globalRenderData.isYUpInNDC ? 1.0f : -1.0f,
2550 globalRenderData.isClipDepthZeroToOne ? 0.0f : -1.0f,
2553 shaders.setUniform(ubufData,
"qt_rhi_properties", rhiProperties, 4 *
sizeof(
float), &cui.rhiPropertiesIdx);
2555 qsizetype imageIdx = 0;
2556 for (QSSGRenderableImage *theImage = inFirstImage; theImage; theImage = theImage->m_nextImage, ++imageIdx) {
2558 const auto &names = imageStringTable[
int(theImage->m_mapType)];
2559 if (imageIdx == cui.imageIndices.size())
2560 cui.imageIndices.append(QSSGRhiShaderPipeline::CommonUniformIndices::ImageIndices());
2561 auto &indices = cui.imageIndices[imageIdx];
2563 const QMatrix4x4 &textureTransform = theImage->m_imageNode.m_textureTransform;
2566 const float *dataPtr(textureTransform.constData());
2570 const float offsets[3] = { dataPtr[12], dataPtr[13], 0.0f };
2571 shaders.setUniform(ubufData, names.imageOffsets, offsets,
sizeof(offsets), &indices.imageOffsetsUniformIndex);
2573 const float rotations[4] = { dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5] };
2574 shaders.setUniform(ubufData, names.imageRotations, rotations,
sizeof(rotations), &indices.imageRotationsUniformIndex);
2577 if (shadowDepthAdjust)
2578 shaders.setUniform(ubufData,
"qt_shadowDepthAdjust", shadowDepthAdjust, 2 *
sizeof(
float), &cui.shadowDepthAdjustIdx);
2580 const bool usesPointsTopology = inProperties.m_usesPointsTopology.getValue(inKey);
2581 if (usesPointsTopology) {
2582 const float pointSize = materialAdapter->pointSize();
2583 shaders.setUniform(ubufData,
"qt_materialPointSize", &pointSize,
sizeof(
float), &cui.pointSizeIdx);
2590 if (inRenderProperties.layer.fog.enabled) {
2591 const float fogColor[4] = {
2592 inRenderProperties.layer.fog.color.x(),
2593 inRenderProperties.layer.fog.color.y(),
2594 inRenderProperties.layer.fog.color.z(),
2595 inRenderProperties.layer.fog.density
2597 shaders.setUniform(ubufData,
"qt_fogColor", fogColor, 4 *
sizeof(
float), &cui.fogColorIdx);
2598 const float fogDepthProperties[4] = {
2599 inRenderProperties.layer.fog.depthBegin,
2600 inRenderProperties.layer.fog.depthEnd,
2601 inRenderProperties.layer.fog.depthCurve,
2602 inRenderProperties.layer.fog.depthEnabled ? 1.0f : 0.0f
2604 shaders.setUniform(ubufData,
"qt_fogDepthProperties", fogDepthProperties, 4 *
sizeof(
float), &cui.fogDepthPropertiesIdx);
2605 const float fogHeightProperties[4] = {
2606 inRenderProperties.layer.fog.heightMin,
2607 inRenderProperties.layer.fog.heightMax,
2608 inRenderProperties.layer.fog.heightCurve,
2609 inRenderProperties.layer.fog.heightEnabled ? 1.0f : 0.0f
2611 shaders.setUniform(ubufData,
"qt_fogHeightProperties", fogHeightProperties, 4 *
sizeof(
float), &cui.fogHeightPropertiesIdx);
2612 const float fogTransmitProperties[4] = {
2613 inRenderProperties.layer.fog.transmitCurve,
2616 inRenderProperties.layer.fog.transmitEnabled ? 1.0f : 0.0f
2618 shaders.setUniform(ubufData,
"qt_fogTransmitProperties", fogTransmitProperties, 4 *
sizeof(
float), &cui.fogTransmitPropertiesIdx);
2621 inPipelineState->lineWidth = materialAdapter->lineWidth();