832 QSSGMaterialVertexPipeline &vertexShader,
833 const QSSGShaderDefaultMaterialKey &inKey,
834 const QSSGShaderDefaultMaterialKeyProperties &keyProps,
835 const QSSGShaderFeatures &featureSet,
836 const QSSGRenderGraphObject &inMaterial,
837 const QSSGUserShaderAugmentation &shaderAugmentation,
838 QSSGShaderLibraryManager &shaderLibraryManager)
840 QSSGShaderMaterialAdapter *materialAdapter = getMaterialAdapter(inMaterial);
841 auto hasCustomFunction = [&shaderLibraryManager, materialAdapter](
const QByteArray &funcName) {
842 return materialAdapter->hasCustomShaderFunction(QSSGShaderCache::ShaderType::Fragment,
844 shaderLibraryManager);
847 auto channelStr = [](
const QSSGShaderKeyTextureChannel &chProp,
const QSSGShaderDefaultMaterialKey &inKey) -> QByteArray {
849 switch (chProp.getTextureChannel(inKey)) {
850 case QSSGShaderKeyTextureChannel::R:
853 case QSSGShaderKeyTextureChannel::G:
856 case QSSGShaderKeyTextureChannel::B:
859 case QSSGShaderKeyTextureChannel::A:
866 auto maskVariableByVertexColorChannel = [&fragmentShader, keyProps, inKey](
const QByteArray &maskVariable,
const QSSGRenderDefaultMaterial::VertexColorMask &maskEnum ){
867 if (keyProps.m_vertexColorsMaskEnabled.getValue(inKey)) {
868 if ( keyProps.m_vertexColorRedMask.getValue(inKey) & maskEnum )
869 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.r;\n";
870 else if ( keyProps.m_vertexColorGreenMask.getValue(inKey) & maskEnum )
871 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.g;\n";
872 else if ( keyProps.m_vertexColorBlueMask.getValue(inKey) & maskEnum )
873 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.b;\n";
874 else if ( keyProps.m_vertexColorAlphaMask.getValue(inKey) & maskEnum )
875 fragmentShader <<
" " << maskVariable <<
" *= qt_vertColorMask.a;\n";
879 generateFragmentDefines(fragmentShader, inKey, keyProps, materialAdapter, shaderLibraryManager, shaderAugmentation);
884 const PassRequirmentsState passRequirmentState(inKey, keyProps, featureSet, samplerState, shaderAugmentation);
886 const bool hasCustomVert = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Vertex);
888 const int viewCount = featureSet.isSet(QSSGShaderFeatures::Feature::DisableMultiView)
889 ? 1 : keyProps.m_viewCount.getValue(inKey);
892 if (passRequirmentState.numMorphTargets > 0 || hasCustomVert) {
893 vertexShader.addDefinition(QByteArrayLiteral(
"QT_MORPH_MAX_COUNT"),
894 QByteArray::number(passRequirmentState.numMorphTargets));
896 if ((offset = keyProps.m_targetPositionOffset.getValue(inKey)) < UINT8_MAX) {
897 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_POSITION_OFFSET"),
898 QByteArray::number(offset));
900 if ((offset = keyProps.m_targetNormalOffset.getValue(inKey)) < UINT8_MAX) {
901 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_NORMAL_OFFSET"),
902 QByteArray::number(offset));
904 if ((offset = keyProps.m_targetTangentOffset.getValue(inKey)) < UINT8_MAX) {
905 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TANGENT_OFFSET"),
906 QByteArray::number(offset));
908 if ((offset = keyProps.m_targetBinormalOffset.getValue(inKey)) < UINT8_MAX) {
909 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_BINORMAL_OFFSET"),
910 QByteArray::number(offset));
912 if ((offset = keyProps.m_targetTexCoord0Offset.getValue(inKey)) < UINT8_MAX) {
913 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TEX0_OFFSET"),
914 QByteArray::number(offset));
916 if ((offset = keyProps.m_targetTexCoord1Offset.getValue(inKey)) < UINT8_MAX) {
917 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_TEX1_OFFSET"),
918 QByteArray::number(offset));
920 if ((offset = keyProps.m_targetColorOffset.getValue(inKey)) < UINT8_MAX) {
921 vertexShader.addDefinition(QByteArrayLiteral(
"QT_TARGET_COLOR_OFFSET"),
922 QByteArray::number(offset));
927 if (shaderAugmentation.hasUserAugmentation())
928 fragmentShader << shaderAugmentation.preamble;
931 for (
const auto &u : shaderAugmentation.propertyUniforms)
932 fragmentShader.addUniform(u.name, u.typeName);
935 const bool hasCustomFrag = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
936 const bool usesSharedVar = materialAdapter->usesSharedVariables();
938 vertexShader.beginFragmentGeneration(shaderLibraryManager, passRequirmentState.oitMethod);
941 vertexShader.generateDepth();
942 fragmentShader.addUniform(
"qt_shadowDepthAdjust",
"vec2");
947 vertexShader.generateShadowWorldPosition(inKey);
950 if (hasCustomFrag && materialAdapter->isUnshaded()) {
964 fragmentShader.addUniform(
"qt_material_emissive_color",
"vec3");
966 fragmentShader.addUniform(
"qt_material_base_color",
"vec4");
967 fragmentShader.addUniform(
"qt_material_properties",
"vec4");
968 fragmentShader.addUniform(
"qt_material_properties2",
"vec4");
969 fragmentShader.addUniform(
"qt_material_properties3",
"vec4");
971 fragmentShader.addUniform(
"qt_material_properties4",
"vec4");
972 if (!hasCustomFrag) {
974 fragmentShader.addUniform(
"qt_material_attenuation",
"vec4");
975 fragmentShader.addUniform(
"qt_material_thickness",
"float");
978 fragmentShader.addUniform(
"qt_material_properties5",
"vec4");
979 fragmentShader.addUniform(
"qt_material_clearcoat_normal_strength",
"float");
980 fragmentShader.addUniform(
"qt_material_clearcoat_fresnel_power",
"float");
984 vertexShader.generateVertexColor(inKey);
986 fragmentShader.append(
" vec4 qt_vertColorMask = vec4(1.0);");
987 fragmentShader.append(
" vec4 qt_vertColor = vec4(1.0);");
991 vertexShader.generateViewVector(inKey);
992 if (keyProps.m_usesProjectionMatrix.getValue(inKey)) {
994 fragmentShader.addUniformArray(
"qt_projectionMatrix",
"mat4", viewCount);
996 fragmentShader.addUniform(
"qt_projectionMatrix",
"mat4");
998 if (keyProps.m_usesInverseProjectionMatrix.getValue(inKey)) {
1000 fragmentShader.addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", viewCount);
1002 fragmentShader.addUniform(
"qt_inverseProjectionMatrix",
"mat4");
1004 vertexShader.generateWorldNormal(inKey);
1005 vertexShader.generateWorldPosition(inKey);
1008 bool genTangent =
false;
1009 bool genBinormal =
false;
1010 vertexShader.generateVarTangentAndBinormal(inKey, genTangent, genBinormal);
1013 QSSGRenderableImage::Type id = QSSGRenderableImage::Type::Unknown;
1018 id = samplerState.hasImage(QSSGRenderableImage::Type::Bump) ? QSSGRenderableImage::Type::Bump : QSSGRenderableImage::Type::Normal;
1019 }
else if (samplerState.hasImage(QSSGRenderableImage::Type::ClearcoatNormal)) {
1021 id = QSSGRenderableImage::Type::ClearcoatNormal;
1025 id = QSSGRenderableImage::Type::Height;
1028 if (id > QSSGRenderableImage::Type::Unknown) {
1029 samplerState.generateImageUVAndSampler(id, vertexShader, fragmentShader, inKey,
true);
1030 fragmentShader <<
" vec2 dUVdx = dFdx(" << samplerState.fragCoordsName(id) <<
");\n"
1031 <<
" vec2 dUVdy = dFdy(" << samplerState.fragCoordsName(id) <<
");\n";
1032 fragmentShader <<
" qt_tangent = (dUVdy.y * dFdx(qt_varWorldPos) - dUVdx.y * dFdy(qt_varWorldPos)) / (dUVdx.x * dUVdy.y - dUVdx.y * dUVdy.x);\n"
1033 <<
" qt_tangent = qt_tangent - dot(qt_world_normal, qt_tangent) * qt_world_normal;\n"
1034 <<
" qt_tangent = normalize(qt_tangent);\n";
1038 fragmentShader <<
" qt_binormal = cross(qt_world_normal, qt_tangent);\n";
1042 fragmentShader.append(
"#if QSHADER_HLSL && QSHADER_VIEW_COUNT >= 2");
1043 fragmentShader.append(
" const float qt_facing = 1.0;");
1044 fragmentShader.append(
"#else");
1045 fragmentShader.append(
" const float qt_facing = gl_FrontFacing ? 1.0 : -1.0;");
1046 fragmentShader.append(
"#endif");
1047 fragmentShader.append(
" qt_world_normal *= qt_facing;\n");
1049 fragmentShader.append(
" qt_tangent *= qt_facing;");
1050 fragmentShader.append(
" qt_binormal *= qt_facing;");
1055 if (hasCustomFrag) {
1061 fragmentShader <<
" float qt_customOcclusionAmount = 1.0;\n";
1062 fragmentShader <<
" float qt_customIOR = 1.5;\n";
1063 fragmentShader <<
" float qt_customSpecularAmount = 0.5;\n";
1064 fragmentShader <<
" float qt_customSpecularRoughness = 0.0;\n";
1065 fragmentShader <<
" float qt_customMetalnessAmount = 0.0;\n";
1066 fragmentShader <<
" float qt_customFresnelPower = 5.0;\n";
1067 fragmentShader <<
" vec4 qt_customBaseColor = vec4(1.0);\n";
1068 fragmentShader <<
" vec3 qt_customEmissiveColor = vec3(0.0);\n";
1070 fragmentShader <<
" float qt_customClearcoatAmount = 0.0;\n";
1071 fragmentShader <<
" float qt_customClearcoatFresnelPower = 5.0;\n";
1072 fragmentShader <<
" float qt_customClearcoatRoughness = 0.0;\n";
1073 fragmentShader <<
" vec3 qt_customClearcoatNormal = qt_world_normal;\n";
1075 fragmentShader <<
" float qt_customClearcoatFresnelScale = 1.0;\n";
1076 fragmentShader <<
" float qt_customClearcoatFresnelBias = 0.0;\n";
1080 fragmentShader <<
" float qt_customFresnelScale = 1.0;\n";
1081 fragmentShader <<
" float qt_customFresnelBias = 0.0;\n";
1085 fragmentShader <<
" float qt_customTransmissionFactor = 0.0;\n";
1086 fragmentShader <<
" float qt_customThicknessFactor = 0.0;\n";
1087 fragmentShader <<
" vec3 qt_customAttenuationColor = vec3(1.0);\n";
1088 fragmentShader <<
" float qt_customAttenuationDistance = 0.0;\n";
1091 fragmentShader <<
" QT_SHARED_VARS qt_customShared;\n";
1094 vertexShader.generateUVCoords(0, inKey);
1095 vertexShader.generateUVCoords(1, inKey);
1097 fragmentShader <<
" qt_customMain(qt_customBaseColor,\n"
1098 <<
" qt_customEmissiveColor,\n"
1099 <<
" qt_customMetalnessAmount,\n"
1100 <<
" qt_customSpecularRoughness,\n"
1101 <<
" qt_customSpecularAmount,\n"
1102 <<
" qt_customFresnelPower,\n"
1103 <<
" qt_world_normal,\n"
1105 <<
" qt_binormal,\n"
1106 <<
" qt_texCoord0,\n"
1107 <<
" qt_texCoord1,\n"
1108 <<
" qt_view_vector,\n"
1109 <<
" qt_customIOR,\n"
1110 <<
" qt_customOcclusionAmount";
1112 fragmentShader <<
",\n qt_customClearcoatAmount,\n"
1113 <<
" qt_customClearcoatFresnelPower,\n"
1114 <<
" qt_customClearcoatRoughness,\n"
1115 <<
" qt_customClearcoatNormal";
1117 fragmentShader <<
",\n qt_customClearcoatFresnelScale,\n"
1118 <<
" qt_customClearcoatFresnelBias";
1122 fragmentShader <<
",\n qt_customFresnelScale,\n"
1123 <<
" qt_customFresnelBias";
1126 fragmentShader <<
",\n qt_customTransmissionFactor,\n"
1127 <<
" qt_customThicknessFactor,\n"
1128 <<
" qt_customAttenuationColor,\n"
1129 <<
" qt_customAttenuationDistance";
1132 fragmentShader <<
"\n, qt_customShared);\n";
1134 fragmentShader <<
");\n";
1136 fragmentShader <<
" vec4 qt_diffuseColor = qt_customBaseColor * qt_vertColor;\n";
1137 fragmentShader <<
" vec3 qt_global_emission = qt_customEmissiveColor;\n";
1138 fragmentShader <<
" float qt_iOR = qt_customIOR;\n";
1140 fragmentShader <<
" vec4 qt_diffuseColor = qt_material_base_color * qt_vertColor;\n";
1141 fragmentShader <<
" vec3 qt_global_emission = qt_material_emissive_color;\n";
1143 fragmentShader <<
" float qt_iOR = qt_material_specular.w;\n";
1146 const bool hasCustomIblProbe = hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_iblProbeProcessor"));
1153 vertexShader.generateLightmapUVCoords(inKey);
1154 fragmentShader.addFunction(
"lightmap");
1163 fragmentShader.addInclude(
"parallaxMapping.glsllib");
1164 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Height, vertexShader, fragmentShader, inKey,
true);
1165 fragmentShader <<
" float qt_heightAmount = qt_material_properties4.x;\n";
1166 maskVariableByVertexColorChannel(
"qt_heightAmount", QSSGRenderDefaultMaterial::HeightAmountMask );
1167 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << samplerState.fragCoordsName(QSSGRenderableImage::Type::Height) <<
",\n"
1168 <<
" " << samplerState.samplerName(QSSGRenderableImage::Type::Height) <<
",\n"
1170 <<
" qt_binormal,\n"
1171 <<
" qt_world_normal,\n"
1172 <<
" qt_varWorldPos, \n"
1173 <<
"#if QSHADER_VIEW_COUNT >= 2\n"
1174 <<
" qt_cameraPosition[qt_viewIndex],\n"
1176 <<
" qt_cameraPosition,\n"
1178 <<
" qt_heightAmount,\n"
1179 <<
" qt_material_properties4.y,\n"
1180 <<
" qt_material_properties4.z);\n";
1185 addLocalVariable(fragmentShader,
"qt_clearcoatNormal",
"vec3");
1190 if (hasCustomFrag) {
1191 fragmentShader <<
" qt_clearcoatNormal = qt_customClearcoatNormal;\n";
1193 if (samplerState.hasImage(QSSGRenderableImage::Type::ClearcoatNormal)) {
1194 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::ClearcoatNormal, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1195 fragmentShader.addFunction(
"sampleNormalTexture");
1196 fragmentShader <<
" float qt_clearcoat_normal_strength = qt_material_clearcoat_normal_strength;\n";
1197 maskVariableByVertexColorChannel(
"qt_clearcoat_normal_strength", QSSGRenderDefaultMaterial::ClearcoatNormalStrengthMask );
1198 fragmentShader <<
" qt_clearcoatNormal = qt_sampleNormalTexture(" << samplerState.samplerName(QSSGRenderableImage::Type::ClearcoatNormal)
1199 <<
", qt_clearcoat_normal_strength, "
1200 << samplerState.fragCoordsName(QSSGRenderableImage::Type::ClearcoatNormal)
1201 <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1205 fragmentShader <<
" qt_clearcoatNormal = qt_world_normal;\n";
1212 if (samplerState.hasImage(QSSGRenderableImage::Type::Bump)) {
1213 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Bump, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1214 fragmentShader.append(
" float qt_bumpAmount = qt_material_properties2.y;\n");
1215 maskVariableByVertexColorChannel(
"qt_bumpAmount", QSSGRenderDefaultMaterial::NormalStrengthMask );
1216 fragmentShader.addInclude(
"defaultMaterialBumpNoLod.glsllib");
1217 fragmentShader <<
" qt_world_normal = qt_defaultMaterialBumpNoLod("
1218 << samplerState.samplerName(QSSGRenderableImage::Type::Bump)
1219 <<
", qt_bumpAmount, " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Bump)
1220 <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1221 }
else if (samplerState.hasImage(QSSGRenderableImage::Type::Normal)) {
1222 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Normal, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1223 fragmentShader.append(
" float qt_normalStrength = qt_material_properties2.y;\n");
1224 maskVariableByVertexColorChannel(
"qt_normalStrength", QSSGRenderDefaultMaterial::NormalStrengthMask );
1225 fragmentShader.addFunction(
"sampleNormalTexture");
1226 fragmentShader <<
" qt_world_normal = qt_sampleNormalTexture(" << samplerState.samplerName(QSSGRenderableImage::Type::Normal)
1227 <<
", qt_normalStrength, " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Normal)
1228 <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1236 fragmentShader.append(
" vec3 tmp_light_color;");
1240 fragmentShader.append(
" vec3 qt_specularBase;");
1241 fragmentShader.addUniform(
"qt_material_specular",
"vec4");
1243 fragmentShader.append(
" vec3 qt_specularTint = vec3(1.0);");
1245 fragmentShader.append(
" vec3 qt_specularTint = qt_material_specular.rgb;");
1249 if ((samplerState.hasImage(QSSGRenderableImage::Type::BaseColor) || samplerState.hasImage(QSSGRenderableImage::Type::Diffuse)) && passRequirmentState
.needsBaseColor) {
1252 QSSGRenderableImage::Type baseImageType = QSSGRenderableImage::Type::Unknown;
1253 if (samplerState.hasImage(QSSGRenderableImage::Type::BaseColor))
1254 baseImageType = QSSGRenderableImage::Type::BaseColor;
1255 else if (samplerState.hasImage(QSSGRenderableImage::Type::Diffuse))
1256 baseImageType = QSSGRenderableImage::Type::Diffuse;
1259 samplerState.generateImageUVAndSampler(baseImageType, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1261 if (keyProps.m_baseColorSingleChannelEnabled.getValue(inKey)) {
1262 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::BaseColorChannel];
1263 fragmentShader <<
" vec4 qt_base_texture_color = vec4(vec3(texture2D(" << samplerState.samplerName(baseImageType)
1264 <<
", " << samplerState.fragCoordsName(baseImageType) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1266 fragmentShader <<
" vec4 qt_base_texture_color = texture2D(" << samplerState.samplerName(baseImageType)
1267 <<
", " << samplerState.fragCoordsName(baseImageType) <<
");\n";
1270 if (keyProps.m_imageMaps[QSSGShaderDefaultMaterialKeyProperties::BaseColorMap].isPreMultipliedAlpha(inKey))
1271 fragmentShader <<
" qt_base_texture_color.rgb /= qt_base_texture_color.a;\n";
1273 if (!keyProps.m_imageMaps[QSSGShaderDefaultMaterialKeyProperties::BaseColorMap].isLinear(inKey)) {
1275 fragmentShader.addInclude(
"tonemapping.glsllib");
1276 fragmentShader <<
" qt_base_texture_color = qt_sRGBToLinear(qt_base_texture_color);\n";
1279 fragmentShader <<
" qt_diffuseColor *= qt_base_texture_color;\n";
1283 if (keyProps.m_alphaMode.getAlphaMode(inKey) == QSSGRenderDefaultMaterial::MaterialAlphaMode::Mask) {
1287 fragmentShader <<
" if (qt_diffuseColor.a < qt_material_properties3.y) {\n"
1288 <<
" qt_diffuseColor = vec4(0.0);\n"
1291 <<
" qt_diffuseColor.a = 1.0;\n"
1293 }
else if (keyProps.m_alphaMode.getAlphaMode(inKey) == QSSGRenderDefaultMaterial::MaterialAlphaMode::Opaque) {
1294 fragmentShader <<
" qt_diffuseColor.a = 1.0;\n";
1298 if (samplerState.hasImage(QSSGRenderableImage::Type::Opacity)) {
1299 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Opacity, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1300 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::OpacityChannel];
1301 fragmentShader <<
" float qt_opacity_map_value = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Opacity)
1302 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Opacity) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1303 if (keyProps.m_invertOpacityMapValue.getValue(inKey))
1304 fragmentShader <<
" qt_opacity_map_value = 1.0 - qt_opacity_map_value;\n";
1305 fragmentShader <<
" qt_objectOpacity *= qt_opacity_map_value;\n";
1310 addLocalVariable(fragmentShader,
"qt_aoFactor",
"float");
1313 fragmentShader.addInclude(
"ssao.glsllib");
1314 fragmentShader.append(
" qt_aoFactor = qt_screenSpaceAmbientOcclusionFactor();");
1316 fragmentShader.append(
" qt_aoFactor = 1.0;");
1320 fragmentShader <<
" qt_aoFactor *= qt_customOcclusionAmount;\n";
1326 fragmentShader <<
" float qt_roughnessAmount = qt_customSpecularRoughness;\n";
1328 fragmentShader <<
" float qt_roughnessAmount = qt_material_properties.y;\n";
1330 maskVariableByVertexColorChannel(
"qt_roughnessAmount", QSSGRenderDefaultMaterial::RoughnessMask );
1332 if (samplerState.hasImage(QSSGRenderableImage::Type::Roughness)) {
1333 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Roughness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1334 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::RoughnessChannel];
1335 fragmentShader <<
" qt_roughnessAmount *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Roughness) <<
", "
1336 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Roughness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1341 fragmentShader <<
" qt_roughnessAmount = clamp(1.0 - qt_roughnessAmount, 0.0, 1.0);\n";
1347 fragmentShader <<
" float qt_metalnessAmount = qt_customMetalnessAmount;\n";
1349 fragmentShader <<
" float qt_metalnessAmount = qt_material_properties.z;\n";
1351 fragmentShader <<
" float qt_metalnessAmount = 0.0;\n";
1353 maskVariableByVertexColorChannel(
"qt_metalnessAmount", QSSGRenderDefaultMaterial::MetalnessMask );
1355 if (passRequirmentState
.hasSpecularLight && samplerState.hasImage(QSSGRenderableImage::Type::Metalness)) {
1356 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::MetalnessChannel];
1357 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Metalness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1358 fragmentShader <<
" float qt_sampledMetalness = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Metalness) <<
", "
1359 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Metalness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1360 fragmentShader <<
" qt_metalnessAmount = clamp(qt_metalnessAmount * qt_sampledMetalness, 0.0, 1.0);\n";
1366 fragmentShader <<
" if ((qt_diffuseColor.a * qt_objectOpacity) < 1.0)\n";
1367 fragmentShader <<
" discard;\n";
1373 vertexShader.generateViewVector(inKey);
1374 fragmentShader.addUniform(
"qt_material_properties",
"vec4");
1377 fragmentShader <<
" qt_specularBase = vec3(1.0);\n";
1379 fragmentShader <<
" qt_specularBase = qt_diffuseColor.rgb;\n";
1381 fragmentShader <<
" float qt_specularFactor = qt_customSpecularAmount;\n";
1383 fragmentShader <<
" float qt_specularFactor = qt_material_properties.x;\n";
1385 maskVariableByVertexColorChannel(
"qt_specularFactor", QSSGRenderDefaultMaterial::SpecularAmountMask );
1388 fragmentShader.addUniform(
"qt_light_ambient_total",
"vec3");
1390 fragmentShader.append(
" vec4 global_diffuse_light = vec4(0.0);");
1393 fragmentShader <<
" global_diffuse_light.rgb = qt_lightmap_color(qt_texCoordLightmap) * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb;\n";
1395 if (hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_ambientLightProcessor"))) {
1397 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");
1399 fragmentShader <<
", qt_customShared);\n";
1401 fragmentShader <<
");\n";
1403 fragmentShader.append(
" global_diffuse_light = vec4(qt_light_ambient_total.rgb * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb, 0.0);");
1407 fragmentShader.append(
" vec3 global_specular_light = vec3(0.0);");
1411 if (samplerState.hasImage(QSSGRenderableImage::Type::SpecularAmountMap)) {
1412 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::SpecularAmountMap, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1414 if (keyProps.m_specularSingleChannelEnabled.getValue(inKey)) {
1415 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::SpecularAmountChannel];
1416 fragmentShader <<
" vec4 qt_specular_amount_map = vec4(vec3(texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::SpecularAmountMap)
1417 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::SpecularAmountMap) <<
")" << channelStr(channelProps, inKey) <<
"), 1.0f);\n";
1419 fragmentShader <<
" vec4 qt_specular_amount_map = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::SpecularAmountMap)
1420 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::SpecularAmountMap) <<
");\n";
1422 fragmentShader <<
" qt_specularBase *= qt_sRGBToLinear(qt_specular_amount_map).rgb;\n";
1427 fragmentShader <<
" qt_specularTint *= qt_specularBase;\n";
1428 fragmentShader <<
" vec3 qt_specularAmount = vec3(1.0);\n";
1430 fragmentShader <<
" vec3 qt_specularAmount = qt_specularBase * vec3(qt_metalnessAmount + qt_specularFactor * (1.0 - qt_metalnessAmount));\n";
1434 if (samplerState.hasImage(QSSGRenderableImage::Type::Translucency)) {
1435 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Translucency, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1436 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::TranslucencyChannel];
1437 fragmentShader <<
" float qt_translucent_depth_range = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Translucency)
1438 <<
", " << samplerState.fragCoordsName(QSSGRenderableImage::Type::Translucency) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1439 fragmentShader <<
" float qt_translucent_thickness = qt_translucent_depth_range * qt_translucent_depth_range;\n";
1440 fragmentShader <<
" float qt_translucent_thickness_exp = exp(qt_translucent_thickness * qt_material_properties2.z);\n";
1444 if (samplerState.hasImage(QSSGRenderableImage::Type::Occlusion)) {
1445 addLocalVariable(fragmentShader,
"qt_ao",
"float");
1446 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Occlusion, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1447 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::OcclusionChannel];
1448 fragmentShader <<
" qt_ao = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Occlusion) <<
", "
1449 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Occlusion) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1450 fragmentShader <<
" qt_aoFactor *= qt_ao * qt_material_properties3.x;\n";
1451 maskVariableByVertexColorChannel(
"qt_aoFactor", QSSGRenderDefaultMaterial::OcclusionAmountMask );
1455 addLocalVariable(fragmentShader,
"qt_clearcoatAmount",
"float");
1456 addLocalVariable(fragmentShader,
"qt_clearcoatRoughness",
"float");
1457 addLocalVariable(fragmentShader,
"qt_clearcoatF0",
"vec3");
1458 addLocalVariable(fragmentShader,
"qt_clearcoatF90",
"vec3");
1459 addLocalVariable(fragmentShader,
"qt_global_clearcoat",
"vec3");
1462 fragmentShader <<
" qt_clearcoatAmount = qt_customClearcoatAmount;\n";
1464 fragmentShader <<
" qt_clearcoatAmount = qt_material_properties3.z;\n";
1465 maskVariableByVertexColorChannel(
"qt_clearcoatAmount", QSSGRenderDefaultMaterial::ClearcoatAmountMask );
1467 fragmentShader <<
" qt_clearcoatRoughness = qt_customClearcoatRoughness;\n";
1469 fragmentShader <<
" qt_clearcoatRoughness = qt_material_properties3.w;\n";
1470 maskVariableByVertexColorChannel(
"qt_clearcoatRoughness", QSSGRenderDefaultMaterial::ClearcoatRoughnessAmountMask );
1471 fragmentShader <<
" qt_clearcoatF0 = vec3(((1.0-qt_iOR) * (1.0-qt_iOR)) / ((1.0+qt_iOR) * (1.0+qt_iOR)));\n";
1472 fragmentShader <<
" qt_clearcoatF90 = vec3(1.0);\n";
1473 fragmentShader <<
" qt_global_clearcoat = vec3(0.0);\n";
1475 if (samplerState.hasImage(QSSGRenderableImage::Type::Clearcoat)) {
1476 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Clearcoat, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1477 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ClearcoatChannel];
1478 fragmentShader <<
" qt_clearcoatAmount *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Clearcoat) <<
", "
1479 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Clearcoat) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1482 if (samplerState.hasImage(QSSGRenderableImage::Type::ClearcoatRoughness)) {
1483 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::ClearcoatRoughness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1484 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ClearcoatRoughnessChannel];
1485 fragmentShader <<
" qt_clearcoatRoughness *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::ClearcoatRoughness) <<
", "
1486 << samplerState.fragCoordsName(QSSGRenderableImage::Type::ClearcoatRoughness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1487 fragmentShader <<
" qt_clearcoatRoughness = clamp(qt_clearcoatRoughness, 0.0, 1.0);\n";
1492 fragmentShader.addInclude(
"transmission.glsllib");
1493 addLocalVariable(fragmentShader,
"qt_transmissionFactor",
"float");
1494 addLocalVariable(fragmentShader,
"qt_global_transmission",
"vec3");
1496 addLocalVariable(fragmentShader,
"qt_thicknessFactor",
"float");
1497 addLocalVariable(fragmentShader,
"qt_attenuationColor",
"vec3");
1498 addLocalVariable(fragmentShader,
"qt_attenuationDistance",
"float");
1499 fragmentShader <<
" qt_global_transmission = vec3(0.0);\n";
1501 if (hasCustomFrag) {
1502 fragmentShader <<
" qt_transmissionFactor = qt_customTransmissionFactor;\n";
1503 fragmentShader <<
" qt_thicknessFactor = qt_customThicknessFactor;\n";
1504 fragmentShader <<
" qt_attenuationColor = qt_customAttenuationColor;\n";
1505 fragmentShader <<
" qt_attenuationDistance = qt_customAttenuationDistance;\n";
1507 fragmentShader <<
" qt_transmissionFactor = qt_material_properties4.w;\n";
1508 maskVariableByVertexColorChannel(
"qt_transmissionFactor", QSSGRenderDefaultMaterial::TransmissionFactorMask );
1510 if (samplerState.hasImage(QSSGRenderableImage::Type::Transmission)) {
1511 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Transmission, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1512 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::TransmissionChannel];
1513 fragmentShader <<
" qt_transmissionFactor *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Transmission) <<
", "
1514 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Transmission) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1517 fragmentShader <<
" qt_thicknessFactor = qt_material_thickness;\n";
1518 maskVariableByVertexColorChannel(
"qt_thicknessFactor", QSSGRenderDefaultMaterial::ThicknessFactorMask );
1519 fragmentShader <<
" qt_attenuationColor = qt_material_attenuation.xyz;\n";
1520 fragmentShader <<
" qt_attenuationDistance = qt_material_attenuation.w;\n";
1522 if (samplerState.hasImage(QSSGRenderableImage::Type::Thickness)) {
1523 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Thickness, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1524 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::ThicknessChannel];
1525 fragmentShader <<
" qt_thicknessFactor *= texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Thickness) <<
", "
1526 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Thickness) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1531 fragmentShader <<
" vec3 qt_f0 = vec3(1.0);\n";
1532 fragmentShader <<
" vec3 qt_f90 = vec3(1.0);\n";
1536 fragmentShader.addInclude(
"principledMaterialFresnel.glsllib");
1538 fragmentShader <<
" qt_f0 = qt_F0_ior(qt_iOR, qt_metalnessAmount, qt_diffuseColor.rgb);\n";
1540 fragmentShader <<
" const float qt_reflectance = max(max(qt_specularTint.r, qt_specularTint.g), qt_specularTint.b);\n";
1541 fragmentShader <<
" qt_f0 = qt_specularTint;\n";
1542 fragmentShader <<
" qt_specularTint = vec3(1.0);\n";
1543 fragmentShader <<
" qt_f90 = vec3(clamp(qt_reflectance * 50.0, 0.0, 1.0));\n";
1544 fragmentShader <<
" qt_diffuseColor.rgb *= (1 - qt_reflectance);\n";
1548 fragmentShader.append(
" vec3 vNormalWsDdx = dFdx(qt_world_normal.xyz);\n");
1549 fragmentShader.append(
" vec3 vNormalWsDdy = dFdy(qt_world_normal.xyz);\n");
1550 fragmentShader.append(
" float flGeometricRoughnessFactor = pow(clamp(max(dot(vNormalWsDdx, vNormalWsDdx), dot(vNormalWsDdy, vNormalWsDdy)), 0.0, 1.0), 0.333);\n");
1551 fragmentShader.append(
" qt_roughnessAmount = max(flGeometricRoughnessFactor, qt_roughnessAmount);\n");
1555 fragmentShader <<
" float qt_fresnelPower = qt_customFresnelPower;\n";
1557 fragmentShader <<
" float qt_fresnelPower = qt_material_properties2.x;\n";
1560 fragmentShader <<
" vec3 qt_principledMaterialFresnelValue = qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1562 if (hasCustomFrag) {
1563 fragmentShader <<
" float qt_fresnelScale = qt_customFresnelScale;\n";
1564 fragmentShader <<
" float qt_fresnelBias = qt_customFresnelBias;\n";
1566 fragmentShader <<
" float qt_fresnelScale = qt_material_properties5.x;\n";
1567 fragmentShader <<
" float qt_fresnelBias = qt_material_properties5.y;\n";
1569 fragmentShader <<
" qt_principledMaterialFresnelValue = clamp(vec3(qt_fresnelBias) + "
1570 <<
"qt_fresnelScale * qt_principledMaterialFresnelValue, 0.0, 1.0);\n";
1572 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnelValue;\n";
1576 fragmentShader <<
" qt_specularTint = mix(vec3(1.0), qt_specularTint, 1.0 - qt_metalnessAmount);\n";
1579 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1584 fragmentShader.addUniform(
"qt_lightAndShadowCounts",
"vec4");
1585 fragmentShader.addFunction(
"processPunctualLighting");
1586 fragmentShader <<
" qt_processPunctualLighting(global_diffuse_light.rgb,\n"
1587 <<
" global_specular_light.rgb,\n"
1588 <<
" qt_diffuseColor.rgb,\n"
1589 <<
" qt_varWorldPos,\n"
1590 <<
" qt_world_normal.xyz,\n"
1591 <<
" qt_view_vector,\n"
1592 <<
"#if QSSG_ENABLE_SPECULAR\n"
1593 <<
" qt_specularAmount,\n"
1594 <<
" qt_specularTint,\n"
1595 <<
"#endif // QSSG_ENABLE_SPECULAR\n"
1596 <<
" qt_roughnessAmount,\n"
1597 <<
" qt_metalnessAmount,\n"
1598 <<
"#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"
1599 <<
" qt_customBaseColor,\n"
1600 <<
"#endif // QSSG_CUSTOM_MATERIAL_*\n"
1601 <<
"#if QSSG_CUSTOM_MATERIAL_SPECULAR_PROCESSOR\n"
1602 <<
" qt_customSpecularAmount,\n"
1603 <<
"#endif // QSSG_CUSTOM_MATERIAL_SPECULAR_PROCESSOR\n"
1604 <<
"#if QSSG_CUSTOM_MATERIAL_SHARED_VARIABLES\n"
1605 <<
" qt_customShared,\n"
1606 <<
"#endif // QSSG_CUSTOM_MATERIAL_SHARED_VARIABLES\n"
1607 <<
"#if QSSG_ENABLE_CLEARCOAT\n"
1608 <<
" qt_global_clearcoat,\n"
1609 <<
" qt_clearcoatNormal,\n"
1610 <<
" qt_clearcoatRoughness,\n"
1611 <<
" qt_clearcoatF0,\n"
1612 <<
" qt_clearcoatF90,\n"
1613 <<
"#endif // QSSG_ENABLE_CLEARCOAT\n"
1614 <<
"#if QSSG_ENABLE_TRANSMISSION\n"
1615 <<
" qt_global_transmission,\n"
1616 <<
" qt_thicknessFactor,\n"
1618 <<
" qt_transmissionFactor,\n"
1619 <<
" qt_attenuationColor,\n"
1620 <<
" qt_attenuationDistance,\n"
1621 <<
"#endif // QSSG_ENABLE_TRANSMISSION\n"
1629 fragmentShader <<
" global_diffuse_light = vec4(global_diffuse_light.rgb * qt_aoFactor, qt_objectOpacity * qt_diffuseColor.a);\n";
1632 vertexShader.generateWorldNormal(inKey);
1633 fragmentShader.addInclude(
"sampleReflectionProbe.glsllib");
1637 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1639 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1644 fragmentShader <<
" global_specular_light += qt_specularTint * qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1646 fragmentShader <<
" global_specular_light += qt_specularAmount * qt_specularTint * qt_sampleGlossyReflection(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1651 fragmentShader <<
" qt_global_clearcoat += qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1654 vertexShader.generateWorldNormal(inKey);
1655 fragmentShader.addInclude(
"sampleProbe.glsllib");
1656 if (hasCustomIblProbe) {
1658 fragmentShader <<
" vec3 qt_iblDiffuse = vec3(0.0);\n";
1659 fragmentShader <<
" vec3 qt_iblSpecular = vec3(0.0);\n";
1660 fragmentShader <<
" qt_iblProbeProcessor(qt_iblDiffuse, qt_iblSpecular, qt_customBaseColor, qt_aoFactor, qt_specularFactor, qt_roughnessAmount, qt_world_normal, qt_view_vector";
1662 fragmentShader <<
", qt_lightProbeOrientation";
1664 fragmentShader <<
", mat3(1.0)";
1666 fragmentShader <<
", qt_customShared);\n";
1668 fragmentShader <<
");\n";
1672 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1674 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1679 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularTint * qt_sampleGlossyPrincipled(qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1681 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularAmount * qt_specularTint * qt_sampleGlossy(qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1686 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyPrincipled(qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1689 fragmentShader <<
" global_diffuse_light.rgb += qt_iblDiffuse * qt_aoFactor;\n";
1691 fragmentShader <<
" global_specular_light += qt_iblSpecular * qt_aoFactor;\n";
1693 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat * qt_aoFactor;\n";
1694 }
else if (hasCustomIblProbe) {
1696 fragmentShader.addUniform(
"qt_lightProbe",
"samplerCube");
1697 fragmentShader.addUniform(
"qt_lightProbeProperties",
"vec4");
1702 fragmentShader <<
" qt_global_transmission += qt_transmissionFactor * qt_getIBLVolumeRefraction(qt_world_normal, qt_view_vector, qt_roughnessAmount, "
1703 "qt_diffuseColor.rgb, qt_specularAmount, qt_varWorldPos, qt_iOR, qt_thicknessFactor, qt_attenuationColor, qt_attenuationDistance);\n";
1708 if (samplerState.hasImage(QSSGRenderableImage::Type::Specular) || samplerState.hasImage(QSSGRenderableImage::Type::Emissive)) {
1709 addLocalVariable(fragmentShader,
"qt_texture_color",
"vec4");
1711 if (samplerState.hasImage(QSSGRenderableImage::Type::Specular)) {
1712 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Specular, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1713 fragmentShader <<
" qt_texture_color = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Specular) <<
", "
1714 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Specular) <<
");\n";
1715 fragmentShader.addInclude(
"tonemapping.glsllib");
1716 fragmentShader <<
" global_specular_light += qt_sRGBToLinear(qt_texture_color.rgb) * qt_specularTint;\n";
1717 fragmentShader <<
" global_diffuse_light.a *= qt_texture_color.a;\n";
1720 if (samplerState.hasImage(QSSGRenderableImage::Type::Emissive)) {
1721 samplerState.generateImageUVAndSampler(QSSGRenderableImage::Type::Emissive, vertexShader, fragmentShader, inKey, passRequirmentState
.hasParallaxMapping);
1722 fragmentShader <<
" qt_texture_color = texture2D(" << samplerState.samplerName(QSSGRenderableImage::Type::Emissive) <<
", "
1723 << samplerState.fragCoordsName(QSSGRenderableImage::Type::Emissive) <<
");\n";
1724 fragmentShader.addInclude(
"tonemapping.glsllib");
1725 if (keyProps.m_emissiveSingleChannelEnabled.getValue(inKey)) {
1726 const auto &channelProps = keyProps.m_textureChannels[QSSGShaderDefaultMaterialKeyProperties::EmissiveChannel];
1727 fragmentShader <<
" qt_global_emission *= qt_sRGBToLinear(vec3(qt_texture_color" <<
1728 channelStr(channelProps, inKey) <<
"));\n";
1730 fragmentShader <<
" qt_global_emission *= qt_sRGBToLinear(qt_texture_color.rgb);\n";
1736 fragmentShader <<
" global_diffuse_light.rgb = mix(global_diffuse_light.rgb, qt_global_transmission, qt_transmissionFactor);\n";
1739 fragmentShader <<
" global_diffuse_light.rgb *= 1.0 - qt_metalnessAmount;\n";
1742 if (passRequirmentState
.hasFog) {
1743 fragmentShader.addInclude(
"fog.glsllib");
1744 fragmentShader <<
" calculateFog(qt_global_emission, global_specular_light, global_diffuse_light.rgb);\n";
1747 fragmentShader <<
" vec4 qt_color_sum = vec4(global_diffuse_light.rgb + global_specular_light + qt_global_emission, global_diffuse_light.a);\n";
1750 fragmentShader.addInclude(
"bsdf.glsllib");
1752 fragmentShader <<
" float qt_clearcoatFresnelPower = qt_customClearcoatFresnelPower;\n";
1754 fragmentShader <<
" float qt_clearcoatFresnelPower = qt_material_clearcoat_fresnel_power;\n";
1755 fragmentShader <<
" vec3 qt_clearcoatFresnel = qt_schlick3(qt_clearcoatF0, qt_clearcoatF90, clamp(dot(qt_clearcoatNormal, qt_view_vector), 0.0, 1.0), qt_clearcoatFresnelPower);\n";
1757 if (hasCustomFrag) {
1758 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_customClearcoatFresnelScale;\n";
1759 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_customClearcoatFresnelBias;\n";
1761 fragmentShader <<
" float qt_clearcoatFresnelScale = qt_material_properties5.z;\n";
1762 fragmentShader <<
" float qt_clearcoatFresnelBias = qt_material_properties5.w;\n";
1764 fragmentShader <<
" qt_clearcoatFresnel = clamp(vec3(qt_clearcoatFresnelBias) + qt_clearcoatFresnelScale * qt_clearcoatFresnel, 0.0, 1.0);\n";
1766 fragmentShader <<
" qt_global_clearcoat = qt_global_clearcoat * qt_clearcoatAmount;\n";
1767 fragmentShader <<
" qt_color_sum.rgb = qt_color_sum.rgb * (1.0 - qt_clearcoatAmount * qt_clearcoatFresnel) + qt_global_clearcoat;\n";
1770 if (hasCustomFrag && hasCustomFunction(QByteArrayLiteral(
"qt_customPostProcessor"))) {
1772 fragmentShader <<
" qt_customPostProcessor(qt_color_sum, global_diffuse_light, global_specular_light, qt_global_emission, qt_texCoord0, qt_texCoord1";
1774 fragmentShader <<
", qt_customShared);\n";
1776 fragmentShader <<
");\n";
1788 fragmentShader.append(
" vec4 qt_color_sum = vec4(qt_diffuseColor.rgb, qt_diffuseColor.a * qt_objectOpacity);");
1790 if (passRequirmentState.oitMethod == QSSGRenderLayer::OITMethod::WeightedBlended) {
1791 fragmentShader.addInclude(
"oitweightedblended.glsllib");
1792 fragmentShader.addInclude(
"tonemapping.glsllib");
1793 fragmentShader.addUniform(
"qt_cameraPosition",
"vec3");
1794 fragmentShader.addUniform(
"qt_cameraProperties",
"vec2");
1795 fragmentShader.append(
" float z = abs(gl_FragCoord.z);");
1796 fragmentShader.append(
" qt_color_sum.rgb = qt_tonemap(qt_color_sum.rgb) * qt_color_sum.a;");
1797 fragmentShader.append(
" fragOutput = qt_color_sum * qt_transparencyWeight(z, qt_color_sum.a, qt_cameraProperties.y);");
1798 fragmentShader.append(
" revealageOutput = vec4(qt_color_sum.a);");
1799 }
else if (passRequirmentState.oitMethod == QSSGRenderLayer::OITMethod::LinkedList) {
1800 fragmentShader.addInclude(
"tonemapping.glsllib");
1801 fragmentShader.addUniform(
"qt_listNodeCount",
"uint");
1802 fragmentShader.addUniform(
"qt_ABufImageWidth",
"uint");
1803 fragmentShader.addUniform(
"qt_viewSize",
"ivec2");
1805 fragmentShader.addDefinition(
"QSSG_MULTISAMPLE",
"1");
1806#ifdef QSSG_OIT_USE_BUFFERS
1807 QSSGShaderResourceMergeContext::setAdditionalBufferAmount(3);
1808 fragmentShader.addUniform(
"qt_samples",
"uint");
1809 fragmentShader.addInclude(
"oitlinkedlist_buf.glsllib");
1811 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, qt_viewIndex, qt_samples);");
1813 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, 0, qt_samples);");
1815 fragmentShader.addInclude(
"oitlinkedlist.glsllib");
1817 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, qt_viewIndex);");
1819 fragmentShader.append(
" fragOutput = qt_oitLinkedList(qt_tonemap(qt_color_sum), qt_listNodeCount, qt_ABufImageWidth, qt_viewSize, 0);");
1823 fragmentShader.addInclude(
"tonemapping.glsllib");
1824 fragmentShader.append(
" fragOutput = vec4(qt_tonemap(qt_color_sum));");
1828 fragmentShader <<
" vec4 fragOutput = vec4(0.0);\n";
1831 Q_ASSERT(viewCount == 1);
1832 fragmentShader <<
" // directional shadow pass\n"
1833 <<
" float qt_shadowDepth = (qt_varDepth + qt_shadowDepthAdjust.x) * qt_shadowDepthAdjust.y;\n"
1834 <<
" fragOutput = vec4(qt_shadowDepth);\n";
1837 Q_ASSERT(viewCount == 1);
1838 fragmentShader.addUniform(
"qt_cameraPosition",
"vec3");
1839 fragmentShader.addUniform(
"qt_cameraProperties",
"vec2");
1840 fragmentShader <<
" // omnidirectional shadow pass\n"
1841 <<
" vec3 qt_shadowCamPos = vec3(qt_cameraPosition.x, qt_cameraPosition.y, qt_cameraPosition.z);\n"
1842 <<
" float qt_shadowDist = length(qt_varShadowWorldPos - qt_shadowCamPos);\n"
1843 <<
" qt_shadowDist = (qt_shadowDist - qt_cameraProperties.x) / (qt_cameraProperties.y - qt_cameraProperties.x);\n"
1844 <<
" fragOutput = vec4(qt_shadowDist, qt_shadowDist, qt_shadowDist, 1.0);\n";
1848 fragmentShader.append(
" fragOutput = vec4(qt_world_normal, qt_roughnessAmount);\n");
1851 fragmentShader.append(
" vec3 debugOutput = vec3(0.0);\n");
1852 switch (passRequirmentState.debugMode) {
1853 case QSSGRenderLayer::MaterialDebugMode::BaseColor:
1854 fragmentShader.addInclude(
"tonemapping.glsllib");
1855 fragmentShader.append(
" debugOutput += qt_tonemap(qt_diffuseColor.rgb);\n");
1857 case QSSGRenderLayer::MaterialDebugMode::Roughness:
1858 fragmentShader.append(
" debugOutput += vec3(qt_roughnessAmount);\n");
1860 case QSSGRenderLayer::MaterialDebugMode::Metalness:
1861 fragmentShader.append(
" debugOutput += vec3(qt_metalnessAmount);\n");
1863 case QSSGRenderLayer::MaterialDebugMode::Diffuse:
1864 fragmentShader.addInclude(
"tonemapping.glsllib");
1865 fragmentShader.append(
" debugOutput += qt_tonemap(global_diffuse_light.rgb);\n");
1867 case QSSGRenderLayer::MaterialDebugMode::Specular:
1868 fragmentShader.addInclude(
"tonemapping.glsllib");
1869 fragmentShader.append(
" debugOutput += qt_tonemap(global_specular_light);\n");
1871 case QSSGRenderLayer::MaterialDebugMode::ShadowOcclusion:
1874 fragmentShader.addFunction(
"debugShadowOcclusion");
1875 vertexShader.generateWorldPosition(inKey);
1876 fragmentShader.append(
" debugOutput += vec3(qt_debugShadowOcclusion());\n");
1878 case QSSGRenderLayer::MaterialDebugMode::Emission:
1879 fragmentShader.addInclude(
"tonemapping.glsllib");
1880 fragmentShader.append(
" debugOutput += qt_tonemap(qt_global_emission);\n");
1882 case QSSGRenderLayer::MaterialDebugMode::AmbientOcclusion:
1883 fragmentShader.append(
" debugOutput += vec3(qt_aoFactor);\n");
1885 case QSSGRenderLayer::MaterialDebugMode::Normal:
1886 fragmentShader.append(
" debugOutput += qt_world_normal * 0.5 + 0.5;\n");
1888 case QSSGRenderLayer::MaterialDebugMode::Tangent:
1889 fragmentShader.append(
" debugOutput += qt_tangent * 0.5 + 0.5;\n");
1891 case QSSGRenderLayer::MaterialDebugMode::Binormal:
1892 fragmentShader.append(
" debugOutput += qt_binormal * 0.5 + 0.5;\n");
1894 case QSSGRenderLayer::MaterialDebugMode::F0:
1896 fragmentShader.append(
" debugOutput += qt_f0;");
1898 case QSSGRenderLayer::MaterialDebugMode::None:
1902 fragmentShader.append(
" fragOutput = vec4(debugOutput, 1.0);\n");
1905 if (shaderAugmentation.hasUserAugmentation())
1906 fragmentShader <<
" " << shaderAugmentation.body <<
";\n";
1984void QSSGMaterialShaderGenerator::setRhiMaterialProperties(
const QSSGRenderContextInterface &renderContext,
1985 QSSGRhiShaderPipeline &shaders,
1987 QSSGRhiGraphicsPipelineState *inPipelineState,
1988 const QSSGRenderGraphObject &inMaterial,
1989 const QSSGShaderDefaultMaterialKey &inKey,
1990 const QSSGShaderDefaultMaterialKeyProperties &inProperties,
1991 const QSSGRenderCameraList &inCameras,
1992 const QSSGRenderMvpArray &inModelViewProjections,
1993 const QMatrix3x3 &inNormalMatrix,
1994 const QMatrix4x4 &inGlobalTransform,
1995 const QMatrix4x4 &clipSpaceCorrMatrix,
1996 const QMatrix4x4 &localInstanceTransform,
1997 const QMatrix4x4 &globalInstanceTransform,
1998 const QSSGDataView<
float> &inMorphWeights,
1999 QSSGRenderableImage *inFirstImage,
2001 const QSSGLayerRenderData &inRenderProperties,
2002 const QSSGShaderLightListView &inLights,
2003 const QSSGShaderReflectionProbe &reflectionProbe,
2004 bool receivesShadows,
2005 bool receivesReflections,
2006 const QVector2D *shadowDepthAdjust,
2007 QRhiTexture *lightmapTexture)
2009 QSSGShaderMaterialAdapter *materialAdapter = getMaterialAdapter(inMaterial);
2010 QSSGRhiShaderPipeline::CommonUniformIndices &cui = shaders.commonUniformIndices;
2012 materialAdapter->setCustomPropertyUniforms(ubufData, shaders, renderContext);
2014 const QVector2D camProperties(inCameras[0]->clipPlanes);
2015 shaders.setUniform(ubufData,
"qt_cameraProperties", &camProperties, 2 *
sizeof(
float), &cui.cameraPropertiesIdx);
2017 const int viewCount = inCameras.count();
2020 QMatrix4x4 camGlobalTransforms[2] { QMatrix4x4{Qt::Uninitialized}, QMatrix4x4{Qt::Uninitialized} };
2021 if (viewCount < 2) {
2022 camGlobalTransforms[0] = inRenderProperties.getGlobalTransform(*inCameras[0]);
2024 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex)
2025 camGlobalTransforms[viewIndex] = inRenderProperties.getGlobalTransform(*inCameras[viewIndex]);
2028 if (viewCount < 2) {
2029 const QMatrix4x4 &camGlobalTransform = camGlobalTransforms[0];
2030 const QVector3D camGlobalPos = QSSGRenderNode::getGlobalPos(camGlobalTransform);
2031 shaders.setUniform(ubufData,
"qt_cameraPosition", &camGlobalPos, 3 *
sizeof(
float), &cui.cameraPositionIdx);
2032 const QVector3D camDirection = QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2033 ? inRenderProperties.renderedCameraData.value()[0].direction
2034 : QVector3D{ 0.0f, 0.0f, -1.0f };
2035 shaders.setUniform(ubufData,
"qt_cameraDirection", &camDirection, 3 *
sizeof(
float), &cui.cameraDirectionIdx);
2037 QVarLengthArray<QVector3D, 2> camGlobalPos(viewCount);
2038 QVarLengthArray<QVector3D> camDirection(viewCount);
2039 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex) {
2040 const QMatrix4x4 &camGlobalTransform = camGlobalTransforms[viewIndex];
2041 camGlobalPos[viewIndex] = QSSGRenderNode::getGlobalPos(camGlobalTransform);
2042 camDirection[viewIndex] = QSSG_GUARD(inRenderProperties.renderedCameraData.has_value())
2043 ? inRenderProperties.renderedCameraData.value()[viewIndex].direction
2044 : QVector3D{ 0.0f, 0.0f, -1.0f };
2046 shaders.setUniformArray(ubufData,
"qt_cameraPosition", camGlobalPos.constData(), viewCount, QSSGRenderShaderValue::Vec3, &cui.cameraPositionIdx);
2047 shaders.setUniformArray(ubufData,
"qt_cameraDirection", camDirection.constData(), viewCount, QSSGRenderShaderValue::Vec3, &cui.cameraDirectionIdx);
2050 const auto globalRenderData = QSSGLayerRenderData::globalRenderProperties(renderContext);
2053 bool usesProjectionMatrix =
false;
2054 bool usesInvProjectionMatrix =
false;
2055 bool usesViewProjectionMatrix =
false;
2056 bool usesModelViewProjectionMatrix =
false;
2057 bool usesNormalMatrix =
false;
2058 bool usesParentMatrix =
false;
2060 if (inMaterial.type == QSSGRenderGraphObject::Type::CustomMaterial) {
2061 const auto *customMaterial =
static_cast<
const QSSGRenderCustomMaterial *>(&inMaterial);
2062 usesProjectionMatrix = customMaterial->m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::ProjectionMatrix);
2063 usesInvProjectionMatrix = customMaterial->m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::InverseProjectionMatrix);
2065 usesViewProjectionMatrix =
true;
2068 const bool usesInstancing = inProperties.m_usesInstancing.getValue(inKey);
2069 if (usesInstancing) {
2071 usesViewProjectionMatrix =
true;
2072 usesParentMatrix =
true;
2074 usesModelViewProjectionMatrix =
true;
2075 usesNormalMatrix =
true;
2078 if (materialAdapter->isTransmissionEnabled())
2079 usesViewProjectionMatrix =
true;
2082 if (usesProjectionMatrix || usesInvProjectionMatrix) {
2083 if (viewCount < 2) {
2084 const QMatrix4x4 projection = clipSpaceCorrMatrix * inCameras[0]->projection;
2085 if (usesProjectionMatrix)
2086 shaders.setUniform(ubufData,
"qt_projectionMatrix", projection.constData(), 16 *
sizeof(
float), &cui.projectionMatrixIdx);
2087 if (usesInvProjectionMatrix)
2088 shaders.setUniform(ubufData,
"qt_inverseProjectionMatrix", projection.inverted().constData(), 16 *
sizeof (
float), &cui.inverseProjectionMatrixIdx);
2090 QVarLengthArray<QMatrix4x4, 2> projections(viewCount);
2091 QVarLengthArray<QMatrix4x4, 2> invertedProjections(viewCount);
2092 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex) {
2093 projections[viewIndex] = clipSpaceCorrMatrix * inCameras[viewIndex]->projection;
2094 if (usesInvProjectionMatrix)
2095 invertedProjections[viewIndex] = projections[viewIndex].inverted();
2097 if (usesProjectionMatrix)
2098 shaders.setUniformArray(ubufData,
"qt_projectionMatrix", projections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.projectionMatrixIdx);
2099 if (usesInvProjectionMatrix)
2100 shaders.setUniformArray(ubufData,
"qt_inverseProjectionMatrix", invertedProjections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.inverseProjectionMatrixIdx);
2104 if (viewCount < 2) {
2105 const QMatrix4x4 viewMatrix = camGlobalTransforms[0].inverted();
2106 shaders.setUniform(ubufData,
"qt_viewMatrix", viewMatrix.constData(), 16 *
sizeof(
float), &cui.viewMatrixIdx);
2108 QVarLengthArray<QMatrix4x4, 2> viewMatrices(viewCount);
2109 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex)
2110 viewMatrices[viewIndex] = camGlobalTransforms[viewIndex].inverted();
2111 shaders.setUniformArray(ubufData,
"qt_viewMatrix", viewMatrices.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.viewMatrixIdx);
2114 if (usesViewProjectionMatrix) {
2115 if (viewCount < 2) {
2116 const QMatrix4x4 &camGlobalTransform = camGlobalTransforms[0];
2117 QMatrix4x4 viewProj(Qt::Uninitialized);
2118 inCameras[0]->calculateViewProjectionMatrix(camGlobalTransform, viewProj);
2119 viewProj = clipSpaceCorrMatrix * viewProj;
2120 shaders.setUniform(ubufData,
"qt_viewProjectionMatrix", viewProj.constData(), 16 *
sizeof(
float), &cui.viewProjectionMatrixIdx);
2122 QVarLengthArray<QMatrix4x4, 2> viewProjections(viewCount);
2123 for (size_t viewIndex = 0; viewIndex != std::size(camGlobalTransforms); ++viewIndex) {
2124 const auto &camGlobalTransform = camGlobalTransforms[viewIndex];
2125 inCameras[viewIndex]->calculateViewProjectionMatrix(camGlobalTransform, viewProjections[viewIndex]);
2126 viewProjections[viewIndex] = clipSpaceCorrMatrix * viewProjections[viewIndex];
2128 shaders.setUniformArray(ubufData,
"qt_viewProjectionMatrix", viewProjections.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.viewProjectionMatrixIdx);
2134 shaders.setUniform(ubufData,
"qt_modelMatrix", localInstanceTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2136 shaders.setUniform(ubufData,
"qt_modelMatrix", inGlobalTransform.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
2138 if (usesModelViewProjectionMatrix) {
2139 if (viewCount < 2) {
2140 QMatrix4x4 mvp { clipSpaceCorrMatrix };
2141 mvp *= inModelViewProjections[0];
2142 shaders.setUniform(ubufData,
"qt_modelViewProjection", mvp.constData(), 16 *
sizeof(
float), &cui.modelViewProjectionIdx);
2144 QVarLengthArray<QMatrix4x4, 2> mvps(viewCount);
2145 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
2146 mvps[viewIndex] = clipSpaceCorrMatrix * inModelViewProjections[viewIndex];
2147 shaders.setUniformArray(ubufData,
"qt_modelViewProjection", mvps.constData(), viewCount, QSSGRenderShaderValue::Matrix4x4, &cui.modelViewProjectionIdx);
2150 if (usesNormalMatrix)
2151 shaders.setUniform(ubufData,
"qt_normalMatrix", inNormalMatrix.constData(), 12 *
sizeof(
float), &cui.normalMatrixIdx,
2152 QSSGRhiShaderPipeline::UniformFlag::Mat3);
2153 if (usesParentMatrix)
2154 shaders.setUniform(ubufData,
"qt_parentMatrix", globalInstanceTransform.constData(), 16 *
sizeof(
float));
2157 const qsizetype morphSize = inProperties.m_targetCount.getValue(inKey);
2158 if (morphSize > 0) {
2159 if (inMorphWeights.mSize >= morphSize) {
2160 shaders.setUniformArray(ubufData,
"qt_morphWeights", inMorphWeights.mData, morphSize,
2161 QSSGRenderShaderValue::Float, &cui.morphWeightsIdx);
2163 const QList<
float> zeroWeights(morphSize - inMorphWeights.mSize, 0.0f);
2164 QList<
float> newWeights(inMorphWeights.mData, inMorphWeights.mData + inMorphWeights.mSize);
2165 newWeights.append(zeroWeights);
2166 shaders.setUniformArray(ubufData,
"qt_morphWeights", newWeights.constData(), morphSize,
2167 QSSGRenderShaderValue::Float, &cui.morphWeightsIdx);
2171 QVector3D theLightAmbientTotal;
2172 quint32 lightCount = 0;
2173 quint32 directionalLightCount = 0;
2174 quint32 shadowCount = 0;
2175 quint32 directionalShadowCount = 0;
2176 QSSGShaderLightsUniformData &lightsUniformData(shaders.lightsUniformData());
2177 QSSGShaderDirectionalLightsUniformData &directionalLightsUniformData(shaders.directionalLightsUniformData());
2179 for (quint32 lightIdx = 0, lightEnd = inLights.size();
2180 lightIdx < lightEnd && lightIdx < QSSG_MAX_NUM_LIGHTS; ++lightIdx)
2182 QSSGRenderLight *theLight(inLights[lightIdx].light);
2185 const bool lightShadows = inLights[lightIdx].shadows;
2186 const float brightness = theLight->m_brightness;
2187 quint32 lightmapState = 0;
2188 if (theLight->m_bakingEnabled) {
2189 if (theLight->m_fullyBaked) {
2198 const QVector3D diffuseColor(theLight->m_diffuseColor.x() * brightness,
2199 theLight->m_diffuseColor.y() * brightness,
2200 theLight->m_diffuseColor.z() * brightness);
2201 const QVector3D specularColor(theLight->m_specularColor.x() * brightness,
2202 theLight->m_specularColor.y() * brightness,
2203 theLight->m_specularColor.z() * brightness);
2204 const QVector3D direction(inLights[lightIdx].direction);
2207 if (theLight->type == QSSGRenderGraphObject::Type::DirectionalLight) {
2209 QSSGShaderDirectionalLightData &lightData(directionalLightsUniformData.directionalLightData[directionalLightCount]);
2210 lightData.direction[0] = direction.x();
2211 lightData.direction[1] = direction.y();
2212 lightData.direction[2] = direction.z();
2213 lightData.diffuseColor[0] = diffuseColor.x();
2214 lightData.diffuseColor[1] = diffuseColor.y();
2215 lightData.diffuseColor[2] = diffuseColor.z();
2216 lightData.specularColor[0] = specularColor.x();
2217 lightData.specularColor[1] = specularColor.y();
2218 lightData.specularColor[2] = specularColor.z();
2219 lightData.lightmapState = lightmapState;
2220 if (lightShadows && receivesShadows) {
2221 lightData.enableShadows = 1.0f;
2222 QSSGShadowMapEntry *pEntry = inRenderProperties.getShadowMapManager()->shadowMapEntry(lightIdx);
2225 const quint32 layerCount = pEntry->m_csmNumSplits + 1;
2227 for (quint32 i = 0; i < layerCount; ++i)
2228 memcpy(lightData.matrices[i], pEntry->m_fixedScaleBiasMatrix[i].constData(), 16 *
sizeof(
float));
2230 lightData.shadowBias = theLight->m_shadowBias;
2232 const bool noCascades = !(pEntry->m_csmActive[0] || pEntry->m_csmActive[1] || pEntry->m_csmActive[2] || pEntry->m_csmActive[3]);
2233 if (theLight->type == QSSGRenderLight::Type::DirectionalLight && noCascades)
2234 lightData.enableShadows = 0.0f;
2235 lightData.shadowFactor = theLight->m_shadowFactor;
2236 lightData.shadowMapFar = theLight->m_shadowMapFar;
2237 lightData.shadowPcfSamples = softShadowQualityToInt(theLight->m_softShadowQuality);
2238 lightData.shadowPcfFactor = theLight->m_pcfFactor;
2240 for (quint32 i = 0; i < layerCount; ++i) {
2241 const auto &atlasInfo = pEntry->m_atlasInfo[i];
2242 lightData.atlasLocations[i][0] = atlasInfo.uOffset;
2243 lightData.atlasLocations[i][1] = atlasInfo.vOffset;
2244 lightData.atlasLocations[i][2] = atlasInfo.uvScale;
2245 lightData.atlasLocations[i][3] = atlasInfo.layerIndex;
2248 lightData.csmNumSplits = pEntry->m_csmNumSplits;
2249 memcpy(lightData.csmSplits, pEntry->m_csmSplits, 4 *
sizeof(
float));
2250 memcpy(lightData.csmActive, pEntry->m_csmActive, 4 *
sizeof(
float));
2251 lightData.csmBlendRatio = theLight->m_csmBlendRatio;
2252 for (quint32 i = 0; i < layerCount; ++i)
2253 memcpy(lightData.dimensionsInverted[i], &pEntry->m_dimensionsInverted[i], 4 *
sizeof(
float));
2255 directionalShadowCount++;
2257 lightData.enableShadows = 0.0f;
2259 directionalLightCount++;
2262 QSSGShaderLightData &lightData(lightsUniformData.lightData[lightCount]);
2263 const auto gt = inRenderProperties.getGlobalTransform(*theLight);
2264 const QVector3D globalPos = QSSGRenderNode::getGlobalPos(gt);
2265 lightData.position[0] = globalPos.x();
2266 lightData.position[1] = globalPos.y();
2267 lightData.position[2] = globalPos.z();
2268 lightData.constantAttenuation = QSSGUtils::aux::translateConstantAttenuation(theLight->m_constantFade);
2269 lightData.linearAttenuation = QSSGUtils::aux::translateLinearAttenuation(theLight->m_linearFade);
2270 lightData.quadraticAttenuation = QSSGUtils::aux::translateQuadraticAttenuation(theLight->m_quadraticFade);
2271 lightData.coneAngle = 360.0f;
2272 lightData.direction[0] = direction.x();
2273 lightData.direction[1] = direction.y();
2274 lightData.direction[2] = direction.z();
2275 lightData.diffuseColor[0] = diffuseColor.x();
2276 lightData.diffuseColor[1] = diffuseColor.y();
2277 lightData.diffuseColor[2] = diffuseColor.z();
2278 lightData.specularColor[0] = specularColor.x();
2279 lightData.specularColor[1] = specularColor.y();
2280 lightData.specularColor[2] = specularColor.z();
2281 lightData.lightmapState = lightmapState;
2282 if (theLight->type == QSSGRenderLight::Type::SpotLight) {
2286 const float coneAngle = theLight->m_coneAngle;
2287 const float innerConeAngle = (theLight->m_innerConeAngle > coneAngle) ? coneAngle : theLight->m_innerConeAngle;
2288 lightData.coneAngle = qCos(qDegreesToRadians(coneAngle));
2289 lightData.innerConeAngle = qCos(qDegreesToRadians(innerConeAngle));
2292 if (lightShadows && receivesShadows) {
2293 QSSGShadowMapEntry *pEntry = inRenderProperties.getShadowMapManager()->shadowMapEntry(lightIdx);
2295 lightData.enableShadows = 1.0f;
2296 lightData.shadowPcfFactor = theLight->m_pcfFactor;
2297 lightData.shadowPcfSamples = softShadowQualityToInt(theLight->m_softShadowQuality);
2298 lightData.shadowFactor = theLight->m_shadowFactor;
2299 lightData.shadowBias = theLight->m_shadowBias;
2300 lightData.shadowClipNear = 1.0f;
2301 lightData.shadowMapFar = pEntry->m_shadowMapFar;
2302 lightData.shadowTextureSize = pEntry->m_atlasInfo[0].uvScale;
2304 if (theLight->type == QSSGRenderLight::Type::SpotLight) {
2306 static const QMatrix4x4 bias = {
2310 0.0, 0.0, 0.0, 1.0 };
2311 const QMatrix4x4 m = bias * pEntry->m_lightViewProjection[0];
2312 memcpy(lightData.shadowMatrix, m.constData(), 16 *
sizeof(
float));
2313 lightData.shadowAtlasUV0[0] = pEntry->m_atlasInfo[0].uOffset;
2314 lightData.shadowAtlasUV0[1] = pEntry->m_atlasInfo[0].vOffset;
2315 lightData.shadowAtlasLayer0 = pEntry->m_atlasInfo[0].layerIndex;
2318 Q_ASSERT(theLight->type == QSSGRenderLight::Type::PointLight);
2319 memcpy(lightData.shadowMatrix, pEntry->m_lightView.constData(), 16 *
sizeof(
float));
2320 lightData.shadowAtlasUV0[0] = pEntry->m_atlasInfo[0].uOffset;
2321 lightData.shadowAtlasUV0[1] = pEntry->m_atlasInfo[0].vOffset;
2322 lightData.shadowAtlasLayer0 = pEntry->m_atlasInfo[0].layerIndex;
2323 lightData.shadowAtlasUV1[0] = pEntry->m_atlasInfo[1].uOffset;
2324 lightData.shadowAtlasUV1[1] = pEntry->m_atlasInfo[1].vOffset;
2325 lightData.shadowAtlasLayer1 = pEntry->m_atlasInfo[1].layerIndex;
2330 lightData.enableShadows = 0.0f;
2336 theLightAmbientTotal += theLight->m_ambientColor;
2340 if (shadowCount > 0 || directionalShadowCount > 0) {
2341 shaders.setShadowMapAtlasTexture(inRenderProperties.getShadowMapManager()->shadowMapAtlasTexture());
2342 shaders.setShadowMapBlueNoiseTexture(inRenderProperties.getShadowMapManager()->shadowMapBlueNoiseTexture());
2344 shaders.setShadowMapAtlasTexture(
nullptr);
2345 shaders.setShadowMapBlueNoiseTexture(
nullptr);
2348 const QSSGRhiRenderableTexture *depthTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::DepthTexture);
2349 const QSSGRhiRenderableTexture *normalTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::NormalTexture);
2350 const QSSGRhiRenderableTexture *ssaoTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::AoTexture);
2351 const QSSGRhiRenderableTexture *screenTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::ScreenTexture);
2352 const QSSGRhiRenderableTexture *motionVectorTexture = inRenderProperties.getRenderResult(QSSGRenderResult::Key::MotionVectorTexture);
2354 shaders.setDepthTexture(depthTexture->texture);
2355 shaders.setNormalTexture(normalTexture->texture);
2356 shaders.setSsaoTexture(ssaoTexture->texture);
2357 shaders.setScreenTexture(screenTexture->texture);
2358 shaders.setLightmapTexture(lightmapTexture);
2359 shaders.setMotionVectorTexture(motionVectorTexture->texture);
2361#ifdef QSSG_OIT_USE_BUFFERS
2362 shaders.setOITImages((QRhiTexture*)inRenderProperties.getOitRenderContextConst().aBuffer,
2363 (QRhiTexture*)inRenderProperties.getOitRenderContextConst().auxBuffer,
2364 (QRhiTexture*)inRenderProperties.getOitRenderContextConst().counterBuffer);
2365 if (inRenderProperties.getOitRenderContextConst().aBuffer) {
2367 const QSSGRhiRenderableTexture *abuf = inRenderProperties.getRenderResult(QSSGRenderResult::Key::ABufferImage);
2368 const QSSGRhiRenderableTexture *aux = inRenderProperties.getRenderResult(QSSGRenderResult::Key::AuxiliaryImage);
2369 const QSSGRhiRenderableTexture *counter = inRenderProperties.getRenderResult(QSSGRenderResult::Key::CounterImage);
2370 shaders.setOITImages(abuf->texture, aux->texture, counter->texture);
2371 if (abuf->texture) {
2373 int abufWidth = RenderHelpers::rhiCalculateABufferSize(inRenderProperties.layer.oitNodeCount);
2374 int listNodeCount = abufWidth * abufWidth;
2375 shaders.setUniform(ubufData,
"qt_ABufImageWidth", &abufWidth,
sizeof(
int), &cui.abufImageWidth);
2376 shaders.setUniform(ubufData,
"qt_listNodeCount", &listNodeCount,
sizeof(
int), &cui.listNodeCount);
2377 int viewSize[2] = {inRenderProperties.layerPrepResult.textureDimensions().width(), inRenderProperties.layerPrepResult.textureDimensions().height()};
2378 shaders.setUniform(ubufData,
"qt_viewSize", viewSize,
sizeof(
int) * 2, &cui.viewSize);
2379 int samples = inPipelineState->samples;
2380 shaders.setUniform(ubufData,
"qt_samples", &samples,
sizeof(
int), &cui.samples);
2383 const QSSGRenderLayer &layer = QSSGLayerRenderData::getCurrent(*renderContext.renderer())->layer;
2384 QSSGRenderImage *theLightProbe = layer.lightProbe;
2385 const auto &lightProbeData = layer.lightProbeSettings;
2388 QSSGRenderImage *materialIblProbe = materialAdapter->iblProbe();
2389 if (materialIblProbe)
2390 theLightProbe = materialIblProbe;
2391 QSSGRenderImageTexture lightProbeTexture;
2393 lightProbeTexture = renderContext.bufferManager()->loadRenderImage(theLightProbe, QSSGBufferManager::MipModeBsdf);
2394 if (theLightProbe && lightProbeTexture.m_texture) {
2395 QSSGRenderTextureCoordOp theHorzLightProbeTilingMode = theLightProbe->m_horizontalTilingMode;
2396 QSSGRenderTextureCoordOp theVertLightProbeTilingMode = theLightProbe->m_verticalTilingMode;
2397 const int maxMipLevel = lightProbeTexture.m_mipmapCount - 1;
2399 if (!materialIblProbe && !lightProbeData.probeOrientation.isIdentity()) {
2400 shaders.setUniform(ubufData,
"qt_lightProbeOrientation",
2401 lightProbeData.probeOrientation.constData(),
2402 12 *
sizeof(
float), &cui.lightProbeOrientationIdx,
2403 QSSGRhiShaderPipeline::UniformFlag::Mat3);
2406 const float props[4] = { 0.0f,
float(maxMipLevel), lightProbeData.probeHorizon, lightProbeData.probeExposure };
2407 shaders.setUniform(ubufData,
"qt_lightProbeProperties", props, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2409 shaders.setLightProbeTexture(lightProbeTexture.m_texture, theHorzLightProbeTilingMode, theVertLightProbeTilingMode);
2412 const float emptyProps[4] = { 0.0f, 0.0f, -1.0f, 0.0f };
2413 shaders.setUniform(ubufData,
"qt_lightProbeProperties", emptyProps, 4 *
sizeof(
float), &cui.lightProbePropertiesIdx);
2415 shaders.setLightProbeTexture(
nullptr);
2418 if (receivesReflections && reflectionProbe.enabled) {
2419 shaders.setUniform(ubufData,
"qt_reflectionProbeCubeMapCenter", &reflectionProbe.probeCubeMapCenter, 3 *
sizeof(
float), &cui.reflectionProbeCubeMapCenter);
2420 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMin", &reflectionProbe.probeBoxMin, 3 *
sizeof(
float), &cui.reflectionProbeBoxMin);
2421 shaders.setUniform(ubufData,
"qt_reflectionProbeBoxMax", &reflectionProbe.probeBoxMax, 3 *
sizeof(
float), &cui.reflectionProbeBoxMax);
2422 shaders.setUniform(ubufData,
"qt_reflectionProbeCorrection", &reflectionProbe.parallaxCorrection,
sizeof(
int), &cui.reflectionProbeCorrection);
2425 const QVector3D emissiveColor = materialAdapter->emissiveColor();
2426 shaders.setUniform(ubufData,
"qt_material_emissive_color", &emissiveColor, 3 *
sizeof(
float), &cui.material_emissiveColorIdx);
2428 const auto qMix = [](
float x,
float y,
float a) {
2429 return (x * (1.0f - a) + (y * a));
2432 const auto qMix3 = [&qMix](
const QVector3D &x,
const QVector3D &y,
float a) {
2433 return QVector3D{qMix(x.x(), y.x(), a), qMix(x.y(), y.y(), a), qMix(x.z(), y.z(), a)};
2436 const QVector4D color = materialAdapter->color();
2437 const QVector3D materialSpecularTint = materialAdapter->specularTint();
2438 const QVector3D specularTint = materialAdapter->isPrincipled() ? qMix3(QVector3D(1.0f, 1.0f, 1.0f), color.toVector3D(), materialSpecularTint.x())
2439 : materialSpecularTint;
2440 shaders.setUniform(ubufData,
"qt_material_base_color", &color, 4 *
sizeof(
float), &cui.material_baseColorIdx);
2442 const float ior = materialAdapter->ior();
2443 QVector4D specularColor(specularTint, ior);
2444 shaders.setUniform(ubufData,
"qt_material_specular", &specularColor, 4 *
sizeof(
float), &cui.material_specularIdx);
2446 const bool hasLighting = materialAdapter->hasLighting();
2447 shaders.setLightsEnabled(hasLighting);
2449 const float lightAndShadowCounts[4] = {
2451 float(directionalLightCount),
2453 float(directionalShadowCount)
2455 shaders.setUniform(ubufData,
"qt_lightAndShadowCounts", &lightAndShadowCounts, 4 *
sizeof(
float), &cui.lightAndShadowCountsIdx);
2457 const size_t lightDataSize = lightCount *
sizeof(QSSGShaderLightData);
2458 const size_t directionalLightDataSize = directionalLightCount *
sizeof(QSSGShaderDirectionalLightData);
2460 memcpy(ubufData + shaders.ub0LightDataOffset(), &lightsUniformData, lightDataSize);
2461 memcpy(ubufData + shaders.ub0DirectionalLightDataOffset(), &directionalLightsUniformData, directionalLightDataSize);
2464 shaders.setUniform(ubufData,
"qt_light_ambient_total", &theLightAmbientTotal, 3 *
sizeof(
float), &cui.light_ambient_totalIdx);
2466 const float materialProperties[4] = {
2467 materialAdapter->specularAmount(),
2468 materialAdapter->specularRoughness(),
2469 materialAdapter->metalnessAmount(),
2472 shaders.setUniform(ubufData,
"qt_material_properties", materialProperties, 4 *
sizeof(
float), &cui.material_propertiesIdx);
2474 const float materialProperties2[4] = {
2475 materialAdapter->fresnelPower(),
2476 materialAdapter->bumpAmount(),
2477 materialAdapter->translucentFallOff(),
2478 materialAdapter->diffuseLightWrap()
2480 shaders.setUniform(ubufData,
"qt_material_properties2", materialProperties2, 4 *
sizeof(
float), &cui.material_properties2Idx);
2482 const float materialProperties3[4] = {
2483 materialAdapter->occlusionAmount(),
2484 materialAdapter->alphaCutOff(),
2485 materialAdapter->clearcoatAmount(),
2486 materialAdapter->clearcoatRoughnessAmount()
2488 shaders.setUniform(ubufData,
"qt_material_properties3", materialProperties3, 4 *
sizeof(
float), &cui.material_properties3Idx);
2490 const float materialProperties4[4] = {
2491 materialAdapter->heightAmount(),
2492 materialAdapter->minHeightSamples(),
2493 materialAdapter->maxHeightSamples(),
2494 materialAdapter->transmissionFactor()
2496 shaders.setUniform(ubufData,
"qt_material_properties4", materialProperties4, 4 *
sizeof(
float), &cui.material_properties4Idx);
2498 const bool hasCustomFrag = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
2499 if (!hasCustomFrag) {
2500 if (inProperties.m_fresnelScaleBiasEnabled.getValue(inKey) || inProperties.m_clearcoatFresnelScaleBiasEnabled.getValue(inKey)) {
2501 const float materialProperties5[4] = {
2502 materialAdapter->fresnelScale(),
2503 materialAdapter->fresnelBias(),
2504 materialAdapter->clearcoatFresnelScale(),
2505 materialAdapter->clearcoatFresnelBias()
2507 shaders.setUniform(ubufData,
"qt_material_properties5", materialProperties5, 4 *
sizeof(
float), &cui.material_properties5Idx);
2510 const float material_clearcoat_normal_strength = materialAdapter->clearcoatNormalStrength();
2511 shaders.setUniform(ubufData,
"qt_material_clearcoat_normal_strength", &material_clearcoat_normal_strength,
sizeof(
float), &cui.clearcoatNormalStrengthIdx);
2513 const float material_clearcoat_fresnel_power = materialAdapter->clearcoatFresnelPower();
2514 shaders.setUniform(ubufData,
"qt_material_clearcoat_fresnel_power", &material_clearcoat_fresnel_power,
sizeof(
float), &cui.clearcoatFresnelPowerIdx);
2516 if (materialAdapter->isTransmissionEnabled()) {
2517 const QVector4D attenuationProperties(materialAdapter->attenuationColor(), materialAdapter->attenuationDistance());
2518 shaders.setUniform(ubufData,
"qt_material_attenuation", &attenuationProperties, 4 *
sizeof(
float), &cui.material_attenuationIdx);
2520 const float thickness = materialAdapter->thicknessFactor();
2521 shaders.setUniform(ubufData,
"qt_material_thickness", &thickness,
sizeof(
float), &cui.thicknessFactorIdx);
2525 const float rhiProperties[4] = {
2526 globalRenderData.isYUpInFramebuffer ? 1.0f : -1.0f,
2527 globalRenderData.isYUpInNDC ? 1.0f : -1.0f,
2528 globalRenderData.isClipDepthZeroToOne ? 0.0f : -1.0f,
2531 shaders.setUniform(ubufData,
"qt_rhi_properties", rhiProperties, 4 *
sizeof(
float), &cui.rhiPropertiesIdx);
2533 qsizetype imageIdx = 0;
2534 for (QSSGRenderableImage *theImage = inFirstImage; theImage; theImage = theImage->m_nextImage, ++imageIdx) {
2536 const auto &names = imageStringTable[
int(theImage->m_mapType)];
2537 if (imageIdx == cui.imageIndices.size())
2538 cui.imageIndices.append(QSSGRhiShaderPipeline::CommonUniformIndices::ImageIndices());
2539 auto &indices = cui.imageIndices[imageIdx];
2541 const QMatrix4x4 &textureTransform = theImage->m_imageNode.m_textureTransform;
2544 const float *dataPtr(textureTransform.constData());
2548 const float offsets[3] = { dataPtr[12], dataPtr[13], 0.0f };
2549 shaders.setUniform(ubufData, names.imageOffsets, offsets,
sizeof(offsets), &indices.imageOffsetsUniformIndex);
2551 const float rotations[4] = { dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5] };
2552 shaders.setUniform(ubufData, names.imageRotations, rotations,
sizeof(rotations), &indices.imageRotationsUniformIndex);
2555 if (shadowDepthAdjust)
2556 shaders.setUniform(ubufData,
"qt_shadowDepthAdjust", shadowDepthAdjust, 2 *
sizeof(
float), &cui.shadowDepthAdjustIdx);
2558 const bool usesPointsTopology = inProperties.m_usesPointsTopology.getValue(inKey);
2559 if (usesPointsTopology) {
2560 const float pointSize = materialAdapter->pointSize();
2561 shaders.setUniform(ubufData,
"qt_materialPointSize", &pointSize,
sizeof(
float), &cui.pointSizeIdx);
2568 if (inRenderProperties.layer.fog.enabled) {
2569 const float fogColor[4] = {
2570 inRenderProperties.layer.fog.color.x(),
2571 inRenderProperties.layer.fog.color.y(),
2572 inRenderProperties.layer.fog.color.z(),
2573 inRenderProperties.layer.fog.density
2575 shaders.setUniform(ubufData,
"qt_fogColor", fogColor, 4 *
sizeof(
float), &cui.fogColorIdx);
2576 const float fogDepthProperties[4] = {
2577 inRenderProperties.layer.fog.depthBegin,
2578 inRenderProperties.layer.fog.depthEnd,
2579 inRenderProperties.layer.fog.depthCurve,
2580 inRenderProperties.layer.fog.depthEnabled ? 1.0f : 0.0f
2582 shaders.setUniform(ubufData,
"qt_fogDepthProperties", fogDepthProperties, 4 *
sizeof(
float), &cui.fogDepthPropertiesIdx);
2583 const float fogHeightProperties[4] = {
2584 inRenderProperties.layer.fog.heightMin,
2585 inRenderProperties.layer.fog.heightMax,
2586 inRenderProperties.layer.fog.heightCurve,
2587 inRenderProperties.layer.fog.heightEnabled ? 1.0f : 0.0f
2589 shaders.setUniform(ubufData,
"qt_fogHeightProperties", fogHeightProperties, 4 *
sizeof(
float), &cui.fogHeightPropertiesIdx);
2590 const float fogTransmitProperties[4] = {
2591 inRenderProperties.layer.fog.transmitCurve,
2594 inRenderProperties.layer.fog.transmitEnabled ? 1.0f : 0.0f
2596 shaders.setUniform(ubufData,
"qt_fogTransmitProperties", fogTransmitProperties, 4 *
sizeof(
float), &cui.fogTransmitPropertiesIdx);
2599 inPipelineState->lineWidth = materialAdapter->lineWidth();