Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qssgvertexpipelineimpl.cpp
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
6
7#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
8#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
10#include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrendershaderlibrarymanager_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgrendershadercodegenerator_p.h>
13#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h>
14#include <QtQuick3DRuntimeRender/private/qssgshadermaterialadapter_p.h>
15
17
19 const QSSGShaderDefaultMaterialKeyProperties &materialProperties,
20 QSSGShaderMaterialAdapter *materialAdapter)
21 : m_programGenerator(&programGen)
22 , defaultMaterialShaderKeyProperties(materialProperties)
23 , materialAdapter(materialAdapter)
24 , hasCustomShadedMain(false)
25 , skipCustomFragmentSnippet(false)
26{
27}
28
29static inline void insertProcessorArgs(QByteArray &snippet, const char *argKey, const char* (*argListFunc)(), bool usesShared = false, bool isSharedInout = false)
30{
31 const int argKeyLen = int(strlen(argKey));
32 const int argKeyPos = snippet.indexOf(argKey);
33 if (argKeyPos >= 0) {
34 if (!usesShared) {
35 snippet = snippet.left(argKeyPos) + argListFunc() + snippet.mid(argKeyPos + argKeyLen);
36 } else {
37 const char *inoutString = isSharedInout ? ", inout " : ", in ";
38 snippet = snippet.left(argKeyPos) + argListFunc() + inoutString + QByteArrayLiteral("QT_SHARED_VARS SHARED") + snippet.mid(argKeyPos + argKeyLen);
39 }
40 }
41}
42
43static inline void insertDirectionalLightProcessorArgs(QByteArray &snippet, bool usesShared)
44{
45 insertProcessorArgs(snippet, "/*%QT_ARGS_DIRECTIONAL_LIGHT%*/", QSSGMaterialShaderGenerator::directionalLightProcessorArgumentList, usesShared, true);
46}
47
48static inline void insertPointLightProcessorArgs(QByteArray &snippet, bool usesShared)
49{
50 insertProcessorArgs(snippet, "/*%QT_ARGS_POINT_LIGHT%*/", QSSGMaterialShaderGenerator::pointLightProcessorArgumentList, usesShared, true);
51}
52
53static inline void insertSpotLightProcessorArgs(QByteArray &snippet, bool usesShared)
54{
55 insertProcessorArgs(snippet, "/*%QT_ARGS_SPOT_LIGHT%*/", QSSGMaterialShaderGenerator::spotLightProcessorArgumentList, usesShared, true);
56}
57
58static inline void insertAmbientLightProcessorArgs(QByteArray &snippet, bool usesShared)
59{
60 insertProcessorArgs(snippet, "/*%QT_ARGS_AMBIENT_LIGHT%*/", QSSGMaterialShaderGenerator::ambientLightProcessorArgumentList, usesShared, true);
61}
62
63static inline void insertIblProbeProcessorArgs(QByteArray &snippet, bool usesShared)
64{
65 insertProcessorArgs(snippet, "/*%QT_ARGS_IBL_PROBE%*/", QSSGMaterialShaderGenerator::iblProbeProcessorArgumentList, usesShared, true);
66}
67
68static inline void insertSpecularLightProcessorArgs(QByteArray &snippet, bool usesShared)
69{
70 insertProcessorArgs(snippet, "/*%QT_ARGS_SPECULAR_LIGHT%*/", QSSGMaterialShaderGenerator::specularLightProcessorArgumentList, usesShared, true);
71}
72
73static inline void insertFragmentMainArgs(QByteArray &snippet, bool usesShared = false)
74{
75 insertProcessorArgs(snippet, "/*%QT_ARGS_MAIN%*/", QSSGMaterialShaderGenerator::shadedFragmentMainArgumentList, usesShared, true);
76}
77
78static inline void insertPostProcessorArgs(QByteArray &snippet, bool usesShared)
79{
80 insertProcessorArgs(snippet, "/*%QT_ARGS_POST_PROCESS%*/", QSSGMaterialShaderGenerator::postProcessorArgumentList, usesShared, false);
81}
82
83static inline void insertVertexMainArgs(QByteArray &snippet)
84{
86}
87
92
93static inline const char *customMainCallWithArguments(bool usesInstancing)
94{
95 if (usesInstancing)
96 return " qt_customMain(qt_vertPosition.xyz, qt_vertNormal, qt_vertUV0, qt_vertUV1, qt_vertTangent, qt_vertBinormal, qt_vertJoints, qt_vertWeights, qt_vertColor, qt_instancedModelMatrix, qt_instancedMVPMatrix);";
97 else
98 return " qt_customMain(qt_vertPosition.xyz, qt_vertNormal, qt_vertUV0, qt_vertUV1, qt_vertTangent, qt_vertBinormal, qt_vertJoints, qt_vertWeights, qt_vertColor);\n";
99}
100
102 const QSSGShaderFeatures &inFeatureSet,
103 QSSGShaderLibraryManager &shaderLibraryManager)
104{
105 QSSGShaderGeneratorStageFlags theStages(QSSGProgramGenerator::defaultFlags());
106 programGenerator()->beginProgram(theStages);
107
108 QSSGStageGeneratorBase &vertexShader(vertex());
109
116 const bool meshHasTexCoordLightmap = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
124 const bool meshHasJointsAndWeights = defaultMaterialShaderKeyProperties.m_vertexAttributes.getBitValue(
126 const bool overridesPosition = defaultMaterialShaderKeyProperties.m_overridesPosition.getValue(inKey);
127 const bool usesProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesProjectionMatrix.getValue(inKey);
128 const bool usesInvProjectionMatrix = defaultMaterialShaderKeyProperties.m_usesInverseProjectionMatrix.getValue(inKey);
129 const bool usesPointsTopology = defaultMaterialShaderKeyProperties.m_usesPointsTopology.getValue(inKey);
130 const bool usesFloatJointIndices = defaultMaterialShaderKeyProperties.m_usesFloatJointIndices.getValue(inKey);
131 const bool blendParticles = defaultMaterialShaderKeyProperties.m_blendParticles.getValue(inKey);
134 const auto morphSize = defaultMaterialShaderKeyProperties.m_targetCount.getValue(inKey);
135 m_hasMorphing = morphSize > 0;
138 const bool usesViewIndex = defaultMaterialShaderKeyProperties.m_usesViewIndex.getValue(inKey);
139
140 vertexShader.addIncoming("attr_pos", "vec3");
141 if (usesInstancing) {
142 vertexShader.addIncoming("qt_instanceTransform0", "vec4");
143 vertexShader.addIncoming("qt_instanceTransform1", "vec4");
144 vertexShader.addIncoming("qt_instanceTransform2", "vec4");
145 vertexShader.addIncoming("qt_instanceColor", "vec4");
146 vertexShader.addIncoming("qt_instanceData", "vec4");
147 }
148 if (blendParticles) {
149 vertexShader.addInclude("particles.glsllib");
150 vertexShader.addUniform("qt_particleTexture", "sampler2D");
151 vertexShader.addUniform("qt_countPerSlice", "uint");
152 vertexShader.addUniform("qt_oneOverParticleImageSize", "vec2");
153 vertexShader.addUniform("qt_particleMatrix", "mat4");
154 vertexShader.addUniform("qt_particleIndexOffset", "uint");
155 }
156
157 if (m_hasSkinning && meshHasJointsAndWeights) {
158 vertexShader.addInclude("skinanim.glsllib");
159 if (usesFloatJointIndices)
160 vertexShader.addIncoming("attr_joints", "vec4");
161 else
162 vertexShader.addIncoming("attr_joints", "ivec4");
163 vertexShader.addIncoming("attr_weights", "vec4");
164
165 vertexShader.addUniform("qt_boneTexture", "sampler2D");
166 }
167 if (m_hasMorphing) {
168 vertexShader.addInclude("morphanim.glsllib");
169 vertexShader.addUniformArray("qt_morphWeights", "float", morphSize);
170 vertexShader.addUniform("qt_morphTargetTexture", "sampler2DArray");
171 }
172
175 if (hasCustomVertexShader) {
177 shaderLibraryManager,
178 m_viewCount >= 2);
180 QByteArrayLiteral("qt_customMain"),
181 shaderLibraryManager))
182 {
183 if (usesInstancing)
185 else
186 insertVertexMainArgs(snippet);
187
189 vertexShader.addInclude("skinanim.glsllib");
190 vertexShader.addUniform("qt_boneTexture", "sampler2D");
191 m_hasSkinning = false;
192 }
193
195 vertexShader.addInclude("morphanim_custom.glsllib");
196 if (morphSize > 0)
197 vertexShader.addUniformArray("qt_morphWeights", "float", morphSize);
198 vertexShader.addUniform("qt_morphTargetTexture", "sampler2DArray");
199 m_hasMorphing = false;
200 }
201
202 if (!materialAdapter->isUnshaded()) {
203 hasCustomShadedMain = true;
204 }
205 }
206 vertexShader << snippet;
207 }
208
209 vertexShader << "void main()"
210 << "\n"
211 << "{"
212 << "\n";
213 // These local variables will be used for whole the pipeline
214 // instead of each attributes since it is more convenient
215 // for adding new routines.
216 vertexShader.append(" vec4 qt_vertPosition = vec4(attr_pos, 1.0);");
217 vertexShader.append(" vec3 qt_vertNormal = vec3(0.0);");
218 vertexShader.append(" vec3 qt_vertTangent = vec3(0.0);");
219 vertexShader.append(" vec3 qt_vertBinormal = vec3(0.0);");
220 if (meshHasTexCoord0 || hasCustomVertexShader)
221 vertexShader.append(" vec2 qt_vertUV0 = vec2(0.0);");
222 if (meshHasTexCoord1 || hasCustomVertexShader)
223 vertexShader.append(" vec2 qt_vertUV1 = vec2(0.0);");
224 if (m_hasSkinning || hasCustomVertexShader)
225 vertexShader.append(" ivec4 qt_vertJoints = ivec4(0);");
226 if (meshHasJointsAndWeights || m_hasSkinning || hasCustomVertexShader)
227 vertexShader.append(" vec4 qt_vertWeights = vec4(0.0);");
228 if (meshHasColors || usesInstancing || blendParticles || hasCustomVertexShader || hasCustomFragmentShader)
229 vertexShader.append(" vec4 qt_vertColor = vec4(1.0);"); // must be 1,1,1,1 to not alter when multiplying with it
230
231 if (!usesInstancing) {
232 if (m_viewCount < 2)
233 vertexShader.addUniform("qt_modelViewProjection", "mat4");
234 else
235 vertexShader.addUniformArray("qt_modelViewProjection", "mat4", m_viewCount);
236 } else {
237 // Must manualy calculate a MVP
238 vertexShader.addUniform("qt_modelMatrix", "mat4");
239 vertexShader.addUniform("qt_parentMatrix", "mat4");
240 if (m_viewCount < 2)
241 vertexShader.addUniform("qt_viewProjectionMatrix", "mat4");
242 else
243 vertexShader.addUniformArray("qt_viewProjectionMatrix", "mat4", m_viewCount);
244 }
245
246 // The custom fragment main should be skipped if this is a
247 // depth pass, but not if it is also a OpaqueDepthPrePass
248 // because then we need to know the real alpha values
250 const bool isDepthPass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::DepthPass);
251 const bool isOpaqueDepthPrePass = inFeatureSet.isSet(QSSGShaderFeatures::Feature::OpaqueDepthPrePass);
252 skipCustomFragmentSnippet = (isDepthPass && !isOpaqueDepthPrePass);
253
254 if (hasCustomVertexShader || hasCustomFragmentShader) {
255 // This is both for unshaded and shaded. Regardless of any other
256 // condition we have to ensure the keywords (VIEW_MATRIX etc.) promised
257 // by the documentation are available in *both* the custom vertex and
258 // fragment shader snippets, even if only one of them is present.
259 if (m_viewCount < 2) {
260 vertexShader.addUniform("qt_viewProjectionMatrix", "mat4");
261 vertexShader.addUniform("qt_viewMatrix", "mat4");
262 vertexShader.addUniform("qt_cameraPosition", "vec3");
263 vertexShader.addUniform("qt_cameraDirection", "vec3");
264 if (usesProjectionMatrix)
265 vertexShader.addUniform("qt_projectionMatrix", "mat4");
266 if (usesInvProjectionMatrix)
267 vertexShader.addUniform("qt_inverseProjectionMatrix", "mat4");
268 } else {
269 vertexShader.addUniformArray("qt_viewProjectionMatrix", "mat4", m_viewCount);
270 vertexShader.addUniformArray("qt_viewMatrix", "mat4", m_viewCount);
271 vertexShader.addUniformArray("qt_cameraPosition", "vec3", m_viewCount);
272 vertexShader.addUniformArray("qt_cameraDirection", "vec3", m_viewCount);
273 if (usesProjectionMatrix)
274 vertexShader.addUniformArray("qt_projectionMatrix", "mat4", m_viewCount);
275 if (usesInvProjectionMatrix)
276 vertexShader.addUniformArray("qt_inverseProjectionMatrix", "mat4", m_viewCount);
277 }
278 vertexShader.addUniform("qt_modelMatrix", "mat4");
279 vertexShader.addUniform("qt_normalMatrix", "mat3");
280 vertexShader.addUniform("qt_cameraProperties", "vec2");
281 }
282
283 // With multiview, qt_viewIndex (aka VIEW_INDEX) is always present.
284 // Otherwise, we still make VIEW_INDEX functional (always 0) in custom
285 // materials, if the keyword is used.
286 if (m_viewCount >= 2) {
287 addFlatParameter("qt_viewIndex", "uint");
288 vertexShader.append(" qt_viewIndex = gl_ViewIndex;");
289 } else if (usesViewIndex) {
290 addFlatParameter("qt_viewIndex", "uint");
291 vertexShader.append(" qt_viewIndex = 0;");
292 }
293
294 if (meshHasNormals) {
295 vertexShader.append(" qt_vertNormal = attr_norm;");
296 vertexShader.addIncoming("attr_norm", "vec3");
297 }
298 if (meshHasTexCoord0) {
299 vertexShader.append(" qt_vertUV0 = attr_uv0;");
300 vertexShader.addIncoming("attr_uv0", "vec2");
301 }
302 if (meshHasTexCoord1) {
303 vertexShader.append(" qt_vertUV1 = attr_uv1;");
304 vertexShader.addIncoming("attr_uv1", "vec2");
305 }
306 if (meshHasTexCoordLightmap) {
307 vertexShader.append(" vec2 qt_vertLightmapUV = attr_lightmapuv;");
308 vertexShader.addIncoming("attr_lightmapuv", "vec2");
309 }
310 if (meshHasTangents) {
311 vertexShader.append(" qt_vertTangent = attr_textan;");
312 vertexShader.addIncoming("attr_textan", "vec3");
313 }
314 if (meshHasBinormals) {
315 vertexShader.append(" qt_vertBinormal = attr_binormal;");
316 vertexShader.addIncoming("attr_binormal", "vec3");
317 }
318 if (meshHasColors) {
319 vertexShader.append(" qt_vertColor = attr_color;");
320 vertexShader.addIncoming("attr_color", "vec4");
321 }
322
323 if (meshHasJointsAndWeights && (m_hasSkinning || hasCustomVertexShader)) {
324 if (usesFloatJointIndices) {
325 vertexShader.addIncoming("attr_joints", "vec4");
326 vertexShader.append(" qt_vertJoints = ivec4(attr_joints);");
327 } else {
328 vertexShader.addIncoming("attr_joints", "ivec4");
329 vertexShader.append(" qt_vertJoints = attr_joints;");
330 }
331 vertexShader.addIncoming("attr_weights", "vec4");
332 vertexShader.append(" qt_vertWeights = attr_weights;");
333 }
334
335 if (usesInstancing) {
336 vertexShader.append(" qt_vertColor *= qt_instanceColor;");
337 vertexShader.append(" mat4 qt_instanceMatrix = mat4(qt_instanceTransform0, qt_instanceTransform1, qt_instanceTransform2, vec4(0.0, 0.0, 0.0, 1.0));");
338 if (m_hasSkinning)
339 vertexShader.append(" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix);");
340 else
341 vertexShader.append(" mat4 qt_instancedModelMatrix = qt_parentMatrix * transpose(qt_instanceMatrix) * qt_modelMatrix;");
342 vertexShader.append(" mat3 qt_instancedNormalMatrix = mat3(transpose(inverse(qt_instancedModelMatrix)));");
343 if (m_viewCount < 2)
344 vertexShader.append(" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix * qt_instancedModelMatrix;");
345 else
346 vertexShader.append(" mat4 qt_instancedMVPMatrix = qt_viewProjectionMatrix[qt_viewIndex] * qt_instancedModelMatrix;");
347 }
348
349 if (!materialAdapter->isUnshaded() || !hasCustomVertexShader) {
350 vertexShader << " vec3 qt_uTransform;\n";
351 vertexShader << " vec3 qt_vTransform;\n";
352
355
356 if (m_hasMorphing && !hasCustomVertexShader)
357 vertexShader.append(" qt_vertPosition.xyz = qt_getTargetPosition(qt_vertPosition.xyz);");
358
359 if (m_hasSkinning) {
360 vertexShader.append(" mat4 skinMat = mat4(1);");
361 vertexShader.append(" if (qt_vertWeights != vec4(0.0)) {");
362 vertexShader.append(" skinMat = qt_getSkinMatrix(qt_vertJoints, qt_vertWeights);");
363 vertexShader.append(" qt_vertPosition = skinMat * qt_vertPosition;");
364 vertexShader.append(" }");
365 }
366 if (blendParticles) {
367 vertexShader.append(" qt_vertPosition.xyz = qt_applyParticle(qt_vertPosition.xyz, qt_vertNormal, qt_vertColor, qt_vertNormal, qt_vertColor, qt_particleMatrix);");
368 }
369
370 if (!hasCustomShadedMain || !overridesPosition) {
371 if (!usesInstancing) {
372 if (m_viewCount < 2)
373 vertexShader.append(" gl_Position = qt_modelViewProjection * qt_vertPosition;");
374 else
375 vertexShader.append(" gl_Position = qt_modelViewProjection[qt_viewIndex] * qt_vertPosition;");
376 } else {
377 vertexShader.append(" gl_Position = qt_instancedMVPMatrix * qt_vertPosition;");
378 }
379 }
380 }
381
382 if (usesPointsTopology && !hasCustomVertexShader) {
383 vertexShader.addUniform("qt_materialPointSize", "float");
384 vertexShader.append(" gl_PointSize = qt_materialPointSize;");
385 } // with a custom vertex shader it is up to it to set gl_PointSize (aka POINT_SIZE)
386}
387
389{
390 fragment().addUniform("qt_material_properties", "vec4");
391 fragment().addUniform("qt_rhi_properties", "vec4");
392
395 shaderLibraryManager,
396 m_viewCount >= 2);
397 if (!materialAdapter->isUnshaded()) {
398 const bool usesShared = materialAdapter->usesSharedVariables();
399 insertAmbientLightProcessorArgs(snippet, usesShared);
400 insertIblProbeProcessorArgs(snippet, usesShared);
401 insertSpecularLightProcessorArgs(snippet, usesShared);
402 insertSpotLightProcessorArgs(snippet, usesShared);
403 insertPointLightProcessorArgs(snippet, usesShared);
404 insertDirectionalLightProcessorArgs(snippet, usesShared);
405 insertFragmentMainArgs(snippet, usesShared);
406 insertPostProcessorArgs(snippet, usesShared);
407 }
408 fragment() << snippet;
409 }
410
411 fragment() << "void main()"
412 << "\n"
413 << "{"
414 << "\n";
415
417 fragment() << " float qt_objectOpacity = qt_material_properties.a;\n";
418}
419
420void QSSGMaterialVertexPipeline::assignOutput(const QByteArray &inVarName, const QByteArray &inVarValue)
421{
422 vertex() << " " << inVarName << " = " << inVarValue << ";\n";
423}
424
426{
427 QSSGStageGeneratorBase &vertexGenerator(vertex());
429 if (!usesInstancing)
430 vertexGenerator.addUniform("qt_normalMatrix", "mat3");
431 if (m_hasMorphing)
432 vertexGenerator.append(" qt_vertNormal = qt_getTargetNormal(qt_vertNormal);");
433 if (m_hasSkinning) {
434 vertexGenerator.append(" if (qt_vertWeights != vec4(0.0))");
435 vertexGenerator.append(" qt_vertNormal = qt_getSkinNormalMatrix(qt_vertJoints, qt_vertWeights) * qt_vertNormal;");
436 }
437 // If new model->skin is used,
438 // both qt_normalMatrix and qt_modelMatrix are identity.
439 if (!usesInstancing) {
440 if (m_hasSkinning)
441 vertexGenerator.append(" vec3 qt_world_normal = normalize(qt_vertNormal);");
442 else
443 vertexGenerator.append(" vec3 qt_world_normal = normalize(qt_normalMatrix * qt_vertNormal);");
444 } else {
445 vertexGenerator.append(" vec3 qt_world_normal = normalize(qt_instancedNormalMatrix * qt_vertNormal);");
446 }
447 vertexGenerator.append(" qt_varNormal = qt_world_normal;");
448}
449
451{
452 if (m_hasMorphing)
453 vertex() << " qt_vertTangent = qt_getTargetTangent(qt_vertTangent);\n";
454 if (m_hasSkinning) {
455 vertex() << " if (qt_vertWeights != vec4(0.0))\n"
456 << " qt_vertTangent = (skinMat * vec4(qt_vertTangent, 0.0)).xyz;\n";
457
458 }
460 if (!usesInstancing) {
461 if (!m_hasSkinning)
462 vertex() << " qt_varTangent = (qt_modelMatrix * vec4(qt_vertTangent, 0.0)).xyz;\n";
463 else
464 vertex() << " qt_varTangent = qt_vertTangent;\n";
465 } else {
466 vertex() << " qt_varTangent = (qt_instancedModelMatrix * vec4(qt_vertTangent, 0.0)).xyz;\n";
467 }
468}
469
471{
472 if (m_hasMorphing)
473 vertex() << " qt_vertBinormal = qt_getTargetBinormal(qt_vertBinormal);\n";
474 if (m_hasSkinning) {
475 vertex() << " if (qt_vertWeights != vec4(0.0))\n"
476 << " qt_vertBinormal = (skinMat * vec4(qt_vertBinormal, 0.0)).xyz;\n";
477 }
479 if (!usesInstancing) {
480 if (!m_hasSkinning)
481 vertex() << " qt_varBinormal = (qt_modelMatrix * vec4(qt_vertBinormal, 0.0)).xyz;\n";
482 else
483 vertex() << " qt_varBinormal = qt_vertBinormal;\n";
484 } else {
485 vertex() << " qt_varBinormal = (qt_instancedModelMatrix * vec4(qt_vertBinormal, 0.0)).xyz;\n";
486 }
487}
488
494
501
509
511{
512 vertex().addOutgoing(inName, inType);
513 fragment().addIncoming(inName, inType);
514}
515
517{
518 vertex().addFlatOutgoing(inName, inType);
519 fragment().addFlatIncoming(inName, inType);
520}
521
526
\inmodule QtCore
Definition qbytearray.h:57
static constexpr QSSGShaderGeneratorStageFlags defaultFlags()
void beginProgram(QSSGShaderGeneratorStageFlags inEnabledStages=defaultFlags())
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
static void insertVertexMainArgs(QByteArray &snippet)
static void insertPostProcessorArgs(QByteArray &snippet, bool usesShared)
static void insertPointLightProcessorArgs(QByteArray &snippet, bool usesShared)
static void insertAmbientLightProcessorArgs(QByteArray &snippet, bool usesShared)
static void insertProcessorArgs(QByteArray &snippet, const char *argKey, const char *(*argListFunc)(), bool usesShared=false, bool isSharedInout=false)
static const char * customMainCallWithArguments(bool usesInstancing)
static void insertFragmentMainArgs(QByteArray &snippet, bool usesShared=false)
static void insertIblProbeProcessorArgs(QByteArray &snippet, bool usesShared)
static void insertSpecularLightProcessorArgs(QByteArray &snippet, bool usesShared)
static void insertVertexInstancedMainArgs(QByteArray &snippet)
static void insertVertexMainArgs(QByteArray &snippet)
static void insertSpotLightProcessorArgs(QByteArray &snippet, bool usesShared)
static void insertDirectionalLightProcessorArgs(QByteArray &snippet, bool usesShared)
void addFlatParameter(const QByteArray &inParamName, const QByteArray &inParamType)
void beginVertexGeneration(const QSSGShaderDefaultMaterialKey &inKey, const QSSGShaderFeatures &inFeatureSet, QSSGShaderLibraryManager &shaderLibraryManager)
QSSGStageGeneratorBase & vertex()
QSSGShaderMaterialAdapter * materialAdapter
QSSGMaterialVertexPipeline(QSSGProgramGenerator &inProgram, const QSSGShaderDefaultMaterialKeyProperties &materialProperties, QSSGShaderMaterialAdapter *materialAdapter)
QSSGStageGeneratorBase & fragment()
void doGenerateVarTangent(const QSSGShaderDefaultMaterialKey &inKey)
void beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager)
const QSSGShaderDefaultMaterialKeyProperties & defaultMaterialShaderKeyProperties
void doGenerateVarBinormal(const QSSGShaderDefaultMaterialKey &inKey)
void addInterpolationParameter(const QByteArray &inParamName, const QByteArray &inParamType)
void doGenerateWorldNormal(const QSSGShaderDefaultMaterialKey &inKey)
QSSGStageGeneratorBase & activeStage()
bool hasAttributeInKey(QSSGShaderKeyVertexAttribute::VertexAttributeBits inAttr, const QSSGShaderDefaultMaterialKey &inKey)
void assignOutput(const QByteArray &inVarName, const QByteArray &inVarValueExpr)
QSSGProgramGenerator * programGenerator() const
QSSGShaderKeyVertexAttribute m_vertexAttributes
bool getValue(QSSGDataView< quint32 > inDataStore) const
quint32 getValue(QSSGDataView< quint32 > inDataStore) const
bool getBitValue(VertexAttributeBits bit, QSSGDataView< quint32 > inKeySet) const
virtual bool usesCustomMorphing()=0
virtual bool usesCustomSkinning()=0
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)
virtual void addFlatIncoming(const QByteArray &name, const QByteArray &type)
virtual void addFlatOutgoing(const QByteArray &name, const QByteArray &type)
virtual void addUniformArray(const QByteArray &name, const QByteArray &type, quint32 size)
virtual void addUniform(const QByteArray &name, const QByteArray &type)
virtual void append(const QByteArray &data)
virtual void addOutgoing(const QByteArray &name, const QByteArray &type)
virtual void addIncoming(const QByteArray &name, const QByteArray &type)
virtual void addInclude(const QByteArray &name) final