144void QSSGMaterialVertexPipeline::beginVertexGeneration(
const QSSGShaderDefaultMaterialKey &inKey,
145 const QSSGShaderFeatures &inFeatureSet,
146 QSSGShaderLibraryManager &shaderLibraryManager)
148 QSSGShaderGeneratorStageFlags theStages(QSSGProgramGenerator::defaultFlags());
149 programGenerator()->beginProgram(theStages);
151 QSSGStageGeneratorBase &vertexShader(vertex());
153 const bool meshHasNormals = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
154 QSSGShaderKeyVertexAttribute::Normal, inKey);
155 const bool meshHasTexCoord0 = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
156 QSSGShaderKeyVertexAttribute::TexCoord0, inKey);
157 const bool meshHasTexCoord1 = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
158 QSSGShaderKeyVertexAttribute::TexCoord1, inKey);
159 const bool meshHasTexCoordLightmap = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
160 QSSGShaderKeyVertexAttribute::TexCoordLightmap, inKey);
161 const bool meshHasTangents = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
162 QSSGShaderKeyVertexAttribute::Tangent, inKey);
163 const bool meshHasBinormals = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
164 QSSGShaderKeyVertexAttribute::Binormal, inKey);
165 const bool meshHasColors = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
166 QSSGShaderKeyVertexAttribute::Color, inKey);
167 const bool meshHasJointsAndWeights = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
168 QSSGShaderKeyVertexAttribute::JointAndWeight, inKey);
169 const bool overridesPosition = defaultMaterialShaderKeyProperties.m_overridesPosition.getValue(inKey);
170 const bool usesProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesProjectionMatrix.getValue(inKey);
171 const bool usesInvProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesInverseProjectionMatrix.getValue(inKey);
172 const bool usesPointsTopology = defaultMaterialShaderKeyProperties.m_usesPointsTopology.getValue(inKey);
173 const bool usesFloatJointIndices = defaultMaterialShaderKeyProperties.m_usesFloatJointIndices.getValue(inKey);
174 const bool blendParticles = defaultMaterialShaderKeyProperties.m_blendParticles.getValue(inKey);
175 usesInstancing = defaultMaterialShaderKeyProperties.m_usesInstancing.getValue(inKey);
176 m_hasSkinning = defaultMaterialShaderKeyProperties.m_boneCount.getValue(inKey) > 0;
177 const auto morphSize = defaultMaterialShaderKeyProperties.m_targetCount.getValue(inKey);
178 m_hasMorphing = morphSize > 0;
179 m_viewCount = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DisableMultiView)
180 ? 1 : defaultMaterialShaderKeyProperties.m_viewCount.getValue(inKey);
181 const bool usesViewIndex = defaultMaterialShaderKeyProperties.m_usesViewIndex.getValue(inKey);
183 vertexShader.addIncoming(
"attr_pos",
"vec3");
184 if (usesInstancing) {
185 vertexShader.addIncoming(
"qt_instanceTransform0",
"vec4");
186 vertexShader.addIncoming(
"qt_instanceTransform1",
"vec4");
187 vertexShader.addIncoming(
"qt_instanceTransform2",
"vec4");
188 vertexShader.addIncoming(
"qt_instanceColor",
"vec4");
189 vertexShader.addIncoming(
"qt_instanceData",
"vec4");
191 if (blendParticles) {
192 vertexShader.addInclude(
"particles.glsllib");
193 vertexShader.addUniform(
"qt_particleTexture",
"sampler2D");
194 vertexShader.addUniform(
"qt_countPerSlice",
"uint");
195 vertexShader.addUniform(
"qt_oneOverParticleImageSize",
"vec2");
196 vertexShader.addUniform(
"qt_particleMatrix",
"mat4");
197 vertexShader.addUniform(
"qt_particleIndexOffset",
"uint");
200 if (m_hasSkinning && meshHasJointsAndWeights) {
201 vertexShader.addInclude(
"skinanim.glsllib");
202 if (usesFloatJointIndices)
203 vertexShader.addIncoming(
"attr_joints",
"vec4");
205 vertexShader.addIncoming(
"attr_joints",
"ivec4");
206 vertexShader.addIncoming(
"attr_weights",
"vec4");
208 vertexShader.addUniform(
"qt_boneTexture",
"sampler2D");
211 vertexShader.addInclude(
"morphanim.glsllib");
212 vertexShader.addUniformArray(
"qt_morphWeights",
"float", morphSize);
213 vertexShader.addUniform(
"qt_morphTargetTexture",
"sampler2DArray");
216 const bool hasCustomVertexShader = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Vertex);
217 const bool hasCustomFragmentShader = materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment);
218 if (hasCustomVertexShader) {
219 QByteArray snippet = materialAdapter->customShaderSnippet(QSSGShaderCache::ShaderType::Vertex,
220 shaderLibraryManager,
222 if (materialAdapter->hasCustomShaderFunction(QSSGShaderCache::ShaderType::Vertex,
223 QByteArrayLiteral(
"qt_customMain"),
224 shaderLibraryManager))
227 insertVertexInstancedMainArgs(snippet);
229 insertVertexMainArgs(snippet);
231 if (materialAdapter->usesCustomSkinning()) {
232 vertexShader.addInclude(
"skinanim.glsllib");
233 vertexShader.addUniform(
"qt_boneTexture",
"sampler2D");
236 if (materialAdapter->usesCustomMorphing()) {
237 vertexShader.addInclude(
"morphanim_custom.glsllib");
239 vertexShader.addUniformArray(
"qt_morphWeights",
"float", morphSize);
240 vertexShader.addUniform(
"qt_morphTargetTexture",
"sampler2DArray");
241 m_hasMorphing =
false;
244 if (!materialAdapter->isUnshaded()) {
245 hasCustomShadedMain =
true;
248 vertexShader << snippet;
251 vertexShader <<
"void main()"
258 vertexShader.append(
" vec4 qt_vertPosition = vec4(attr_pos, 1.0);");
259 vertexShader.append(
" vec3 qt_vertNormal = vec3(0.0);");
260 vertexShader.append(
" vec3 qt_vertTangent = vec3(0.0);");
261 vertexShader.append(
" vec3 qt_vertBinormal = vec3(0.0);");
262 if (meshHasTexCoord0 || hasCustomVertexShader)
263 vertexShader.append(
" vec2 qt_vertUV0 = vec2(0.0);");
264 if (meshHasTexCoord1 || hasCustomVertexShader)
265 vertexShader.append(
" vec2 qt_vertUV1 = vec2(0.0);");
266 if (m_hasSkinning || hasCustomVertexShader)
267 vertexShader.append(
" ivec4 qt_vertJoints = ivec4(0);");
268 if (meshHasJointsAndWeights || m_hasSkinning || hasCustomVertexShader)
269 vertexShader.append(
" vec4 qt_vertWeights = vec4(0.0);");
270 if (meshHasColors || usesInstancing || blendParticles || hasCustomVertexShader || hasCustomFragmentShader)
271 vertexShader.append(
" vec4 qt_vertColor = vec4(1.0);");
273 if (!usesInstancing) {
275 vertexShader.addUniform(
"qt_modelViewProjection",
"mat4");
277 vertexShader.addUniformArray(
"qt_modelViewProjection",
"mat4", m_viewCount);
280 vertexShader.addUniform(
"qt_modelMatrix",
"mat4");
281 vertexShader.addUniform(
"qt_parentMatrix",
"mat4");
283 vertexShader.addUniform(
"qt_viewProjectionMatrix",
"mat4");
285 vertexShader.addUniformArray(
"qt_viewProjectionMatrix",
"mat4", m_viewCount);
291 skipCustomFragmentSnippet =
false;
292 const bool isDepthPass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DepthPass);
293 const bool isOpaqueDepthPrePass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::OpaqueDepthPrePass);
294 const bool isNormalPass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::NormalPass);
295 skipCustomFragmentSnippet = (isDepthPass && !isOpaqueDepthPrePass) || isNormalPass;
297 if (hasCustomVertexShader || hasCustomFragmentShader) {
302 if (m_viewCount < 2) {
303 vertexShader.addUniform(
"qt_viewProjectionMatrix",
"mat4");
304 vertexShader.addUniform(
"qt_viewMatrix",
"mat4");
305 vertexShader.addUniform(
"qt_cameraPosition",
"vec3");
306 vertexShader.addUniform(
"qt_cameraDirection",
"vec3");
307 if (usesProjectionMatrix)
308 vertexShader.addUniform(
"qt_projectionMatrix",
"mat4");
309 if (usesInvProjectionMatrix)
310 vertexShader.addUniform(
"qt_inverseProjectionMatrix",
"mat4");
312 vertexShader.addUniformArray(
"qt_viewProjectionMatrix",
"mat4", m_viewCount);
313 vertexShader.addUniformArray(
"qt_viewMatrix",
"mat4", m_viewCount);
314 vertexShader.addUniformArray(
"qt_cameraPosition",
"vec3", m_viewCount);
315 vertexShader.addUniformArray(
"qt_cameraDirection",
"vec3", m_viewCount);
316 if (usesProjectionMatrix)
317 vertexShader.addUniformArray(
"qt_projectionMatrix",
"mat4", m_viewCount);
318 if (usesInvProjectionMatrix)
319 vertexShader.addUniformArray(
"qt_inverseProjectionMatrix",
"mat4", m_viewCount);
321 vertexShader.addUniform(
"qt_modelMatrix",
"mat4");
322 vertexShader.addUniform(
"qt_normalMatrix",
"mat3");
323 vertexShader.addUniform(
"qt_cameraProperties",
"vec2");
329 if (m_viewCount >= 2) {
330 addFlatParameter(
"qt_viewIndex",
"uint");
331 vertexShader.append(
" qt_viewIndex = gl_ViewIndex;");
332 }
else if (usesViewIndex) {
333 addFlatParameter(
"qt_viewIndex",
"uint");
334 vertexShader.append(
" qt_viewIndex = 0;");
337 if (meshHasNormals) {
338 vertexShader.append(
" qt_vertNormal = attr_norm;");
339 vertexShader.addIncoming(
"attr_norm",
"vec3");
341 if (meshHasTexCoord0) {
342 vertexShader.append(
" qt_vertUV0 = attr_uv0;");
343 vertexShader.addIncoming(
"attr_uv0",
"vec2");
345 if (meshHasTexCoord1) {
346 vertexShader.append(
" qt_vertUV1 = attr_uv1;");
347 vertexShader.addIncoming(
"attr_uv1",
"vec2");
349 if (meshHasTexCoordLightmap) {
350 vertexShader.append(
" vec2 qt_vertLightmapUV = attr_lightmapuv;");
351 vertexShader.addIncoming(
"attr_lightmapuv",
"vec2");
353 if (meshHasTangents) {
354 vertexShader.append(
" qt_vertTangent = attr_textan;");
355 vertexShader.addIncoming(
"attr_textan",
"vec3");
357 if (meshHasBinormals) {
358 vertexShader.append(
" qt_vertBinormal = attr_binormal;");
359 vertexShader.addIncoming(
"attr_binormal",
"vec3");
362 vertexShader.append(
" qt_vertColor = attr_color;");
363 vertexShader.addIncoming(
"attr_color",
"vec4");
366 if (meshHasJointsAndWeights && (m_hasSkinning || hasCustomVertexShader)) {
367 if (usesFloatJointIndices) {
368 vertexShader.addIncoming(
"attr_joints",
"vec4");
369 vertexShader.append(
" qt_vertJoints = ivec4(attr_joints);");
371 vertexShader.addIncoming(
"attr_joints",
"ivec4");
372 vertexShader.append(
" qt_vertJoints = attr_joints;");
374 vertexShader.addIncoming(
"attr_weights",
"vec4");
375 vertexShader.append(
" qt_vertWeights = attr_weights;");
378 if (usesInstancing) {
379 vertexShader.append(
" qt_vertColor *= qt_instanceColor;");
380 vertexShader.append(
" mat4 qt_instanceMatrix = mat4(qt_instanceTransform0, qt_instanceTransform1, qt_instanceTransform2, vec4(0.0, 0.0, 0.0, 1.0));");
382 vertexShader.append(
" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix);");
384 vertexShader.append(
" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix) * qt_modelMatrix;");
385 vertexShader.append(
" mat3 qt_instancedNormalMatrix = mat3(transpose(inverse(qt_instancedModelMatrix)));");
387 vertexShader.append(
" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix * qt_instancedModelMatrix;");
389 vertexShader.append(
" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix[qt_viewIndex] * qt_instancedModelMatrix;");
392 if (!materialAdapter->isUnshaded() || !hasCustomVertexShader) {
393 vertexShader <<
" vec3 qt_uTransform;\n";
394 vertexShader <<
" vec3 qt_vTransform;\n";
396 if (hasCustomShadedMain)
399 if (m_hasMorphing && !hasCustomVertexShader)
400 vertexShader.append(
" qt_vertPosition.xyz = qt_getTargetPosition(qt_vertPosition.xyz);");
402 m_needsSkinning = m_hasSkinning && !materialAdapter->usesCustomSkinning();
403 if (m_needsSkinning) {
404 vertexShader.append(
" mat4 skinMat = mat4(1);");
405 vertexShader.append(
" if (qt_vertWeights != vec4(0.0)) {");
406 vertexShader.append(
" skinMat = qt_getSkinMatrix(qt_vertJoints, qt_vertWeights);");
407 vertexShader.append(
" qt_vertPosition = skinMat * qt_vertPosition;");
408 vertexShader.append(
" }");
410 if (blendParticles) {
411 vertexShader.append(
" qt_vertPosition.xyz = qt_applyParticle(qt_vertPosition.xyz, qt_vertNormal, qt_vertColor, qt_vertNormal, qt_vertColor, qt_particleMatrix);");
414 if (!hasCustomShadedMain || !overridesPosition) {
415 if (!usesInstancing) {
417 vertexShader.append(
" gl_Position = qt_modelViewProjection * qt_vertPosition;");
419 vertexShader.append(
" gl_Position = qt_modelViewProjection[qt_viewIndex] * qt_vertPosition;");
421 vertexShader.append(
" gl_Position = qt_instancedMVPMatrix * qt_vertPosition;");
426 if (usesPointsTopology && !hasCustomVertexShader) {
427 vertexShader.addUniform(
"qt_materialPointSize",
"float");
428 vertexShader.append(
" gl_PointSize = qt_materialPointSize;");
432void QSSGMaterialVertexPipeline::beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager, QSSGRenderLayer::OITMethod oitMethod)
434 fragment().addUniform(
"qt_material_properties",
"vec4");
435 fragment().addUniform(
"qt_rhi_properties",
"vec4");
437 if (m_viewCount < 2) {
438 fragment().addUniform(
"qt_viewMatrix",
"mat4");
440 fragment().addUniformArray(
"qt_viewMatrix",
"mat4", m_viewCount);
443 if (!skipCustomFragmentSnippet && materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment)) {
444 QByteArray snippet = materialAdapter->customShaderSnippet(QSSGShaderCache::ShaderType::Fragment,
445 shaderLibraryManager,
447 if (!materialAdapter->isUnshaded()) {
448 insertAmbientLightProcessorArgs(snippet, materialAdapter);
449 insertIblProbeProcessorArgs(snippet, materialAdapter);
450 insertSpecularLightProcessorArgs(snippet, materialAdapter);
451 insertSpotLightProcessorArgs(snippet, materialAdapter);
452 insertPointLightProcessorArgs(snippet, materialAdapter);
453 insertDirectionalLightProcessorArgs(snippet, materialAdapter);
454 insertFragmentMainArgs(snippet, materialAdapter);
455 insertPostProcessorArgs(snippet, materialAdapter);
456 auto sharedVars = extractSharedVarsTypeDefinition(snippet, materialAdapter);
457 fragment().addTypeDeclaration(
"QT_SHARED_VARS", sharedVars);
459 fragment() << snippet;
461 if (oitMethod != QSSGRenderLayer::OITMethod::None) {
462 if (oitMethod == QSSGRenderLayer::OITMethod::WeightedBlended) {
463 fragment().addDefinition(
"QSSG_OIT_METHOD",
"QSSG_OIT_WEIGHTED_BLENDED");
464 fragment() <<
"layout(location = 1) out vec4 revealageOutput;" <<
"\n";
467 fragment() <<
"void main()"
472 if (!materialAdapter->isUnshaded() || !materialAdapter->hasCustomShaderSnippet(QSSGShaderCache::ShaderType::Fragment))
473 fragment() <<
" float qt_objectOpacity = qt_material_properties.a;\n";