7#include <QtQuick3DRuntimeRender/private/qssgshadermaterialadapter_p.h>
9#include <QtQuick3DRuntimeRender/private/qssgrhicustommaterialsystem_p.h>
17 switch (materialNode.type) {
18 case QSSGRenderGraphObject::Type::DefaultMaterial:
19 case QSSGRenderGraphObject::Type::PrincipledMaterial:
20 case QSSGRenderGraphObject::Type::SpecularGlossyMaterial:
23 case QSSGRenderGraphObject::Type::CustomMaterial:
71 : m_material(material)
77 return m_material.
type == QSSGRenderGraphObject::Type::PrincipledMaterial;
82 return m_material.
type == QSSGRenderGraphObject::Type::SpecularGlossyMaterial;
192 return m_material.
color;
202 return m_material.
ior;
346 : m_material(material)
625 return std::numeric_limits<float>::infinity();
630 return { 1.0f, 1.0f, 1.0f };
648 bool multiViewCompatible)
674 context.customMaterialSystem()->applyRhiShaderPropertyValues(ubufData, m_material, shaderPipeline);
688 {
"MODELVIEWPROJECTION_MATRIX",
"qt_modelViewProjection",
true },
689 {
"VIEWPROJECTION_MATRIX",
"qt_viewProjectionMatrix",
true },
690 {
"MODEL_MATRIX",
"qt_modelMatrix",
false },
691 {
"VIEW_MATRIX",
"qt_viewMatrix",
true },
692 {
"NORMAL_MATRIX",
"qt_normalMatrix",
false },
693 {
"BONE_TRANSFORMS",
"qt_getTexMatrix",
false },
694 {
"BONE_NORMAL_TRANSFORMS",
"qt_getTexMatrix",
false },
695 {
"PROJECTION_MATRIX",
"qt_projectionMatrix",
true },
696 {
"INVERSE_PROJECTION_MATRIX",
"qt_inverseProjectionMatrix",
true },
697 {
"CAMERA_POSITION",
"qt_cameraPosition",
true },
698 {
"CAMERA_DIRECTION",
"qt_cameraDirection",
true },
699 {
"CAMERA_PROPERTIES",
"qt_cameraProperties",
false },
700 {
"FRAMEBUFFER_Y_UP",
"qt_rhi_properties.x",
false },
701 {
"NDC_Y_UP",
"qt_rhi_properties.y",
false },
702 {
"NEAR_CLIP_VALUE",
"qt_rhi_properties.z",
false },
703 {
"IBL_MAXMIPMAP",
"qt_lightProbeProperties.y",
false },
704 {
"IBL_HORIZON",
"qt_lightProbeProperties.z",
false },
705 {
"IBL_EXPOSE",
"qt_lightProbeProperties.w",
false },
708 {
"POSITION",
"gl_Position",
false },
709 {
"FRAGCOLOR",
"fragOutput",
false },
710 {
"POINT_SIZE",
"gl_PointSize",
false },
713 {
"FRAGCOORD",
"gl_FragCoord",
false },
716 {
"DIRECTIONAL_LIGHT",
"qt_directionalLightProcessor",
false },
717 {
"POINT_LIGHT",
"qt_pointLightProcessor",
false },
718 {
"SPOT_LIGHT",
"qt_spotLightProcessor",
false },
719 {
"AMBIENT_LIGHT",
"qt_ambientLightProcessor",
false },
720 {
"SPECULAR_LIGHT",
"qt_specularLightProcessor",
false },
721 {
"MAIN",
"qt_customMain",
false },
722 {
"POST_PROCESS",
"qt_customPostProcessor",
false },
723 {
"IBL_PROBE",
"qt_iblProbeProcessor",
false },
726 {
"SCREEN_TEXTURE",
"qt_screenTexture",
true },
727 {
"SCREEN_MIP_TEXTURE",
"qt_screenTexture",
true },
728 {
"DEPTH_TEXTURE",
"qt_depthTexture",
true },
729 {
"AO_TEXTURE",
"qt_aoTexture",
true },
730 {
"IBL_TEXTURE",
"qt_lightProbe",
false },
731 {
"LIGHTMAP",
"qt_lightmap",
false },
737 {
"VAR_WORLD_NORMAL",
"qt_varNormal",
false },
738 {
"VAR_WORLD_TANGENT",
"qt_varTangent",
false },
739 {
"VAR_WORLD_BINORMAL",
"qt_varBinormal",
false },
740 {
"VAR_WORLD_POSITION",
"qt_varWorldPos",
false },
742 {
"VAR_COLOR",
"qt_varColor",
false },
745 {
"INPUT",
"qt_inputTexture",
true },
746 {
"INPUT_UV",
"qt_inputUV",
false },
747 {
"TEXTURE_UV",
"qt_textureUV",
false },
748 {
"INPUT_SIZE",
"qt_inputSize",
false },
749 {
"OUTPUT_SIZE",
"qt_outputSize",
false },
750 {
"FRAME",
"qt_frame_num",
false },
753 {
"INSTANCE_COLOR",
"qt_instanceColor",
false },
754 {
"INSTANCE_DATA",
"qt_instanceData",
false },
755 {
"INSTANCE_INDEX",
"gl_InstanceIndex",
false },
758 {
"MORPH_POSITION",
"qt_getTargetPositionFromTargetId",
false },
759 {
"MORPH_NORMAL",
"qt_getTargetNormalFromTargetId",
false },
760 {
"MORPH_TANGENT",
"qt_getTargetTangentFromTargetId",
false },
761 {
"MORPH_BINORMAL",
"qt_getTargetBinormalFromTargetId",
false },
762 {
"MORPH_WEIGHTS",
"qt_morphWeights",
false },
765 {
"SHARED_VARS",
"struct QT_SHARED_VARS",
false },
768 {
"VIEW_INDEX",
"qt_viewIndex",
false }
805 const char *identifier;
815Tokenizer::Token Tokenizer::next()
825 return Token_Comment;
826 }
else if (*
pos ==
'*') {
831 return Token_Comment;
833 return Token_Unspecified;
835 case ';':
return Token_SemiColon;
836 case '\0':
return Token_EOF;
837 case '{':
return Token_OpenBrace;
838 case '}':
return Token_CloseBrace;
839 case '(':
return Token_OpenParen;
840 case ')':
return Token_CloseParen;
841 case '[':
return Token_OpenBraket;
842 case ']':
return Token_CloseBraket;
849 if ((
c >=
'a' &&
c <=
'z' ) || (
c >=
'A' &&
c <=
'Z' ) ||
c ==
'_') {
850 identifier =
pos - 1;
851 while (*
pos && ((*
pos >=
'a' && *
pos <=
'z')
852 || (*
pos >=
'A' && *
pos <=
'Z')
854 || (*
pos >=
'0' && *
pos <=
'9'))) {
857 return Token_Identifier;
859 return Token_Unspecified;
875 bool multiViewCompatible)
881 tok.initialize(shaderCode);
894 result.prepend(
"#line 1\n");
895 const char *lastPos = shaderCode.constData();
897 int funcFinderState = 0;
898 int useJointTexState = -1;
899 int useJointNormalTexState = -1;
901 Tokenizer::Token
t = tok.next();
902 while (
t != Tokenizer::Token_EOF) {
904 case Tokenizer::Token_Comment:
906 case Tokenizer::Token_Identifier:
915 while (
t != Tokenizer::Token_EOF) {
917 if (
t == Tokenizer::Token_Identifier) {
918 if (vtype.isEmpty()) {
919 vtype =
data.trimmed();
924 }
else if (vname.isEmpty()) {
925 vname =
data.trimmed();
928 if (
t == Tokenizer::Token_SemiColon)
934 outputs.append((vflat ?
"flat " :
"") + vtype +
" " + vname);
936 inputs.append((vflat ?
"flat " :
"") + vtype +
" " + vname);
940 funcFinderState += 1;
941 }
else if (funcFinderState == 1) {
942 auto begin = qssg_func_injectarg_tab;
943 const auto end = qssg_func_injectarg_tab + (
sizeof(qssg_func_injectarg_tab) /
sizeof(qssg_func_injectarg_tab[0]));
945 if (foundIt !=
end) {
946 currentShadedFunc = trimmedId;
947 funcFinderState += 1;
981 if (trimmedId == subst.builtin) {
983 newExpr.
assign(subst.actualName);
984 if (subst.multiViewDependent && multiViewCompatible) {
993 id.replace(subst.builtin, newExpr);
995 useJointTexState = 0;
998 useJointNormalTexState = 0;
1013 case Tokenizer::Token_OpenParen:
1015 if (funcFinderState == 2) {
1017 result += currentShadedFunc;
1020 if (currentShadedFunc == subst.builtin) {
1021 currentShadedFunc = subst.actualName.toByteArray();
1025 md.customFunctions.insert(currentShadedFunc);
1026 currentShadedFunc.clear();
1028 funcFinderState = 0;
1030 case Tokenizer::Token_OpenBraket:
1033 if (useJointTexState == 0) {
1037 }
else if (useJointNormalTexState == 0) {
1039 ++useJointNormalTexState;
1043 if (useJointTexState >= 0)
1045 else if (useJointNormalTexState >= 0)
1046 ++useJointNormalTexState;
1049 case Tokenizer::Token_CloseBraket:
1056 if (useJointTexState <= 0 && useJointNormalTexState <= 0) {
1060 if (useJointTexState > 1) {
1064 }
else if (useJointNormalTexState > 1) {
1066 --useJointNormalTexState;
1070 useJointTexState = -1;
1071 useJointNormalTexState = -1;
1091 if (multiViewCompatible)
1092 allUniforms.
append({
"sampler2DArray",
"qt_depthTextureArray" });
1094 allUniforms.append({
"sampler2D",
"qt_depthTexture" });
1099 if (multiViewCompatible)
1100 allUniforms.append({
"sampler2DArray",
"qt_screenTextureArray" });
1102 allUniforms.append({
"sampler2D",
"qt_screenTexture" });
1107 if (multiViewCompatible)
1108 allUniforms.append({
"sampler2DArray",
"qt_aoTextureArray" });
1110 allUniforms.append({
"sampler2D",
"qt_aoTexture" });
1115 if (multiViewCompatible)
1116 allUniforms.append({
"sampler2DArray",
"qt_inputTextureArray" });
1118 allUniforms.append({
"sampler2D",
"qt_inputTexture" });
1122 allUniforms.append({
"sampler2D",
"qt_lightmap" });
1124 static const char *metaStart =
"#ifdef QQ3D_SHADER_META\n/*{\n \"uniforms\": [\n";
1125 static const char *metaEnd =
" ]\n}*/\n#endif\n";
1126 dst.append(metaStart);
1127 for (
int i = 0,
count = allUniforms.size();
i <
count; ++
i) {
1128 const auto &typeAndName(allUniforms[
i]);
1129 dst.append(
" { \"type\": \"" + typeAndName.first +
"\", \"name\": \"" + typeAndName.second +
"\" }");
1134 dst.append(metaEnd);
1138 QVarLengthArray<bool, 16> inputIsFlat(allInputs.count(),
false);
1139 for (
const QByteArray &inputTypeAndName : inputs) {
1141 if (typeAndName.size() == 2) {
1142 allInputs.append({ typeAndName[0].trimmed(), typeAndName[1].trimmed() });
1143 inputIsFlat.append(
false);
1144 }
else if (typeAndName.size() == 3 && typeAndName[0].startsWith(
"flat")) {
1145 allInputs.append({ typeAndName[1].trimmed(), typeAndName[2].trimmed() });
1146 inputIsFlat.append(
true);
1149 if (!allInputs.isEmpty()) {
1150 static const char *metaStart =
"#ifdef QQ3D_SHADER_META\n/*{\n \"inputs\": [\n";
1151 static const char *metaEnd =
" ]\n}*/\n#endif\n";
1152 dst.append(metaStart);
1154 dst.append(
" { \"type\": \"" + allInputs[
i].
first
1155 +
"\", \"name\": \"" + allInputs[
i].second
1156 +
"\", \"stage\": \"" + stageStr
1157 + (inputIsFlat[
i] ?
"\", \"flat\": true" :
"\"")
1163 dst.append(metaEnd);
1167 QVarLengthArray<bool, 16> outputIsFlat(allOutputs.count(),
false);
1168 for (
const QByteArray &outputTypeAndName : outputs) {
1170 if (typeAndName.size() == 2) {
1171 allOutputs.append({ typeAndName[0].trimmed(), typeAndName[1].trimmed() });
1172 outputIsFlat.append(
false);
1173 }
else if (typeAndName.size() == 3 && typeAndName[0].startsWith(
"flat")) {
1174 allOutputs.append({ typeAndName[1].trimmed(), typeAndName[2].trimmed() });
1175 outputIsFlat.append(
true);
1178 if (!allOutputs.isEmpty()) {
1179 static const char *metaStart =
"#ifdef QQ3D_SHADER_META\n/*{\n \"outputs\": [\n";
1180 static const char *metaEnd =
" ]\n}*/\n#endif\n";
1181 dst.append(metaStart);
1182 for (
int i = 0,
count = allOutputs.size();
i <
count; ++
i) {
1183 dst.append(
" { \"type\": \"" + allOutputs[
i].
first
1184 +
"\", \"name\": \"" + allOutputs[
i].second
1185 +
"\", \"stage\": \"" + stageStr
1186 + (outputIsFlat[
i] ?
"\", \"flat\": true" :
"\"")
1192 dst.append(metaEnd);
1200 QList<QByteArrayView> k;
1201 k.reserve(std::size(qssg_var_subst_tab));
1202 for (
const auto &
v : qssg_var_subst_tab)
1203 k.push_back(
v.builtin);
QByteArray trimmed() const &
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
QByteArray & assign(QByteArrayView v)
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
static bool shaderDebuggingEnabled()
QSSGCustomShaderMetaData getShaderMetaData(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
QByteArray getShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
bool contains(const T &value) const
The QVector3D class represents a vector or vertex in 3D space.
The QVector4D class represents a vector or vertex in 4D space.
Combined button and popup list for selecting options.
Q_QUICK3DRUNTIMERENDER_EXPORT QList< QByteArrayView > preprocessorVars()
#define QByteArrayLiteral(str)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
GLsizei const GLfloat * v
[13]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLenum input
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
CustomShaderPresence m_customShaderPresence
RenderFlags m_renderFlags
ShadingMode m_shadingMode
@ MultiViewShaderPathKeyIndex
@ RegularShaderPathKeyIndex
QSSGRenderImage * m_iblProbe
bool m_usesSharedVariables
QByteArray m_shaderPathKey[2]
float clearcoatNormalStrength
bool isClearcoatEnabled() const
bool isEmissiveSingleChannelEnabled() const
bool isMetalnessEnabled() const
QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel
bool isVertexColorsEnabled() const
bool isVertexColorsMaskEnabled() const
bool isSpecularAmountSingleChannelEnabled() const
VertexColorMaskFlags vertexColorAlphaMask
float clearcoatFresnelPower
QSSGRenderImage * iblProbe
bool isSpecularEnabled() const
VertexColorMaskFlags vertexColorBlueMask
bool isBaseColorSingleChannelEnabled() const
float clearcoatRoughnessAmount
float clearcoatFresnelScale
float clearcoatFresnelScaleBiasEnabled
VertexColorMaskFlags vertexColorGreenMask
bool isTransmissionEnabled() const
float fresnelScaleBiasEnabled
float attenuationDistance
bool isInvertOpacityMapValue() const
VertexColorMaskFlags vertexColorRedMask
QVector3D attenuationColor
float clearcoatFresnelBias
QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode
static ShaderCodeAndMetaData prepareCustomShader(QByteArray &dst, const QByteArray &shaderCode, QSSGShaderCache::ShaderType type, const StringPairList &baseUniforms, const StringPairList &baseInputs=StringPairList(), const StringPairList &baseOutputs=StringPairList(), bool multiViewCompatible=false)
bool isInvertOpacityMapValue() override
bool isSpecularGlossy() override
float translucentFallOff() override
float alphaCutOff() override
bool isUnshaded() override
bool usesCustomMorphing() override
bool isEmissiveSingleChannelEnabled() override
bool hasCustomShaderSnippet(QSSGShaderCache::ShaderType type) override
float pointSize() override
QVector3D attenuationColor() override
float fresnelScale() override
bool isSpecularEnabled() override
float fresnelPower() override
bool usesCustomSkinning() override
bool isMetalnessEnabled() override
float transmissionFactor() override
float lineWidth() override
float diffuseLightWrap() override
bool hasCustomShaderFunction(QSSGShaderCache::ShaderType shaderType, const QByteArray &funcName, QSSGShaderLibraryManager &shaderLibraryManager) override
bool hasLighting() override
void setCustomPropertyUniforms(char *ubufData, QSSGRhiShaderPipeline &shaderPipeline, const QSSGRenderContextInterface &context) override
float occlusionAmount() override
QVector4D color() override
float thicknessFactor() override
float bumpAmount() override
bool isClearcoatEnabled() override
bool isTransmissionEnabled() override
bool isClearcoatFresnelScaleBiasEnabled() override
float specularAmount() override
float clearcoatNormalStrength() override
float clearcoatFresnelScale() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorBlueMask() override
float clearcoatAmount() override
QByteArray customShaderSnippet(QSSGShaderCache::ShaderType type, QSSGShaderLibraryManager &shaderLibraryManager, bool multiViewCompatible) override
float fresnelBias() override
float specularRoughness() override
float clearcoatFresnelPower() override
bool isPrincipled() override
bool isSpecularAmountSingleChannelEnabled() override
float clearcoatRoughnessAmount() override
float clearcoatFresnelBias() override
QSSGRenderImage * iblProbe() override
QVector3D emissiveColor() override
bool isVertexColorsEnabled() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorGreenMask() override
float maxHeightSamples() override
QSSGShaderCustomMaterialAdapter(const QSSGRenderCustomMaterial &material)
bool usesSharedVariables() override
QPair< QByteArray, QSSGCustomShaderMetaData > ShaderCodeAndMetaData
bool isBaseColorSingleChannelEnabled() override
bool isFresnelScaleBiasEnabled() override
float metalnessAmount() override
float minHeightSamples() override
float heightAmount() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorAlphaMask() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorRedMask() override
float attenuationDistance() override
QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel() override
QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode() override
bool isVertexColorsMaskEnabled() override
QVector3D specularTint() override
QVector3D attenuationColor() override
float heightAmount() override
bool usesCustomMorphing() override
bool isSpecularGlossy() override
bool isSpecularEnabled() override
float maxHeightSamples() override
QVector3D emissiveColor() override
bool isMetalnessEnabled() override
float clearcoatNormalStrength() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorGreenMask() override
QVector3D specularTint() override
bool isVertexColorsMaskEnabled() override
float clearcoatFresnelBias() override
float specularRoughness() override
float fresnelPower() override
bool isFresnelScaleBiasEnabled() override
float attenuationDistance() override
bool isInvertOpacityMapValue() override
float clearcoatAmount() override
bool hasLighting() override
bool isVertexColorsEnabled() override
bool isBaseColorSingleChannelEnabled() override
QSSGShaderDefaultMaterialAdapter(const QSSGRenderDefaultMaterial &material)
bool isClearcoatFresnelScaleBiasEnabled() override
QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel() override
float minHeightSamples() override
float metalnessAmount() override
bool usesCustomSkinning() override
float bumpAmount() override
float translucentFallOff() override
float occlusionAmount() override
float clearcoatFresnelScale() override
float clearcoatRoughnessAmount() override
float transmissionFactor() override
bool isPrincipled() override
float alphaCutOff() override
float clearcoatFresnelPower() override
QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode() override
float pointSize() override
bool isEmissiveSingleChannelEnabled() override
float specularAmount() override
float fresnelBias() override
float fresnelScale() override
float diffuseLightWrap() override
QSSGRenderImage * iblProbe() override
bool isSpecularAmountSingleChannelEnabled() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorRedMask() override
QVector4D color() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorBlueMask() override
bool isTransmissionEnabled() override
float lineWidth() override
float thicknessFactor() override
bool isClearcoatEnabled() override
QSSGRenderDefaultMaterial::VertexColorMaskFlags vertexColorAlphaMask() override
virtual ~QSSGShaderMaterialAdapter()
virtual bool isUnshaded()
virtual bool hasCustomShaderFunction(QSSGShaderCache::ShaderType shaderType, const QByteArray &funcName, QSSGShaderLibraryManager &shaderLibraryManager)
virtual QByteArray customShaderSnippet(QSSGShaderCache::ShaderType type, QSSGShaderLibraryManager &shaderLibraryManager, bool multiViewCompatible)
virtual bool hasCustomShaderSnippet(QSSGShaderCache::ShaderType type)
static QSSGShaderMaterialAdapter * create(const QSSGRenderGraphObject &materialNode)
virtual bool usesSharedVariables()
virtual void setCustomPropertyUniforms(char *ubufData, QSSGRhiShaderPipeline &shaderPipeline, const QSSGRenderContextInterface &context)