7#include <QtQuick3DUtils/private/qssgutils_p.h>
9#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h>
10#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrendershadercodegenerator_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgrenderimage_p.h>
13#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
14#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
15#include <QtQuick3DRuntimeRender/private/qssgrendershadowmap_p.h>
16#include <QtQuick3DRuntimeRender/private/qssgrendercustommaterial_p.h>
17#include <QtQuick3DRuntimeRender/private/qssgrendershaderlibrarymanager_p.h>
18#include <QtQuick3DRuntimeRender/private/qssgrendershaderkeys_p.h>
19#include <QtQuick3DRuntimeRender/private/qssgshadermaterialadapter_p.h>
21#include <QtCore/QByteArray>
28#define DefineImageStrings(V) template<> struct ImageStrings<Type::V> \
30 static constexpr const char* sampler() { return "qt_"#V"Map_sampler"; }\
31 static constexpr const char* offsets() { return "qt_"#V"Map_offsets"; }\
32 static constexpr const char* rotations() { return "qt_"#V"Map_rotations"; }\
33 static constexpr const char* fragCoords1() { return "qt_"#V"Map_uv_coords1"; }\
34 static constexpr const char* fragCoords2() { return "qt_"#V"Map_uv_coords2"; }\
35 static constexpr const char* samplerSize() { return "qt_"#V"Map_size"; }\
68#define DefineImageStringTableEntry(V) \
69 { ImageStrings<Type::V>::sampler(), ImageStrings<Type::V>::fragCoords1(), ImageStrings<Type::V>::fragCoords2(), \
70 ImageStrings<Type::V>::offsets(), ImageStrings<Type::V>::rotations(), ImageStrings<Type::V>::samplerSize() }
102 outString[14] =
'0' + uvSet;
111 outString[11] =
'0' + uvSet;
123 inGenerator <<
" " << inType <<
" " << inName <<
";\n";
129 transform =
" qt_uTransform = vec3(" + imageRotations +
".x, " + imageRotations +
".y, " + imageOffsets +
".x);\n";
130 transform +=
" qt_vTransform = vec3(" + imageRotations +
".z, " + imageRotations +
".w, " + imageOffsets +
".y);\n";
136 if (
image.m_imageNode.type == QSSGRenderGraphObject::Type::ImageCube) {
137 qWarning(
"Sampler %s expects a 2D texture but the associated texture is a cube map. "
138 "This will lead to problems.",
147 bool forceFragmentShader =
false,
149 bool reuseImageCoords =
false)
151 const auto &
names = imageStringTable[int(
image.m_mapType)];
152 char textureCoordName[TEXCOORD_VAR_LEN];
155 if (!forceFragmentShader) {
164 if (!forceFragmentShader) {
165 vertexShader << uvTrans;
167 vertexShader.
addFunction(
"getTransformedUVCoords");
169 fragmentShader << uvTrans;
170 fragmentShader.
addFunction(
"getTransformedUVCoords");
173 if (!forceFragmentShader) {
174 textureCoordVaryingName(textureCoordName, uvSet);
175 vertexShader <<
" vec2 " <<
names.imageFragCoordsTemp <<
" = qt_getTransformedUVCoords(vec3(" << textureCoordName <<
", 1.0), qt_uTransform, qt_vTransform);\n";
178 textureCoordVariableName(textureCoordName, uvSet);
179 if (reuseImageCoords)
180 fragmentShader <<
" ";
182 fragmentShader <<
" vec2 ";
183 fragmentShader <<
names.imageFragCoords <<
" = qt_getTransformedUVCoords(vec3(" << textureCoordName <<
", 1.0), qt_uTransform, qt_vTransform);\n";
188 fragmentShader << uvTrans;
190 fragmentShader.
addFunction(
"getTransformedUVCoords");
191 if (reuseImageCoords)
192 fragmentShader <<
" ";
194 fragmentShader <<
" vec2 ";
195 fragmentShader <<
names.imageFragCoords <<
" = qt_getTransformedUVCoords(environment_map_reflection, qt_uTransform, qt_vTransform);\n";
203 char (&outString)[TEXCOORD_VAR_LEN],
206 const auto &
names = imageStringTable[int(
image.m_mapType)];
210 textureCoordVariableName(outString, uvSet);
220 fragmentShader.
addInclude(
"physGlossyBSDF.glsllib");
221 fragmentShader <<
" global_specular_light += qt_lightAttenuation * qt_shadow_map_occl * qt_specularAmount"
222 " * qt_kggxGlossyDefaultMtl(qt_world_normal, qt_tangent, -" << inLightDir <<
".xyz, qt_view_vector, " << inLightSpecColor <<
".rgb, qt_specularTint, qt_roughnessAmount).rgb;\n";
225 fragmentShader <<
" global_specular_light += qt_lightAttenuation * qt_shadow_map_occl * qt_specularAmount"
226 " * qt_specularBSDF(qt_world_normal, -" << inLightDir <<
".xyz, qt_view_vector, " << inLightSpecColor <<
".rgb, 2.56 / (qt_roughnessAmount + 0.01)).rgb;\n";
234 if (
image ==
nullptr)
237 infragmentShader.
addFunction(
"diffuseReflectionWrapBSDF");
238 infragmentShader <<
" tmp_light_color = " << lightVarNames.
lightColor <<
".rgb * (1.0 - qt_metalnessAmount);\n";
239 infragmentShader <<
" global_diffuse_light.rgb += qt_lightAttenuation * qt_shadow_map_occl * qt_translucent_thickness_exp * qt_diffuseReflectionWrapBSDF(-qt_world_normal, -"
240 << lightVarNames.
normalizedDirection <<
", tmp_light_color, qt_material_properties2.w).rgb;\n";
251 if (
names.shadowMapStem.isEmpty()) {
259 names.shadowMatrixStem.append(
"_matrix");
261 names.shadowCoordStem.append(
"_coord");
262 names.shadowControlStem =
names.shadowMapStem;
263 names.shadowControlStem.append(
"_control");
276 fragmentShader.
addInclude(
"defaultMaterialFresnel.glsllib");
277 fragmentShader <<
" // Add fresnel ratio\n";
279 fragmentShader <<
" qt_specularAmount *= qt_defaultMaterialSimpleFresnel(qt_specularBase, qt_metalnessAmount, qt_world_normal, qt_view_vector, "
280 "qt_dielectricSpecular(qt_material_specular.w), qt_material_properties2.x);\n";
282 fragmentShader <<
" qt_specularAmount *= qt_defaultMaterialSimpleFresnelNoMetalness(qt_world_normal, qt_view_vector, "
283 "qt_dielectricSpecular(qt_material_specular.w), qt_material_properties2.x);\n";
312 names.lightColor = lightStem;
314 names.lightDirection = lightStem;
316 names.lightSpecularColor = lightStem;
318 if (inLight.
type == QSSGRenderLight::Type::PointLight) {
319 names.lightPos = lightStem;
321 names.lightConstantAttenuation = lightStem;
322 names.lightConstantAttenuation.
append(
"constantAttenuation");
323 names.lightLinearAttenuation = lightStem;
324 names.lightLinearAttenuation.
append(
"linearAttenuation");
325 names.lightQuadraticAttenuation = lightStem;
326 names.lightQuadraticAttenuation.
append(
"quadraticAttenuation");
327 }
else if (inLight.
type == QSSGRenderLight::Type::SpotLight) {
328 names.lightPos = lightStem;
330 names.lightConstantAttenuation = lightStem;
331 names.lightConstantAttenuation.
append(
"constantAttenuation");
332 names.lightLinearAttenuation = lightStem;
333 names.lightLinearAttenuation.
append(
"linearAttenuation");
334 names.lightQuadraticAttenuation = lightStem;
335 names.lightQuadraticAttenuation.
append(
"quadraticAttenuation");
336 names.lightConeAngle = lightStem;
338 names.lightInnerConeAngle = lightStem;
339 names.lightInnerConeAngle.
append(
"innerConeAngle");
348 bool inShadowEnabled,
353 if (inShadowEnabled) {
356 fragmentShader.
addInclude(
"shadowMapping.glsllib");
357 if (inType == QSSGRenderLight::Type::DirectionalLight) {
365 if (inType != QSSGRenderLight::Type::DirectionalLight) {
366 fragmentShader <<
" qt_shadow_map_occl = qt_sampleCubemap(" <<
names.shadowCubeStem <<
", " <<
names.shadowControlStem <<
", " <<
names.shadowMatrixStem <<
", " << lightVarNames.
lightPos <<
".xyz, qt_varWorldPos, vec2(1.0, " <<
names.shadowControlStem <<
".z));\n";
368 fragmentShader <<
" qt_shadow_map_occl = qt_sampleOrthographic(" <<
names.shadowMapStem <<
", " <<
names.shadowControlStem <<
", " <<
names.shadowMatrixStem <<
", qt_varWorldPos, vec2(1.0, " <<
names.shadowControlStem <<
".z));\n";
371 fragmentShader <<
" qt_shadow_map_occl = 1.0;\n";
377 switch (inMaterial.
type) {
378 case QSSGRenderGraphObject::Type::DefaultMaterial:
379 case QSSGRenderGraphObject::Type::PrincipledMaterial:
380 case QSSGRenderGraphObject::Type::SpecularGlossyMaterial:
382 case QSSGRenderGraphObject::Type::CustomMaterial:
397 {
"SPECULAR_AMOUNT" },
398 {
"EMISSIVE_COLOR" },
400 {
"LIGHT_ATTENUATION" },
402 {
"SHADOW_CONTRIB" },
403 {
"FRESNEL_CONTRIB" },
407 {
"TOTAL_AMBIENT_COLOR" },
412 {
"INSTANCE_MODEL_MATRIX" },
413 {
"INSTANCE_MODELVIEWPROJECTION_MATRIX" },
421 return "inout vec3 DIFFUSE, in vec3 LIGHT_COLOR, in float SHADOW_CONTRIB, in vec3 TO_LIGHT_DIR, in vec3 NORMAL, in vec4 BASE_COLOR, in float METALNESS, in float ROUGHNESS, in vec3 VIEW_VECTOR";
426 return "inout vec3 DIFFUSE, in vec3 LIGHT_COLOR, in float LIGHT_ATTENUATION, in float SHADOW_CONTRIB, in vec3 TO_LIGHT_DIR, in vec3 NORMAL, in vec4 BASE_COLOR, in float METALNESS, in float ROUGHNESS, in vec3 VIEW_VECTOR";
431 return "inout vec3 DIFFUSE, in vec3 LIGHT_COLOR, in float LIGHT_ATTENUATION, float SPOT_FACTOR, in float SHADOW_CONTRIB, in vec3 TO_LIGHT_DIR, in vec3 NORMAL, in vec4 BASE_COLOR, in float METALNESS, in float ROUGHNESS, in vec3 VIEW_VECTOR";
436 return "inout vec3 DIFFUSE, in vec3 TOTAL_AMBIENT_COLOR, in vec3 NORMAL, in vec3 VIEW_VECTOR";
441 return "inout vec3 SPECULAR, in vec3 LIGHT_COLOR, in float LIGHT_ATTENUATION, in float SHADOW_CONTRIB, in vec3 FRESNEL_CONTRIB, in vec3 TO_LIGHT_DIR, in vec3 NORMAL, in vec4 BASE_COLOR, in float METALNESS, in float ROUGHNESS, in float SPECULAR_AMOUNT, in vec3 VIEW_VECTOR";
446 return "inout vec4 BASE_COLOR, inout vec3 EMISSIVE_COLOR, inout float METALNESS, inout float ROUGHNESS, inout float SPECULAR_AMOUNT, inout float FRESNEL_POWER, inout vec3 NORMAL, inout vec3 TANGENT, inout vec3 BINORMAL, in vec2 UV0, in vec2 UV1, in vec3 VIEW_VECTOR";
451 return "inout vec4 COLOR_SUM, in vec4 DIFFUSE, in vec3 SPECULAR, in vec3 EMISSIVE, in vec2 UV0, in vec2 UV1";
456 return "inout vec3 DIFFUSE, inout vec3 SPECULAR, in vec4 BASE_COLOR, in float AO_FACTOR, in float SPECULAR_AMOUNT, in float ROUGHNESS, in vec3 NORMAL, in vec3 VIEW_VECTOR, in mat3 IBL_ORIENTATION";
461 return "inout vec3 VERTEX, inout vec3 NORMAL, inout vec2 UV0, inout vec2 UV1, inout vec3 TANGENT, inout vec3 BINORMAL, inout ivec4 JOINTS, inout vec4 WEIGHTS, inout vec4 COLOR";
466 return "inout vec3 VERTEX, inout vec3 NORMAL, inout vec2 UV0, inout vec2 UV1, inout vec3 TANGENT, inout vec3 BINORMAL, inout ivec4 JOINTS, inout vec4 WEIGHTS, inout vec4 COLOR, inout mat4 INSTANCE_MODEL_MATRIX, inout mat4 INSTANCE_MODELVIEWPROJECTION_MATRIX";
469#define MAX_MORPH_TARGET 8
483 fragmentShader <<
" tmp_light_color = " << lightVarNames.
lightColor <<
".rgb;\n";
485 fragmentShader <<
" tmp_light_color = " << lightVarNames.
lightColor <<
".rgb * (1.0 - qt_metalnessAmount);\n";
494 bool specularLightingEnabled,
495 bool enableClearcoat,
496 bool enableTransmission,
497 bool useNormalizedDirection)
504 fragmentShader <<
" qt_specularLightProcessor(global_specular_light, " << lightVarNames.
lightSpecularColor <<
".rgb, qt_lightAttenuation, qt_shadow_map_occl, "
505 <<
"qt_specularAmount, -" << directionToUse <<
".xyz, qt_world_normal, qt_customBaseColor, "
506 <<
"qt_metalnessAmount, qt_roughnessAmount, qt_customSpecularAmount, qt_view_vector";
508 fragmentShader <<
", qt_customShared);\n";
510 fragmentShader <<
");\n";
514 if (specularLightingEnabled)
520 fragmentShader <<
" global_specular_light += qt_lightAttenuation * qt_shadow_map_occl * qt_specularTint"
521 " * qt_specularGGXBSDF(qt_world_normal, -"
522 << directionToUse <<
".xyz, qt_view_vector, "
523 << lightVarNames.
lightSpecularColor <<
".rgb, qt_f0, qt_f90, qt_roughnessAmount).rgb;\n";
533 fragmentShader <<
" qt_global_clearcoat += qt_lightAttenuation * qt_shadow_map_occl"
534 " * qt_specularGGXBSDF(qt_clearcoatNormal, -"
535 << directionToUse <<
".xyz, qt_view_vector, "
536 << lightVarNames.
lightSpecularColor <<
".rgb, qt_clearcoatF0, qt_clearcoatF90, qt_clearcoatRoughness).rgb;\n";
539 if (enableTransmission)
541 fragmentShader <<
" {\n";
542 fragmentShader <<
" vec3 transmissionRay = qt_getVolumeTransmissionRay(qt_world_normal, qt_view_vector, qt_thicknessFactor, qt_material_specular.w);\n";
543 fragmentShader <<
" vec3 pointToLight = -" << directionToUse <<
".xyz;\n";
544 fragmentShader <<
" pointToLight -= transmissionRay;\n";
545 fragmentShader <<
" vec3 l = normalize(pointToLight);\n";
546 fragmentShader <<
" vec3 intensity = vec3(1.0);\n";
547 fragmentShader <<
" vec3 transmittedLight = intensity * qt_getPunctualRadianceTransmission(qt_world_normal, "
548 "qt_view_vector, l, qt_roughnessAmount, qt_f0, qt_f90, qt_diffuseColor.rgb, qt_material_specular.w);\n";
549 fragmentShader <<
" transmittedLight = qt_applyVolumeAttenuation(transmittedLight, length(transmissionRay), "
550 "qt_attenuationColor, qt_attenuationDistance);\n";
551 fragmentShader <<
" qt_global_transmission += qt_transmissionFactor * transmittedLight;\n";
552 fragmentShader <<
" }\n";
564 bool specularLightingEnabled,
565 bool enableClearcoat,
566 bool enableTransmission)
570 fragmentShader <<
" qt_directionalLightProcessor(global_diffuse_light.rgb, tmp_light_color, qt_shadow_map_occl, -"
571 << lightVarNames.
lightDirection <<
".xyz, qt_world_normal, qt_customBaseColor, "
572 <<
"qt_metalnessAmount, qt_roughnessAmount, qt_view_vector";
574 fragmentShader <<
", qt_customShared);\n";
576 fragmentShader <<
");\n";
579 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * qt_shadow_map_occl * "
580 <<
"qt_diffuseBurleyBSDF(qt_world_normal, -" << lightVarNames.
lightDirection <<
".xyz, "
581 <<
"qt_view_vector, tmp_light_color, qt_roughnessAmount).rgb;\n";
583 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * qt_shadow_map_occl * qt_diffuseReflectionBSDF(qt_world_normal, -"
584 << lightVarNames.
lightDirection <<
".xyz, tmp_light_color).rgb;\n";
591 shaderLibraryManager,
594 specularLightingEnabled,
617 fragmentShader <<
" vec3 " << lightVarNames.
relativeDirection <<
" = qt_varWorldPos - " << lightVarNames.
lightPos <<
".xyz;\n"
629 bool specularLightingEnabled,
630 bool enableClearcoat,
631 bool enableTransmission)
635 fragmentShader <<
" qt_pointLightProcessor(global_diffuse_light.rgb, tmp_light_color, qt_lightAttenuation, qt_shadow_map_occl, -"
637 <<
"qt_metalnessAmount, qt_roughnessAmount, qt_view_vector";
639 fragmentShader <<
", qt_customShared);\n";
641 fragmentShader <<
");\n";
644 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * qt_lightAttenuation * qt_shadow_map_occl * "
645 <<
"qt_diffuseBurleyBSDF(qt_world_normal, -" << lightVarNames.
normalizedDirection <<
".xyz, qt_view_vector, "
646 <<
"tmp_light_color, qt_roughnessAmount).rgb;\n";
648 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * qt_lightAttenuation * qt_shadow_map_occl * "
649 <<
"qt_diffuseReflectionBSDF(qt_world_normal, -" << lightVarNames.
normalizedDirection <<
".xyz, tmp_light_color).rgb;\n";
656 shaderLibraryManager,
659 specularLightingEnabled,
672 bool specularLightingEnabled,
673 bool enableClearcoat,
674 bool enableTransmission)
676 lightVarNames.
spotAngle = lightVarPrefix;
680 <<
", normalize(vec3(" << lightVarNames.
lightDirection <<
")));\n";
682 fragmentShader <<
" float spotFactor = smoothstep(" << lightVarNames.
lightConeAngle
688 fragmentShader <<
" qt_spotLightProcessor(global_diffuse_light.rgb, tmp_light_color, qt_lightAttenuation, spotFactor, qt_shadow_map_occl, -"
690 <<
"qt_metalnessAmount, qt_roughnessAmount, qt_view_vector";
692 fragmentShader <<
", qt_customShared);\n";
694 fragmentShader <<
");\n";
697 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * spotFactor * qt_lightAttenuation * qt_shadow_map_occl * "
698 <<
"qt_diffuseBurleyBSDF(qt_world_normal, -" << lightVarNames.
normalizedDirection <<
".xyz, qt_view_vector, "
699 <<
"tmp_light_color, qt_roughnessAmount).rgb;\n";
701 fragmentShader <<
" global_diffuse_light.rgb += qt_diffuseColor.rgb * spotFactor * qt_lightAttenuation * qt_shadow_map_occl * "
702 <<
"qt_diffuseReflectionBSDF(qt_world_normal, -" << lightVarNames.
normalizedDirection <<
".xyz, tmp_light_color).rgb;\n";
707 fragmentShader <<
" qt_lightAttenuation *= spotFactor;\n";
712 shaderLibraryManager,
715 specularLightingEnabled,
720 fragmentShader <<
" }\n";
726 fragmentShader.
addFunction(
"calculatePointLightAttenuation");
728 fragmentShader <<
" qt_lightAttenuation = qt_calculatePointLightAttenuation(vec3("
743 bool enableShadowMaps,
744 bool specularLightingEnabled,
745 bool enableClearcoat,
746 bool enableTransmission)
753 int shadowMapCount = 0;
755 for (
qint32 lightIdx = 0; lightIdx < lights.
size(); ++lightIdx) {
756 auto &shaderLight = lights[lightIdx];
764 const bool isDirectional = lightNode->
type == QSSGRenderLight::Type::DirectionalLight;
765 const bool isSpot = lightNode->
type == QSSGRenderLight::Type::SpotLight;
770 fragmentShader.
append(
"");
771 char lightIdxStr[11];
772 snprintf(lightIdxStr, 11,
"%d", lightIdx);
775 lightVarPrefix.
append(lightIdxStr);
777 fragmentShader <<
" //Light " << lightIdxStr << (isDirectional ?
" [directional]" : isSpot ?
" [spot]" :
" [point]") <<
"\n";
779 lightVarPrefix.
append(
"_");
791 shaderLibraryManager,
792 specularLightingEnabled,
796 generateDirections(fragmentShader, lightVarNames, lightVarPrefix, vertexShader, inKey);
807 shaderLibraryManager,
810 specularLightingEnabled,
817 shaderLibraryManager,
820 specularLightingEnabled,
827 fragmentShader.
append(
"");
844 shaderLibraryManager);
857 bool hasImage = firstImage !=
nullptr;
860 bool specularLightingEnabled = metalnessEnabled || materialAdapter->
isSpecularEnabled() || hasIblProbe;
891 char imageFragCoords[TEXCOORD_VAR_LEN];
913 if (
img->m_imageNode.isImageTransformIdentity())
915 if (
img->m_mapType == QSSGRenderableImage::Type::BaseColor ||
img->m_mapType == QSSGRenderableImage::Type::Diffuse) {
917 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Bump) {
919 }
else if (
img->m_mapType == QSSGRenderableImage::Type::SpecularAmountMap) {
920 specularAmountImage =
img;
921 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Roughness) {
922 roughnessImage =
img;
923 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Metalness) {
924 metalnessImage =
img;
925 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Occlusion) {
926 occlusionImage =
img;
927 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Normal) {
929 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Translucency) {
930 translucencyImage =
img;
931 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Opacity) {
933 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Height) {
935 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Clearcoat) {
936 clearcoatImage =
img;
937 }
else if (
img->m_mapType == QSSGRenderableImage::Type::ClearcoatRoughness) {
938 clearcoatRoughnessImage =
img;
939 }
else if (
img->m_mapType == QSSGRenderableImage::Type::ClearcoatNormal) {
940 clearcoatNormalImage =
img;
941 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Transmission) {
942 transmissionImage =
img;
943 }
else if (
img->m_mapType == QSSGRenderableImage::Type::Thickness) {
944 thicknessImage =
img;
957 bool enableBumpNormal = normalImage || bumpImage;
958 bool genBumpNormalImageCoords =
false;
959 bool enableParallaxMapping = heightImage !=
nullptr;
963 specularLightingEnabled |= specularAmountImage !=
nullptr;
964 specularLightingEnabled |= hasReflectionProbe;
971 if (numMorphTargets > 0 || hasCustomVert) {
1005 bool includeCustomFragmentMain =
true;
1006 if (isDepthPass || isOrthoShadowPass || isCubeShadowPass) {
1007 hasLighting =
false;
1009 enableShadowMaps =
false;
1010 enableLightmap =
false;
1012 metalnessEnabled =
false;
1013 specularLightingEnabled =
false;
1015 if (!isOpaqueDepthPrePass) {
1016 vertexColorsEnabled =
false;
1017 baseImage =
nullptr;
1018 includeCustomFragmentMain =
false;
1022 bool includeSSAOVars = enableSSAO || enableShadowMaps;
1029 if (hasCustomFrag && materialAdapter->
isUnshaded())
1036 fragmentShader.
addUniform(
"qt_material_emissive_color",
"vec3");
1037 fragmentShader.
addUniform(
"qt_material_base_color",
"vec4");
1038 fragmentShader.
addUniform(
"qt_material_properties",
"vec4");
1039 fragmentShader.
addUniform(
"qt_material_properties2",
"vec4");
1040 fragmentShader.
addUniform(
"qt_material_properties3",
"vec4");
1041 if (enableParallaxMapping || enableTransmission)
1042 fragmentShader.
addUniform(
"qt_material_properties4",
"vec4");
1043 if (enableTransmission) {
1044 fragmentShader.
addUniform(
"qt_material_attenuation",
"vec4");
1045 fragmentShader.
addUniform(
"qt_material_thickness",
"float");
1048 if (vertexColorsEnabled)
1051 fragmentShader.
append(
" vec4 qt_vertColor = vec4(1.0);");
1053 if (hasImage && ((!isDepthPass && !isOrthoShadowPass && !isCubeShadowPass) || isOpaqueDepthPrePass)) {
1054 fragmentShader.
append(
" vec3 qt_uTransform;");
1055 fragmentShader.
append(
" vec3 qt_vTransform;");
1058 if (hasLighting || hasCustomFrag) {
1062 fragmentShader.
addUniform(
"qt_projectionMatrix",
"mat4");
1064 fragmentShader.
addUniform(
"qt_inverseProjectionMatrix",
"mat4");
1071 const bool needsTangentAndBinormal = hasCustomFrag || enableParallaxMapping || clearcoatNormalImage || enableBumpNormal || usingDefaultMaterialSpecularGGX || tangentOrBinormalDebugMode;
1074 if (needsTangentAndBinormal) {
1075 bool genTangent =
false;
1076 bool genBinormal =
false;
1079 if (enableBumpNormal && !genTangent) {
1083 auto *bumpNormalImage = bumpImage !=
nullptr ? bumpImage : normalImage;
1084 generateImageUVCoordinates(vertexShader, fragmentShader, inKey, *bumpNormalImage,
true, bumpNormalImage->m_imageNode.m_indexUV);
1085 genBumpNormalImageCoords =
true;
1087 int id = (bumpImage !=
nullptr) ?
int(QSSGRenderableImage::Type::Bump) : int(QSSGRenderableImage::Type::Normal);
1088 const auto &
names = imageStringTable[
id];
1089 fragmentShader <<
" vec2 dUVdx = dFdx(" <<
names.imageFragCoords <<
");\n"
1090 <<
" vec2 dUVdy = dFdy(" <<
names.imageFragCoords <<
");\n";
1091 fragmentShader <<
" qt_tangent = (dUVdy.y * dFdx(qt_varWorldPos) - dUVdx.y * dFdy(qt_varWorldPos)) / (dUVdx.x * dUVdy.y - dUVdx.y * dUVdy.x);\n"
1092 <<
" qt_tangent = qt_tangent - dot(qt_world_normal, qt_tangent) * qt_world_normal;\n"
1093 <<
" qt_tangent = normalize(qt_tangent);\n";
1096 fragmentShader <<
" qt_binormal = cross(qt_world_normal, qt_tangent);\n";
1099 if (isDoubleSided) {
1100 fragmentShader.
append(
" const float qt_facing = gl_FrontFacing ? 1.0 : -1.0;\n");
1101 fragmentShader.
append(
" qt_world_normal *= qt_facing;\n");
1102 if (needsTangentAndBinormal) {
1103 fragmentShader.
append(
" qt_tangent *= qt_facing;");
1104 fragmentShader.
append(
" qt_binormal *= qt_facing;");
1109 if (hasCustomFrag) {
1116 fragmentShader <<
" QT_SHARED_VARS qt_customShared;\n";
1118 fragmentShader <<
" float qt_customSpecularAmount = 0.5;\n";
1119 fragmentShader <<
" float qt_customSpecularRoughness = 0.0;\n";
1120 fragmentShader <<
" float qt_customMetalnessAmount = 0.0;\n";
1121 fragmentShader <<
" float qt_customFresnelPower = 5.0;\n";
1122 fragmentShader <<
" vec4 qt_customBaseColor = vec4(1.0);\n";
1123 fragmentShader <<
" vec3 qt_customEmissiveColor = vec3(0.0);\n";
1129 fragmentShader <<
" qt_customMain(qt_customBaseColor, qt_customEmissiveColor, qt_customMetalnessAmount, qt_customSpecularRoughness,"
1130 " qt_customSpecularAmount, qt_customFresnelPower, qt_world_normal, qt_tangent, qt_binormal,"
1131 " qt_texCoord0, qt_texCoord1, qt_view_vector";
1133 fragmentShader <<
", qt_customShared);\n";
1135 fragmentShader <<
");\n";
1137 fragmentShader <<
" vec4 qt_diffuseColor = qt_customBaseColor * qt_vertColor;\n";
1138 fragmentShader <<
" vec3 qt_global_emission = qt_customEmissiveColor;\n";
1140 fragmentShader <<
" vec4 qt_diffuseColor = qt_material_base_color * qt_vertColor;\n";
1141 fragmentShader <<
" vec3 qt_global_emission = qt_material_emissive_color;\n";
1146 fragmentShader <<
" vec4 fragOutput = vec4(0.0);\n";
1148 if (isOrthoShadowPass)
1151 if (isCubeShadowPass)
1158 if (includeSSAOVars)
1161 if (enableLightmap) {
1170 fragmentShader.
addFunction(
"diffuseReflectionBSDF");
1172 if (enableParallaxMapping) {
1175 const bool hasIdentityMap = identityImages.
contains(heightImage);
1180 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Height)];
1181 fragmentShader.
addInclude(
"parallaxMapping.glsllib");
1182 fragmentShader <<
" qt_texCoord0 = qt_parallaxMapping(" << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
", " <<
names.imageSampler <<
", qt_tangent, qt_binormal, qt_world_normal, qt_varWorldPos, qt_cameraPosition, qt_material_properties4.x, qt_material_properties4.y, qt_material_properties4.z);\n";
1186 if (enableClearcoat) {
1192 if (clearcoatNormalImage) {
1194 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::ClearcoatNormal)];
1195 fragmentShader.
addFunction(
"sampleNormalTexture");
1197 fragmentShader <<
" qt_clearcoatNormal = qt_sampleNormalTexture3(" <<
names.imageSampler <<
", 1.0, " <<
names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1201 fragmentShader <<
" qt_clearcoatNormal = qt_world_normal;\n";
1205 if (bumpImage !=
nullptr) {
1206 if (enableParallaxMapping || !genBumpNormalImageCoords) {
1208 *bumpImage, enableParallaxMapping,
1210 genBumpNormalImageCoords);
1212 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Bump)];
1214 fragmentShader.
append(
" float bumpAmount = qt_material_properties2.y;\n");
1215 fragmentShader.
addInclude(
"defaultMaterialBumpNoLod.glsllib");
1216 fragmentShader <<
" qt_world_normal = qt_defaultMaterialBumpNoLod(" <<
names.imageSampler <<
", bumpAmount, " <<
names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal, " <<
names.imageSamplerSize <<
");\n";
1217 }
else if (normalImage !=
nullptr) {
1218 if (enableParallaxMapping || !genBumpNormalImageCoords) {
1220 *normalImage, enableParallaxMapping,
1222 genBumpNormalImageCoords);
1224 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Normal)];
1225 fragmentShader.
append(
" float normalStrength = qt_material_properties2.y;\n");
1226 fragmentShader.
addFunction(
"sampleNormalTexture");
1227 fragmentShader <<
" qt_world_normal = qt_sampleNormalTexture3(" <<
names.imageSampler <<
", normalStrength, " <<
names.imageFragCoords <<
", qt_tangent, qt_binormal, qt_world_normal);\n";
1230 fragmentShader.
append(
" vec3 tmp_light_color;");
1233 if (specularLightingEnabled || hasImage) {
1234 fragmentShader.
append(
" vec3 qt_specularBase;");
1235 fragmentShader.
addUniform(
"qt_material_specular",
"vec4");
1237 fragmentShader.
append(
" vec3 qt_specularTint = vec3(1.0);");
1239 fragmentShader.
append(
" vec3 qt_specularTint = qt_material_specular.rgb;");
1243 const bool hasIdentityMap = identityImages.
contains(baseImage);
1252 fragmentShader.
addInclude(
"tonemapping.glsllib");
1253 fragmentShader <<
" vec4 qt_base_texture_color = qt_sRGBToLinear(texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
"));\n";
1254 fragmentShader <<
" qt_diffuseColor *= qt_base_texture_color;\n";
1262 fragmentShader <<
" if (qt_diffuseColor.a < qt_material_properties3.y) {\n"
1263 <<
" qt_diffuseColor = vec4(0.0);\n"
1266 <<
" qt_diffuseColor.a = 1.0;\n"
1269 fragmentShader <<
" qt_diffuseColor.a = 1.0;\n";
1273 const bool hasIdentityMap = identityImages.
contains(opacityImage);
1279 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Opacity)];
1281 fragmentShader <<
" qt_objectOpacity *= texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1285 if (specularLightingEnabled) {
1287 fragmentShader.
addUniform(
"qt_material_properties",
"vec4");
1290 fragmentShader <<
" qt_specularBase = vec3(1.0);\n";
1292 fragmentShader <<
" qt_specularBase = qt_diffuseColor.rgb;\n";
1294 fragmentShader <<
" float qt_specularFactor = qt_customSpecularAmount;\n";
1296 fragmentShader <<
" float qt_specularFactor = qt_material_properties.x;\n";
1301 fragmentShader <<
" float qt_metalnessAmount = qt_customMetalnessAmount;\n";
1303 fragmentShader <<
" float qt_metalnessAmount = qt_material_properties.z;\n";
1305 fragmentShader <<
" float qt_metalnessAmount = 0.0;\n";
1307 if (specularLightingEnabled && metalnessImage) {
1309 const bool hasIdentityMap = identityImages.
contains(metalnessImage);
1315 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Metalness)];
1316 fragmentShader <<
" float qt_sampledMetalness = texture2D(" <<
names.imageSampler <<
", "
1317 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1318 fragmentShader <<
" qt_metalnessAmount = clamp(qt_metalnessAmount * qt_sampledMetalness, 0.0, 1.0);\n";
1321 fragmentShader.
addUniform(
"qt_light_ambient_total",
"vec3");
1323 fragmentShader.
append(
" vec4 global_diffuse_light = vec4(0.0);");
1325 if (enableLightmap) {
1326 fragmentShader <<
" global_diffuse_light.rgb = qt_lightmap_color(qt_texCoordLightmap) * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb;\n";
1330 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");
1332 fragmentShader <<
", qt_customShared);\n";
1334 fragmentShader <<
");\n";
1336 fragmentShader.
append(
" global_diffuse_light = vec4(qt_light_ambient_total.rgb * (1.0 - qt_metalnessAmount) * qt_diffuseColor.rgb, 0.0);");
1340 fragmentShader.
append(
" vec3 global_specular_light = vec3(0.0);");
1342 if (!lights.
isEmpty() || hasCustomFrag) {
1343 fragmentShader.
append(
" float qt_shadow_map_occl = 1.0;");
1344 fragmentShader.
append(
" float qt_lightAttenuation = 1.0;");
1349 if (specularAmountImage) {
1350 const bool hasIdentityMap = identityImages.
contains(specularAmountImage);
1356 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::SpecularAmountMap)];
1357 fragmentShader <<
" qt_specularBase *= qt_sRGBToLinear(texture2D(" <<
names.imageSampler <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")).rgb;\n";
1360 if (specularLightingEnabled) {
1362 fragmentShader <<
" qt_specularTint *= qt_specularBase;\n";
1363 fragmentShader <<
" vec3 qt_specularAmount = vec3(1.0);\n";
1365 fragmentShader <<
" vec3 qt_specularAmount = qt_specularBase * vec3(qt_metalnessAmount + qt_specularFactor * (1.0 - qt_metalnessAmount));\n";
1369 if (translucencyImage !=
nullptr) {
1370 const bool hasIdentityMap = identityImages.
contains(translucencyImage);
1376 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Translucency)];
1378 fragmentShader <<
" float qt_translucent_depth_range = texture2D(" <<
names.imageSampler
1379 <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1380 fragmentShader <<
" float qt_translucent_thickness = qt_translucent_depth_range * qt_translucent_depth_range;\n";
1381 fragmentShader <<
" float qt_translucent_thickness_exp = exp(qt_translucent_thickness * qt_material_properties2.z);\n";
1387 fragmentShader.
append(
" qt_aoFactor = qt_screenSpaceAmbientOcclusionFactor();");
1389 fragmentShader.
append(
" qt_aoFactor = 1.0;");
1392 fragmentShader <<
" float qt_roughnessAmount = qt_customSpecularRoughness;\n";
1394 fragmentShader <<
" float qt_roughnessAmount = qt_material_properties.y;\n";
1397 if (occlusionImage) {
1400 const bool hasIdentityMap = identityImages.
contains(occlusionImage);
1405 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Occlusion)];
1406 fragmentShader <<
" qt_ao = texture2D(" <<
names.imageSampler <<
", "
1407 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1408 fragmentShader <<
" qt_aoFactor *= qt_ao * qt_material_properties3.x;\n";
1411 if (specularLightingEnabled && roughnessImage) {
1413 const bool hasIdentityMap = identityImages.
contains(roughnessImage);
1419 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Roughness)];
1420 fragmentShader <<
" qt_roughnessAmount *= texture2D(" <<
names.imageSampler <<
", "
1421 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1426 fragmentShader <<
" qt_roughnessAmount = clamp(1.0 - qt_roughnessAmount, 0.0, 1.0);\n";
1428 if (enableClearcoat) {
1435 fragmentShader <<
" qt_clearcoatAmount = qt_material_properties3.z;\n";
1436 fragmentShader <<
" qt_clearcoatRoughness = qt_material_properties3.w;\n";
1437 fragmentShader <<
" qt_clearcoatF0 = vec3(((1.0-qt_material_specular.w) * (1.0-qt_material_specular.w)) / ((1.0+qt_material_specular.w) * (1.0+qt_material_specular.w)));\n";
1438 fragmentShader <<
" qt_clearcoatF90 = vec3(1.0);\n";
1439 fragmentShader <<
" qt_global_clearcoat = vec3(0.0);\n";
1441 if (clearcoatImage) {
1443 const bool hasIdentityMap = identityImages.
contains(clearcoatImage);
1448 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Clearcoat)];
1449 fragmentShader <<
" qt_clearcoatAmount *= texture2D(" <<
names.imageSampler <<
", "
1450 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1453 if (clearcoatRoughnessImage) {
1455 const bool hasIdentityMap = identityImages.
contains(clearcoatRoughnessImage);
1460 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::ClearcoatRoughness)];
1461 fragmentShader <<
" qt_clearcoatRoughness *= texture2D(" <<
names.imageSampler <<
", "
1462 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1463 fragmentShader <<
" qt_clearcoatRoughness = clamp(qt_clearcoatRoughness, 0.0, 1.0);\n";
1467 if (enableTransmission) {
1468 fragmentShader.
addInclude(
"transmission.glsllib");
1471 fragmentShader <<
" qt_transmissionFactor = qt_material_properties4.w;\n";
1472 fragmentShader <<
" qt_global_transmission = vec3(0.0);\n";
1474 if (transmissionImage) {
1476 const bool hasIdentityMap = identityImages.
contains(transmissionImage);
1481 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Transmission)];
1482 fragmentShader <<
" qt_transmissionFactor *= texture2D(" <<
names.imageSampler <<
", "
1483 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1491 fragmentShader <<
" qt_thicknessFactor = qt_material_thickness;\n";
1492 fragmentShader <<
" qt_attenuationColor = qt_material_attenuation.xyz;\n";
1493 fragmentShader <<
" qt_attenuationDistance = qt_material_attenuation.w;\n";
1495 if (thicknessImage) {
1497 const bool hasIdentityMap = identityImages.
contains(thicknessImage);
1502 const auto &
names = imageStringTable[int(QSSGRenderableImage::Type::Thickness)];
1503 fragmentShader <<
" qt_thicknessFactor *= texture2D(" <<
names.imageSampler <<
", "
1504 << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
")" << channelStr(channelProps, inKey) <<
";\n";
1508 if (specularLightingEnabled) {
1510 fragmentShader.
addInclude(
"principledMaterialFresnel.glsllib");
1511 const bool useF90 = !lights.
isEmpty() || enableTransmission;
1516 fragmentShader <<
" qt_f0 = qt_F0_ior(qt_material_specular.w, qt_metalnessAmount, qt_diffuseColor.rgb);\n";
1518 fragmentShader <<
" qt_f90 = vec3(1.0);\n";
1522 fragmentShader <<
" qt_reflectance = max(max(qt_specularTint.r, qt_specularTint.g), qt_specularTint.b);\n";
1523 fragmentShader <<
" qt_f0 = qt_specularTint;\n";
1524 fragmentShader <<
" qt_specularTint = vec3(1.0);\n";
1526 fragmentShader <<
" qt_f90 = vec3(clamp(qt_reflectance * 50.0, 0.0, 1.0));\n";
1527 fragmentShader <<
" qt_diffuseColor.rgb *= (1 - qt_reflectance);\n";
1530 if (specularAAEnabled) {
1531 fragmentShader.
append(
" vec3 vNormalWsDdx = dFdx(qt_world_normal.xyz);\n");
1532 fragmentShader.
append(
" vec3 vNormalWsDdy = dFdy(qt_world_normal.xyz);\n");
1533 fragmentShader.
append(
" float flGeometricRoughnessFactor = pow(clamp(max(dot(vNormalWsDdx, vNormalWsDdx), dot(vNormalWsDdy, vNormalWsDdy)), 0.0, 1.0), 0.333);\n");
1534 fragmentShader.
append(
" qt_roughnessAmount = max(flGeometricRoughnessFactor, qt_roughnessAmount);\n");
1538 fragmentShader <<
" float qt_fresnelPower = qt_customFresnelPower;\n";
1540 fragmentShader <<
" float qt_fresnelPower = qt_material_properties2.x;\n";
1543 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, "
1544 <<
"qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1548 fragmentShader <<
" qt_specularTint = mix(vec3(1.0), qt_specularTint, 1.0 - qt_metalnessAmount);\n";
1550 fragmentShader <<
" qt_specularAmount *= qt_principledMaterialFresnel(qt_world_normal, qt_view_vector, "
1551 <<
"qt_f0, qt_roughnessAmount, qt_fresnelPower);\n";
1555 fragmentShader.
addInclude(
"defaultMaterialFresnel.glsllib");
1556 fragmentShader <<
" qt_diffuseColor.rgb *= (1.0 - qt_dielectricSpecular(qt_material_specular.w)) * (1.0 - qt_metalnessAmount);\n";
1567 shaderLibraryManager,
1573 specularLightingEnabled,
1575 enableTransmission);
1581 fragmentShader <<
" global_diffuse_light = vec4(global_diffuse_light.rgb * qt_aoFactor, qt_objectOpacity * qt_diffuseColor.a);\n";
1583 if (hasReflectionProbe) {
1585 fragmentShader.
addInclude(
"sampleReflectionProbe.glsllib");
1587 fragmentShader <<
" vec3 qt_reflectionDiffuse = vec3(0.0);\n";
1589 fragmentShader <<
" qt_reflectionDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1591 fragmentShader <<
" qt_reflectionDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuseReflection(qt_reflectionMap, qt_world_normal).rgb;\n";
1594 if (specularLightingEnabled) {
1595 fragmentShader <<
" vec3 qt_reflectionSpecular = vec3(0.0);\n";
1597 fragmentShader <<
" qt_reflectionSpecular = "
1598 <<
"qt_specularTint * qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1600 fragmentShader <<
" qt_reflectionSpecular = qt_specularAmount * "
1601 <<
"qt_specularTint * qt_sampleGlossyReflection(qt_reflectionMap, qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1604 if (enableClearcoat) {
1605 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyReflectionPrincipled(qt_reflectionMap, qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1608 fragmentShader <<
" global_diffuse_light.rgb += qt_reflectionDiffuse;\n";
1609 if (specularLightingEnabled)
1610 fragmentShader <<
" global_specular_light += qt_reflectionSpecular;\n";
1611 if (enableClearcoat)
1612 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat;\n";
1613 }
else if (hasIblProbe) {
1615 fragmentShader.
addInclude(
"sampleProbe.glsllib");
1616 if (hasCustomIblProbe) {
1618 fragmentShader <<
" vec3 qt_iblDiffuse = vec3(0.0);\n";
1619 fragmentShader <<
" vec3 qt_iblSpecular = vec3(0.0);\n";
1620 fragmentShader <<
" qt_iblProbeProcessor(qt_iblDiffuse, qt_iblSpecular, qt_customBaseColor, qt_aoFactor, qt_specularFactor, qt_roughnessAmount, qt_world_normal, qt_view_vector";
1621 if (hasIblOrientation)
1622 fragmentShader <<
", qt_lightProbeOrientation";
1624 fragmentShader <<
", mat3(1.0)";
1626 fragmentShader <<
", qt_customShared);\n";
1628 fragmentShader <<
");\n";
1631 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * (1.0 - qt_specularAmount) * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1633 fragmentShader <<
" vec3 qt_iblDiffuse = qt_diffuseColor.rgb * qt_sampleDiffuse(qt_world_normal).rgb;\n";
1635 if (specularLightingEnabled) {
1637 fragmentShader <<
" vec3 qt_iblSpecular = "
1638 <<
"qt_specularTint * qt_sampleGlossyPrincipled(qt_world_normal, qt_view_vector, qt_specularAmount, qt_roughnessAmount).rgb;\n";
1640 fragmentShader <<
" vec3 qt_iblSpecular = qt_specularAmount * "
1641 <<
"qt_specularTint * qt_sampleGlossy(qt_world_normal, qt_view_vector, qt_roughnessAmount).rgb;\n";
1644 if (enableClearcoat) {
1645 fragmentShader <<
" vec3 qt_iblClearcoat = qt_sampleGlossyPrincipled(qt_clearcoatNormal, qt_view_vector, qt_clearcoatF0, qt_clearcoatRoughness).rgb;\n";
1649 fragmentShader <<
" global_diffuse_light.rgb += qt_iblDiffuse * qt_aoFactor;\n";
1650 if (specularLightingEnabled)
1651 fragmentShader <<
" global_specular_light += qt_iblSpecular * qt_aoFactor;\n";
1652 if (enableClearcoat)
1653 fragmentShader <<
" qt_global_clearcoat += qt_iblClearcoat * qt_aoFactor;\n";
1654 }
else if (hasCustomIblProbe) {
1656 fragmentShader.
addUniform(
"qt_lightProbe",
"samplerCube");
1657 fragmentShader.
addUniform(
"qt_lightProbeProperties",
"vec4");
1661 if (enableTransmission) {
1662 fragmentShader <<
" qt_global_transmission += qt_transmissionFactor * qt_getIBLVolumeRefraction(qt_world_normal, qt_view_vector, qt_roughnessAmount, "
1663 "qt_diffuseColor.rgb, qt_specularAmount, qt_varWorldPos, qt_material_specular.w, qt_thicknessFactor, qt_attenuationColor, qt_attenuationDistance);\n";
1667 bool texColorDeclared =
false;
1670 if (
image->m_mapType != QSSGRenderableImage::Type::Specular
1671 &&
image->m_mapType != QSSGRenderableImage::Type::Emissive)
1676 if (!texColorDeclared) {
1677 fragmentShader.
append(
" vec4 qt_texture_color;");
1678 texColorDeclared =
true;
1687 const auto &
names = imageStringTable[int(
image->m_mapType)];
1688 fragmentShader <<
" qt_texture_color = texture2D(" <<
names.imageSampler
1689 <<
", " << (hasIdentityMap ? imageFragCoords :
names.imageFragCoords) <<
");\n";
1691 switch (
image->m_mapType) {
1692 case QSSGRenderableImage::Type::Specular:
1693 fragmentShader.
addInclude(
"tonemapping.glsllib");
1694 fragmentShader.
append(
" global_specular_light += qt_sRGBToLinear(qt_texture_color.rgb) * qt_specularTint;");
1695 fragmentShader.
append(
" global_diffuse_light.a *= qt_texture_color.a;");
1697 case QSSGRenderableImage::Type::Emissive:
1698 fragmentShader.
addInclude(
"tonemapping.glsllib");
1699 fragmentShader.
append(
" qt_global_emission *= qt_sRGBToLinear(qt_texture_color.rgb);");
1708 if (enableTransmission)
1709 fragmentShader <<
" global_diffuse_light.rgb = mix(global_diffuse_light.rgb, qt_global_transmission, qt_transmissionFactor);\n";
1712 fragmentShader <<
" global_diffuse_light.rgb *= 1.0 - qt_metalnessAmount;\n";
1717 fragmentShader <<
" calculateFog(qt_global_emission, global_specular_light, global_diffuse_light.rgb);\n";
1720 fragmentShader <<
" vec4 qt_color_sum = vec4(global_diffuse_light.rgb + global_specular_light + qt_global_emission, global_diffuse_light.a);\n";
1722 if (enableClearcoat) {
1724 fragmentShader <<
" vec3 qt_clearcoatFresnel = qt_schlick3(qt_clearcoatF0, qt_clearcoatF90, clamp(dot(qt_clearcoatNormal, qt_view_vector), 0.0, 1.0));\n";
1725 fragmentShader <<
" qt_global_clearcoat = qt_global_clearcoat * qt_clearcoatAmount;\n";
1726 fragmentShader <<
" qt_color_sum.rgb = qt_color_sum.rgb * (1.0 - qt_clearcoatAmount * qt_clearcoatFresnel) + qt_global_clearcoat;\n";
1731 fragmentShader <<
" qt_customPostProcessor(qt_color_sum, global_diffuse_light, global_specular_light, qt_global_emission, qt_texCoord0, qt_texCoord1";
1733 fragmentShader <<
", qt_customShared);\n";
1735 fragmentShader <<
");\n";
1738 Q_ASSERT(!isDepthPass && !isOrthoShadowPass && !isCubeShadowPass);
1739 fragmentShader.
addInclude(
"tonemapping.glsllib");
1740 fragmentShader.
append(
" fragOutput = vec4(qt_tonemap(qt_color_sum));");
1744 fragmentShader.
append(
" vec3 debugOutput = vec3(0.0);\n");
1745 switch (debugMode) {
1747 fragmentShader.
append(
" debugOutput += qt_tonemap(qt_diffuseColor.rgb);\n");
1750 fragmentShader.
append(
" debugOutput += vec3(qt_roughnessAmount);\n");
1753 fragmentShader.
append(
" debugOutput += vec3(qt_metalnessAmount);\n");
1756 fragmentShader.
append(
" debugOutput += qt_tonemap(global_diffuse_light.rgb);\n");
1759 fragmentShader.
append(
" debugOutput += qt_tonemap(global_specular_light);\n");
1762 fragmentShader.
append(
" debugOutput += vec3(qt_shadow_map_occl);\n");
1765 fragmentShader.
append(
" debugOutput += qt_tonemap(qt_global_emission);\n");
1768 fragmentShader.
append(
" debugOutput += vec3(qt_aoFactor);\n");
1771 fragmentShader.
append(
" debugOutput += qt_world_normal * 0.5 + 0.5;\n");
1774 fragmentShader.
append(
" debugOutput += qt_tangent * 0.5 + 0.5;\n");
1777 fragmentShader.
append(
" debugOutput += qt_binormal * 0.5 + 0.5;\n");
1781 fragmentShader.
append(
" debugOutput += qt_f0;");
1787 fragmentShader.
append(
" fragOutput = vec4(debugOutput, 1.0);\n");
1790 if ((isOrthoShadowPass || isCubeShadowPass || isDepthPass) && isOpaqueDepthPrePass) {
1791 fragmentShader <<
" if ((qt_diffuseColor.a * qt_objectOpacity) < 1.0)\n";
1792 fragmentShader <<
" discard;\n";
1795 if (isOrthoShadowPass) {
1796 fragmentShader.
addUniform(
"qt_shadowDepthAdjust",
"vec2");
1797 fragmentShader <<
" // directional shadow pass\n"
1798 <<
" float qt_shadowDepth = (qt_varDepth + qt_shadowDepthAdjust.x) * qt_shadowDepthAdjust.y;\n"
1799 <<
" fragOutput = vec4(qt_shadowDepth);\n";
1800 }
else if (isCubeShadowPass) {
1801 fragmentShader.
addUniform(
"qt_cameraPosition",
"vec3");
1802 fragmentShader.
addUniform(
"qt_cameraProperties",
"vec2");
1803 fragmentShader <<
" // omnidirectional shadow pass\n"
1804 <<
" vec3 qt_shadowCamPos = vec3(qt_cameraPosition.x, qt_cameraPosition.y, qt_cameraPosition.z);\n"
1805 <<
" float qt_shadowDist = length(qt_varShadowWorldPos - qt_shadowCamPos);\n"
1806 <<
" qt_shadowDist = (qt_shadowDist - qt_cameraProperties.x) / (qt_cameraProperties.y - qt_cameraProperties.x);\n"
1807 <<
" fragOutput = vec4(qt_shadowDist, qt_shadowDist, qt_shadowDist, 1.0);\n";
1809 fragmentShader.
addInclude(
"tonemapping.glsllib");
1810 fragmentShader.
append(
" fragOutput = vec4(qt_tonemap(qt_diffuseColor.rgb), qt_diffuseColor.a * qt_objectOpacity);");
1829 materialInfoString = inShaderKeyPrefix;
1830 key.toString(materialInfoString, inProperties);
1863 bool receivesShadows,
1864 bool receivesReflections,
1881 bool usesProjectionMatrix =
false;
1882 bool usesInvProjectionMatrix =
false;
1883 bool usesViewMatrix =
false;
1884 bool usesViewProjectionMatrix =
false;
1885 bool usesModelViewProjectionMatrix =
false;
1886 bool usesNormalMatrix =
false;
1887 bool usesParentMatrix =
false;
1889 if (inMaterial.
type == QSSGRenderGraphObject::Type::CustomMaterial) {
1894 usesViewMatrix =
true;
1895 usesViewProjectionMatrix =
true;
1898 if (usesInstancing) {
1900 usesViewProjectionMatrix =
true;
1901 usesParentMatrix =
true;
1903 usesModelViewProjectionMatrix =
true;
1904 usesNormalMatrix =
true;
1908 usesViewProjectionMatrix =
true;
1911 if (usesProjectionMatrix || usesInvProjectionMatrix) {
1913 if (usesProjectionMatrix)
1915 if (usesInvProjectionMatrix)
1918 if (usesViewMatrix) {
1922 if (usesViewProjectionMatrix) {
1925 viewProj = clipSpaceCorrMatrix * viewProj;
1935 if (usesModelViewProjectionMatrix) {
1937 mvp *= inModelViewProjection;
1940 if (usesNormalMatrix)
1943 if (usesParentMatrix)
1944 shaders.setUniform(ubufData,
"qt_parentMatrix", globalInstanceTransform.
constData(), 16 *
sizeof(
float));
1948 if (morphSize > 0) {
1949 if (inMorphWeights.
mSize >= morphSize) {
1950 shaders.setUniformArray(ubufData,
"qt_morphWeights", inMorphWeights.
mData, morphSize,
1955 newWeights.
append(zeroWeights);
1956 shaders.setUniformArray(ubufData,
"qt_morphWeights", newWeights.
constData(), morphSize,
1965 lightsUniformData.
count = 0;
1967 for (
quint32 lightIdx = 0, shadowMapCount = 0, lightEnd = inLights.
size();
1971 const bool lightShadows = inLights[lightIdx].shadows;
1976 lightsUniformData.
count += 1;
1979 lightData.
specular[0] = lightSpecular.
x() * brightness;
1980 lightData.
specular[1] = lightSpecular.
y() * brightness;
1981 lightData.
specular[2] = lightSpecular.
z() * brightness;
2007 if (theLight->
type != QSSGRenderLight::Type::DirectionalLight) {
2010 if (receivesShadows)
2017 if (receivesShadows) {
2023 0.0, 0.0, 0.0, 1.0 };
2025 shaders.setUniform(ubufData,
names.shadowMatrixStem,
m.constData(), 16 *
sizeof(
float));
2031 if (receivesShadows) {
2036 shaders.setUniform(ubufData,
names.shadowControlStem, &shadowControl, 4 *
sizeof(
float));
2042 if (theLight->
type == QSSGRenderLight::Type::PointLight
2043 || theLight->
type == QSSGRenderLight::Type::SpotLight) {
2053 if (theLight->
type == QSSGRenderLight::Type::SpotLight) {
2068 shaders.setLightmapTexture(lightmapTexture);
2074 if (materialIblProbe)
2075 theLightProbe = materialIblProbe;
2079 if (theLightProbe && lightProbeTexture.
m_texture) {
2082 const int maxMipLevel = lightProbeTexture.
m_mipmapCount - 1;
2085 shaders.setUniform(ubufData,
"qt_lightProbeOrientation",
2094 shaders.setLightProbeTexture(lightProbeTexture.
m_texture, theHorzLightProbeTilingMode, theVertLightProbeTilingMode);
2097 const float emptyProps[4] = { 0.0f, 0.0f, -1.0f, 0.0f };
2100 shaders.setLightProbeTexture(
nullptr);
2103 if (receivesReflections && reflectionProbe.
enabled) {
2113 const auto qMix = [](
float x,
float y,
float a) {
2114 return (
x * (1.0f -
a) + (
y *
a));
2118 return QVector3D{qMix(
x.x(),
y.x(),
a), qMix(
x.y(),
y.y(),
a), qMix(
x.z(),
y.z(),
a)};
2124 : materialSpecularTint;
2127 const float ior = materialAdapter->
ior();
2128 QVector4D specularColor(specularTint, ior);
2132 const bool hasLighting = materialAdapter->
hasLighting();
2133 shaders.setLightsEnabled(hasLighting);
2135 for (
int lightIdx = 0; lightIdx < lightsUniformData.
count; ++lightIdx) {
2137 lightData.
diffuse[0] = lightColor[lightIdx][0];
2138 lightData.
diffuse[1] = lightColor[lightIdx][1];
2139 lightData.
diffuse[2] = lightColor[lightIdx][2];
2142 memcpy(ubufData +
shaders.ub0LightDataOffset(), &lightsUniformData,
shaders.ub0LightDataSize());
2147 const float materialProperties[4] = {
2155 const float materialProperties2[4] = {
2163 const float materialProperties3[4] = {
2171 const float materialProperties4[4] = {
2188 const float rhiProperties[4] = {
2190 inRenderProperties.
isYUpInNDC ? 1.0f : -1.0f,
2199 const auto &
names = imageStringTable[int(theImage->m_mapType)];
2204 const QMatrix4x4 &textureTransform = theImage->m_imageNode.m_textureTransform;
2207 const float *dataPtr(textureTransform.
constData());
2211 const float offsets[3] = { dataPtr[12], dataPtr[13], 0.0f };
2214 const float rotations[4] = { dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5] };
2215 shaders.setUniform(ubufData,
names.imageRotations, rotations,
sizeof(rotations), &
indices.imageRotationsUniformIndex);
2218 if (shadowDepthAdjust)
2222 if (usesPointsTopology) {
2223 const float pointSize = materialAdapter->
pointSize();
2224 shaders.setUniform(ubufData,
"qt_materialPointSize", &pointSize,
sizeof(
float), &cui.
pointSizeIdx);
2232 const float fogColor[4] = {
2238 shaders.setUniform(ubufData,
"qt_fogColor", fogColor, 4 *
sizeof(
float), &cui.
fogColorIdx);
2239 const float fogDepthProperties[4] = {
2246 const float fogHeightProperties[4] = {
2253 const float fogTransmitProperties[4] = {
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isIdentity() const
Returns true if this matrix is the identity; false otherwise.
const T * constData() const
Returns a constant pointer to the raw data of this matrix.
const_pointer constData() const noexcept
void push_back(parameter_type t)
void append(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
QMatrix4x4 inverted(bool *invertible=nullptr) const
Returns the inverse of this matrix.
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
QSSGRhiShaderPipelinePtr compileGeneratedRhiShader(const QByteArray &inMaterialInfoString, const QSSGShaderFeatures &inFeatureSet, QSSGShaderLibraryManager &shaderLibraryManager, QSSGShaderCache &theCache, QSSGRhiShaderPipeline::StageFlags stageFlags)
const std::unique_ptr< QSSGBufferManager > & bufferManager() const
QSSGShadowMapEntry * shadowMapEntry(int lightIdx)
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr float z() const noexcept
Returns the z coordinate of this point.
The QVector4D class represents a vector or vertex in 4D space.
Combined button and popup list for selecting options.
void textureCoordVariableName(char(&outString)[TEXCOORD_VAR_LEN], quint8 uvSet)
const int TEXCOORD_VAR_LEN
void textureCoordVaryingName(char(&outString)[TEXCOORD_VAR_LEN], quint8 uvSet)
constexpr ImageStringSet imageStringTable[]
Q_QUICK3DRUNTIMERENDER_EXPORT QList< QByteArrayView > reservedArgumentNames()
constexpr Initialization Uninitialized
Q_DECL_CONSTEXPR float translateConstantAttenuation(float attenuation)
Q_DECL_CONSTEXPR float translateQuadraticAttenuation(float attenuation)
Q_DECL_CONSTEXPR float translateLinearAttenuation(float attenuation)
#define QByteArrayLiteral(str)
Q_CORE_EXPORT char * qstrncpy(char *dst, const char *src, size_t len)
Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt,...)
constexpr float qDegreesToRadians(float degrees)
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLsizei const GLenum * props
GLenum GLuint GLintptr offset
GLsizei GLenum const void * indices
GLuint GLenum GLenum transform
GLuint GLsizei const GLuint const GLintptr * offsets
GLsizei GLsizei GLuint * shaders
#define DefineImageStringTableEntry(V)
static void calculatePointLightAttenuation(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames)
static void handleDirectionalLight(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, bool usesSharedVar, bool hasCustomFrag, QSSGShaderMaterialAdapter *materialAdapter, QSSGShaderLibraryManager &shaderLibraryManager, bool specularLightingEnabled, bool enableClearcoat, bool enableTransmission)
static void sanityCheckImageForSampler(const QSSGRenderableImage &image, const char *samplerName)
static void handleSpecularLight(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, QSSGShaderMaterialAdapter *materialAdapter, QSSGShaderLibraryManager &shaderLibraryManager, bool usesSharedVar, bool hasCustomFrag, bool specularLightingEnabled, bool enableClearcoat, bool enableTransmission, bool useNormalizedDirection)
static void generateTempLightColor(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, QSSGShaderMaterialAdapter *materialAdapter)
static QByteArray uvTransform(const QByteArray &imageRotations, const QByteArray &imageOffsets)
static void generateImageUVSampler(QSSGMaterialVertexPipeline &vertexGenerator, QSSGStageGeneratorBase &fragmentShader, const QSSGShaderDefaultMaterialKey &key, const QSSGRenderableImage &image, char(&outString)[TEXCOORD_VAR_LEN], quint8 uvSet=0)
static void generateMainLightCalculation(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialVertexPipeline &vertexShader, const QSSGShaderDefaultMaterialKey &inKey, const QSSGRenderGraphObject &inMaterial, const QSSGShaderLightListView &lights, QSSGShaderLibraryManager &shaderLibraryManager, QSSGRenderableImage *translucencyImage, bool hasCustomFrag, bool usesSharedVar, bool enableLightmap, bool enableShadowMaps, bool specularLightingEnabled, bool enableClearcoat, bool enableTransmission)
static void generateImageUVCoordinates(QSSGMaterialVertexPipeline &vertexShader, QSSGStageGeneratorBase &fragmentShader, const QSSGShaderDefaultMaterialKey &key, QSSGRenderableImage &image, bool forceFragmentShader=false, quint32 uvSet=0, bool reuseImageCoords=false)
static void addLocalVariable(QSSGStageGeneratorBase &inGenerator, const QByteArray &inName, const QByteArray &inType)
static bool hasCustomFunction(const QByteArray &funcName, QSSGShaderMaterialAdapter *materialAdapter, QSSGShaderLibraryManager &shaderLibraryManager)
static void addTranslucencyIrradiance(QSSGStageGeneratorBase &infragmentShader, QSSGRenderableImage *image, const QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames)
static float ZERO_MATRIX[16]
static QVarLengthArray< QSSGMaterialShaderGenerator::ShadowVariableNames, 16 > q3ds_shadowMapVariableNames
static QSSGMaterialShaderGenerator::ShadowVariableNames setupShadowMapVariableNames(qsizetype lightIdx)
static void generateShadowMapOcclusion(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialVertexPipeline &vertexShader, quint32 lightIdx, bool inShadowEnabled, QSSGRenderLight::Type inType, const QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, const QSSGShaderDefaultMaterialKey &inKey)
#define DefineImageStrings(V)
static void handleSpotLight(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, const QByteArray &lightVarPrefix, QSSGShaderMaterialAdapter *materialAdapter, QSSGShaderLibraryManager &shaderLibraryManager, bool usesSharedVar, bool hasCustomFrag, bool specularLightingEnabled, bool enableClearcoat, bool enableTransmission)
static void handlePointLight(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, QSSGShaderMaterialAdapter *materialAdapter, QSSGShaderLibraryManager &shaderLibraryManager, bool usesSharedVar, bool hasCustomFrag, bool specularLightingEnabled, bool enableClearcoat, bool enableTransmission)
static constexpr QByteArrayView qssg_shader_arg_names[]
static void outputSpecularEquation(QSSGRenderDefaultMaterial::MaterialSpecularModel inSpecularModel, QSSGStageGeneratorBase &fragmentShader, const QByteArray &inLightDir, const QByteArray &inLightSpecColor)
static void generateDirections(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialShaderGenerator::LightVariableNames &lightVarNames, const QByteArray &lightVarPrefix, QSSGMaterialVertexPipeline &vertexShader, const QSSGShaderDefaultMaterialKey &inKey)
static void generateFragmentShader(QSSGStageGeneratorBase &fragmentShader, QSSGMaterialVertexPipeline &vertexShader, const QSSGShaderDefaultMaterialKey &inKey, const QSSGShaderDefaultMaterialKeyProperties &keyProps, const QSSGShaderFeatures &featureSet, const QSSGRenderGraphObject &inMaterial, const QSSGShaderLightListView &lights, QSSGRenderableImage *firstImage, QSSGShaderLibraryManager &shaderLibraryManager)
static void maybeAddMaterialFresnel(QSSGStageGeneratorBase &fragmentShader, const QSSGShaderDefaultMaterialKeyProperties &keyProps, QSSGDataView< quint32 > inKey, bool hasMetalness)
static QSSGShaderMaterialAdapter * getMaterialAdapter(const QSSGRenderGraphObject &inMaterial)
static QSSGMaterialShaderGenerator::LightVariableNames setupLightVariableNames(qint32 lightIdx, QSSGRenderLight &inLight)
std::shared_ptr< QSSGRhiShaderPipeline > QSSGRhiShaderPipelinePtr
#define QSSG_MAX_NUM_LIGHTS
#define QSSG_MAX_NUM_SHADOW_MAPS
bool contains(const AT &t) const noexcept
QRhiTexture * rhiScreenTexture
const QMatrix3x3 & probeOrientation
bool isClipDepthZeroToOne
const QSSGCameraRenderData & cameraData
const QSSGRenderLayer & layer
QRhiTexture * rhiDepthTexture
QSSGRenderShadowMap * shadowMapManager
QSSGRenderImage * lightProbe
QRhiTexture * rhiSsaoTexture
QByteArray lightConstantAttenuation
QByteArray normalizedDirection
QByteArray lightConeAngle
QByteArray lightSpecularColor
QByteArray lightInnerConeAngle
QByteArray lightQuadraticAttenuation
QByteArray lightLinearAttenuation
QByteArray lightDirection
QByteArray relativeDistance
QByteArray relativeDirection
static QSSGRhiShaderPipelinePtr generateMaterialRhiShader(const QByteArray &inShaderKeyPrefix, QSSGMaterialVertexPipeline &vertexGenerator, const QSSGShaderDefaultMaterialKey &key, QSSGShaderDefaultMaterialKeyProperties &inProperties, const QSSGShaderFeatures &inFeatureSet, const QSSGRenderGraphObject &inMaterial, const QSSGShaderLightListView &inLights, QSSGRenderableImage *inFirstImage, QSSGShaderLibraryManager &shaderLibraryManager, QSSGShaderCache &theCache)
static const char * vertexMainArgumentList()
static const char * vertexInstancedMainArgumentList()
static const char * getSamplerName(QSSGRenderableImage::Type type)
static const char * postProcessorArgumentList()
static const char * specularLightProcessorArgumentList()
static const char * ambientLightProcessorArgumentList()
static const char * iblProbeProcessorArgumentList()
static const char * spotLightProcessorArgumentList()
static const char * pointLightProcessorArgumentList()
static const char * directionalLightProcessorArgumentList()
static const char * shadedFragmentMainArgumentList()
static void setRhiMaterialProperties(const QSSGRenderContextInterface &, QSSGRhiShaderPipeline &shaders, char *ubufData, QSSGRhiGraphicsPipelineState *inPipelineState, const QSSGRenderGraphObject &inMaterial, const QSSGShaderDefaultMaterialKey &inKey, QSSGShaderDefaultMaterialKeyProperties &inProperties, const QSSGRenderCamera &inCamera, const QMatrix4x4 &inModelViewProjection, const QMatrix3x3 &inNormalMatrix, const QMatrix4x4 &inGlobalTransform, const QMatrix4x4 &clipSpaceCorrMatrix, const QMatrix4x4 &localInstanceTransform, const QMatrix4x4 &globalInstanceTransform, const QSSGDataView< float > &inMorphWeights, QSSGRenderableImage *inFirstImage, float inOpacity, const QSSGLayerGlobalRenderProperties &inRenderProperties, const QSSGShaderLightListView &inLights, const QSSGShaderReflectionProbe &reflectionProbe, bool receivesShadows, bool receivesReflections, const QVector2D *shadowDepthAdjust, QRhiTexture *lightmapTexture)
void generateShadowWorldPosition(const QSSGShaderDefaultMaterialKey &inKey)
void beginVertexGeneration(const QSSGShaderDefaultMaterialKey &inKey, const QSSGShaderFeatures &inFeatureSet, QSSGShaderLibraryManager &shaderLibraryManager)
void addDefinition(const QByteArray &name, const QByteArray &value=QByteArray())
void addUniform(const QByteArray &name, const QByteArray &type)
void generateEnvMapReflection(const QSSGShaderDefaultMaterialKey &inKey)
QSSGStageGeneratorBase & fragment()
void beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager)
void generateVertexColor(const QSSGShaderDefaultMaterialKey &inKey)
void endFragmentGeneration()
void generateVarTangentAndBinormal(const QSSGShaderDefaultMaterialKey &inKey, bool &genTangent, bool &genBinormal)
void assignOutput(const QByteArray &inVarName, const QByteArray &inVarValueExpr)
QSSGProgramGenerator * programGenerator() const
void generateViewVector(const QSSGShaderDefaultMaterialKey &inKey)
void addOutgoing(const QByteArray &name, const QByteArray &type)
void addFunction(const QByteArray &functionName)
void generateWorldNormal(const QSSGShaderDefaultMaterialKey &inKey)
void generateWorldPosition(const QSSGShaderDefaultMaterialKey &inKey)
void endVertexGeneration()
void generateUVCoords(quint32 inUVSet, const QSSGShaderDefaultMaterialKey &inKey)
Generates UV coordinates in shader code.
void generateLightmapUVCoords(const QSSGShaderDefaultMaterialKey &inKey)
void calculateViewProjectionMatrix(QMatrix4x4 &outMatrix) const
RenderFlags m_renderFlags
@ InverseProjectionMatrix
QSSGRenderTextureCoordOp m_horizontalTilingMode
QSSGRenderTextureCoordOp m_verticalTilingMode
struct QSSGRenderLayer::FogOptions fog
QVector3D m_specularColor
QMatrix4x4 globalTransform
QVector3D getGlobalPos() const
QSSGRenderableImage * m_nextImage
const QSSGRenderImage & m_imageNode
QRhiTexture * shadowMapTexture
QByteArray shadowMapTextureUniformName
QSSGShaderKeyBoolean m_usesInverseProjectionMatrix
QSSGShaderKeyUnsigned< 4 > m_debugMode
QSSGShaderKeyBoolean m_usesProjectionMatrix
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord1Offset
QSSGShaderKeyBoolean m_fogEnabled
QSSGShaderKeyBoolean m_usesInstancing
QSSGShaderKeyBoolean m_blendParticles
QSSGShaderKeyTextureChannel m_textureChannels[SingleChannelImageCount]
@ ClearcoatRoughnessChannel
QSSGShaderKeyBoolean m_isDoubleSided
QSSGShaderKeyUnsigned< 8 > m_targetPositionOffset
QSSGShaderKeyBoolean m_hasIbl
QSSGShaderKeyUnsigned< 8 > m_targetTangentOffset
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord0Offset
QSSGShaderKeyUnsigned< 8 > m_targetColorOffset
QSSGShaderKeyUnsigned< 8 > m_targetNormalOffset
QSSGShaderKeyBoolean m_fresnelEnabled
QSSGShaderKeyUnsigned< 8 > m_targetBinormalOffset
QSSGShaderKeyUnsigned< 8 > m_targetCount
QSSGShaderKeyBoolean m_usesPointsTopology
QSSGShaderKeyBoolean m_specularAAEnabled
constexpr bool isSet(Feature feature) const
bool getValue(QSSGDataView< quint32 > inDataStore) const
TexturChannelBits getTextureChannel(QSSGDataView< quint32 > inKeySet) const
quint32 getValue(QSSGDataView< quint32 > inDataStore) const
float constantAttenuation
float quadraticAttenuation
virtual float bumpAmount()=0
virtual float clearcoatRoughnessAmount()=0
virtual float heightAmount()=0
virtual QVector3D specularTint()=0
virtual float maxHeightSamples()=0
virtual bool isVertexColorsEnabled()=0
virtual float occlusionAmount()=0
virtual QSSGRenderImage * iblProbe()=0
virtual float specularAmount()=0
virtual float attenuationDistance()=0
virtual QVector3D attenuationColor()=0
virtual bool isUnshaded()
virtual float clearcoatAmount()=0
virtual float transmissionFactor()=0
virtual bool isPrincipled()=0
virtual bool isSpecularEnabled()=0
virtual bool hasCustomShaderFunction(QSSGShaderCache::ShaderType shaderType, const QByteArray &funcName, QSSGShaderLibraryManager &shaderLibraryManager)
virtual QVector3D emissiveColor()=0
virtual bool hasCustomShaderSnippet(QSSGShaderCache::ShaderType type)
virtual float specularRoughness()=0
virtual bool isTransmissionEnabled()=0
virtual float pointSize()=0
virtual float fresnelPower()=0
virtual float metalnessAmount()=0
virtual float lineWidth()=0
virtual QVector4D color()=0
virtual float alphaCutOff()=0
virtual float translucentFallOff()=0
virtual float diffuseLightWrap()=0
virtual float minHeightSamples()=0
virtual float thicknessFactor()=0
virtual bool hasLighting()=0
virtual bool isSpecularGlossy()=0
virtual QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel()=0
virtual bool usesSharedVariables()
virtual bool isClearcoatEnabled()=0
virtual QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode()=0
virtual void setCustomPropertyUniforms(char *ubufData, QSSGRhiShaderPipeline &shaderPipeline, const QSSGRenderContextInterface &context)
virtual bool isMetalnessEnabled()=0
QVector3D probeCubeMapCenter
QMatrix4x4 m_lightVP
light view projection matrix
QRhiTexture * m_rhiDepthMap
QRhiTexture * m_rhiDepthCube
QMatrix4x4 m_lightView
light view transform
virtual void addFunction(const QByteArray &functionName) final
virtual void addUniform(const QByteArray &name, const QByteArray &type)
virtual void append(const QByteArray &data)
virtual void addInclude(const QByteArray &name) final
const char * imageSampler
const char * imageFragCoordsTemp
const char * imageRotations
const char * imageOffsets
const char * imageFragCoords
const char * imageSamplerSize