34 QSSGShaderMaterialAdapter *materialAdapter =
nullptr,
bool isSharedInout =
false)
36 const int argKeyLen =
int(strlen(argKey));
37 const int argKeyPos = snippet.indexOf(argKey);
40 if (materialAdapter) {
41 if (materialAdapter->isClearcoatEnabled()) {
42 flexArgs += QByteArrayLiteral(
", inout float CLEARCOAT_AMOUNT, inout float CLEARCOAT_FRESNEL_POWER, inout float CLEARCOAT_ROUGHNESS, inout vec3 CLEARCOAT_NORMAL");
43 if (materialAdapter->isClearcoatFresnelScaleBiasEnabled())
44 flexArgs += QByteArrayLiteral(
", inout float CLEARCOAT_FRESNEL_SCALE, inout float CLEARCOAT_FRESNEL_BIAS");
46 if (materialAdapter->isSheenEnabled())
47 flexArgs += QByteArrayLiteral(
", inout vec3 SHEEN_COLOR, inout float SHEEN_ROUGHNESS");
48 if (materialAdapter->isAnisotropyEnabled())
49 flexArgs += QByteArrayLiteral(
", inout float ANISOTROPY_STRENGTH, inout float ANISOTROPY_ROTATION");
50 if (materialAdapter->isIridescenceEnabled())
51 flexArgs += QByteArrayLiteral(
", inout float IRIDESCENCE_FACTOR, inout float IRIDESCENCE_IOR, inout float IRIDESCENCE_THICKNESS");
52 if (materialAdapter->isFresnelScaleBiasEnabled())
53 flexArgs += QByteArrayLiteral(
", inout float FRESNEL_SCALE, inout float FRESNEL_BIAS");
54 if (materialAdapter->isDispersionEnabled())
55 flexArgs += QByteArrayLiteral(
", inout float DISPERSION");
56 if (materialAdapter->isTransmissionEnabled())
57 flexArgs += QByteArrayLiteral(
", inout float TRANSMISSION_FACTOR, inout float THICKNESS_FACTOR, inout vec3 ATTENUATION_COLOR, inout float ATTENUATION_DISTANCE");
58 if (materialAdapter->usesSharedVariables()) {
59 const char *inoutString = isSharedInout ?
", inout " :
", in ";
60 flexArgs += inoutString + QByteArrayLiteral(
"QT_SHARED_VARS SHARED");
63 snippet = snippet.left(argKeyPos) + argListFunc() + flexArgs + snippet.mid(argKeyPos + argKeyLen);
154void QSSGMaterialVertexPipeline::beginVertexGeneration(
const QSSGShaderDefaultMaterialKey &inKey,
155 const QSSGShaderFeatures &inFeatureSet,
156 QSSGShaderLibraryManager &shaderLibraryManager)
158 QSSGShaderGeneratorStageFlags theStages(QSSGProgramGenerator::defaultFlags());
159 programGenerator()->beginProgram(theStages);
161 QSSGStageGeneratorBase &vertexShader(vertex());
163 const bool meshHasNormals = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
164 QSSGShaderKeyVertexAttribute::Normal, inKey);
165 const bool meshHasTexCoord0 = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
166 QSSGShaderKeyVertexAttribute::TexCoord0, inKey);
167 const bool meshHasTexCoord1 = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
168 QSSGShaderKeyVertexAttribute::TexCoord1, inKey);
169 const bool meshHasTexCoordLightmap = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
170 QSSGShaderKeyVertexAttribute::TexCoordLightmap, inKey);
171 const bool meshHasTangents = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
172 QSSGShaderKeyVertexAttribute::Tangent, inKey);
173 const bool meshHasBinormals = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
174 QSSGShaderKeyVertexAttribute::Binormal, inKey);
175 const bool meshHasColors = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
176 QSSGShaderKeyVertexAttribute::Color, inKey);
177 const bool meshHasJointsAndWeights = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
178 QSSGShaderKeyVertexAttribute::JointAndWeight, inKey);
179 const bool overridesPosition = defaultMaterialShaderKeyProperties.m_overridesPosition.getValue(inKey);
180 const bool usesProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesProjectionMatrix.getValue(inKey);
181 const bool usesInvProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesInverseProjectionMatrix.getValue(inKey);
182 const bool usesPointsTopology = defaultMaterialShaderKeyProperties.m_usesPointsTopology.getValue(inKey);
183 const bool usesFloatJointIndices = defaultMaterialShaderKeyProperties.m_usesFloatJointIndices.getValue(inKey);
184 const bool blendParticles = defaultMaterialShaderKeyProperties.m_blendParticles.getValue(inKey);
185 usesInstancing = defaultMaterialShaderKeyProperties.m_usesInstancing.getValue(inKey);
186 m_hasSkinning = defaultMaterialShaderKeyProperties.m_boneCount.getValue(inKey) > 0;
187 const auto morphSize = defaultMaterialShaderKeyProperties.m_targetCount.getValue(inKey);
188 m_hasMorphing = morphSize > 0;
189 m_viewCount = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DisableMultiView)
190 ? 1 : defaultMaterialShaderKeyProperties.m_viewCount.getValue(inKey);
191 const bool usesViewIndex = defaultMaterialShaderKeyProperties.m_usesViewIndex.getValue(inKey);
193 vertexShader.addIncoming(
"attr_pos",
"vec3");
194 if (usesInstancing) {
195 vertexShader.addIncoming(
"qt_instanceTransform0",
"vec4");
196 vertexShader.addIncoming(
"qt_instanceTransform1",
"vec4");
197 vertexShader.addIncoming(
"qt_instanceTransform2",
"vec4");
198 vertexShader.addIncoming(
"qt_instanceColor",
"vec4");
199 vertexShader.addIncoming(
"qt_instanceData",
"vec4");
201 if (blendParticles) {
202 vertexShader.addInclude(
"particles.glsllib");
203 vertexShader.addUniform(
"qt_particleTexture",
"sampler2D");
204 vertexShader.addUniform(
"qt_countPerSlice",
"uint");
205 vertexShader.addUniform(
"qt_oneOverParticleImageSize",
"vec2");
206 vertexShader.addUniform(
"qt_particleMatrix",
"mat4");
207 vertexShader.addUniform(
"qt_particleIndexOffset",
"uint");
210 if (m_hasSkinning && meshHasJointsAndWeights) {
211 vertexShader.addInclude(
"skinanim.glsllib");
212 if (usesFloatJointIndices)
213 vertexShader.addIncoming(
"attr_joints",
"vec4");
215 vertexShader.addIncoming(
"attr_joints",
"ivec4");
216 vertexShader.addIncoming(
"attr_weights",
"vec4");
218 vertexShader.addUniform(
"qt_boneTexture",
"sampler2D");
221 vertexShader.addInclude(
"morphanim.glsllib");
222 vertexShader.addUniformArray(
"qt_morphWeights",
"float", morphSize);
223 vertexShader.addUniform(
"qt_morphTargetTexture",
"sampler2DArray");
226 const bool hasCustomVertexShader = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Vertex);
227 const bool hasCustomFragmentShader = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
228 if (hasCustomVertexShader) {
229 QByteArray snippet = materialAdapter->customShaderSnippet(QSSGShaderCache::ShaderType::Vertex,
230 shaderLibraryManager,
232 if (materialAdapter->hasCustomShaderFunction(QSSGShaderCache::ShaderType::Vertex,
233 QByteArrayLiteral(
"qt_customMain"),
234 shaderLibraryManager))
237 insertVertexInstancedMainArgs(snippet);
239 insertVertexMainArgs(snippet);
241 if (materialAdapter->usesCustomSkinning()) {
242 vertexShader.addInclude(
"skinanim.glsllib");
243 vertexShader.addUniform(
"qt_boneTexture",
"sampler2D");
246 if (materialAdapter->usesCustomMorphing()) {
247 vertexShader.addInclude(
"morphanim_custom.glsllib");
249 vertexShader.addUniformArray(
"qt_morphWeights",
"float", morphSize);
250 vertexShader.addUniform(
"qt_morphTargetTexture",
"sampler2DArray");
251 m_hasMorphing =
false;
254 if (!materialAdapter->isUnshaded()) {
255 hasCustomShadedMain =
true;
258 vertexShader << snippet;
261 vertexShader <<
"void main()"
268 vertexShader.append(
" vec4 qt_vertPosition = vec4(attr_pos, 1.0);");
269 vertexShader.append(
" vec3 qt_vertNormal = vec3(0.0);");
270 vertexShader.append(
" vec3 qt_vertTangent = vec3(0.0);");
271 vertexShader.append(
" vec3 qt_vertBinormal = vec3(0.0);");
272 if (meshHasTexCoord0 || hasCustomVertexShader)
273 vertexShader.append(
" vec2 qt_vertUV0 = vec2(0.0);");
274 if (meshHasTexCoord1 || hasCustomVertexShader)
275 vertexShader.append(
" vec2 qt_vertUV1 = vec2(0.0);");
276 if (m_hasSkinning || hasCustomVertexShader)
277 vertexShader.append(
" ivec4 qt_vertJoints = ivec4(0);");
278 if (meshHasJointsAndWeights || m_hasSkinning || hasCustomVertexShader)
279 vertexShader.append(
" vec4 qt_vertWeights = vec4(0.0);");
280 if (meshHasColors || usesInstancing || blendParticles || hasCustomVertexShader || hasCustomFragmentShader)
281 vertexShader.append(
" vec4 qt_vertColor = vec4(1.0);");
283 if (!usesInstancing) {
285 vertexShader.addUniform(
"qt_modelViewProjection",
"mat4");
287 vertexShader.addUniformArray(
"qt_modelViewProjection",
"mat4", m_viewCount);
290 vertexShader.addUniform(
"qt_modelMatrix",
"mat4");
291 vertexShader.addUniform(
"qt_parentMatrix",
"mat4");
293 vertexShader.addUniform(
"qt_viewProjectionMatrix",
"mat4");
295 vertexShader.addUniformArray(
"qt_viewProjectionMatrix",
"mat4", m_viewCount);
301 skipCustomFragmentSnippet =
false;
302 const bool isDepthPass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DepthPass);
303 const bool isOpaqueDepthPrePass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::OpaqueDepthPrePass);
304 skipCustomFragmentSnippet = (isDepthPass && !isOpaqueDepthPrePass);
306 if (hasCustomVertexShader || hasCustomFragmentShader) {
311 if (m_viewCount < 2) {
312 vertexShader.addUniform(
"qt_viewProjectionMatrix",
"mat4");
313 vertexShader.addUniform(
"qt_viewMatrix",
"mat4");
314 vertexShader.addUniform(
"qt_cameraPosition",
"vec3");
315 vertexShader.addUniform(
"qt_cameraDirection",
"vec3");
316 if (usesProjectionMatrix)
317 vertexShader.addUniform(
"qt_projectionMatrix",
"mat4");
318 if (usesInvProjectionMatrix)
319 vertexShader.addUniform(
"qt_inverseProjectionMatrix",
"mat4");
321 vertexShader.addUniformArray(
"qt_viewProjectionMatrix",
"mat4", m_viewCount);
322 vertexShader.addUniformArray(
"qt_viewMatrix",
"mat4", m_viewCount);
323 vertexShader.addUniformArray(
"qt_cameraPosition",
"vec3", m_viewCount);
324 vertexShader.addUniformArray(
"qt_cameraDirection",
"vec3", m_viewCount);
325 if (usesProjectionMatrix)
326 vertexShader.addUniformArray(
"qt_projectionMatrix",
"mat4", m_viewCount);
327 if (usesInvProjectionMatrix)
328 vertexShader.addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", m_viewCount);
330 vertexShader.addUniform(
"qt_modelMatrix",
"mat4");
331 vertexShader.addUniform(
"qt_normalMatrix",
"mat3");
332 vertexShader.addUniform(
"qt_cameraProperties",
"vec2");
338 if (m_viewCount >= 2) {
339 addFlatParameter(
"qt_viewIndex",
"uint");
340 vertexShader.append(
" qt_viewIndex = gl_ViewIndex;");
341 }
else if (usesViewIndex) {
342 addFlatParameter(
"qt_viewIndex",
"uint");
343 vertexShader.append(
" qt_viewIndex = 0;");
346 if (meshHasNormals) {
347 vertexShader.append(
" qt_vertNormal = attr_norm;");
348 vertexShader.addIncoming(
"attr_norm",
"vec3");
350 if (meshHasTexCoord0) {
351 vertexShader.append(
" qt_vertUV0 = attr_uv0;");
352 vertexShader.addIncoming(
"attr_uv0",
"vec2");
354 if (meshHasTexCoord1) {
355 vertexShader.append(
" qt_vertUV1 = attr_uv1;");
356 vertexShader.addIncoming(
"attr_uv1",
"vec2");
358 if (meshHasTexCoordLightmap) {
359 vertexShader.append(
" vec2 qt_vertLightmapUV = attr_lightmapuv;");
360 vertexShader.addIncoming(
"attr_lightmapuv",
"vec2");
362 if (meshHasTangents) {
363 vertexShader.append(
" qt_vertTangent = attr_textan;");
364 vertexShader.addIncoming(
"attr_textan",
"vec3");
366 if (meshHasBinormals) {
367 vertexShader.append(
" qt_vertBinormal = attr_binormal;");
368 vertexShader.addIncoming(
"attr_binormal",
"vec3");
371 vertexShader.append(
" qt_vertColor = attr_color;");
372 vertexShader.addIncoming(
"attr_color",
"vec4");
375 if (meshHasJointsAndWeights && (m_hasSkinning || hasCustomVertexShader)) {
376 if (usesFloatJointIndices) {
377 vertexShader.addIncoming(
"attr_joints",
"vec4");
378 vertexShader.append(
" qt_vertJoints = ivec4(attr_joints);");
380 vertexShader.addIncoming(
"attr_joints",
"ivec4");
381 vertexShader.append(
" qt_vertJoints = attr_joints;");
383 vertexShader.addIncoming(
"attr_weights",
"vec4");
384 vertexShader.append(
" qt_vertWeights = attr_weights;");
387 if (usesInstancing) {
388 vertexShader.append(
" qt_vertColor *= qt_instanceColor;");
389 vertexShader.append(
" mat4 qt_instanceMatrix = mat4(qt_instanceTransform0, qt_instanceTransform1, qt_instanceTransform2, vec4(0.0, 0.0, 0.0, 1.0));");
391 vertexShader.append(
" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix);");
393 vertexShader.append(
" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix) * qt_modelMatrix;");
394 vertexShader.append(
" mat3 qt_instancedNormalMatrix = mat3(transpose(inverse(qt_instancedModelMatrix)));");
396 vertexShader.append(
" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix * qt_instancedModelMatrix;");
398 vertexShader.append(
" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix[qt_viewIndex] * qt_instancedModelMatrix;");
401 if (!materialAdapter->isUnshaded() || !hasCustomVertexShader) {
402 vertexShader <<
" vec3 qt_uTransform;\n";
403 vertexShader <<
" vec3 qt_vTransform;\n";
405 if (hasCustomShadedMain)
408 if (m_hasMorphing && !hasCustomVertexShader)
409 vertexShader.append(
" qt_vertPosition.xyz = qt_getTargetPosition(qt_vertPosition.xyz);");
411 m_needsSkinning = m_hasSkinning && !materialAdapter->usesCustomSkinning();
412 if (m_needsSkinning) {
413 vertexShader.append(
" mat4 skinMat = mat4(1);");
414 vertexShader.append(
" if (qt_vertWeights != vec4(0.0)) {");
415 vertexShader.append(
" skinMat = qt_getSkinMatrix(qt_vertJoints, qt_vertWeights);");
416 vertexShader.append(
" qt_vertPosition = skinMat * qt_vertPosition;");
417 vertexShader.append(
" }");
419 if (blendParticles) {
420 vertexShader.append(
" qt_vertPosition.xyz = qt_applyParticle(qt_vertPosition.xyz, qt_vertNormal, qt_vertColor, qt_vertNormal, qt_vertColor, qt_particleMatrix);");
423 if (!hasCustomShadedMain || !overridesPosition) {
424 if (!usesInstancing) {
426 vertexShader.append(
" gl_Position = qt_modelViewProjection * qt_vertPosition;");
428 vertexShader.append(
" gl_Position = qt_modelViewProjection[qt_viewIndex] * qt_vertPosition;");
430 vertexShader.append(
" gl_Position = qt_instancedMVPMatrix * qt_vertPosition;");
435 if (usesPointsTopology && !hasCustomVertexShader) {
436 vertexShader.addUniform(
"qt_materialPointSize",
"float");
437 vertexShader.append(
" gl_PointSize = qt_materialPointSize;");
441void QSSGMaterialVertexPipeline::beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager, QSSGRenderLayer::OITMethod oitMethod)
443 fragment().addUniform(
"qt_material_properties",
"vec4");
444 fragment().addUniform(
"qt_rhi_properties",
"vec4");
446 if (m_viewCount < 2) {
447 fragment().addUniform(
"qt_viewMatrix",
"mat4");
449 fragment().addUniformArray(
"qt_viewMatrix",
"mat4", m_viewCount);
452 if (!skipCustomFragmentSnippet && materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment)) {
453 QByteArray snippet = materialAdapter->customShaderSnippet(QSSGShaderCache::ShaderType::Fragment,
454 shaderLibraryManager,
456 if (!materialAdapter->isUnshaded()) {
457 insertAmbientLightProcessorArgs(snippet, materialAdapter);
458 insertIblProbeProcessorArgs(snippet, materialAdapter);
459 insertSpecularLightProcessorArgs(snippet, materialAdapter);
460 insertSpotLightProcessorArgs(snippet, materialAdapter);
461 insertPointLightProcessorArgs(snippet, materialAdapter);
462 insertDirectionalLightProcessorArgs(snippet, materialAdapter);
463 insertFragmentMainArgs(snippet, materialAdapter);
464 insertPostProcessorArgs(snippet, materialAdapter);
465 auto sharedVars = extractSharedVarsTypeDefinition(snippet, materialAdapter);
466 fragment().addTypeDeclaration(
"QT_SHARED_VARS", sharedVars);
468 fragment() << snippet;
471 if (oitMethod != QSSGRenderLayer::OITMethod::None) {
472 if (oitMethod == QSSGRenderLayer::OITMethod::LinkedList) {
476 fragment() <<
"layout(early_fragment_tests) in;" <<
"\n";
478 if (oitMethod == QSSGRenderLayer::OITMethod::WeightedBlended) {
479 fragment().addDefinition(
"QSSG_OIT_METHOD",
"QSSG_OIT_WEIGHTED_BLENDED");
480 fragment() <<
"layout(location = 1) out vec4 revealageOutput;" <<
"\n";
481 }
else if (oitMethod == QSSGRenderLayer::OITMethod::LinkedList) {
482 fragment() <<
"#extension GL_ARB_shading_language_packing : enable" <<
"\n";
483 fragment().addDefinition(
"QSSG_OIT_METHOD",
"QSSG_OIT_LINKED_LIST");
486 fragment() <<
"void main()"
491 if (!materialAdapter->isUnshaded() || !materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment))
492 fragment() <<
" float qt_objectOpacity = qt_material_properties.a;\n";