7#ifndef QSSG_RENDER_SHADER_KEY_H
8#define QSSG_RENDER_SHADER_KEY_H
21#include <QtQuick3DUtils/private/qssgdataref_p.h>
22#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
23#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
24#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h>
36struct QSSGShaderKeyPropertyBase
40 explicit constexpr QSSGShaderKeyPropertyBase(
const char *inName =
"") : name(inName), offset(0) {}
41 quint32 getOffset()
const {
return offset; }
42 void setOffset(quint32 of) { offset = of; }
44 template<quint32 TBitWidth>
45 quint32 getMaskTemplate()
const
47 quint32 bit = offset % 32;
48 quint32 startValue = (1 << TBitWidth) - 1;
49 quint32 mask = startValue << bit;
53 quint32 getIdx()
const {
return offset / 32; }
56 void internalToString(QByteArray &ioStr,
const QByteArrayView &inBuffer)
const
60 ioStr.append(inBuffer);
63 static void internalToString(QByteArray &ioStr,
const QByteArrayView &name,
bool inValue)
68 ioStr.append(inValue ? QByteArrayView(
"true") : QByteArrayView(
"false"));
71 static bool getBoolValue(
const QByteArray& str,
const QByteArrayView &name)
73 const int index = str.indexOf(name);
76 const qsizetype nameLen = name.size();
77 if (str[index + nameLen] !=
'=')
79 if (str.mid(index + nameLen + 1, 4) == QByteArrayView(
"true"))
94 void setValue(QSSGDataRef<quint32> inDataStore,
bool inValue)
const
96 const qint32 idx = qint32(getIdx());
97 Q_ASSERT(idx >= 0 && idx <= INT32_MAX);
98 Q_ASSERT(inDataStore.size() > idx);
99 quint32 mask = getMask();
100 quint32 &target = inDataStore[idx];
102 target = target | mask;
105 target = target & mask;
109 bool getValue(QSSGDataView<quint32> inDataStore)
const
111 quint32 idx = getIdx();
112 quint32 mask = getMask();
113 const quint32 &target = inDataStore[idx];
114 return (target & mask) ?
true :
false;
117 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
119 bool isHigh = getValue(inKeySet);
120 internalToString(ioStr, name, isHigh);
122 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
124 setValue(inKeySet, getBoolValue(ioStr, name));
128template<quint32 TBitWidth>
136 void setValue(QSSGDataRef<quint32> inDataStore, quint32 inValue)
const
138 quint32 startValue = (1 << TBitWidth) - 1;
140 inValue = inValue & startValue;
141 quint32 bit = offset % 32;
142 quint32 mask = getMask();
143 quint32 idx = getIdx();
144 inValue = inValue << bit;
145 quint32 &target = inDataStore[idx];
147 quint32 inverseMask = ~mask;
148 target = target & inverseMask;
149 target = target | inValue;
154 quint32 idx = getIdx();
155 quint32 bit = offset % 32;
156 quint32 mask = getMask();
157 const quint32 &target = inDataStore[idx];
159 quint32 retval = target & mask;
160 retval = retval >> bit;
164 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
166 quint32 value = getValue(inKeySet);
168 memset(buf, 0,
sizeof (buf));
169 toStr(value, toDataRef(buf, 64));
170 internalToString(ioStr, buf);
173 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
175 const qsizetype nameLen = name.size();
176 const qsizetype strOffset = ioStr.indexOf(name);
177 if (strOffset >= 0) {
179 if (ioStr[strOffset + nameLen] !=
'=')
181 const QByteArray s = ioStr.right(ioStr.size() - strOffset - nameLen - 1);
183 while (QChar(QLatin1Char(s[i])).isDigit())
185 const quint32 value = s.left(i).toInt();
186 setValue(inKeySet, value);
191 static quint32 toStr(quint32 item, QSSGDataRef<
char> buffer)
194 return static_cast<quint32>(::snprintf(buffer.begin(), buffer.size(),
"%u", item));
215 setValue(inKeySet, quint32(channel));
223 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
227 ioStr.append(textureChannelToChar[getTextureChannel(inKeySet)]);
229 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
231 const qsizetype nameLen = name.size();
232 const qsizetype strOffset = ioStr.indexOf(name);
233 if (strOffset >= 0) {
235 if (ioStr[strOffset + nameLen] !=
'=')
237 const char ch = ioStr[strOffset + nameLen + 1];
266 return (getValue(inKeySet) & imageBit) ?
true :
false;
271 quint32 theValue = getValue(inKeySet);
272 quint32 mask = imageBit;
274 theValue = theValue | mask;
277 theValue = theValue & mask;
279 setValue(inKeySet, theValue);
282 bool isEnabled(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(Enabled, inKeySet); }
283 void setEnabled(QSSGDataRef<quint32> inKeySet,
bool val) { setBitValue(Enabled, val, inKeySet); }
285 bool isEnvMap(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(EnvMap, inKeySet); }
286 void setEnvMap(QSSGDataRef<quint32> inKeySet,
bool val) { setBitValue(EnvMap, val, inKeySet); }
288 bool isLightProbe(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(LightProbe, inKeySet); }
289 void setLightProbe(QSSGDataRef<quint32> inKeySet,
bool val) { setBitValue(LightProbe, val, inKeySet); }
291 bool isIdentityTransform(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(Identity, inKeySet); }
294 bool isUsingUV1(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(UsesUV1, inKeySet); }
295 void setUsesUV1(QSSGDataRef<quint32> inKeySet,
bool val) { setBitValue(UsesUV1, val, inKeySet); }
297 bool isLinear(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(Linear, inKeySet); }
298 void setLinear(QSSGDataRef<quint32> inKeySet,
bool val) { setBitValue(Linear, val, inKeySet); }
300 bool isPreMultipliedAlpha(QSSGDataView<quint32> inKeySet)
const {
return getBitValue(PreMultipliedAlpha, inKeySet); }
301 void setPreMultipliedAlpha(QSSGDataRef<quint32> inKeySet,
bool val) { setBitValue(PreMultipliedAlpha, val, inKeySet); }
303 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
306 ioStr.append(QByteArrayView(
"={"));
307 internalToString(ioStr, QByteArrayView(
"enabled"), isEnabled(inKeySet));
309 internalToString(ioStr, QByteArrayView(
"envMap"), isEnvMap(inKeySet));
311 internalToString(ioStr, QByteArrayView(
"lightProbe"), isLightProbe(inKeySet));
313 internalToString(ioStr, QByteArrayView(
"identity"), isIdentityTransform(inKeySet));
315 internalToString(ioStr, QByteArrayView(
"usesUV1"), isUsingUV1(inKeySet));
317 internalToString(ioStr, QByteArrayView(
"linear"), isLinear(inKeySet));
319 internalToString(ioStr, QByteArrayView(
"preMultipliedAlpha"), isPreMultipliedAlpha(inKeySet));
328 void setSpecularModel(QSSGDataRef<quint32> inKeySet, QSSGRenderDefaultMaterial::MaterialSpecularModel inModel)
330 setValue(inKeySet, quint32(inModel));
335 return static_cast<QSSGRenderDefaultMaterial::MaterialSpecularModel>(getValue(inKeySet));
338 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
342 switch (getSpecularModel(inKeySet)) {
343 case QSSGRenderDefaultMaterial::MaterialSpecularModel::SchlickGGX:
344 ioStr.append(QByteArrayView(
"SchlickGGX"));
346 case QSSGRenderDefaultMaterial::MaterialSpecularModel::BlinnPhong:
347 ioStr.append(QByteArrayView(
"BlinnPhong"));
351 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
353 const qsizetype nameLen = name.size();
354 const int strOffset = ioStr.indexOf(name);
355 if (strOffset >= 0) {
357 if (ioStr[strOffset + nameLen] !=
'=')
359 const int codeOffsetBegin = strOffset + nameLen + 1;
361 while (ioStr[codeOffsetBegin + codeOffset] !=
';')
363 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
364 if (val == QByteArrayView(
"SchlickGGX"))
365 setSpecularModel(inKeySet, QSSGRenderDefaultMaterial::MaterialSpecularModel::SchlickGGX);
366 if (val == QByteArrayView(
"BlinnPhong"))
367 setSpecularModel(inKeySet, QSSGRenderDefaultMaterial::MaterialSpecularModel::BlinnPhong);
376 void setDiffuseModel(QSSGDataRef<quint32> inKeySet, QSSGRenderDefaultMaterial::MaterialDiffuseModel inModel)
378 setValue(inKeySet, quint32(inModel));
383 return static_cast<QSSGRenderDefaultMaterial::MaterialDiffuseModel>(getValue(inKeySet));
386 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
390 switch (getDiffuseModel(inKeySet)) {
391 case QSSGRenderDefaultMaterial::MaterialDiffuseModel::Burley:
392 ioStr.append(QByteArrayView(
"Burley"));
394 case QSSGRenderDefaultMaterial::MaterialDiffuseModel::Lambert:
395 ioStr.append(QByteArrayView(
"Lambert"));
397 case QSSGRenderDefaultMaterial::MaterialDiffuseModel::LambertWrap:
398 ioStr.append(QByteArrayView(
"LambertWrap"));
402 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
404 const qsizetype nameLen = name.size();
405 const int strOffset = ioStr.indexOf(name);
406 if (strOffset >= 0) {
408 if (ioStr[strOffset + nameLen] !=
'=')
410 const int codeOffsetBegin = strOffset + nameLen + 1;
412 while (ioStr[codeOffsetBegin + codeOffset] !=
';')
414 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
415 if (val == QByteArrayView(
"Burley"))
416 setDiffuseModel(inKeySet, QSSGRenderDefaultMaterial::MaterialDiffuseModel::Burley);
417 if (val == QByteArrayView(
"Lambert"))
418 setDiffuseModel(inKeySet, QSSGRenderDefaultMaterial::MaterialDiffuseModel::Lambert);
419 if (val == QByteArrayView(
"LambertWrap"))
420 setDiffuseModel(inKeySet, QSSGRenderDefaultMaterial::MaterialDiffuseModel::LambertWrap);
436 void setShadowSoftness(QSSGDataRef<quint32> inKeySet, QSSGRenderLight::SoftShadowQuality inQuality)
440 case QSSGRenderLight::SoftShadowQuality::Hard:
443 case QSSGRenderLight::SoftShadowQuality::PCF4:
446 case QSSGRenderLight::SoftShadowQuality::PCF8:
449 case QSSGRenderLight::SoftShadowQuality::PCF16:
454 setValue(inKeySet, val);
459 quint32 val = getValue(inKeySet);
462 return QSSGRenderLight::SoftShadowQuality::Hard;
464 return QSSGRenderLight::SoftShadowQuality::PCF4;
466 return QSSGRenderLight::SoftShadowQuality::PCF8;
469 return QSSGRenderLight::SoftShadowQuality::PCF16;
473 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
477 switch (getShadowSoftness(inKeySet)) {
478 case QSSGRenderLight::SoftShadowQuality::Hard:
479 ioStr.append(QByteArrayView(
"Hard"));
481 case QSSGRenderLight::SoftShadowQuality::PCF4:
482 ioStr.append(QByteArrayView(
"PCF4"));
484 case QSSGRenderLight::SoftShadowQuality::PCF8:
485 ioStr.append(QByteArrayView(
"PCF8"));
487 case QSSGRenderLight::SoftShadowQuality::PCF16:
488 case QSSGRenderLight::SoftShadowQuality::PCF32:
489 case QSSGRenderLight::SoftShadowQuality::PCF64:
490 ioStr.append(QByteArrayView(
"PCF16"));
495 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
497 const qsizetype nameLen = name.size();
498 const int strOffset = ioStr.indexOf(name);
499 if (strOffset >= 0) {
501 if (ioStr[strOffset + nameLen] !=
'=')
503 const int codeOffsetBegin = strOffset + nameLen + 1;
505 while (ioStr[codeOffsetBegin + codeOffset] !=
';')
507 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
508 if (val == QByteArrayView(
"Hard"))
509 setShadowSoftness(inKeySet, QSSGRenderLight::SoftShadowQuality::Hard);
510 if (val == QByteArrayView(
"PCF4"))
511 setShadowSoftness(inKeySet, QSSGRenderLight::SoftShadowQuality::PCF4);
512 if (val == QByteArrayView(
"PCF8"))
513 setShadowSoftness(inKeySet, QSSGRenderLight::SoftShadowQuality::PCF8);
514 if (val == QByteArrayView(
"PCF16"))
515 setShadowSoftness(inKeySet, QSSGRenderLight::SoftShadowQuality::PCF16);
525 void setAlphaMode(QSSGDataRef<quint32> inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode inMode)
527 setValue(inKeySet, quint32(inMode));
532 return static_cast<QSSGRenderDefaultMaterial::MaterialAlphaMode>(getValue(inKeySet));
535 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
539 switch (getAlphaMode(inKeySet)) {
540 case QSSGRenderDefaultMaterial::MaterialAlphaMode::Default:
541 ioStr.append(QByteArrayView(
"Default"));
543 case QSSGRenderDefaultMaterial::MaterialAlphaMode::Mask:
544 ioStr.append(QByteArrayView(
"Mask"));
546 case QSSGRenderDefaultMaterial::MaterialAlphaMode::Blend:
547 ioStr.append(QByteArrayView(
"Blend"));
549 case QSSGRenderDefaultMaterial::MaterialAlphaMode::Opaque:
550 ioStr.append(QByteArrayView(
"Opaque"));
554 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
556 const qsizetype nameLen = name.size();
557 const qsizetype strOffset = ioStr.indexOf(name);
558 if (strOffset >= 0) {
560 if (ioStr[strOffset + nameLen] !=
'=')
562 const int codeOffsetBegin = strOffset + nameLen + 1;
564 while (ioStr[codeOffsetBegin + codeOffset] !=
';')
566 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
567 if (val == QByteArrayView(
"Default"))
568 setAlphaMode(inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode::Default);
569 if (val == QByteArrayView(
"Mask"))
570 setAlphaMode(inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode::Mask);
571 if (val == QByteArrayView(
"Blend"))
572 setAlphaMode(inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode::Blend);
573 if (val == QByteArrayView(
"Opaque"))
574 setAlphaMode(inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode::Opaque);
597 return (getValue(inKeySet) & bit) ?
true :
false;
601 quint32 v = getValue(inKeySet);
602 v = value ? (v | bit) : (v & ~bit);
603 setValue(inKeySet, v);
606 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet)
const
609 ioStr.append(QByteArrayView(
"={"));
610 internalToString(ioStr, QByteArrayView(
"position"), getBitValue(Position, inKeySet));
612 internalToString(ioStr, QByteArrayView(
"normal"), getBitValue(Normal, inKeySet));
614 internalToString(ioStr, QByteArrayView(
"texcoord0"), getBitValue(TexCoord0, inKeySet));
616 internalToString(ioStr, QByteArrayView(
"texcoord1"), getBitValue(TexCoord1, inKeySet));
618 internalToString(ioStr, QByteArrayView(
"tangent"), getBitValue(Tangent, inKeySet));
620 internalToString(ioStr, QByteArrayView(
"binormal"), getBitValue(Binormal, inKeySet));
622 internalToString(ioStr, QByteArrayView(
"color"), getBitValue(Color, inKeySet));
624 internalToString(ioStr, QByteArrayView(
"texcoordlightmap"), getBitValue(TexCoordLightmap, inKeySet));
626 internalToString(ioStr, QByteArrayView(
"joint&weight"), getBitValue(JointAndWeight, inKeySet));
629 void fromString(
const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
631 const qsizetype nameLen = name.size();
632 const qsizetype strOffset = ioStr.indexOf(name);
633 if (strOffset >= 0) {
635 if (ioStr[strOffset + nameLen] !=
'=')
637 if (ioStr[strOffset + nameLen + 1] !=
'{')
639 const int codeOffsetBegin = strOffset + nameLen + 2;
641 while (ioStr[codeOffsetBegin + codeOffset] !=
'}')
643 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
644 const QVector<QByteArray> list = val.split(
';');
645 if (list.size() != 8)
647 setBitValue(Position, inKeySet, getBoolValue(list[0], QByteArrayView(
"position")));
648 setBitValue(Normal, inKeySet, getBoolValue(list[1], QByteArrayView(
"normal")));
649 setBitValue(TexCoord0, inKeySet, getBoolValue(list[2], QByteArrayView(
"texcoord0")));
650 setBitValue(TexCoord1, inKeySet, getBoolValue(list[3], QByteArrayView(
"texcoord1")));
651 setBitValue(Tangent, inKeySet, getBoolValue(list[4], QByteArrayView(
"tangent")));
652 setBitValue(Binormal, inKeySet, getBoolValue(list[5], QByteArrayView(
"binormal")));
653 setBitValue(Color, inKeySet, getBoolValue(list[6], QByteArrayView(
"color")));
654 setBitValue(TexCoordLightmap, inKeySet, getBoolValue(list[7], QByteArrayView(
"texcoordlightmap")));
816 m_imageMaps[0].name =
"diffuseMap";
817 m_imageMaps[1].name =
"emissiveMap";
818 m_imageMaps[2].name =
"specularMap";
819 m_imageMaps[3].name =
"baseColorMap";
820 m_imageMaps[4].name =
"bumpMap";
821 m_imageMaps[5].name =
"specularAmountMap";
822 m_imageMaps[6].name =
"normalMap";
823 m_imageMaps[7].name =
"clearcoatNormalMap";
824 m_imageMaps[8].name =
"opacityMap";
825 m_imageMaps[9].name =
"roughnessMap";
826 m_imageMaps[10].name =
"metalnessMap";
827 m_imageMaps[11].name =
"occlusionMap";
828 m_imageMaps[12].name =
"translucencyMap";
829 m_imageMaps[13].name =
"heightMap";
830 m_imageMaps[14].name =
"clearcoatMap";
831 m_imageMaps[15].name =
"clearcoatRoughnessMap";
832 m_imageMaps[16].name =
"transmissionMap";
833 m_imageMaps[17].name =
"thicknessMap";
835 m_textureChannels[0].name =
"opacityMap_channel";
836 m_textureChannels[1].name =
"roughnessMap_channel";
837 m_textureChannels[2].name =
"metalnessMap_channel";
838 m_textureChannels[3].name =
"occlusionMap_channel";
839 m_textureChannels[4].name =
"translucencyMap_channel";
840 m_textureChannels[5].name =
"heightMap_channel";
841 m_textureChannels[6].name =
"clearcoatMap_channel";
842 m_textureChannels[7].name =
"clearcoatRoughnessMap_channel";
843 m_textureChannels[8].name =
"transmissionMap_channel";
844 m_textureChannels[9].name =
"thicknessMap_channel";
845 m_textureChannels[10].name =
"baseColorMap_channel";
846 m_textureChannels[11].name =
"specularAmountMap_channel";
847 m_textureChannels[12].name =
"emissiveMap_channel";
852 template<
typename TVisitor>
855 inVisitor.visit(m_hasLighting);
856 inVisitor.visit(m_hasPunctualLights);
857 inVisitor.visit(m_hasShadows);
858 inVisitor.visit(m_hasIbl);
859 inVisitor.visit(m_specularEnabled);
860 inVisitor.visit(m_fresnelEnabled);
861 inVisitor.visit(m_fresnelScaleBiasEnabled);
862 inVisitor.visit(m_clearcoatFresnelScaleBiasEnabled);
863 inVisitor.visit(m_baseColorSingleChannelEnabled);
864 inVisitor.visit(m_specularSingleChannelEnabled);
865 inVisitor.visit(m_emissiveSingleChannelEnabled);
866 inVisitor.visit(m_invertOpacityMapValue);
867 inVisitor.visit(m_vertexColorsEnabled);
868 inVisitor.visit(m_vertexColorsMaskEnabled);
869 inVisitor.visit(m_vertexColorRedMask);
870 inVisitor.visit(m_vertexColorGreenMask);
871 inVisitor.visit(m_vertexColorBlueMask);
872 inVisitor.visit(m_vertexColorAlphaMask);
873 inVisitor.visit(m_specularModel);
874 inVisitor.visit(m_diffuseModel);
876 for (quint32 idx = 0, end = ImageMapCount; idx < end; ++idx)
877 inVisitor.visit(m_imageMaps[idx]);
879 for (
auto &textureChannel : m_textureChannels)
880 inVisitor.visit(textureChannel);
882 inVisitor.visit(m_boneCount);
883 inVisitor.visit(m_isDoubleSided);
884 inVisitor.visit(m_overridesPosition);
885 inVisitor.visit(m_usesProjectionMatrix);
886 inVisitor.visit(m_usesInverseProjectionMatrix);
887 inVisitor.visit(m_usesPointsTopology);
888 inVisitor.visit(m_usesVarColor);
889 inVisitor.visit(m_alphaMode);
890 inVisitor.visit(m_vertexAttributes);
891 inVisitor.visit(m_usesFloatJointIndices);
892 inVisitor.visit(m_usesInstancing);
893 inVisitor.visit(m_targetCount);
894 inVisitor.visit(m_targetPositionOffset);
895 inVisitor.visit(m_targetNormalOffset);
896 inVisitor.visit(m_targetTangentOffset);
897 inVisitor.visit(m_targetBinormalOffset);
898 inVisitor.visit(m_targetTexCoord0Offset);
899 inVisitor.visit(m_targetTexCoord1Offset);
900 inVisitor.visit(m_targetColorOffset);
901 inVisitor.visit(m_blendParticles);
902 inVisitor.visit(m_clearcoatEnabled);
903 inVisitor.visit(m_transmissionEnabled);
904 inVisitor.visit(m_specularAAEnabled);
905 inVisitor.visit(m_lightmapEnabled);
906 inVisitor.visit(m_specularGlossyEnabled);
907 inVisitor.visit(m_metallicRoughnessEnabled);
908 inVisitor.visit(m_debugMode);
909 inVisitor.visit(m_fogEnabled);
910 inVisitor.visit(m_viewCount);
911 inVisitor.visit(m_usesViewIndex);
912 inVisitor.visit(m_oitMSAA);
913 inVisitor.visit(m_orderIndependentTransparency);
914 inVisitor.visit(m_shadowSoftness);
921 template<
typename TPropType>
928 quint32 bit = m_offset % 32;
929 if (bit + TPropType::BitWidth > 32) {
930 m_offset += 32 - bit;
933 inProp.setOffset(m_offset);
934 m_offset += TPropType::BitWidth;
944 size += prop.name.size();
956 offsetVisitor.visit(prop);
957 stringSizeVisitor.visit(prop);
964 visitProperties(visitor);
967 Q_ASSERT(visitor.offsetVisitor.m_offset < 800);
970 m_stringBufferSizeHint = visitor.stringSizeVisitor.size;
974template <
typename Props, size_t size>
985 for (size_t idx = 0; idx < DataBufferSize; ++idx)
986 m_dataBuffer[idx] = 0;
991 for (size_t idx = 0; idx < DataBufferSize; ++idx)
992 m_dataBuffer[idx] = 0;
999 retval = retval ^ qHash(m_dataBuffer[idx]);
1000 return retval ^ m_featureSetHash;
1006 for (size_t idx = 0; idx < DataBufferSize && retval; ++idx)
1007 retval = m_dataBuffer[idx] == other.m_dataBuffer[idx];
1008 return retval && m_featureSetHash == other.m_featureSetHash;
1040 template<
typename TPropType>
1043 prop.fromString(m_str, m_keyStore);
1047 void toString(QByteArray &ioString,
const Props &inProperties)
const
1049 ioString.reserve(inProperties.m_stringBufferSizeHint);
1050 StringVisitor theVisitor(ioString, *
this);
1051 const_cast<Props &>(inProperties).visitProperties(theVisitor);
1056 inProperties.visitProperties(theVisitor);
1061 ret.resize(
sizeof(m_dataBuffer));
1062 memcpy(ret.data(), m_dataBuffer,
sizeof(m_dataBuffer));
1067 if (data.size() !=
sizeof(m_dataBuffer))
1069 memcpy((
void *)m_dataBuffer, data.data(),
sizeof(m_dataBuffer));
1076Q_STATIC_ASSERT(std::is_trivially_destructible<QSSGShaderDefaultMaterialKey>::value);
QSSGShaderBaseMaterialKey< QSSGShaderDefaultMaterialKeyProperties, 25 > QSSGShaderDefaultMaterialKey
size_t qHash(const QSSGShaderDefaultMaterialKey &key)
QSSGDataRef< quint32 > m_keyStore
StringInVisitor(const QByteArray &s, QSSGDataRef< quint32 > ks)
void visit(TPropType &prop)
bool operator==(const QSSGShaderBaseMaterialKey< Props, size > &other) const
void toString(QByteArray &ioString, const Props &inProperties) const
bool fromByteArray(const QByteArray &data) const
QSSGShaderBaseMaterialKey()
QSSGShaderBaseMaterialKey(size_t inFeatureSetHash)
void fromString(QByteArray &ioString, Props &inProperties)
QByteArray toByteArray() const
quint32 m_dataBuffer[DataBufferSize]
OffsetVisitor offsetVisitor
StringSizeVisitor stringSizeVisitor
void visit(TPropType &inProp)
constexpr void visit(const P &prop)
QSSGShaderKeyBoolean m_usesInverseProjectionMatrix
QSSGShaderKeyUnsigned< 4 > m_debugMode
QSSGShaderKeyBoolean m_usesProjectionMatrix
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord1Offset
QSSGShaderKeyBoolean m_vertexColorsMaskEnabled
QSSGShaderKeyBoolean m_oitMSAA
QSSGShaderKeyBoolean m_baseColorSingleChannelEnabled
QSSGShaderKeyBoolean m_fogEnabled
QSSGShaderKeyBoolean m_usesInstancing
void visitProperties(TVisitor &inVisitor)
QSSGShaderKeyBoolean m_blendParticles
QSSGShaderKeyBoolean m_hasLighting
QSSGShaderKeyBoolean m_hasPunctualLights
@ SingleChannelImagesFirst
QSSGShaderKeyTextureChannel m_textureChannels[SingleChannelImageCount]
QSSGShaderKeyBoolean m_clearcoatEnabled
QSSGShaderKeyUnsigned< 16 > m_vertexColorAlphaMask
@ ClearcoatRoughnessChannel
QSSGShaderKeyBoolean m_transmissionEnabled
QSSGShaderKeyBoolean m_lightmapEnabled
QSSGShaderKeyBoolean m_usesVarColor
QSSGShaderKeyBoolean m_overridesPosition
QSSGShaderKeyBoolean m_isDoubleSided
QSSGShaderKeyImageMap m_imageMaps[ImageMapCount]
QSSGShaderKeySpecularModel m_specularModel
QSSGShaderKeyBoolean m_usesFloatJointIndices
QSSGShaderKeyBoolean m_specularEnabled
QSSGShaderDefaultMaterialKeyProperties()
QSSGShaderKeyBoolean m_usesViewIndex
QSSGShaderKeyUnsigned< 8 > m_targetPositionOffset
QSSGShaderKeyUnsigned< 16 > m_boneCount
QSSGShaderKeyBoolean m_hasIbl
qsizetype m_stringBufferSizeHint
QSSGShaderKeyUnsigned< 8 > m_targetTangentOffset
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord0Offset
QSSGShaderKeyUnsigned< 16 > m_vertexColorBlueMask
QSSGShaderKeyUnsigned< 8 > m_targetColorOffset
QSSGShaderKeyBoolean m_emissiveSingleChannelEnabled
QSSGShaderKeyBoolean m_vertexColorsEnabled
QSSGShaderKeyVertexAttribute m_vertexAttributes
QSSGShaderKeyUnsigned< 8 > m_targetNormalOffset
QSSGShaderKeyBoolean m_fresnelEnabled
QSSGShaderKeyUnsigned< 8 > m_targetBinormalOffset
QSSGShaderKeyShadowSoftness m_shadowSoftness
QSSGShaderKeyBoolean m_fresnelScaleBiasEnabled
QSSGShaderKeyUnsigned< 16 > m_vertexColorGreenMask
QSSGShaderKeyBoolean m_clearcoatFresnelScaleBiasEnabled
QSSGShaderKeyBoolean m_metallicRoughnessEnabled
QSSGShaderKeyUnsigned< 3 > m_viewCount
@ SingleChannelImageCount
QSSGShaderKeyAlphaMode m_alphaMode
QSSGShaderKeyBoolean m_specularSingleChannelEnabled
QSSGShaderKeyUnsigned< 3 > m_orderIndependentTransparency
QSSGShaderKeyUnsigned< 8 > m_targetCount
QSSGShaderKeyBoolean m_specularGlossyEnabled
QSSGShaderKeyDiffuseModel m_diffuseModel
QSSGShaderKeyBoolean m_hasShadows
QSSGShaderKeyBoolean m_usesPointsTopology
QSSGShaderKeyBoolean m_invertOpacityMapValue
QSSGShaderKeyUnsigned< 16 > m_vertexColorRedMask
QSSGShaderKeyBoolean m_specularAAEnabled
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
QSSGRenderDefaultMaterial::MaterialAlphaMode getAlphaMode(QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyAlphaMode(const char *inName="")
void setAlphaMode(QSSGDataRef< quint32 > inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode inMode)
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setValue(QSSGDataRef< quint32 > inDataStore, bool inValue) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
constexpr QSSGShaderKeyBoolean(const char *inName="")
bool getValue(QSSGDataView< quint32 > inDataStore) const
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
QSSGShaderKeyDiffuseModel(const char *inName="")
void setDiffuseModel(QSSGDataRef< quint32 > inKeySet, QSSGRenderDefaultMaterial::MaterialDiffuseModel inModel)
QSSGRenderDefaultMaterial::MaterialDiffuseModel getDiffuseModel(QSSGDataView< quint32 > inKeySet) const
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
void setIdentityTransform(QSSGDataRef< quint32 > inKeySet, bool val)
void setPreMultipliedAlpha(QSSGDataRef< quint32 > inKeySet, bool val)
bool isPreMultipliedAlpha(QSSGDataView< quint32 > inKeySet) const
void setBitValue(ImageMapBits imageBit, bool inValue, QSSGDataRef< quint32 > inKeySet)
void setEnabled(QSSGDataRef< quint32 > inKeySet, bool val)
bool isUsingUV1(QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyImageMap(const char *inName="")
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
bool isIdentityTransform(QSSGDataView< quint32 > inKeySet) const
bool isEnabled(QSSGDataView< quint32 > inKeySet) const
bool isLightProbe(QSSGDataView< quint32 > inKeySet) const
void setLinear(QSSGDataRef< quint32 > inKeySet, bool val)
void setUsesUV1(QSSGDataRef< quint32 > inKeySet, bool val)
bool isEnvMap(QSSGDataView< quint32 > inKeySet) const
bool getBitValue(ImageMapBits imageBit, QSSGDataView< quint32 > inKeySet) const
void setLightProbe(QSSGDataRef< quint32 > inKeySet, bool val)
bool isLinear(QSSGDataView< quint32 > inKeySet) const
void setEnvMap(QSSGDataRef< quint32 > inKeySet, bool val)
QSSGShaderKeyShadowSoftness(const char *inName="")
void setShadowSoftness(QSSGDataRef< quint32 > inKeySet, QSSGRenderLight::SoftShadowQuality inQuality)
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
QSSGRenderLight::SoftShadowQuality getShadowSoftness(QSSGDataView< quint32 > inKeySet) const
QSSGRenderDefaultMaterial::MaterialSpecularModel getSpecularModel(QSSGDataView< quint32 > inKeySet) const
void setSpecularModel(QSSGDataRef< quint32 > inKeySet, QSSGRenderDefaultMaterial::MaterialSpecularModel inModel)
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeySpecularModel(const char *inName="")
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setTextureChannel(TexturChannelBits channel, QSSGDataRef< quint32 > inKeySet)
static constexpr char textureChannelToChar[4]
TexturChannelBits getTextureChannel(QSSGDataView< quint32 > inKeySet) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyTextureChannel(const char *inName="")
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
constexpr QSSGShaderKeyUnsigned(const char *inName="")
void setValue(QSSGDataRef< quint32 > inDataStore, quint32 inValue) const
quint32 getValue(QSSGDataView< quint32 > inDataStore) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
bool getBitValue(VertexAttributeBits bit, QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyVertexAttribute(const char *inName="")
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setBitValue(VertexAttributeBits bit, QSSGDataRef< quint32 > inKeySet, bool value) const