884 QSSGMaterialVertexPipeline &vertexShader,
885 const QSSGShaderDefaultMaterialKey &inKey,
886 const QSSGShaderDefaultMaterialKeyProperties &keyProps,
887 const QSSGShaderFeatures &featureSet,
888 const QSSGRenderGraphObject &inMaterial,
889 const QSSGUserShaderAugmentation &shaderAugmentation,
890 QSSGShaderLibraryManager &shaderLibraryManager)
892 QSSGShaderMaterialAdapter *materialAdapter = getMaterialAdapter(inMaterial);
893 auto hasCustomFunction = [&shaderLibraryManager, materialAdapter](
const QByteArray &funcName) {
894 return materialAdapter->hasCustomShaderFunction(QSSGShaderCache::ShaderType::Fragment,
896 shaderLibraryManager);
899 auto channelStr = [](
const QSSGShaderKeyTextureChannel &chProp,
const QSSGShaderDefaultMaterialKey &inKey) -> QByteArray {
901 switch (chProp.getTextureChannel(inKey)) {
902 case QSSGShaderKeyTextureChannel::R:
905 case QSSGShaderKeyTextureChannel::G:
908 case QSSGShaderKeyTextureChannel::B:
911 case QSSGShaderKeyTextureChannel::A:
918 auto maskVariableByVertexColorChannel = [&fragmentShader, keyProps, inKey](
const QByteArray &maskVariable,
const QSSGRenderDefaultMaterial::VertexColorMask &maskEnum ){
919 if (keyProps.m_vertexColorsMaskEnabled.getValue(inKey)) {
920 if ( keyProps.m_vertexColorRedMask.getValue(inKey) & maskEnum )
921 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.r;\n";
922 else if ( keyProps.m_vertexColorGreenMask.getValue(inKey) & maskEnum )
923 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.g;\n";
924 else if ( keyProps.m_vertexColorBlueMask.getValue(inKey) & maskEnum )
925 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.b;\n";
926 else if ( keyProps.m_vertexColorAlphaMask.getValue(inKey) & maskEnum )
927 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.a;\n";
931 generateFragmentDefines(fragmentShader, inKey, keyProps, materialAdapter, shaderLibraryManager, shaderAugmentation);
936 const PassRequirmentsState passRequirmentState(inKey, keyProps, featureSet, samplerState, shaderAugmentation);
938 const bool hasCustomVert = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Vertex);
940 const int viewCount = featureSet.isSet(QSSGShaderFeatures::Feature::DisableMultiView)
941 ? 1 : keyProps.m_viewCount.getValue(inKey);
944 if (passRequirmentState.numMorphTargets > 0 || hasCustomVert) {
945 vertexShader.addDefinition(QByteArrayLiteral(
"QT_MORPH_MAX_COUNT"),
946 QByteArray::number(passRequirmentState.numMorphTargets));
948 if ((offset = keyProps.m_targetPositionOffset.getValue(inKey)) < UINT8_MAX) {
949 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_POSITION_OFFSET"),
950 QByteArray::number(offset));
952 if ((offset = keyProps.m_targetNormalOffset.getValue(inKey)) < UINT8_MAX) {
953 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_NORMAL_OFFSET"),
954 QByteArray::number(offset));
956 if ((offset = keyProps.m_targetTangentOffset.getValue(inKey)) < UINT8_MAX) {
957 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TANGENT_OFFSET"),
958 QByteArray::number(offset));
960 if ((offset = keyProps.m_targetBinormalOffset.getValue(inKey)) < UINT8_MAX) {
961 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_BINORMAL_OFFSET"),
962 QByteArray::number(offset));
964 if ((offset = keyProps.m_targetTexCoord0Offset.getValue(inKey)) < UINT8_MAX) {
965 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TEX0_OFFSET"),
966 QByteArray::number(offset));
968 if ((offset = keyProps.m_targetTexCoord1Offset.getValue(inKey)) < UINT8_MAX) {
969 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TEX1_OFFSET"),
970 QByteArray::number(offset));
972 if ((offset = keyProps.m_targetColorOffset.getValue(inKey)) < UINT8_MAX) {
973 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_COLOR_OFFSET"),
974 QByteArray::number(offset));
979 if (shaderAugmentation.hasUserAugmentation())
980 fragmentShader << shaderAugmentation.preamble;
983 for (
const auto &u : shaderAugmentation.propertyUniforms)
984 fragmentShader.addUniform(u.name, u.typeName);
987 const bool hasCustomFrag = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
988 const bool usesSharedVar = materialAdapter->usesSharedVariables();
990 vertexShader.beginFragmentGeneration(shaderLibraryManager, passRequirmentState.oitMethod);
993 vertexShader.generateDepth();
994 fragmentShader.addUniform(
"qt_shadowDepthAdjust",
"vec2");
999 vertexShader.generateShadowWorldPosition(inKey);
1002 if (hasCustomFrag && materialAdapter->isUnshaded()) {
1016 fragmentShader.addUniform(
"qt_material_emissive_color",
"vec3");
1018 fragmentShader.addUniform(
"qt_material_base_color",
"vec4");
1019 fragmentShader.addUniform(
"qt_material_properties",
"vec4");
1020 fragmentShader.addUniform(
"qt_material_properties2",
"vec4");
1021 fragmentShader.addUniform(
"qt_material_properties3",
"vec4");
1023 fragmentShader.addUniform(
"qt_material_properties4",
"vec4");
1024 if (!hasCustomFrag) {
1026 fragmentShader.addUniform(
"qt_material_attenuation",
"vec4");
1027 fragmentShader.addUniform(
"qt_material_thickness",
"float");
1029 fragmentShader.addUniform(
"qt_material_dispersion",
"float");
1032 fragmentShader.addUniform(
"qt_material_properties5",
"vec4");
1033 fragmentShader.addUniform(
"qt_material_clearcoat_normal_strength",
"float");
1034 fragmentShader.addUniform(
"qt_material_clearcoat_fresnel_power",
"float");
1036 fragmentShader.addUniform(
"qt_material_sheen_color",
"vec3");
1037 fragmentShader.addUniform(
"qt_material_sheen_roughness",
"float");
1041 fragmentShader.addUniform(
"qt_material_anisotropy",
"vec3");
1045 fragmentShader.addUniform(
"qt_material_iridescence",
"vec4");
1050 vertexShader.generateVertexColor(inKey);
1052 fragmentShader.append(
" vec4 qt_vertColorMask = vec4(1.0);");
1053 fragmentShader.append(
" vec4 qt_vertColor = vec4(1.0);");
1057 vertexShader.generateViewVector(inKey);
1058 if (keyProps.m_usesProjectionMatrix.getValue(inKey)) {
1060 fragmentShader.addUniformArray(
"qt_projectionMatrix",
"mat4", viewCount);
1062 fragmentShader.addUniform(
"qt_projectionMatrix",
"mat4");
1064 if (keyProps.m_usesInverseProjectionMatrix.getValue(inKey)) {
1066 fragmentShader.addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", viewCount);
1068 fragmentShader.addUniform(
"qt_inverseProjectionMatrix",
"mat4");
1070 vertexShader.generateWorldNormal(inKey);
1071 vertexShader.generateWorldPosition(inKey);
1074 bool genTangent =
false;
1075 bool genBinormal =
false;
1076 vertexShader.generateVarTangentAndBinormal(inKey, genTangent, genBinormal);
1079 QSSGRenderableImage::Type id = QSSGRenderableImage::Type::Unknown;
1084 id = samplerState.hasImage(QSSGRenderableImage::Type::Bump) ? QSSGRenderableImage::Type::Bump : QSSGRenderableImage::Type::Normal;
1085 }
else if (samplerState.hasImage(QSSGRenderableImage::Type::ClearcoatNormal)) {
1087 id = QSSGRenderableImage::Type::ClearcoatNormal;
1091 id = QSSGRenderableImage::Type::Height;
1092 }
else if (samplerState.hasImage(QSSGRenderableImage::Type::Anisotropy)) {
1093 id = QSSGRenderableImage::Type::Anisotropy;
1096 if (id > QSSGRenderableImage::Type::Unknown) {
1097 samplerState.generateImageUVAndSampler(id, vertexShader, fragmentShader, inKey,
true);
1098 fragmentShader <<
" vec2 dUVdx = dFdx(" << samplerState.fragCoordsName(id) <<
");\n"
1099 <<
" vec2 dUVdy = dFdy(" << samplerState.fragCoordsName(id) <<
");\n";
1100 fragmentShader <<
" qt_tangent = (dUVdy.y * dFdx(qt_varWorldPos) - dUVdx.y * dFdy(qt_varWorldPos)) / (dUVdx.x * dUVdy.y - dUVdx.y * dUVdy.x);\n"
1101 <<
" qt_tangent = qt_tangent - dot(qt_world_normal, qt_tangent) * qt_world_normal;\n"
1102 <<
" qt_tangent = normalize(qt_tangent);\n";
1105 fragmentShader.addInclude(
"anisotropy.glsllib");
1106 fragmentShader <<
" qt_tangent = qt_orthonormalTangent(qt_world_normal);\n";
1110 fragmentShader <<
" qt_binormal = cross(qt_world_normal, qt_tangent);\n";
1114 fragmentShader.append(
"#if QSHADER_HLSL && QSHADER_VIEW_COUNT >= 2");
1115 fragmentShader.append(
" const float qt_facing = 1.0;");
1116 fragmentShader.append(
"#else");
1117 fragmentShader.append(
" const float qt_facing = gl_FrontFacing ? 1.0 : -1.0;");
1118 fragmentShader.append(
"#endif");
1119 fragmentShader.append(
" qt_world_normal *= qt_facing;\n");
1121 fragmentShader.append(
" qt_tangent *= qt_facing;");
1122 fragmentShader.append(
" qt_binormal *= qt_facing;");
1127 if (hasCustomFrag) {
1133 fragmentShader <<
" float qt_customOcclusionAmount = 1.0;\n";
1134 fragmentShader <<
" float qt_customIOR = 1.5;\n";
1135 fragmentShader <<
" float qt_customSpecularAmount = 0.5;\n";
1136 fragmentShader <<
" float qt_customSpecularRoughness = 0.0;\n";
1137 fragmentShader <<
" float qt_customMetalnessAmount = 0.0;\n";
1138 fragmentShader <<
" float qt_customFresnelPower = 5.0;\n";
1139 fragmentShader <<
" vec4 qt_customBaseColor = vec4(1.0);\n";
1140 fragmentShader <<
" vec3 qt_customEmissiveColor = vec3(0.0);\n";
1142 fragmentShader <<
" float qt_customClearcoatAmount = 0.0;\n";
1143 fragmentShader <<
" float qt_customClearcoatFresnelPower = 5.0;\n";
1144 fragmentShader <<
" float qt_customClearcoatRoughness = 0.0;\n";
1145 fragmentShader <<
" vec3 qt_customClearcoatNormal = qt_world_normal;\n";
1147 fragmentShader <<
" float qt_customClearcoatFresnelScale = 1.0;\n";
1148 fragmentShader <<
" float qt_customClearcoatFresnelBias = 0.0;\n";
1152 fragmentShader <<
" vec3 qt_customSheenColor = vec3(0.0);\n";
1153 fragmentShader <<
" float qt_customSheenRoughness = 0.0;\n";
1156 fragmentShader <<
" float qt_customAnisotropyStrength = 0.0;\n";
1157 fragmentShader <<
" float qt_customAnisotropyRotation = 0.0;\n";
1160 fragmentShader <<
" float qt_customIridescenceFactor = 0.0;\n";
1161 fragmentShader <<
" float qt_customIridescenceIor = 1.3;\n";
1162 fragmentShader <<
" float qt_customIridescenceThickness = 400.0;\n";
1165 fragmentShader <<
" float qt_customFresnelScale = 1.0;\n";
1166 fragmentShader <<
" float qt_customFresnelBias = 0.0;\n";
1170 fragmentShader <<
" float qt_customDispersion = 0.0;\n";
1173 fragmentShader <<
" float qt_customTransmissionFactor = 0.0;\n";
1174 fragmentShader <<
" float qt_customThicknessFactor = 0.0;\n";
1175 fragmentShader <<
" vec3 qt_customAttenuationColor = vec3(1.0);\n";
1176 fragmentShader <<
" float qt_customAttenuationDistance = 0.0;\n";
1179 fragmentShader <<
" QT_SHARED_VARS qt_customShared;\n";
1182 vertexShader.generateUVCoords(0, inKey);
1183 vertexShader.generateUVCoords(1, inKey);
1185 fragmentShader <<
" qt_customMain(qt_customBaseColor,\n"
1186 <<
" qt_customEmissiveColor,\n"
1187 <<
" qt_customMetalnessAmount,\n"
1188 <<
" qt_customSpecularRoughness,\n"
1189 <<
" qt_customSpecularAmount,\n"
1190 <<
" qt_customFresnelPower,\n"
1191 <<
" qt_world_normal,\n"
1193 <<
" qt_binormal,\n"
1194 <<
" qt_texCoord0,\n"
1195 <<
" qt_texCoord1,\n"
1196 <<
" qt_view_vector,\n"
1197 <<
" qt_customIOR,\n"
1198 <<
" qt_customOcclusionAmount";
1200 fragmentShader <<
",\n qt_customClearcoatAmount,\n"
1201 <<
" qt_customClearcoatFresnelPower,\n"
1202 <<
" qt_customClearcoatRoughness,\n"
1203 <<
" qt_customClearcoatNormal";
1205 fragmentShader <<
",\n qt_customClearcoatFresnelScale,\n"
1206 <<
" qt_customClearcoatFresnelBias";
1210 fragmentShader <<
",\n qt_customSheenColor,\n"
1211 <<
" qt_customSheenRoughness";
1214 fragmentShader <<
",\n qt_customAnisotropyStrength,\n"
1215 <<
" qt_customAnisotropyRotation";
1218 fragmentShader <<
",\n qt_customIridescenceFactor,\n"
1219 <<
" qt_customIridescenceIor,\n"
1220 <<
" qt_customIridescenceThickness";
1223 fragmentShader <<
",\n qt_customFresnelScale,\n"
1224 <<
" qt_customFresnelBias";
1227 fragmentShader <<
",\n qt_customDispersion";
1229 fragmentShader <<
",\n qt_customTransmissionFactor,\n"
1230 <<
" qt_customThicknessFactor,\n"
1231 <<
" qt_customAttenuationColor,\n"
1232 <<
" qt_customAttenuationDistance";
1235 fragmentShader <<
"\n, qt_customShared);\n";
1237 fragmentShader <<
");\n";
1239 fragmentShader <<
" vec4 qt_diffuseColor = qt_customBaseColor * qt_vertColor;\n";
1240 fragmentShader <<
" vec3 qt_global_emission = qt_customEmissiveColor;\n";
1241 fragmentShader <<
" float qt_iOR = qt_customIOR;\n";
1243 fragmentShader <<
" vec4 qt_diffuseColor = qt_material_base_color * qt_vertColor;\n";
1244 fragmentShader <<
" vec3 qt_global_emission = qt_material_emissive_color;\n";
1246 fragmentShader <<
" float qt_iOR = qt_material_specular.w;\n";
1249 const bool hasCustomIblProbe = hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_iblProbeProcessor"));
1256 vertexShader.generateLightmapUVCoords(inKey);
1257 fragmentShader.addFunction(
"lightmap");
1266 fragmentShader.addInclude(
"parallaxMapping.glsllib");
1267 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Height, vertexShader, fragmentShader, inKey,
true);
1268 fragmentShader <<
" float qt_heightAmount = qt_material_properties4.x;\n";
1269 maskVariableByVertexColorChannel(
"qt_heightAmount", QSSGRenderDefaultMaterial::HeightAmountMask );
1270 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << samplerState.fragCoordsName(QSSGRenderableImage::Type::Height) <<
",\n"
1271 <<
" " << samplerState.samplerName(QSSGRenderableImage::Type::Height) <<
",\n"
1273 <<
" qt_binormal,\n"
1274 <<
" qt_world_normal,\n"
1275 <<
" qt_varWorldPos, \n"
1276 <<
"#if QSHADER_VIEW_COUNT >= 2\n"
1277 <<
" qt_cameraPosition[qt_viewIndex],\n"
1279 <<
" qt_cameraPosition,\n"
1281 <<
" qt_heightAmount,\n"
1282 <<
" qt_material_properties4.y,\n"
1283 <<
" qt_material_properties4.z);\n";
1288 addLocalVariable(fragmentShader,
"qt_clearcoatNormal",
"vec3");
1293 if (hasCustomFrag) {
1294 fragmentShader <<
" qt_clearcoatNormal = qt_customClearcoatNormal;\n";
1296 if (samplerState.hasImage(QSSGRenderableImage::Type::ClearcoatNormal)) {
1297 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::ClearcoatNormal, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1298 fragmentShader.addFunction(
"sampleNormalTexture");
1299 fragmentShader <<
" float qt_clearcoat_normal_strength = qt_material_clearcoat_normal_strength;\n";
1300 maskVariableByVertexColorChannel(
"qt_clearcoat_normal_strength", QSSGRenderDefaultMaterial::ClearcoatNormalStrengthMask );
1301 fragmentShader <<
" qt_clearcoatNormal = qt_sampleNormalTexture(" << samplerState.samplerName(QSSGRenderableImage::Type::ClearcoatNormal)
1302 <<
", qt_clearcoat_normal_strength, "
1303 << samplerState.fragCoordsName(QSSGRenderableImage::Type::ClearcoatNormal)
1304 <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1308 fragmentShader <<
" qt_clearcoatNormal = qt_world_normal;\n";
1315 if (samplerState.hasImage(QSSGRenderableImage::Type::Bump)) {
1316 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Bump, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1317 fragmentShader.append(
" float qt_bumpAmount = qt_material_properties2.y;\n");
1318 maskVariableByVertexColorChannel(
"qt_bumpAmount", QSSGRenderDefaultMaterial::NormalStrengthMask );
1319 fragmentShader.addInclude(
"defaultMaterialBumpNoLod.glsllib");
1320 fragmentShader <<
" qt_world_normal = qt_defaultMaterialBumpNoLod("
1321 << samplerState.samplerName(QSSGRenderableImage::Type::Bump)
1322 <<
", qt_bumpAmount, " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Bump)
1323 <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1324 }
else if (samplerState.hasImage(QSSGRenderableImage::Type::Normal)) {
1325 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Normal, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1326 fragmentShader.append(
" float qt_normalStrength = qt_material_properties2.y;\n");
1327 maskVariableByVertexColorChannel(
"qt_normalStrength", QSSGRenderDefaultMaterial::NormalStrengthMask );
1328 fragmentShader.addFunction(
"sampleNormalTexture");
1329 fragmentShader <<
" qt_world_normal = qt_sampleNormalTexture(" << samplerState.samplerName(QSSGRenderableImage::Type::Normal)
1330 <<
", qt_normalStrength, " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Normal)
1331 <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1339 fragmentShader.append(
" vec3 tmp_light_color;");
1343 fragmentShader.append(
" vec3 qt_specularBase;");
1344 fragmentShader.addUniform(
"qt_material_specular",
"vec4");
1346 fragmentShader.append(
" vec3 qt_specularTint = vec3(1.0);");
1348 fragmentShader.append(
" vec3 qt_specularTint = qt_material_specular.rgb;");
1352 if ((samplerState.hasImage(QSSGRenderableImage::Type::BaseColor) || samplerState.hasImage(QSSGRenderableImage::Type::Diffuse)) && passRequirmentState
.needsBaseColor) {
1355 QSSGRenderableImage::Type baseImageType = QSSGRenderableImage::Type::Unknown;
1356 if (samplerState.hasImage(QSSGRenderableImage::Type::BaseColor))
1357 baseImageType = QSSGRenderableImage::Type::BaseColor;
1358 else if (samplerState.hasImage(QSSGRenderableImage::Type::Diffuse))
1359 baseImageType = QSSGRenderableImage::Type::Diffuse;
1362 samplerState.generateImageUVAndSampler(baseImageType, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1364 if (keyProps.m_baseColorSingleChannelEnabled.getValue(inKey)) {
1365 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::BaseColorChannel];
1366 fragmentShader <<
" vec4 qt_base_texture_color = vec4(vec3(texture2D(" << samplerState.samplerName(baseImageType)
1367 <<
", " << samplerState.fragCoordsName(baseImageType) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1369 fragmentShader <<
" vec4 qt_base_texture_color = texture2D(" << samplerState.samplerName(baseImageType)
1370 <<
", " << samplerState.fragCoordsName(baseImageType) <<
");\n";
1373 if (keyProps.m_imageMaps[QSSGShaderDefaultMaterialKeyProperties::BaseColorMap].isPreMultipliedAlpha(inKey))
1374 fragmentShader <<
" qt_base_texture_color.rgb /= qt_base_texture_color.a;\n";
1376 if (!keyProps.m_imageMaps[QSSGShaderDefaultMaterialKeyProperties::BaseColorMap].isLinear(inKey)) {
1378 fragmentShader.addInclude(
"tonemapping.glsllib");
1379 fragmentShader <<
" qt_base_texture_color = qt_sRGBToLinear(qt_base_texture_color);\n";
1382 fragmentShader <<
" qt_diffuseColor *= qt_base_texture_color;\n";
1386 if (keyProps.m_alphaMode.getAlphaMode(inKey) == QSSGRenderDefaultMaterial::MaterialAlphaMode::Mask) {
1390 fragmentShader <<
" if (qt_diffuseColor.a < qt_material_properties3.y) {\n"
1391 <<
" qt_diffuseColor = vec4(0.0);\n"
1394 <<
" qt_diffuseColor.a = 1.0;\n"
1396 }
else if (keyProps.m_alphaMode.getAlphaMode(inKey) == QSSGRenderDefaultMaterial::MaterialAlphaMode::Opaque) {
1397 fragmentShader <<
" qt_diffuseColor.a = 1.0;\n";
1401 if (samplerState.hasImage(QSSGRenderableImage::Type::Opacity)) {
1402 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Opacity, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1403 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::OpacityChannel];
1404 fragmentShader <<
" float qt_opacity_map_value = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Opacity)
1405 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Opacity) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1406 if (keyProps.m_invertOpacityMapValue.getValue(inKey))
1407 fragmentShader <<
" qt_opacity_map_value = 1.0 - qt_opacity_map_value;\n";
1408 fragmentShader <<
" qt_objectOpacity *= qt_opacity_map_value;\n";
1413 addLocalVariable(fragmentShader,
"qt_aoFactor",
"float");
1416 fragmentShader.addInclude(
"ssao.glsllib");
1417 fragmentShader.append(
" qt_aoFactor = qt_screenSpaceAmbientOcclusionFactor();");
1419 fragmentShader.append(
" qt_aoFactor = 1.0;");
1423 fragmentShader <<
" qt_aoFactor *= qt_customOcclusionAmount;\n";
1429 fragmentShader <<
" float qt_roughnessAmount = qt_customSpecularRoughness;\n";
1431 fragmentShader <<
" float qt_roughnessAmount = qt_material_properties.y;\n";
1433 maskVariableByVertexColorChannel(
"qt_roughnessAmount", QSSGRenderDefaultMaterial::RoughnessMask );
1435 if (samplerState.hasImage(QSSGRenderableImage::Type::Roughness)) {
1436 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Roughness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1437 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::RoughnessChannel];
1438 fragmentShader <<
" qt_roughnessAmount *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Roughness) <<
", "
1439 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Roughness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1444 fragmentShader <<
" qt_roughnessAmount = clamp(1.0 - qt_roughnessAmount, 0.0, 1.0);\n";
1450 fragmentShader <<
" float qt_metalnessAmount = qt_customMetalnessAmount;\n";
1452 fragmentShader <<
" float qt_metalnessAmount = qt_material_properties.z;\n";
1454 fragmentShader <<
" float qt_metalnessAmount = 0.0;\n";
1456 maskVariableByVertexColorChannel(
"qt_metalnessAmount", QSSGRenderDefaultMaterial::MetalnessMask );
1458 if (passRequirmentState
.hasSpecularLight && samplerState.hasImage(QSSGRenderableImage::Type::Metalness)) {
1459 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::MetalnessChannel];
1460 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Metalness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1461 fragmentShader <<
" float qt_sampledMetalness = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Metalness) <<
", "
1462 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Metalness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1463 fragmentShader <<
" qt_metalnessAmount = clamp(qt_metalnessAmount * qt_sampledMetalness, 0.0, 1.0);\n";
1470 fragmentShader <<
" if ((qt_diffuseColor.a * qt_objectOpacity) < (1.0 - 1e-6))\n";
1471 fragmentShader <<
" discard;\n";
1477 vertexShader.generateViewVector(inKey);
1478 fragmentShader.addUniform(
"qt_material_properties",
"vec4");
1481 fragmentShader <<
" qt_specularBase = vec3(1.0);\n";
1483 fragmentShader <<
" qt_specularBase = qt_diffuseColor.rgb;\n";
1485 fragmentShader <<
" float qt_specularFactor = qt_customSpecularAmount;\n";
1487 fragmentShader <<
" float qt_specularFactor = qt_material_properties.x;\n";
1489 maskVariableByVertexColorChannel(
"qt_specularFactor", QSSGRenderDefaultMaterial::SpecularAmountMask );
1492 fragmentShader.addUniform(
"qt_light_ambient_total",
"vec3");
1494 fragmentShader.append(
" vec4 global_diffuse_light = vec4(0.0);");
1497 fragmentShader <<
" global_diffuse_light.rgb = qt_lightmap_color(qt_texCoordLightmap) * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb;\n";
1499 if (hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_ambientLightProcessor"))) {
1501 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");
1503 fragmentShader <<
", qt_customShared);\n";
1505 fragmentShader <<
");\n";
1507 fragmentShader.append(
" global_diffuse_light = vec4(qt_light_ambient_total.rgb * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb, 0.0);");
1511 fragmentShader.append(
" vec3 global_specular_light = vec3(0.0);");
1515 if (samplerState.hasImage(QSSGRenderableImage::Type::SpecularAmountMap)) {
1516 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::SpecularAmountMap, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1518 if (keyProps.m_specularSingleChannelEnabled.getValue(inKey)) {
1519 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::SpecularAmountChannel];
1520 fragmentShader <<
" vec4 qt_specular_amount_map = vec4(vec3(texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::SpecularAmountMap)
1521 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::SpecularAmountMap) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1523 fragmentShader <<
" vec4 qt_specular_amount_map = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::SpecularAmountMap)
1524 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::SpecularAmountMap) <<
");\n";
1526 fragmentShader <<
" qt_specularBase *= qt_sRGBToLinear(qt_specular_amount_map).rgb;\n";
1531 fragmentShader <<
" qt_specularTint *= qt_specularBase;\n";
1532 fragmentShader <<
" vec3 qt_specularAmount = vec3(1.0);\n";
1534 fragmentShader <<
" vec3 qt_specularAmount = qt_specularBase * vec3(qt_metalnessAmount + qt_specularFactor * (1.0 - qt_metalnessAmount));\n";
1538 if (samplerState.hasImage(QSSGRenderableImage::Type::Translucency)) {
1539 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Translucency, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1540 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::TranslucencyChannel];
1541 fragmentShader <<
" float qt_translucent_depth_range = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Translucency)
1542 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Translucency) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1543 fragmentShader <<
" float qt_translucent_thickness = qt_translucent_depth_range * qt_translucent_depth_range;\n";
1544 fragmentShader <<
" float qt_translucent_thickness_exp = exp(qt_translucent_thickness * qt_material_properties2.z);\n";
1548 if (samplerState.hasImage(QSSGRenderableImage::Type::Occlusion)) {
1549 addLocalVariable(fragmentShader,
"qt_ao",
"float");
1550 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Occlusion, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1551 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::OcclusionChannel];
1552 fragmentShader <<
" qt_ao = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Occlusion) <<
", "
1553 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Occlusion) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1554 fragmentShader <<
" qt_aoFactor *= qt_ao * qt_material_properties3.x;\n";
1555 maskVariableByVertexColorChannel(
"qt_aoFactor", QSSGRenderDefaultMaterial::OcclusionAmountMask );
1559 fragmentShader.addInclude(
"sheen.glsllib");
1560 addLocalVariable(fragmentShader,
"qt_sheenColor",
"vec3");
1561 addLocalVariable(fragmentShader,
"qt_sheenRoughness",
"float");
1562 addLocalVariable(fragmentShader,
"qt_global_sheen",
"vec3");
1565 fragmentShader <<
" qt_sheenColor = qt_customSheenColor;\n";
1567 fragmentShader <<
" qt_sheenColor = qt_material_sheen_color;\n";
1569 fragmentShader <<
" qt_sheenRoughness = qt_customSheenRoughness;\n";
1571 fragmentShader <<
" qt_sheenRoughness = qt_material_sheen_roughness;\n";
1572 fragmentShader <<
" qt_global_sheen = vec3(0.0);\n";
1574 if (samplerState.hasImage(QSSGRenderableImage::Type::SheenColor)) {
1575 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::SheenColor, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1576 fragmentShader <<
" vec3 qt_sheenColorSample = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::SheenColor) <<
", "
1577 << samplerState.fragCoordsName(QSSGRenderableImage::Type::SheenColor) <<
").rgb;\n";
1578 if (!keyProps.m_imageMaps[QSSGShaderDefaultMaterialKeyProperties::SheenColorMap].isLinear(inKey)) {
1579 fragmentShader.addInclude(
"tonemapping.glsllib");
1580 fragmentShader <<
" qt_sheenColorSample = qt_sRGBToLinear(qt_sheenColorSample);\n";
1582 fragmentShader <<
" qt_sheenColor *= qt_sheenColorSample;\n";
1585 if (samplerState.hasImage(QSSGRenderableImage::Type::SheenRoughness)) {
1586 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::SheenRoughness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1587 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::SheenRoughnessChannel];
1588 fragmentShader <<
" qt_sheenRoughness *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::SheenRoughness) <<
", "
1589 << samplerState.fragCoordsName(QSSGRenderableImage::Type::SheenRoughness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1590 fragmentShader <<
" qt_sheenRoughness = clamp(qt_sheenRoughness, 0.0, 1.0);\n";
1595 addLocalVariable(fragmentShader,
"qt_clearcoatAmount",
"float");
1596 addLocalVariable(fragmentShader,
"qt_clearcoatRoughness",
"float");
1597 addLocalVariable(fragmentShader,
"qt_clearcoatF0",
"vec3");
1598 addLocalVariable(fragmentShader,
"qt_clearcoatF90",
"vec3");
1599 addLocalVariable(fragmentShader,
"qt_global_clearcoat",
"vec3");
1602 fragmentShader <<
" qt_clearcoatAmount = qt_customClearcoatAmount;\n";
1604 fragmentShader <<
" qt_clearcoatAmount = qt_material_properties3.z;\n";
1605 maskVariableByVertexColorChannel(
"qt_clearcoatAmount", QSSGRenderDefaultMaterial::ClearcoatAmountMask );
1607 fragmentShader <<
" qt_clearcoatRoughness = qt_customClearcoatRoughness;\n";
1609 fragmentShader <<
" qt_clearcoatRoughness = qt_material_properties3.w;\n";
1610 maskVariableByVertexColorChannel(
"qt_clearcoatRoughness", QSSGRenderDefaultMaterial::ClearcoatRoughnessAmountMask );
1611 fragmentShader <<
" qt_clearcoatF0 = vec3(((1.0-qt_iOR) * (1.0-qt_iOR)) / ((1.0+qt_iOR) * (1.0+qt_iOR)));\n";
1612 fragmentShader <<
" qt_clearcoatF90 = vec3(1.0);\n";
1613 fragmentShader <<
" qt_global_clearcoat = vec3(0.0);\n";
1615 if (samplerState.hasImage(QSSGRenderableImage::Type::Clearcoat)) {
1616 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Clearcoat, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1617 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ClearcoatChannel];
1618 fragmentShader <<
" qt_clearcoatAmount *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Clearcoat) <<
", "
1619 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Clearcoat) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1622 if (samplerState.hasImage(QSSGRenderableImage::Type::ClearcoatRoughness)) {
1623 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::ClearcoatRoughness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1624 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ClearcoatRoughnessChannel];
1625 fragmentShader <<
" qt_clearcoatRoughness *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::ClearcoatRoughness) <<
", "
1626 << samplerState.fragCoordsName(QSSGRenderableImage::Type::ClearcoatRoughness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1627 fragmentShader <<
" qt_clearcoatRoughness = clamp(qt_clearcoatRoughness, 0.0, 1.0);\n";
1632 fragmentShader.addInclude(
"transmission.glsllib");
1633 addLocalVariable(fragmentShader,
"qt_transmissionFactor",
"float");
1634 addLocalVariable(fragmentShader,
"qt_global_transmission",
"vec3");
1636 addLocalVariable(fragmentShader,
"qt_thicknessFactor",
"float");
1637 addLocalVariable(fragmentShader,
"qt_attenuationColor",
"vec3");
1638 addLocalVariable(fragmentShader,
"qt_attenuationDistance",
"float");
1639 fragmentShader <<
" qt_global_transmission = vec3(0.0);\n";
1641 if (hasCustomFrag) {
1642 fragmentShader <<
" qt_transmissionFactor = qt_customTransmissionFactor;\n";
1643 fragmentShader <<
" qt_thicknessFactor = qt_customThicknessFactor;\n";
1644 fragmentShader <<
" qt_attenuationColor = qt_customAttenuationColor;\n";
1645 fragmentShader <<
" qt_attenuationDistance = qt_customAttenuationDistance;\n";
1647 fragmentShader <<
" qt_transmissionFactor = qt_material_properties4.w;\n";
1648 maskVariableByVertexColorChannel(
"qt_transmissionFactor", QSSGRenderDefaultMaterial::TransmissionFactorMask );
1650 if (samplerState.hasImage(QSSGRenderableImage::Type::Transmission)) {
1651 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Transmission, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1652 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::TransmissionChannel];
1653 fragmentShader <<
" qt_transmissionFactor *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Transmission) <<
", "
1654 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Transmission) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1657 fragmentShader <<
" qt_thicknessFactor = qt_material_thickness;\n";
1658 maskVariableByVertexColorChannel(
"qt_thicknessFactor", QSSGRenderDefaultMaterial::ThicknessFactorMask );
1659 fragmentShader <<
" qt_attenuationColor = qt_material_attenuation.xyz;\n";
1660 fragmentShader <<
" qt_attenuationDistance = qt_material_attenuation.w;\n";
1662 if (samplerState.hasImage(QSSGRenderableImage::Type::Thickness)) {
1663 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Thickness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1664 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ThicknessChannel];
1665 fragmentShader <<
" qt_thicknessFactor *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Thickness) <<
", "
1666 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Thickness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1671 addLocalVariable(fragmentShader,
"qt_dispersion",
"float");
1673 fragmentShader <<
" qt_dispersion = qt_customDispersion;\n";
1675 fragmentShader <<
" qt_dispersion = qt_material_dispersion;\n";
1679 fragmentShader <<
" vec3 qt_f0 = vec3(1.0);\n";
1680 fragmentShader <<
" vec3 qt_f90 = vec3(1.0);\n";
1684 fragmentShader.addInclude(
"principledMaterialFresnel.glsllib");
1686 fragmentShader <<
" qt_f0 = qt_F0_ior(qt_iOR, qt_metalnessAmount, qt_diffuseColor.rgb);\n";
1688 fragmentShader <<
" const float qt_reflectance = max(max(qt_specularTint.r, qt_specularTint.g), qt_specularTint.b);\n";
1689 fragmentShader <<
" qt_f0 = qt_specularTint;\n";
1690 fragmentShader <<
" qt_specularTint = vec3(1.0);\n";
1691 fragmentShader <<
" qt_f90 = vec3(clamp(qt_reflectance * 50.0, 0.0, 1.0));\n";
1692 fragmentShader <<
" qt_diffuseColor.rgb *= (1 - qt_reflectance);\n";
1697 fragmentShader.addDefinition(
"QSSG_ENABLE_IRIDESCENCE",
"1");
1698 fragmentShader.addInclude(
"iridescence.glsllib");
1699 fragmentShader <<
" float qt_iridescenceFactor = ";
1701 fragmentShader <<
"qt_customIridescenceFactor;\n";
1703 fragmentShader <<
"qt_material_iridescence.x;\n";
1704 fragmentShader <<
" float qt_iridescenceIor = ";
1706 fragmentShader <<
"qt_customIridescenceIor;\n";
1708 fragmentShader <<
"qt_material_iridescence.y;\n";
1711 const char *thicknessMinimum = hasCustomFrag ?
"qt_customIridescenceThickness"
1712 :
"qt_material_iridescence.z";
1713 const char *thicknessMaximum = hasCustomFrag ?
"qt_customIridescenceThickness"
1714 :
"qt_material_iridescence.w";
1716 fragmentShader <<
" float qt_iridescenceThickness = " << thicknessMaximum <<
";\n";
1718 if (samplerState.hasImage(QSSGRenderableImage::Type::Iridescence)) {
1719 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Iridescence, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1720 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::IridescenceChannel];
1721 fragmentShader <<
" qt_iridescenceFactor *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Iridescence) <<
", "
1722 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Iridescence) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1725 if (samplerState.hasImage(QSSGRenderableImage::Type::IridescenceThickness)) {
1726 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::IridescenceThickness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1727 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::IridescenceThicknessChannel];
1728 fragmentShader <<
" qt_iridescenceThickness = mix(" << thicknessMinimum <<
", " << thicknessMaximum
1730 << samplerState.samplerName(QSSGRenderableImage::Type::IridescenceThickness) <<
", "
1731 << samplerState.fragCoordsName(QSSGRenderableImage::Type::IridescenceThickness) <<
")" << channelStr(channelProps, inKey) <<
");\n";
1734 fragmentShader <<
" float qt_iridescenceNdotV = clamp(dot(qt_world_normal, qt_view_vector), 0.0, 1.0);\n";
1735 fragmentShader <<
" qt_f0 = mix(qt_f0, qt_evalIridescence(1.0, qt_iridescenceIor, qt_iridescenceNdotV, "
1736 <<
"qt_iridescenceThickness, qt_f0), qt_iridescenceFactor);\n";
1740 fragmentShader.append(
" vec3 vNormalWsDdx = dFdx(qt_world_normal.xyz);\n");
1741 fragmentShader.append(
" vec3 vNormalWsDdy = dFdy(qt_world_normal.xyz);\n");
1742 fragmentShader.append(
" float flGeometricRoughnessFactor = pow(clamp(max(dot(vNormalWsDdx, vNormalWsDdx), dot(vNormalWsDdy, vNormalWsDdy)), 0.0, 1.0), 0.333);\n");
1743 fragmentShader.append(
" qt_roughnessAmount = max(flGeometricRoughnessFactor, qt_roughnessAmount);\n");
1748 fragmentShader.addDefinition(
"QSSG_ENABLE_ANISOTROPY",
"1");
1749 fragmentShader.addInclude(
"anisotropy.glsllib");
1750 addLocalVariable(fragmentShader,
"qt_anisotropyStrength",
"float");
1751 addLocalVariable(fragmentShader,
"qt_anisotropicT",
"vec3");
1752 addLocalVariable(fragmentShader,
"qt_anisotropicB",
"vec3");
1753 addLocalVariable(fragmentShader,
"qt_anisotropyAlphaT",
"float");
1754 addLocalVariable(fragmentShader,
"qt_anisotropyAlphaB",
"float");
1756 fragmentShader <<
" vec2 qt_anisotropyDirection = vec2(1.0, 0.0);\n";
1757 if (hasCustomFrag) {
1758 fragmentShader <<
" qt_anisotropyStrength = qt_customAnisotropyStrength;\n";
1759 fragmentShader <<
" float qt_anisotropyCos = cos(qt_customAnisotropyRotation);\n";
1760 fragmentShader <<
" float qt_anisotropySin = sin(qt_customAnisotropyRotation);\n";
1762 fragmentShader <<
" qt_anisotropyStrength = qt_material_anisotropy.x;\n";
1763 fragmentShader <<
" float qt_anisotropyCos = qt_material_anisotropy.y;\n";
1764 fragmentShader <<
" float qt_anisotropySin = qt_material_anisotropy.z;\n";
1767 if (samplerState.hasImage(QSSGRenderableImage::Type::Anisotropy)) {
1768 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Anisotropy, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1769 fragmentShader <<
" vec3 qt_anisotropySample = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Anisotropy) <<
", "
1770 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Anisotropy) <<
").rgb;\n";
1771 fragmentShader <<
" qt_anisotropyDirection = qt_anisotropySample.rg * 2.0 - vec2(1.0);\n";
1772 fragmentShader <<
" qt_anisotropyStrength *= qt_anisotropySample.b;\n";
1775 fragmentShader <<
" qt_anisotropyDirection = vec2(qt_anisotropyCos * qt_anisotropyDirection.x - qt_anisotropySin * qt_anisotropyDirection.y,\n"
1776 <<
" qt_anisotropySin * qt_anisotropyDirection.x + qt_anisotropyCos * qt_anisotropyDirection.y);\n";
1777 fragmentShader <<
" qt_anisotropicT = qt_anisotropyDirection.x * qt_tangent + qt_anisotropyDirection.y * qt_binormal;\n";
1779 fragmentShader <<
" qt_anisotropicT -= dot(qt_world_normal, qt_anisotropicT) * qt_world_normal;\n";
1781 fragmentShader <<
" qt_anisotropicT = dot(qt_anisotropicT, qt_anisotropicT) > 1e-8 ? normalize(qt_anisotropicT)\n"
1782 <<
" : qt_orthonormalTangent(qt_world_normal);\n";
1783 fragmentShader <<
" qt_anisotropicB = normalize(cross(qt_world_normal, qt_anisotropicT));\n";
1785 fragmentShader <<
" qt_anisotropyAlphaB = clamp(qt_roughnessAmount * qt_roughnessAmount, 0.001, 1.0);\n";
1786 fragmentShader <<
" qt_anisotropyAlphaT = mix(qt_anisotropyAlphaB, 1.0, qt_anisotropyStrength * qt_anisotropyStrength);\n";
1790 fragmentShader <<
" float qt_fresnelPower = qt_customFresnelPower;\n";
1792 fragmentShader <<
" float qt_fresnelPower = qt_material_properties2.x;\n";
1795 fragmentShader <<
" vec3 qt_principledMaterialFresnelValue = qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1797 if (hasCustomFrag) {
1798 fragmentShader <<
" float qt_fresnelScale = qt_customFresnelScale;\n";
1799 fragmentShader <<
" float qt_fresnelBias = qt_customFresnelBias;\n";
1801 fragmentShader <<
" float qt_fresnelScale = qt_material_properties5.x;\n";
1802 fragmentShader <<
" float qt_fresnelBias = qt_material_properties5.y;\n";
1804 fragmentShader <<
" qt_principledMaterialFresnelValue = clamp(vec3(qt_fresnelBias) + "
1805 <<
"qt_fresnelScale * qt_principledMaterialFresnelValue, 0.0, 1.0);\n";
1807 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnelValue;\n";
1811 fragmentShader <<
" qt_specularTint = mix(vec3(1.0), qt_specularTint, 1.0 - qt_metalnessAmount);\n";
1814 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1819 fragmentShader.addUniform(
"qt_lightAndShadowCounts",
"vec4");
1820 fragmentShader.addFunction(
"processPunctualLighting");
1821 fragmentShader <<
" qt_processPunctualLighting(global_diffuse_light.rgb,\n"
1822 <<
" global_specular_light.rgb,\n"
1823 <<
" qt_diffuseColor.rgb,\n"
1824 <<
" qt_varWorldPos,\n"
1825 <<
" qt_world_normal.xyz,\n"
1826 <<
" qt_view_vector,\n"
1827 <<
"#if QSSG_ENABLE_SPECULAR\n"
1828 <<
" qt_specularAmount,\n"
1829 <<
" qt_specularTint,\n"
1830 <<
"#endif // QSSG_ENABLE_SPECULAR\n"
1831 <<
" qt_roughnessAmount,\n"
1832 <<
" qt_metalnessAmount,\n"
1833 <<
"#if QSSG_CUSTOM_MATERIAL_DIRECTIONAL_LIGHT_PROCESSOR || QSSG_CUSTOM_MATERIAL_POINT_LIGHT_PROCESSOR || QSSG_CUSTOM_MATERIAL_SPOT_LIGHT_PROCESSOR || QSSG_CUSTOM_MATERIAL_SPECULAR_PROCESSOR\n"
1834 <<
" qt_customBaseColor,\n"
1835 <<
"#endif // QSSG_CUSTOM_MATERIAL_*\n"
1836 <<
"#if QSSG_CUSTOM_MATERIAL_SPECULAR_PROCESSOR\n"
1837 <<
" qt_customSpecularAmount,\n"
1838 <<
"#endif // QSSG_CUSTOM_MATERIAL_SPECULAR_PROCESSOR\n"
1839 <<
"#if QSSG_CUSTOM_MATERIAL_SHARED_VARIABLES\n"
1840 <<
" qt_customShared,\n"
1841 <<
"#endif // QSSG_CUSTOM_MATERIAL_SHARED_VARIABLES\n"
1842 <<
"#if QSSG_ENABLE_CLEARCOAT\n"
1843 <<
" qt_global_clearcoat,\n"
1844 <<
" qt_clearcoatNormal,\n"
1845 <<
" qt_clearcoatRoughness,\n"
1846 <<
" qt_clearcoatF0,\n"
1847 <<
" qt_clearcoatF90,\n"
1848 <<
"#endif // QSSG_ENABLE_CLEARCOAT\n"
1849 <<
"#if QSSG_ENABLE_SHEEN\n"
1850 <<
" qt_global_sheen,\n"
1851 <<
" qt_sheenColor,\n"
1852 <<
" qt_sheenRoughness,\n"
1853 <<
"#endif // QSSG_ENABLE_SHEEN\n"
1854 <<
"#if QSSG_ENABLE_ANISOTROPY\n"
1855 <<
" qt_anisotropicT,\n"
1856 <<
" qt_anisotropicB,\n"
1857 <<
" qt_anisotropyAlphaT,\n"
1858 <<
" qt_anisotropyAlphaB,\n"
1859 <<
"#endif // QSSG_ENABLE_ANISOTROPY\n"
1860 <<
"#if QSSG_ENABLE_TRANSMISSION\n"
1861 <<
" qt_global_transmission,\n"
1862 <<
" qt_thicknessFactor,\n"
1864 <<
" qt_transmissionFactor,\n"
1865 <<
" qt_attenuationColor,\n"
1866 <<
" qt_attenuationDistance,\n"
1867 <<
"#endif // QSSG_ENABLE_TRANSMISSION\n"
1875 fragmentShader <<
" global_diffuse_light = vec4(global_diffuse_light.rgb * qt_aoFactor, qt_objectOpacity * qt_diffuseColor.a);\n";
1878 vertexShader.generateWorldNormal(inKey);
1879 fragmentShader.addInclude(
"sampleReflectionProbe.glsllib");
1883 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1885 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1890 fragmentShader <<
" vec3 qt_anisotropyIblNormal = qt_anisotropicBentNormal(qt_world_normal, "
1891 <<
"qt_view_vector, qt_anisotropicB, qt_anisotropyStrength, qt_roughnessAmount);\n";
1894 fragmentShader <<
" global_specular_light += qt_specularTint * qt_sampleGlossyAnisotropicReflectionProbe("
1895 <<
"qt_reflectionMap, qt_world_normal, qt_anisotropyIblNormal, qt_view_vector, "
1896 <<
"qt_specularAmount, qt_roughnessAmount).rgb;\n";
1898 fragmentShader <<
" global_specular_light += qt_specularTint * qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, "
1899 <<
"qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1901 fragmentShader <<
" global_specular_light += qt_specularAmount * qt_specularTint * qt_sampleGlossyReflection(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1906 fragmentShader <<
" qt_global_clearcoat += qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1908 fragmentShader <<
" qt_global_sheen += qt_sampleGlossySheenReflectionProbe(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_sheenColor, qt_sheenRoughness).rgb;\n";
1911 vertexShader.generateWorldNormal(inKey);
1912 fragmentShader.addInclude(
"sampleProbe.glsllib");
1913 if (hasCustomIblProbe) {
1915 fragmentShader <<
" vec3 qt_iblDiffuse = vec3(0.0);\n";
1916 fragmentShader <<
" vec3 qt_iblSpecular = vec3(0.0);\n";
1918 fragmentShader <<
" vec3 qt_iblClearcoat = vec3(0.0);\n";
1920 fragmentShader <<
" vec3 qt_iblSheen = vec3(0.0);\n";
1921 fragmentShader <<
" qt_iblProbeProcessor(qt_iblDiffuse, qt_iblSpecular, qt_customBaseColor, qt_aoFactor, qt_specularFactor, qt_roughnessAmount, qt_world_normal, qt_view_vector";
1923 fragmentShader <<
", qt_lightProbeOrientation";
1925 fragmentShader <<
", mat3(1.0)";
1927 fragmentShader <<
", qt_customShared);\n";
1929 fragmentShader <<
");\n";
1933 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1935 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1940 fragmentShader <<
" vec3 qt_anisotropyIblNormal = qt_anisotropicBentNormal(qt_world_normal, "
1941 <<
"qt_view_vector, qt_anisotropicB, qt_anisotropyStrength, qt_roughnessAmount);\n";
1944 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularTint * qt_sampleGlossyAnisotropic("
1945 <<
"qt_world_normal, qt_anisotropyIblNormal, qt_view_vector, "
1946 <<
"qt_specularAmount, qt_roughnessAmount).rgb;\n";
1948 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularTint * qt_sampleGlossyPrincipled("
1949 <<
"qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1951 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularAmount * qt_specularTint * qt_sampleGlossy(qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1956 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyPrincipled(qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1959 fragmentShader <<
" vec3 qt_iblSheen = qt_sampleGlossySheen(qt_world_normal, qt_view_vector, qt_sheenColor, qt_sheenRoughness).rgb;\n";
1962 fragmentShader <<
" global_diffuse_light.rgb += qt_iblDiffuse * qt_aoFactor;\n";
1964 fragmentShader <<
" global_specular_light += qt_iblSpecular * qt_aoFactor;\n";
1966 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat * qt_aoFactor;\n";
1968 fragmentShader <<
" qt_global_sheen += qt_iblSheen * qt_aoFactor;\n";
1969 }
else if (hasCustomIblProbe) {
1971 fragmentShader.addUniform(
"qt_lightProbe",
"samplerCube");
1972 fragmentShader.addUniform(
"qt_lightProbeProperties",
"vec4");
1977 fragmentShader <<
" qt_global_transmission += qt_transmissionFactor * qt_getIBLVolumeRefraction(qt_world_normal, qt_view_vector, qt_roughnessAmount, "
1978 "qt_diffuseColor.rgb, qt_specularAmount, qt_varWorldPos, qt_iOR, qt_thicknessFactor, qt_attenuationColor, qt_attenuationDistance"
1979 <<
"\n#if QSSG_ENABLE_DISPERSION\n"
1980 <<
" , qt_dispersion\n"
1981 <<
"#endif // QSSG_ENABLE_DISPERSION\n"
1987 if (samplerState.hasImage(QSSGRenderableImage::Type::Specular) || samplerState.hasImage(QSSGRenderableImage::Type::Emissive)) {
1988 addLocalVariable(fragmentShader,
"qt_texture_color",
"vec4");
1990 if (samplerState.hasImage(QSSGRenderableImage::Type::Specular)) {
1991 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Specular, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1992 fragmentShader <<
" qt_texture_color = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Specular) <<
", "
1993 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Specular) <<
");\n";
1994 fragmentShader.addInclude(
"tonemapping.glsllib");
1995 fragmentShader <<
" global_specular_light += qt_sRGBToLinear(qt_texture_color.rgb) * qt_specularTint;\n";
1996 fragmentShader <<
" global_diffuse_light.a *= qt_texture_color.a;\n";
1999 if (samplerState.hasImage(QSSGRenderableImage::Type::Emissive)) {
2000 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Emissive, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
2001 fragmentShader <<
" qt_texture_color = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Emissive) <<
", "
2002 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Emissive) <<
");\n";
2003 fragmentShader.addInclude(
"tonemapping.glsllib");
2004 if (keyProps.m_emissiveSingleChannelEnabled.getValue(inKey)) {
2005 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::EmissiveChannel];
2006 fragmentShader <<
" qt_global_emission *= qt_sRGBToLinear(vec3(qt_texture_color" <<
2007 channelStr(channelProps, inKey) <<
"));\n";
2009 fragmentShader <<
" qt_global_emission *= qt_sRGBToLinear(qt_texture_color.rgb);\n";
2015 fragmentShader <<
" global_diffuse_light.rgb = mix(global_diffuse_light.rgb, qt_global_transmission, qt_transmissionFactor);\n";
2018 fragmentShader <<
" global_diffuse_light.rgb *= 1.0 - qt_metalnessAmount;\n";
2021 if (passRequirmentState
.hasFog) {
2022 fragmentShader.addInclude(
"fog.glsllib");
2023 fragmentShader <<
" calculateFog(qt_global_emission, global_specular_light, global_diffuse_light.rgb);\n";
2026 fragmentShader <<
" vec4 qt_color_sum = vec4(global_diffuse_light.rgb + global_specular_light + qt_global_emission, global_diffuse_light.a);\n";
2030 fragmentShader.addInclude(
"sheen.glsllib");
2031 fragmentShader <<
" float qt_sheenScaling = qt_sheenAlbedoScaling(qt_sheenColor, clamp(dot(qt_world_normal, qt_view_vector), 0.0, 1.0), qt_sheenRoughness);\n";
2032 fragmentShader <<
" qt_color_sum.rgb = qt_color_sum.rgb * qt_sheenScaling + qt_global_sheen;\n";
2036 fragmentShader.addInclude(
"bsdf.glsllib");
2038 fragmentShader <<
" float qt_clearcoatFresnelPower = qt_customClearcoatFresnelPower;\n";
2040 fragmentShader <<
" float qt_clearcoatFresnelPower = qt_material_clearcoat_fresnel_power;\n";
2041 fragmentShader <<
" vec3 qt_clearcoatFresnel = qt_schlick3(qt_clearcoatF0, qt_clearcoatF90, clamp(dot(qt_clearcoatNormal, qt_view_vector), 0.0, 1.0), qt_clearcoatFresnelPower);\n";
2043 if (hasCustomFrag) {
2044 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_customClearcoatFresnelScale;\n";
2045 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_customClearcoatFresnelBias;\n";
2047 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_material_properties5.z;\n";
2048 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_material_properties5.w;\n";
2050 fragmentShader <<
" qt_clearcoatFresnel = clamp(vec3(qt_clearcoatFresnelBias) + qt_clearcoatFresnelScale * qt_clearcoatFresnel, 0.0, 1.0);\n";
2052 fragmentShader <<
" qt_global_clearcoat = qt_global_clearcoat * qt_clearcoatAmount;\n";
2053 fragmentShader <<
" qt_color_sum.rgb = qt_color_sum.rgb * (1.0 - qt_clearcoatAmount * qt_clearcoatFresnel) + qt_global_clearcoat;\n";
2056 if (hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_customPostProcessor"))) {
2058 fragmentShader <<
" qt_customPostProcessor(qt_color_sum, global_diffuse_light, global_specular_light, qt_global_emission, qt_texCoord0, qt_texCoord1";
2060 fragmentShader <<
", qt_customShared);\n";
2062 fragmentShader <<
");\n";
2074 fragmentShader.append(
" vec4 qt_color_sum = vec4(qt_diffuseColor.rgb, qt_diffuseColor.a * qt_objectOpacity);");
2076 if (passRequirmentState.oitMethod == QSSGRenderLayer::OITMethod::WeightedBlended) {
2077 fragmentShader.addInclude(
"oitweightedblended.glsllib");
2078 fragmentShader.addInclude(
"tonemapping.glsllib");
2079 fragmentShader.addUniform(
"qt_cameraPosition",
"vec3");
2080 fragmentShader.addUniform(
"qt_cameraProperties",
"vec2");
2081 fragmentShader.append(
" float z = abs(gl_FragCoord.z);");
2082 fragmentShader.append(
" qt_color_sum.rgb = qt_tonemap(qt_color_sum.rgb) * qt_color_sum.a;");
2083 fragmentShader.append(
" fragOutput = qt_color_sum * qt_transparencyWeight(z, qt_color_sum.a, qt_cameraProperties.y);");
2084 fragmentShader.append(
" revealageOutput = vec4(qt_color_sum.a);");
2085 }
else if (passRequirmentState.oitMethod == QSSGRenderLayer::OITMethod::LinkedList) {
2086 fragmentShader.addInclude(
"tonemapping.glsllib");
2087 fragmentShader.addUniform(
"qt_listNodeCount",
"uint");
2088 fragmentShader.addUniform(
"qt_ABufImageWidth",
"uint");
2089 fragmentShader.addUniform(
"qt_viewSize",
"ivec2");
2091 fragmentShader.addDefinition(
"QSSG_MULTISAMPLE",
"1");
2092#ifdef QSSG_OIT_USE_BUFFERS
2093 QSSGShaderResourceMergeContext::setAdditionalBufferAmount(3);
2094 fragmentShader.addUniform(
"qt_samples",
"uint");
2095 fragmentShader.addInclude(
"oitlinkedlist_buf.glsllib");
2097 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, qt_viewIndex, qt_samples);");
2099 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, 0, qt_samples);");
2101 fragmentShader.addInclude(
"oitlinkedlist.glsllib");
2103 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, qt_viewIndex);");
2105 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, 0);");
2109 fragmentShader.addInclude(
"tonemapping.glsllib");
2110 fragmentShader.append(
" fragOutput = vec4(qt_tonemap(qt_color_sum));");
2114 fragmentShader <<
" vec4 fragOutput = vec4(0.0);\n";
2117 Q_ASSERT(viewCount == 1);
2118 fragmentShader <<
" // directional shadow pass\n"
2119 <<
" float qt_shadowDepth = (qt_varDepth + qt_shadowDepthAdjust.x) * qt_shadowDepthAdjust.y;\n"
2120 <<
" fragOutput = vec4(qt_shadowDepth);\n";
2123 Q_ASSERT(viewCount == 1);
2124 fragmentShader.addUniform(
"qt_cameraPosition",
"vec3");
2125 fragmentShader.addUniform(
"qt_cameraProperties",
"vec2");
2126 fragmentShader <<
" // omnidirectional shadow pass\n"
2127 <<
" vec3 qt_shadowCamPos = vec3(qt_cameraPosition.x, qt_cameraPosition.y, qt_cameraPosition.z);\n"
2128 <<
" float qt_shadowDist = length(qt_varShadowWorldPos - qt_shadowCamPos);\n"
2129 <<
" qt_shadowDist = (qt_shadowDist - qt_cameraProperties.x) / (qt_cameraProperties.y - qt_cameraProperties.x);\n"
2130 <<
" fragOutput = vec4(qt_shadowDist, qt_shadowDist, qt_shadowDist, 1.0);\n";
2134 fragmentShader.append(
" fragOutput = vec4(qt_world_normal, qt_roughnessAmount);\n");
2137 fragmentShader.append(
" vec3 debugOutput = vec3(0.0);\n");
2138 switch (passRequirmentState.debugMode) {
2139 case QSSGRenderLayer::MaterialDebugMode::BaseColor:
2140 fragmentShader.addInclude(
"tonemapping.glsllib");
2141 fragmentShader.append(
" debugOutput += qt_tonemap(qt_diffuseColor.rgb);\n");
2143 case QSSGRenderLayer::MaterialDebugMode::Roughness:
2144 fragmentShader.append(
" debugOutput += vec3(qt_roughnessAmount);\n");
2146 case QSSGRenderLayer::MaterialDebugMode::Metalness:
2147 fragmentShader.append(
" debugOutput += vec3(qt_metalnessAmount);\n");
2149 case QSSGRenderLayer::MaterialDebugMode::Diffuse:
2150 fragmentShader.addInclude(
"tonemapping.glsllib");
2151 fragmentShader.append(
" debugOutput += qt_tonemap(global_diffuse_light.rgb);\n");
2153 case QSSGRenderLayer::MaterialDebugMode::Specular:
2154 fragmentShader.addInclude(
"tonemapping.glsllib");
2155 fragmentShader.append(
" debugOutput += qt_tonemap(global_specular_light);\n");
2157 case QSSGRenderLayer::MaterialDebugMode::ShadowOcclusion:
2160 fragmentShader.addFunction(
"debugShadowOcclusion");
2161 vertexShader.generateWorldPosition(inKey);
2162 fragmentShader.append(
" debugOutput += vec3(qt_debugShadowOcclusion());\n");
2164 case QSSGRenderLayer::MaterialDebugMode::Emission:
2165 fragmentShader.addInclude(
"tonemapping.glsllib");
2166 fragmentShader.append(
" debugOutput += qt_tonemap(qt_global_emission);\n");
2168 case QSSGRenderLayer::MaterialDebugMode::AmbientOcclusion:
2169 fragmentShader.append(
" debugOutput += vec3(qt_aoFactor);\n");
2171 case QSSGRenderLayer::MaterialDebugMode::Normal:
2172 fragmentShader.append(
" debugOutput += qt_world_normal * 0.5 + 0.5;\n");
2174 case QSSGRenderLayer::MaterialDebugMode::Tangent:
2175 fragmentShader.append(
" debugOutput += qt_tangent * 0.5 + 0.5;\n");
2177 case QSSGRenderLayer::MaterialDebugMode::Binormal:
2178 fragmentShader.append(
" debugOutput += qt_binormal * 0.5 + 0.5;\n");
2180 case QSSGRenderLayer::MaterialDebugMode::F0:
2182 fragmentShader.append(
" debugOutput += qt_f0;");
2184 case QSSGRenderLayer::MaterialDebugMode::None:
2188 fragmentShader.append(
" fragOutput = vec4(debugOutput, 1.0);\n");
2191 if (shaderAugmentation.hasUserAugmentation())
2192 fragmentShader <<
" " << shaderAugmentation.body <<
";\n";
2276void QSSGMaterialShaderGenerator::setRhiMaterialProperties(
const QSSGRenderContextInterface &renderContext,
2277 QSSGRhiShaderPipeline &shaders,
2279 QSSGRhiGraphicsPipelineState *inPipelineState,
2280 const QSSGRenderGraphObject &inMaterial,
2281 const QSSGShaderDefaultMaterialKey &inKey,
2282 const QSSGShaderDefaultMaterialKeyProperties &inProperties,
2283 const QSSGRenderCameraList &inCameras,
2284 const QSSGRenderMvpArray &inModelViewProjections,
2285 const QMatrix3x3 &inNormalMatrix,
2286 const QMatrix4x4 &inGlobalTransform,
2287 const QMatrix4x4 &clipSpaceCorrMatrix,
2288 const QMatrix4x4 &localInstanceTransform,
2289 const QMatrix4x4 &globalInstanceTransform,
2290 const QSSGDataView<
float> &inMorphWeights,
2291 QSSGRenderableImage *inFirstImage,
2293 const QSSGLayerRenderData &inRenderProperties,
2294 const QSSGShaderLightListView &inLights,
2295 const QSSGShaderReflectionProbe &reflectionProbe,
2296 bool receivesShadows,
2297 bool receivesReflections,
2298 const QVector2D *shadowDepthAdjust,
2299 QRhiTexture *lightmapTexture)
2301 QSSGShaderMaterialAdapter *materialAdapter = getMaterialAdapter(inMaterial);
2302 QSSGRhiShaderPipeline::CommonUniformIndices &cui = shaders.commonUniformIndices;
2304 materialAdapter->setCustomPropertyUniforms(ubufData, shaders, renderContext);
2306 const QVector2D camProperties(inCameras[0]->clipPlanes);
2307 shaders.setUniform(ubufData,
"qt_cameraProperties", &camProperties, 2 *
sizeof(
float), &cui.cameraPropertiesIdx);
2309 const int viewCount = inCameras.count();
2312 QMatrix4x4 camGlobalTransforms[2] { QMatrix4x4{Qt::Uninitialized}, QMatrix4x4{Qt::Uninitialized} };
2313 if (viewCount < 2) {
2314 camGlobalTransforms[0] = inRenderProperties.getGlobalTransform(*inCameras[0]);
2316 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex)
2317 camGlobalTransforms[viewIndex] = inRenderProperties.getGlobalTransform(*inCameras[viewIndex]);
2320 if (viewCount < 2) {
2321 const QMatrix4x4 &camGlobalTransform = camGlobalTransforms[0];
2322 const QVector3D camGlobalPos = QSSGRenderNode::getGlobalPos(camGlobalTransform);
2323 shaders.setUniform(ubufData,
"qt_cameraPosition", &camGlobalPos, 3 *
sizeof(
float), &cui.cameraPositionIdx);
2324 const QVector3D camDirection = QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2325 ? inRenderProperties.renderedCameraData.value()[0].direction
2326 : QVector3D{ 0.0f, 0.0f, -1.0f };
2327 shaders.setUniform(ubufData,
"qt_cameraDirection", &camDirection, 3 *
sizeof(
float), &cui.cameraDirectionIdx);
2329 QVarLengthArray<QVector3D, 2> camGlobalPos(viewCount);
2330 QVarLengthArray<QVector3D> camDirection(viewCount);
2331 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex) {
2332 const QMatrix4x4 &camGlobalTransform = camGlobalTransforms[viewIndex];
2333 camGlobalPos[viewIndex] = QSSGRenderNode::getGlobalPos(camGlobalTransform);
2334 camDirection[viewIndex] = QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2335 ? inRenderProperties.renderedCameraData.value()[viewIndex].direction
2336 : QVector3D{ 0.0f, 0.0f, -1.0f };
2338 shaders.setUniformArray(ubufData,
"qt_cameraPosition", camGlobalPos.constData(), viewCount, QSSGRenderShaderValue::Vec3, &cui.cameraPositionIdx);
2339 shaders.setUniformArray(ubufData,
"qt_cameraDirection", camDirection.constData(), viewCount, QSSGRenderShaderValue::Vec3, &cui.cameraDirectionIdx);
2342 const auto globalRenderData = QSSGLayerRenderData::globalRenderProperties(renderContext);
2345 bool usesProjectionMatrix =
false;
2346 bool usesInvProjectionMatrix =
false;
2347 bool usesViewProjectionMatrix =
false;
2348 bool usesModelViewProjectionMatrix =
false;
2349 bool usesNormalMatrix =
false;
2350 bool usesParentMatrix =
false;
2352 if (inMaterial.type == QSSGRenderGraphObject::Type::CustomMaterial) {
2353 const auto *customMaterial =
static_cast<
const QSSGRenderCustomMaterial *>(&inMaterial);
2354 usesProjectionMatrix = customMaterial->m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::ProjectionMatrix);
2355 usesInvProjectionMatrix = customMaterial->m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::InverseProjectionMatrix);
2357 usesViewProjectionMatrix =
true;
2360 const bool usesInstancing = inProperties.m_usesInstancing.getValue(inKey);
2361 if (usesInstancing) {
2363 usesViewProjectionMatrix =
true;
2364 usesParentMatrix =
true;
2366 usesModelViewProjectionMatrix =
true;
2367 usesNormalMatrix =
true;
2370 if (materialAdapter->isTransmissionEnabled())
2371 usesViewProjectionMatrix =
true;
2374 if (usesProjectionMatrix || usesInvProjectionMatrix) {
2375 if (viewCount < 2) {
2376 const QMatrix4x4 projection = clipSpaceCorrMatrix * inCameras[0]->projection;
2377 if (usesProjectionMatrix)
2378 shaders.setUniform(ubufData,
"qt_projectionMatrix", projection.constData(), 16 *
sizeof(
float), &cui.projectionMatrixIdx);
2379 if (usesInvProjectionMatrix)
2380 shaders.setUniform(ubufData,
"qt_inverseProjectionMatrix", projection.inverted().constData(), 16 *
sizeof (
float), &cui.inverseProjectionMatrixIdx);
2382 QVarLengthArray<QMatrix4x4, 2> projections(viewCount);
2383 QVarLengthArray<QMatrix4x4, 2> invertedProjections(viewCount);
2384 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex) {
2385 projections[viewIndex] = clipSpaceCorrMatrix * inCameras[viewIndex]->projection;
2386 if (usesInvProjectionMatrix)
2387 invertedProjections[viewIndex] = projections[viewIndex].inverted();
2389 if (usesProjectionMatrix)
2390 shaders.setUniformArray(ubufData,
"qt_projectionMatrix", projections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.projectionMatrixIdx);
2391 if (usesInvProjectionMatrix)
2392 shaders.setUniformArray(ubufData,
"qt_inverseProjectionMatrix", invertedProjections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.inverseProjectionMatrixIdx);
2396 if (viewCount < 2) {
2397 const QMatrix4x4 viewMatrix = camGlobalTransforms[0].inverted();
2398 shaders.setUniform(ubufData,
"qt_viewMatrix", viewMatrix.constData(), 16 *
sizeof(
float), &cui.viewMatrixIdx);
2400 QVarLengthArray<QMatrix4x4, 2> viewMatrices(viewCount);
2401 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex)
2402 viewMatrices[viewIndex] = camGlobalTransforms[viewIndex].inverted();
2403 shaders.setUniformArray(ubufData,
"qt_viewMatrix", viewMatrices.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.viewMatrixIdx);
2406 if (usesViewProjectionMatrix) {
2407 if (viewCount < 2) {
2408 const QMatrix4x4 &camGlobalTransform = camGlobalTransforms[0];
2409 QMatrix4x4 viewProj(Qt::Uninitialized);
2410 inCameras[0]->calculateViewProjectionMatrix(camGlobalTransform, viewProj);
2411 viewProj = clipSpaceCorrMatrix * viewProj;
2412 shaders.setUniform(ubufData,
"qt_viewProjectionMatrix", viewProj.constData(), 16 *
sizeof(
float), &cui.viewProjectionMatrixIdx);
2414 QVarLengthArray<QMatrix4x4, 2> viewProjections(viewCount);
2415 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex) {
2416 const auto &camGlobalTransform = camGlobalTransforms[viewIndex];
2417 inCameras[viewIndex]->calculateViewProjectionMatrix(camGlobalTransform, viewProjections[viewIndex]);
2418 viewProjections[viewIndex] = clipSpaceCorrMatrix * viewProjections[viewIndex];
2420 shaders.setUniformArray(ubufData,
"qt_viewProjectionMatrix", viewProjections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.viewProjectionMatrixIdx);
2426 shaders.setUniform(ubufData,
"qt_modelMatrix", localInstanceTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2428 shaders.setUniform(ubufData,
"qt_modelMatrix", inGlobalTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2430 if (usesModelViewProjectionMatrix) {
2431 if (viewCount < 2) {
2432 QMatrix4x4 mvp { clipSpaceCorrMatrix };
2433 mvp *= inModelViewProjections[0];
2434 shaders.setUniform(ubufData,
"qt_modelViewProjection", mvp.constData(), 16 *
sizeof(
float), &cui.modelViewProjectionIdx);
2436 QVarLengthArray<QMatrix4x4, 2> mvps(viewCount);
2437 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
2438 mvps[viewIndex] = clipSpaceCorrMatrix * inModelViewProjections[viewIndex];
2439 shaders.setUniformArray(ubufData,
"qt_modelViewProjection", mvps.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.modelViewProjectionIdx);
2442 if (usesNormalMatrix)
2443 shaders.setUniform(ubufData,
"qt_normalMatrix", inNormalMatrix.constData(), 12 *
sizeof(
float), &cui.normalMatrixIdx,
2444 QSSGRhiShaderPipeline::UniformFlag::Mat3);
2445 if (usesParentMatrix)
2446 shaders.setUniform(ubufData,
"qt_parentMatrix", globalInstanceTransform.constData(), 16 *
sizeof(
float));
2449 const qsizetype morphSize = inProperties.m_targetCount.getValue(inKey);
2450 if (morphSize > 0) {
2451 if (inMorphWeights.mSize >= morphSize) {
2452 shaders.setUniformArray(ubufData,
"qt_morphWeights", inMorphWeights.mData, morphSize,
2453 QSSGRenderShaderValue::Float, &cui.morphWeightsIdx);
2455 const QList<
float> zeroWeights(morphSize - inMorphWeights.mSize, 0.0f);
2456 QList<
float> newWeights(inMorphWeights.mData, inMorphWeights.mData + inMorphWeights.mSize);
2457 newWeights.append(zeroWeights);
2458 shaders.setUniformArray(ubufData,
"qt_morphWeights", newWeights.constData(), morphSize,
2459 QSSGRenderShaderValue::Float, &cui.morphWeightsIdx);
2463 QVector3D theLightAmbientTotal;
2464 quint32 lightCount = 0;
2465 quint32 directionalLightCount = 0;
2466 quint32 shadowCount = 0;
2467 quint32 directionalShadowCount = 0;
2468 QSSGShaderLightsUniformData &lightsUniformData(shaders.lightsUniformData());
2469 QSSGShaderDirectionalLightsUniformData &directionalLightsUniformData(shaders.directionalLightsUniformData());
2471 for (quint32 lightIdx = 0, lightEnd = inLights.size();
2472 lightIdx < lightEnd && lightIdx < QSSG_MAX_NUM_LIGHTS; ++lightIdx)
2474 QSSGRenderLight *theLight(inLights[lightIdx].light);
2477 const bool lightShadows = inLights[lightIdx].shadows;
2478 const float brightness = theLight->m_brightness;
2479 quint32 lightmapState = 0;
2480 if (theLight->m_bakingEnabled) {
2481 if (theLight->m_fullyBaked) {
2490 const QVector3D diffuseColor(theLight->m_diffuseColor.x() * brightness,
2491 theLight->m_diffuseColor.y() * brightness,
2492 theLight->m_diffuseColor.z() * brightness);
2493 const QVector3D specularColor(theLight->m_specularColor.x() * brightness,
2494 theLight->m_specularColor.y() * brightness,
2495 theLight->m_specularColor.z() * brightness);
2496 const QVector3D direction(inLights[lightIdx].direction);
2499 if (theLight->type == QSSGRenderGraphObject::Type::DirectionalLight) {
2501 QSSGShaderDirectionalLightData &lightData(directionalLightsUniformData.directionalLightData[directionalLightCount]);
2502 lightData.direction[0] = direction.x();
2503 lightData.direction[1] = direction.y();
2504 lightData.direction[2] = direction.z();
2505 lightData.diffuseColor[0] = diffuseColor.x();
2506 lightData.diffuseColor[1] = diffuseColor.y();
2507 lightData.diffuseColor[2] = diffuseColor.z();
2508 lightData.specularColor[0] = specularColor.x();
2509 lightData.specularColor[1] = specularColor.y();
2510 lightData.specularColor[2] = specularColor.z();
2511 lightData.lightmapState = lightmapState;
2512 if (lightShadows && receivesShadows) {
2513 lightData.enableShadows = 1.0f;
2514 QSSGShadowMapEntry *pEntry = inRenderProperties.getShadowMapManager()->shadowMapEntry(lightIdx);
2517 const quint32 layerCount = pEntry->m_csmNumSplits + 1;
2519 for (quint32 i = 0; i < layerCount; ++i)
2520 memcpy(lightData.matrices[i], pEntry->m_fixedScaleBiasMatrix[i].constData(), 16 *
sizeof(
float));
2522 lightData.shadowBias = theLight->m_shadowBias;
2524 const bool noCascades = !(pEntry->m_csmActive[0] || pEntry->m_csmActive[1] || pEntry->m_csmActive[2] || pEntry->m_csmActive[3]);
2525 if (theLight->type == QSSGRenderLight::Type::DirectionalLight && noCascades)
2526 lightData.enableShadows = 0.0f;
2527 lightData.shadowFactor = theLight->m_shadowFactor;
2528 lightData.shadowMapFar = theLight->m_shadowMapFar;
2529 lightData.shadowPcfSamples = softShadowQualityToInt(theLight->m_softShadowQuality);
2530 lightData.shadowPcfFactor = theLight->m_pcfFactor;
2532 for (quint32 i = 0; i < layerCount; ++i) {
2533 const auto &atlasInfo = pEntry->m_atlasInfo[i];
2534 lightData.atlasLocations[i][0] = atlasInfo.uOffset;
2535 lightData.atlasLocations[i][1] = atlasInfo.vOffset;
2536 lightData.atlasLocations[i][2] = atlasInfo.uvScale;
2537 lightData.atlasLocations[i][3] = atlasInfo.layerIndex;
2540 lightData.csmNumSplits = pEntry->m_csmNumSplits;
2541 memcpy(lightData.csmSplits, pEntry->m_csmSplits, 4 *
sizeof(
float));
2542 memcpy(lightData.csmActive, pEntry->m_csmActive, 4 *
sizeof(
float));
2543 lightData.csmBlendRatio = theLight->m_csmBlendRatio;
2544 for (quint32 i = 0; i < layerCount; ++i)
2545 memcpy(lightData.dimensionsInverted[i], &pEntry->m_dimensionsInverted[i], 4 *
sizeof(
float));
2547 directionalShadowCount++;
2549 lightData.enableShadows = 0.0f;
2551 directionalLightCount++;
2554 QSSGShaderLightData &lightData(lightsUniformData.lightData[lightCount]);
2555 const auto gt = inRenderProperties.getGlobalTransform(*theLight);
2556 const QVector3D globalPos = QSSGRenderNode::getGlobalPos(gt);
2557 lightData.position[0] = globalPos.x();
2558 lightData.position[1] = globalPos.y();
2559 lightData.position[2] = globalPos.z();
2560 lightData.constantAttenuation = QSSGUtils::aux::translateConstantAttenuation(theLight->m_constantFade);
2561 lightData.linearAttenuation = QSSGUtils::aux::translateLinearAttenuation(theLight->m_linearFade);
2562 lightData.quadraticAttenuation = QSSGUtils::aux::translateQuadraticAttenuation(theLight->m_quadraticFade);
2563 lightData.coneAngle = 360.0f;
2564 lightData.direction[0] = direction.x();
2565 lightData.direction[1] = direction.y();
2566 lightData.direction[2] = direction.z();
2567 lightData.diffuseColor[0] = diffuseColor.x();
2568 lightData.diffuseColor[1] = diffuseColor.y();
2569 lightData.diffuseColor[2] = diffuseColor.z();
2570 lightData.specularColor[0] = specularColor.x();
2571 lightData.specularColor[1] = specularColor.y();
2572 lightData.specularColor[2] = specularColor.z();
2573 lightData.lightmapState = lightmapState;
2574 if (theLight->type == QSSGRenderLight::Type::SpotLight) {
2578 const float coneAngle = theLight->m_coneAngle;
2579 const float innerConeAngle = (theLight->m_innerConeAngle > coneAngle) ? coneAngle : theLight->m_innerConeAngle;
2580 lightData.coneAngle = qCos(qDegreesToRadians(coneAngle));
2581 lightData.innerConeAngle = qCos(qDegreesToRadians(innerConeAngle));
2584 if (lightShadows && receivesShadows) {
2585 QSSGShadowMapEntry *pEntry = inRenderProperties.getShadowMapManager()->shadowMapEntry(lightIdx);
2587 lightData.enableShadows = 1.0f;
2588 lightData.shadowPcfFactor = theLight->m_pcfFactor;
2589 lightData.shadowPcfSamples = softShadowQualityToInt(theLight->m_softShadowQuality);
2590 lightData.shadowFactor = theLight->m_shadowFactor;
2591 lightData.shadowBias = theLight->m_shadowBias;
2592 lightData.shadowClipNear = 1.0f;
2593 lightData.shadowMapFar = pEntry->m_shadowMapFar;
2594 lightData.shadowTextureSize = pEntry->m_atlasInfo[0].uvScale;
2596 if (theLight->type == QSSGRenderLight::Type::SpotLight) {
2598 static const QMatrix4x4 bias = {
2602 0.0, 0.0, 0.0, 1.0 };
2603 const QMatrix4x4 m = bias * pEntry->m_lightViewProjection[0];
2604 memcpy(lightData.shadowMatrix, m.constData(), 16 *
sizeof(
float));
2605 lightData.shadowAtlasUV0[0] = pEntry->m_atlasInfo[0].uOffset;
2606 lightData.shadowAtlasUV0[1] = pEntry->m_atlasInfo[0].vOffset;
2607 lightData.shadowAtlasLayer0 = pEntry->m_atlasInfo[0].layerIndex;
2610 Q_ASSERT(theLight->type == QSSGRenderLight::Type::PointLight);
2611 memcpy(lightData.shadowMatrix, pEntry->m_lightView.constData(), 16 *
sizeof(
float));
2612 lightData.shadowAtlasUV0[0] = pEntry->m_atlasInfo[0].uOffset;
2613 lightData.shadowAtlasUV0[1] = pEntry->m_atlasInfo[0].vOffset;
2614 lightData.shadowAtlasLayer0 = pEntry->m_atlasInfo[0].layerIndex;
2615 lightData.shadowAtlasUV1[0] = pEntry->m_atlasInfo[1].uOffset;
2616 lightData.shadowAtlasUV1[1] = pEntry->m_atlasInfo[1].vOffset;
2617 lightData.shadowAtlasLayer1 = pEntry->m_atlasInfo[1].layerIndex;
2622 lightData.enableShadows = 0.0f;
2628 theLightAmbientTotal += theLight->m_ambientColor;
2632 if (shadowCount > 0 || directionalShadowCount > 0) {
2633 shaders.setShadowMapAtlasTexture(inRenderProperties.getShadowMapManager()->shadowMapAtlasTexture());
2634 shaders.setShadowMapBlueNoiseTexture(inRenderProperties.getShadowMapManager()->shadowMapBlueNoiseTexture());
2636 shaders.setShadowMapAtlasTexture(
nullptr);
2637 shaders.setShadowMapBlueNoiseTexture(
nullptr);
2640 const QSSGRhiRenderableTexture *depthTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::DepthTexture);
2641 const QSSGRhiRenderableTexture *normalTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::NormalTexture);
2642 const QSSGRhiRenderableTexture *ssaoTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::AoTexture);
2643 const QSSGRhiRenderableTexture *screenTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::ScreenTexture);
2644 const QSSGRhiRenderableTexture *motionVectorTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::MotionVectorTexture);
2646 shaders.setDepthTexture(depthTexture->texture);
2647 shaders.setNormalTexture(normalTexture->texture);
2648 shaders.setSsaoTexture(ssaoTexture->texture);
2649 shaders.setScreenTexture(screenTexture->texture);
2650 shaders.setLightmapTexture(lightmapTexture);
2651 shaders.setMotionVectorTexture(motionVectorTexture->texture);
2653#ifdef QSSG_OIT_USE_BUFFERS
2654 shaders.setOITImages((QRhiTexture*)inRenderProperties.getOitRenderContextConst().aBuffer,
2655 (QRhiTexture*)inRenderProperties.getOitRenderContextConst().auxBuffer,
2656 (QRhiTexture*)inRenderProperties.getOitRenderContextConst().counterBuffer);
2657 if (inRenderProperties.getOitRenderContextConst().aBuffer) {
2659 int listNodeCount = inRenderProperties.layer.oitNodeCount;
2661 const QSSGRhiRenderableTexture *abuf = inRenderProperties.getRenderResult(QSSGRenderResult::Key::ABufferImage);
2662 const QSSGRhiRenderableTexture *aux = inRenderProperties.getRenderResult(QSSGRenderResult::Key::AuxiliaryImage);
2663 const QSSGRhiRenderableTexture *counter = inRenderProperties.getRenderResult(QSSGRenderResult::Key::CounterImage);
2664 shaders.setOITImages(abuf->texture, aux->texture, counter->texture);
2665 if (abuf->texture) {
2666 int abufWidth = RenderHelpers::rhiCalculateABufferSize(inRenderProperties.layer.oitNodeCount);
2667 int listNodeCount = abufWidth * abufWidth;
2669 shaders.setUniform(ubufData,
"qt_ABufImageWidth", &abufWidth,
sizeof(
int), &cui.abufImageWidth);
2670 shaders.setUniform(ubufData,
"qt_listNodeCount", &listNodeCount,
sizeof(
int), &cui.listNodeCount);
2671 int viewSize[2] = {inRenderProperties.layerPrepResult.textureDimensions().width(), inRenderProperties.layerPrepResult.textureDimensions().height()};
2672 shaders.setUniform(ubufData,
"qt_viewSize", viewSize,
sizeof(
int) * 2, &cui.viewSize);
2673 int samples = inPipelineState->samples;
2674 shaders.setUniform(ubufData,
"qt_samples", &samples,
sizeof(
int), &cui.samples);
2677 QSSGRenderImageTexture resolvedLayerIbl;
2678 QSSGRenderTextureCoordOp hTile = QSSGRenderTextureCoordOp::ClampToEdge;
2679 QSSGRenderTextureCoordOp vTile = QSSGRenderTextureCoordOp::ClampToEdge;
2680 const QSSGRenderLayer &layer = QSSGLayerRenderData::getCurrent(*renderContext.renderer())->layer;
2681 if (layer.lightProbe) {
2682 resolvedLayerIbl = renderContext.bufferManager()->loadRenderImage(layer.lightProbe, QSSGBufferManager::MipModeBsdf);
2683 hTile = layer.lightProbe->m_horizontalTilingMode;
2684 vTile = layer.lightProbe->m_verticalTilingMode;
2685 }
else if (layer.skyMaterial && layer.skyMaterial->enableIBL) {
2686 resolvedLayerIbl = inRenderProperties.skyMaterialTexture;
2689 const auto &lightProbeData = layer.lightProbeSettings;
2692 QSSGRenderImage *materialIblProbe = materialAdapter->iblProbe();
2694 QSSGRenderImageTexture lightProbeTexture;
2695 if (materialIblProbe) {
2696 lightProbeTexture = renderContext.bufferManager()->loadRenderImage(materialIblProbe, QSSGBufferManager::MipModeBsdf);
2697 hTile = materialIblProbe->m_horizontalTilingMode;
2698 vTile = materialIblProbe->m_verticalTilingMode;
2699 }
else if (resolvedLayerIbl.m_texture) {
2700 lightProbeTexture = resolvedLayerIbl;
2703 if (lightProbeTexture.m_texture) {
2704 const int maxMipLevel = lightProbeTexture.m_mipmapCount - 1;
2706 if (!materialIblProbe && !lightProbeData.probeOrientation.isIdentity()) {
2707 shaders.setUniform(ubufData,
"qt_lightProbeOrientation",
2708 lightProbeData.probeOrientation.constData(),
2709 12 *
sizeof(
float), &cui.lightProbeOrientationIdx,
2710 QSSGRhiShaderPipeline::UniformFlag::Mat3);
2713 const float props[4] = { 0.0f,
float(maxMipLevel), lightProbeData.probeHorizon, lightProbeData.probeExposure };
2714 shaders.setUniform(ubufData,
"qt_lightProbeProperties", props, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2716 shaders.setLightProbeTexture(lightProbeTexture.m_texture, hTile, vTile);
2719 const float emptyProps[4] = { 0.0f, 0.0f, -1.0f, 0.0f };
2720 shaders.setUniform(ubufData,
"qt_lightProbeProperties", emptyProps, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2722 shaders.setLightProbeTexture(
nullptr);
2725 if (receivesReflections && reflectionProbe.enabled) {
2726 shaders.setUniform(ubufData,
"qt_reflectionProbeCubeMapCenter", &reflectionProbe.probeCubeMapCenter, 3 *
sizeof(
float), &cui.reflectionProbeCubeMapCenter);
2727 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMin", &reflectionProbe.probeBoxMin, 3 *
sizeof(
float), &cui.reflectionProbeBoxMin);
2728 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMax", &reflectionProbe.probeBoxMax, 3 *
sizeof(
float), &cui.reflectionProbeBoxMax);
2729 shaders.setUniform(ubufData,
"qt_reflectionProbeCorrection", &reflectionProbe.parallaxCorrection,
sizeof(
int), &cui.reflectionProbeCorrection);
2732 const QVector3D emissiveColor = materialAdapter->emissiveColor();
2733 shaders.setUniform(ubufData,
"qt_material_emissive_color", &emissiveColor, 3 *
sizeof(
float), &cui.material_emissiveColorIdx);
2735 const auto qMix = [](
float x,
float y,
float a) {
2736 return (x * (1.0f - a) + (y * a));
2739 const auto qMix3 = [&qMix](
const QVector3D &x,
const QVector3D &y,
float a) {
2740 return QVector3D{qMix(x.x(), y.x(), a), qMix(x.y(), y.y(), a), qMix(x.z(), y.z(), a)};
2743 const QVector4D color = materialAdapter->color();
2744 const QVector3D materialSpecularTint = materialAdapter->specularTint();
2745 const QVector3D specularTint = materialAdapter->isPrincipled() ? qMix3(QVector3D(1.0f, 1.0f, 1.0f), color.toVector3D(), materialSpecularTint.x())
2746 : materialSpecularTint;
2747 shaders.setUniform(ubufData,
"qt_material_base_color", &color, 4 *
sizeof(
float), &cui.material_baseColorIdx);
2749 const float ior = materialAdapter->ior();
2750 QVector4D specularColor(specularTint, ior);
2751 shaders.setUniform(ubufData,
"qt_material_specular", &specularColor, 4 *
sizeof(
float), &cui.material_specularIdx);
2753 const bool hasLighting = materialAdapter->hasLighting();
2754 shaders.setLightsEnabled(hasLighting);
2756 const float lightAndShadowCounts[4] = {
2758 float(directionalLightCount),
2760 float(directionalShadowCount)
2762 shaders.setUniform(ubufData,
"qt_lightAndShadowCounts", &lightAndShadowCounts, 4 *
sizeof(
float), &cui.lightAndShadowCountsIdx);
2764 const size_t lightDataSize = lightCount *
sizeof(QSSGShaderLightData);
2765 const size_t directionalLightDataSize = directionalLightCount *
sizeof(QSSGShaderDirectionalLightData);
2767 memcpy(ubufData + shaders.ub0LightDataOffset(), &lightsUniformData, lightDataSize);
2768 memcpy(ubufData + shaders.ub0DirectionalLightDataOffset(), &directionalLightsUniformData, directionalLightDataSize);
2771 shaders.setUniform(ubufData,
"qt_light_ambient_total", &theLightAmbientTotal, 3 *
sizeof(
float), &cui.light_ambient_totalIdx);
2773 const float materialProperties[4] = {
2774 materialAdapter->specularAmount(),
2775 materialAdapter->specularRoughness(),
2776 materialAdapter->metalnessAmount(),
2779 shaders.setUniform(ubufData,
"qt_material_properties", materialProperties, 4 *
sizeof(
float), &cui.material_propertiesIdx);
2781 const float materialProperties2[4] = {
2782 materialAdapter->fresnelPower(),
2783 materialAdapter->bumpAmount(),
2784 materialAdapter->translucentFallOff(),
2785 materialAdapter->diffuseLightWrap()
2787 shaders.setUniform(ubufData,
"qt_material_properties2", materialProperties2, 4 *
sizeof(
float), &cui.material_properties2Idx);
2789 const float materialProperties3[4] = {
2790 materialAdapter->occlusionAmount(),
2791 materialAdapter->alphaCutOff(),
2792 materialAdapter->clearcoatAmount(),
2793 materialAdapter->clearcoatRoughnessAmount()
2795 shaders.setUniform(ubufData,
"qt_material_properties3", materialProperties3, 4 *
sizeof(
float), &cui.material_properties3Idx);
2797 const float materialProperties4[4] = {
2798 materialAdapter->heightAmount(),
2799 materialAdapter->minHeightSamples(),
2800 materialAdapter->maxHeightSamples(),
2801 materialAdapter->transmissionFactor()
2803 shaders.setUniform(ubufData,
"qt_material_properties4", materialProperties4, 4 *
sizeof(
float), &cui.material_properties4Idx);
2805 const bool hasCustomFrag = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
2806 if (!hasCustomFrag) {
2807 if (inProperties.m_fresnelScaleBiasEnabled.getValue(inKey) || inProperties.m_clearcoatFresnelScaleBiasEnabled.getValue(inKey)) {
2808 const float materialProperties5[4] = {
2809 materialAdapter->fresnelScale(),
2810 materialAdapter->fresnelBias(),
2811 materialAdapter->clearcoatFresnelScale(),
2812 materialAdapter->clearcoatFresnelBias()
2814 shaders.setUniform(ubufData,
"qt_material_properties5", materialProperties5, 4 *
sizeof(
float), &cui.material_properties5Idx);
2817 const float material_clearcoat_normal_strength = materialAdapter->clearcoatNormalStrength();
2818 shaders.setUniform(ubufData,
"qt_material_clearcoat_normal_strength", &material_clearcoat_normal_strength,
sizeof(
float), &cui.clearcoatNormalStrengthIdx);
2820 if (materialAdapter->isSheenEnabled()) {
2821 const QVector3D sheenColor = materialAdapter->sheenColor();
2822 shaders.setUniform(ubufData,
"qt_material_sheen_color", &sheenColor, 3 *
sizeof(
float), &cui.sheenColorIdx);
2823 const float sheenRoughness = materialAdapter->sheenRoughness();
2824 shaders.setUniform(ubufData,
"qt_material_sheen_roughness", &sheenRoughness,
sizeof(
float), &cui.sheenRoughnessIdx);
2827 if (materialAdapter->isAnisotropyEnabled()) {
2828 const float rotation = materialAdapter->anisotropyRotation();
2829 const QVector3D anisotropy(materialAdapter->anisotropyStrength(), std::cos(rotation), std::sin(rotation));
2830 shaders.setUniform(ubufData,
"qt_material_anisotropy", &anisotropy, 3 *
sizeof(
float), &cui.anisotropyIdx);
2833 if (materialAdapter->isIridescenceEnabled()) {
2834 const QVector4D iridescence(materialAdapter->iridescenceFactor(),
2835 materialAdapter->iridescenceIndexOfRefraction(),
2836 materialAdapter->iridescenceThicknessMinimum(),
2837 materialAdapter->iridescenceThicknessMaximum());
2838 shaders.setUniform(ubufData,
"qt_material_iridescence", &iridescence, 4 *
sizeof(
float), &cui.iridescenceIdx);
2841 const float material_clearcoat_fresnel_power = materialAdapter->clearcoatFresnelPower();
2842 shaders.setUniform(ubufData,
"qt_material_clearcoat_fresnel_power", &material_clearcoat_fresnel_power,
sizeof(
float), &cui.clearcoatFresnelPowerIdx);
2844 if (materialAdapter->isTransmissionEnabled()) {
2845 const QVector4D attenuationProperties(materialAdapter->attenuationColor(), materialAdapter->attenuationDistance());
2846 shaders.setUniform(ubufData,
"qt_material_attenuation", &attenuationProperties, 4 *
sizeof(
float), &cui.material_attenuationIdx);
2848 const float thickness = materialAdapter->thicknessFactor();
2849 shaders.setUniform(ubufData,
"qt_material_thickness", &thickness,
sizeof(
float), &cui.thicknessFactorIdx);
2851 if (materialAdapter->isDispersionEnabled()) {
2852 const float dispersion = materialAdapter->dispersion();
2853 shaders.setUniform(ubufData,
"qt_material_dispersion", &dispersion,
sizeof(
float), &cui.dispersionIdx);
2858 const float rhiProperties[4] = {
2859 globalRenderData.isYUpInFramebuffer ? 1.0f : -1.0f,
2860 globalRenderData.isYUpInNDC ? 1.0f : -1.0f,
2861 globalRenderData.isClipDepthZeroToOne ? 0.0f : -1.0f,
2864 shaders.setUniform(ubufData,
"qt_rhi_properties", rhiProperties, 4 *
sizeof(
float), &cui.rhiPropertiesIdx);
2866 qsizetype imageIdx = 0;
2867 for (QSSGRenderableImage *theImage = inFirstImage; theImage; theImage = theImage->m_nextImage, ++imageIdx) {
2869 const auto &names = imageStringTable[
int(theImage->m_mapType)];
2870 if (imageIdx == cui.imageIndices.size())
2871 cui.imageIndices.append(QSSGRhiShaderPipeline::CommonUniformIndices::ImageIndices());
2872 auto &indices = cui.imageIndices[imageIdx];
2874 const QMatrix4x4 &textureTransform = theImage->m_imageNode.m_textureTransform;
2877 const float *dataPtr(textureTransform.constData());
2881 const float offsets[3] = { dataPtr[12], dataPtr[13], 0.0f };
2882 shaders.setUniform(ubufData, names.imageOffsets, offsets,
sizeof(offsets), &indices.imageOffsetsUniformIndex);
2884 const float rotations[4] = { dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5] };
2885 shaders.setUniform(ubufData, names.imageRotations, rotations,
sizeof(rotations), &indices.imageRotationsUniformIndex);
2888 if (shadowDepthAdjust)
2889 shaders.setUniform(ubufData,
"qt_shadowDepthAdjust", shadowDepthAdjust, 2 *
sizeof(
float), &cui.shadowDepthAdjustIdx);
2891 const bool usesPointsTopology = inProperties.m_usesPointsTopology.getValue(inKey);
2892 if (usesPointsTopology) {
2893 const float pointSize = materialAdapter->pointSize();
2894 shaders.setUniform(ubufData,
"qt_materialPointSize", &pointSize,
sizeof(
float), &cui.pointSizeIdx);
2901 if (inRenderProperties.layer.fog.enabled) {
2902 const float fogColor[4] = {
2903 inRenderProperties.layer.fog.color.x(),
2904 inRenderProperties.layer.fog.color.y(),
2905 inRenderProperties.layer.fog.color.z(),
2906 inRenderProperties.layer.fog.density
2908 shaders.setUniform(ubufData,
"qt_fogColor", fogColor, 4 *
sizeof(
float), &cui.fogColorIdx);
2909 const float fogDepthProperties[4] = {
2910 inRenderProperties.layer.fog.depthBegin,
2911 inRenderProperties.layer.fog.depthEnd,
2912 inRenderProperties.layer.fog.depthCurve,
2913 inRenderProperties.layer.fog.depthEnabled ? 1.0f : 0.0f
2915 shaders.setUniform(ubufData,
"qt_fogDepthProperties", fogDepthProperties, 4 *
sizeof(
float), &cui.fogDepthPropertiesIdx);
2916 const float fogHeightProperties[4] = {
2917 inRenderProperties.layer.fog.heightMin,
2918 inRenderProperties.layer.fog.heightMax,
2919 inRenderProperties.layer.fog.heightCurve,
2920 inRenderProperties.layer.fog.heightEnabled ? 1.0f : 0.0f
2922 shaders.setUniform(ubufData,
"qt_fogHeightProperties", fogHeightProperties, 4 *
sizeof(
float), &cui.fogHeightPropertiesIdx);
2923 const float fogTransmitProperties[4] = {
2924 inRenderProperties.layer.fog.transmitCurve,
2927 inRenderProperties.layer.fog.transmitEnabled ? 1.0f : 0.0f
2929 shaders.setUniform(ubufData,
"qt_fogTransmitProperties", fogTransmitProperties, 4 *
sizeof(
float), &cui.fogTransmitPropertiesIdx);
2932 inPipelineState->lineWidth = materialAdapter->lineWidth();