146void QSSGMaterialVertexPipeline::beginVertexGeneration(
const QSSGShaderDefaultMaterialKey &inKey,
147 const QSSGShaderFeatures &inFeatureSet,
148 QSSGShaderLibraryManager &shaderLibraryManager)
150 QSSGShaderGeneratorStageFlags theStages(QSSGProgramGenerator::defaultFlags());
151 programGenerator()->beginProgram(theStages);
153 QSSGStageGeneratorBase &vertexShader(vertex());
155 const bool meshHasNormals = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
156 QSSGShaderKeyVertexAttribute::Normal, inKey);
157 const bool meshHasTexCoord0 = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
158 QSSGShaderKeyVertexAttribute::TexCoord0, inKey);
159 const bool meshHasTexCoord1 = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
160 QSSGShaderKeyVertexAttribute::TexCoord1, inKey);
161 const bool meshHasTexCoordLightmap = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
162 QSSGShaderKeyVertexAttribute::TexCoordLightmap, inKey);
163 const bool meshHasTangents = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
164 QSSGShaderKeyVertexAttribute::Tangent, inKey);
165 const bool meshHasBinormals = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
166 QSSGShaderKeyVertexAttribute::Binormal, inKey);
167 const bool meshHasColors = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
168 QSSGShaderKeyVertexAttribute::Color, inKey);
169 const bool meshHasJointsAndWeights = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
170 QSSGShaderKeyVertexAttribute::JointAndWeight, inKey);
171 const bool overridesPosition = defaultMaterialShaderKeyProperties.m_overridesPosition.getValue(inKey);
172 const bool usesProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesProjectionMatrix.getValue(inKey);
173 const bool usesInvProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesInverseProjectionMatrix.getValue(inKey);
174 const bool usesPointsTopology = defaultMaterialShaderKeyProperties.m_usesPointsTopology.getValue(inKey);
175 const bool usesFloatJointIndices = defaultMaterialShaderKeyProperties.m_usesFloatJointIndices.getValue(inKey);
176 const bool blendParticles = defaultMaterialShaderKeyProperties.m_blendParticles.getValue(inKey);
177 usesInstancing = defaultMaterialShaderKeyProperties.m_usesInstancing.getValue(inKey);
178 m_hasSkinning = defaultMaterialShaderKeyProperties.m_boneCount.getValue(inKey) > 0;
179 const auto morphSize = defaultMaterialShaderKeyProperties.m_targetCount.getValue(inKey);
180 m_hasMorphing = morphSize > 0;
181 m_viewCount = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DisableMultiView)
182 ? 1 : defaultMaterialShaderKeyProperties.m_viewCount.getValue(inKey);
183 const bool usesViewIndex = defaultMaterialShaderKeyProperties.m_usesViewIndex.getValue(inKey);
185 vertexShader.addIncoming(
"attr_pos",
"vec3");
186 if (usesInstancing) {
187 vertexShader.addIncoming(
"qt_instanceTransform0",
"vec4");
188 vertexShader.addIncoming(
"qt_instanceTransform1",
"vec4");
189 vertexShader.addIncoming(
"qt_instanceTransform2",
"vec4");
190 vertexShader.addIncoming(
"qt_instanceColor",
"vec4");
191 vertexShader.addIncoming(
"qt_instanceData",
"vec4");
193 if (blendParticles) {
194 vertexShader.addInclude(
"particles.glsllib");
195 vertexShader.addUniform(
"qt_particleTexture",
"sampler2D");
196 vertexShader.addUniform(
"qt_countPerSlice",
"uint");
197 vertexShader.addUniform(
"qt_oneOverParticleImageSize",
"vec2");
198 vertexShader.addUniform(
"qt_particleMatrix",
"mat4");
199 vertexShader.addUniform(
"qt_particleIndexOffset",
"uint");
202 if (m_hasSkinning && meshHasJointsAndWeights) {
203 vertexShader.addInclude(
"skinanim.glsllib");
204 if (usesFloatJointIndices)
205 vertexShader.addIncoming(
"attr_joints",
"vec4");
207 vertexShader.addIncoming(
"attr_joints",
"ivec4");
208 vertexShader.addIncoming(
"attr_weights",
"vec4");
210 vertexShader.addUniform(
"qt_boneTexture",
"sampler2D");
213 vertexShader.addInclude(
"morphanim.glsllib");
214 vertexShader.addUniformArray(
"qt_morphWeights",
"float", morphSize);
215 vertexShader.addUniform(
"qt_morphTargetTexture",
"sampler2DArray");
218 const bool hasCustomVertexShader = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Vertex);
219 const bool hasCustomFragmentShader = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
220 if (hasCustomVertexShader) {
221 QByteArray snippet = materialAdapter->customShaderSnippet(QSSGShaderCache::ShaderType::Vertex,
222 shaderLibraryManager,
224 if (materialAdapter->hasCustomShaderFunction(QSSGShaderCache::ShaderType::Vertex,
225 QByteArrayLiteral(
"qt_customMain"),
226 shaderLibraryManager))
229 insertVertexInstancedMainArgs(snippet);
231 insertVertexMainArgs(snippet);
233 if (materialAdapter->usesCustomSkinning()) {
234 vertexShader.addInclude(
"skinanim.glsllib");
235 vertexShader.addUniform(
"qt_boneTexture",
"sampler2D");
238 if (materialAdapter->usesCustomMorphing()) {
239 vertexShader.addInclude(
"morphanim_custom.glsllib");
241 vertexShader.addUniformArray(
"qt_morphWeights",
"float", morphSize);
242 vertexShader.addUniform(
"qt_morphTargetTexture",
"sampler2DArray");
243 m_hasMorphing =
false;
246 if (!materialAdapter->isUnshaded()) {
247 hasCustomShadedMain =
true;
250 vertexShader << snippet;
253 vertexShader <<
"void main()"
260 vertexShader.append(
" vec4 qt_vertPosition = vec4(attr_pos, 1.0);");
261 vertexShader.append(
" vec3 qt_vertNormal = vec3(0.0);");
262 vertexShader.append(
" vec3 qt_vertTangent = vec3(0.0);");
263 vertexShader.append(
" vec3 qt_vertBinormal = vec3(0.0);");
264 if (meshHasTexCoord0 || hasCustomVertexShader)
265 vertexShader.append(
" vec2 qt_vertUV0 = vec2(0.0);");
266 if (meshHasTexCoord1 || hasCustomVertexShader)
267 vertexShader.append(
" vec2 qt_vertUV1 = vec2(0.0);");
268 if (m_hasSkinning || hasCustomVertexShader)
269 vertexShader.append(
" ivec4 qt_vertJoints = ivec4(0);");
270 if (meshHasJointsAndWeights || m_hasSkinning || hasCustomVertexShader)
271 vertexShader.append(
" vec4 qt_vertWeights = vec4(0.0);");
272 if (meshHasColors || usesInstancing || blendParticles || hasCustomVertexShader || hasCustomFragmentShader)
273 vertexShader.append(
" vec4 qt_vertColor = vec4(1.0);");
275 if (!usesInstancing) {
277 vertexShader.addUniform(
"qt_modelViewProjection",
"mat4");
279 vertexShader.addUniformArray(
"qt_modelViewProjection",
"mat4", m_viewCount);
282 vertexShader.addUniform(
"qt_modelMatrix",
"mat4");
283 vertexShader.addUniform(
"qt_parentMatrix",
"mat4");
285 vertexShader.addUniform(
"qt_viewProjectionMatrix",
"mat4");
287 vertexShader.addUniformArray(
"qt_viewProjectionMatrix",
"mat4", m_viewCount);
293 skipCustomFragmentSnippet =
false;
294 const bool isDepthPass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DepthPass);
295 const bool isOpaqueDepthPrePass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::OpaqueDepthPrePass);
296 skipCustomFragmentSnippet = (isDepthPass && !isOpaqueDepthPrePass);
298 if (hasCustomVertexShader || hasCustomFragmentShader) {
303 if (m_viewCount < 2) {
304 vertexShader.addUniform(
"qt_viewProjectionMatrix",
"mat4");
305 vertexShader.addUniform(
"qt_viewMatrix",
"mat4");
306 vertexShader.addUniform(
"qt_cameraPosition",
"vec3");
307 vertexShader.addUniform(
"qt_cameraDirection",
"vec3");
308 if (usesProjectionMatrix)
309 vertexShader.addUniform(
"qt_projectionMatrix",
"mat4");
310 if (usesInvProjectionMatrix)
311 vertexShader.addUniform(
"qt_inverseProjectionMatrix",
"mat4");
313 vertexShader.addUniformArray(
"qt_viewProjectionMatrix",
"mat4", m_viewCount);
314 vertexShader.addUniformArray(
"qt_viewMatrix",
"mat4", m_viewCount);
315 vertexShader.addUniformArray(
"qt_cameraPosition",
"vec3", m_viewCount);
316 vertexShader.addUniformArray(
"qt_cameraDirection",
"vec3", m_viewCount);
317 if (usesProjectionMatrix)
318 vertexShader.addUniformArray(
"qt_projectionMatrix",
"mat4", m_viewCount);
319 if (usesInvProjectionMatrix)
320 vertexShader.addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", m_viewCount);
322 vertexShader.addUniform(
"qt_modelMatrix",
"mat4");
323 vertexShader.addUniform(
"qt_normalMatrix",
"mat3");
324 vertexShader.addUniform(
"qt_cameraProperties",
"vec2");
330 if (m_viewCount >= 2) {
331 addFlatParameter(
"qt_viewIndex",
"uint");
332 vertexShader.append(
" qt_viewIndex = gl_ViewIndex;");
333 }
else if (usesViewIndex) {
334 addFlatParameter(
"qt_viewIndex",
"uint");
335 vertexShader.append(
" qt_viewIndex = 0;");
338 if (meshHasNormals) {
339 vertexShader.append(
" qt_vertNormal = attr_norm;");
340 vertexShader.addIncoming(
"attr_norm",
"vec3");
342 if (meshHasTexCoord0) {
343 vertexShader.append(
" qt_vertUV0 = attr_uv0;");
344 vertexShader.addIncoming(
"attr_uv0",
"vec2");
346 if (meshHasTexCoord1) {
347 vertexShader.append(
" qt_vertUV1 = attr_uv1;");
348 vertexShader.addIncoming(
"attr_uv1",
"vec2");
350 if (meshHasTexCoordLightmap) {
351 vertexShader.append(
" vec2 qt_vertLightmapUV = attr_lightmapuv;");
352 vertexShader.addIncoming(
"attr_lightmapuv",
"vec2");
354 if (meshHasTangents) {
355 vertexShader.append(
" qt_vertTangent = attr_textan;");
356 vertexShader.addIncoming(
"attr_textan",
"vec3");
358 if (meshHasBinormals) {
359 vertexShader.append(
" qt_vertBinormal = attr_binormal;");
360 vertexShader.addIncoming(
"attr_binormal",
"vec3");
363 vertexShader.append(
" qt_vertColor = attr_color;");
364 vertexShader.addIncoming(
"attr_color",
"vec4");
367 if (meshHasJointsAndWeights && (m_hasSkinning || hasCustomVertexShader)) {
368 if (usesFloatJointIndices) {
369 vertexShader.addIncoming(
"attr_joints",
"vec4");
370 vertexShader.append(
" qt_vertJoints = ivec4(attr_joints);");
372 vertexShader.addIncoming(
"attr_joints",
"ivec4");
373 vertexShader.append(
" qt_vertJoints = attr_joints;");
375 vertexShader.addIncoming(
"attr_weights",
"vec4");
376 vertexShader.append(
" qt_vertWeights = attr_weights;");
379 if (usesInstancing) {
380 vertexShader.append(
" qt_vertColor *= qt_instanceColor;");
381 vertexShader.append(
" mat4 qt_instanceMatrix = mat4(qt_instanceTransform0, qt_instanceTransform1, qt_instanceTransform2, vec4(0.0, 0.0, 0.0, 1.0));");
383 vertexShader.append(
" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix);");
385 vertexShader.append(
" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix) * qt_modelMatrix;");
386 vertexShader.append(
" mat3 qt_instancedNormalMatrix = mat3(transpose(inverse(qt_instancedModelMatrix)));");
388 vertexShader.append(
" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix * qt_instancedModelMatrix;");
390 vertexShader.append(
" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix[qt_viewIndex] * qt_instancedModelMatrix;");
393 if (!materialAdapter->isUnshaded() || !hasCustomVertexShader) {
394 vertexShader <<
" vec3 qt_uTransform;\n";
395 vertexShader <<
" vec3 qt_vTransform;\n";
397 if (hasCustomShadedMain)
400 if (m_hasMorphing && !hasCustomVertexShader)
401 vertexShader.append(
" qt_vertPosition.xyz = qt_getTargetPosition(qt_vertPosition.xyz);");
403 m_needsSkinning = m_hasSkinning && !materialAdapter->usesCustomSkinning();
404 if (m_needsSkinning) {
405 vertexShader.append(
" mat4 skinMat = mat4(1);");
406 vertexShader.append(
" if (qt_vertWeights != vec4(0.0)) {");
407 vertexShader.append(
" skinMat = qt_getSkinMatrix(qt_vertJoints, qt_vertWeights);");
408 vertexShader.append(
" qt_vertPosition = skinMat * qt_vertPosition;");
409 vertexShader.append(
" }");
411 if (blendParticles) {
412 vertexShader.append(
" qt_vertPosition.xyz = qt_applyParticle(qt_vertPosition.xyz, qt_vertNormal, qt_vertColor, qt_vertNormal, qt_vertColor, qt_particleMatrix);");
415 if (!hasCustomShadedMain || !overridesPosition) {
416 if (!usesInstancing) {
418 vertexShader.append(
" gl_Position = qt_modelViewProjection * qt_vertPosition;");
420 vertexShader.append(
" gl_Position = qt_modelViewProjection[qt_viewIndex] * qt_vertPosition;");
422 vertexShader.append(
" gl_Position = qt_instancedMVPMatrix * qt_vertPosition;");
427 if (usesPointsTopology && !hasCustomVertexShader) {
428 vertexShader.addUniform(
"qt_materialPointSize",
"float");
429 vertexShader.append(
" gl_PointSize = qt_materialPointSize;");
433void QSSGMaterialVertexPipeline::beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager, QSSGRenderLayer::OITMethod oitMethod)
435 fragment().addUniform(
"qt_material_properties",
"vec4");
436 fragment().addUniform(
"qt_rhi_properties",
"vec4");
438 if (m_viewCount < 2) {
439 fragment().addUniform(
"qt_viewMatrix",
"mat4");
441 fragment().addUniformArray(
"qt_viewMatrix",
"mat4", m_viewCount);
444 if (!skipCustomFragmentSnippet && materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment)) {
445 QByteArray snippet = materialAdapter->customShaderSnippet(QSSGShaderCache::ShaderType::Fragment,
446 shaderLibraryManager,
448 if (!materialAdapter->isUnshaded()) {
449 insertAmbientLightProcessorArgs(snippet, materialAdapter);
450 insertIblProbeProcessorArgs(snippet, materialAdapter);
451 insertSpecularLightProcessorArgs(snippet, materialAdapter);
452 insertSpotLightProcessorArgs(snippet, materialAdapter);
453 insertPointLightProcessorArgs(snippet, materialAdapter);
454 insertDirectionalLightProcessorArgs(snippet, materialAdapter);
455 insertFragmentMainArgs(snippet, materialAdapter);
456 insertPostProcessorArgs(snippet, materialAdapter);
457 auto sharedVars = extractSharedVarsTypeDefinition(snippet, materialAdapter);
458 fragment().addTypeDeclaration(
"QT_SHARED_VARS", sharedVars);
460 fragment() << snippet;
463 if (oitMethod != QSSGRenderLayer::OITMethod::None) {
464 if (oitMethod == QSSGRenderLayer::OITMethod::LinkedList) {
468 fragment() <<
"layout(early_fragment_tests) in;" <<
"\n";
470 if (oitMethod == QSSGRenderLayer::OITMethod::WeightedBlended) {
471 fragment().addDefinition(
"QSSG_OIT_METHOD",
"QSSG_OIT_WEIGHTED_BLENDED");
472 fragment() <<
"layout(location = 1) out vec4 revealageOutput;" <<
"\n";
473 }
else if (oitMethod == QSSGRenderLayer::OITMethod::LinkedList) {
474 fragment() <<
"#extension GL_ARB_shading_language_packing : enable" <<
"\n";
475 fragment().addDefinition(
"QSSG_OIT_METHOD",
"QSSG_OIT_LINKED_LIST");
478 fragment() <<
"void main()"
483 if (!materialAdapter->isUnshaded() || !materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment))
484 fragment() <<
" float qt_objectOpacity = qt_material_properties.a;\n";