Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qssgvertexpipelineimpl_p.h
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
5#ifndef QSSG_VERTEX_PIPELINE_IMPL_H
6#define QSSG_VERTEX_PIPELINE_IMPL_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h>
20#include <QtQuick3DRuntimeRender/private/qssgrendershaderkeys_p.h>
21
22#include <QtCore/QSharedPointer>
23
25
27{
28 enum class GenerationFlag
29 {
30 UVCoords = 1,
31 EnvMapReflection = 1 << 1,
32 ViewVector = 1 << 2,
33 WorldNormal = 1 << 3,
34 ObjectNormal = 1 << 4,
35 WorldPosition = 1 << 5,
36 TangentBinormal = 1 << 6,
37 UVCoords1 = 1 << 7,
38 VertexColor = 1 << 8,
39 PerspDivDepth = 1 << 9,
40 PerspDivWorldPos = 1 << 10
41 };
42
46
49
55
62
64 const QSSGShaderDefaultMaterialKeyProperties &materialProperties,
66
68
69 // Trues true if the code was *not* set.
71 {
72 if (m_generationFlags & inCode)
73 return true;
74 m_generationFlags |= inCode;
75 return false;
76 }
77 bool hasCode(GenerationFlag inCode) { return (m_generationFlags & inCode); }
79
81 {
83 }
85 {
87 }
88
97 {
98 if (inUVSet == 0 && setCode(GenerationFlag::UVCoords))
99 return;
100 if (inUVSet == 1 && setCode(GenerationFlag::UVCoords1))
101 return;
102
103 const bool meshHasUV0 = hasAttributeInKey(QSSGShaderKeyVertexAttribute::TexCoord0, inKey);
104 const bool meshHasUV1 = hasAttributeInKey(QSSGShaderKeyVertexAttribute::TexCoord1, inKey);
105
106 Q_ASSERT(inUVSet == 0 || inUVSet == 1);
107
108 if (inUVSet == 0) {
109 if (hasCustomShadedMain || meshHasUV0) {
110 addInterpolationParameter("qt_varTexCoord0", "vec2");
111 if (m_hasMorphing)
112 vertex().append(" qt_vertUV0 = qt_getTargetTex0(qt_vertUV0);");
113 vertex() << " qt_varTexCoord0 = qt_vertUV0;\n";
114 fragment() <<" vec2 qt_texCoord0 = qt_varTexCoord0;\n";
115 } else {
116 vertex() << " vec2 qt_varTexCoord0 = vec2(0.0);\n";
117 fragment() << " vec2 qt_texCoord0 = vec2(0.0);\n";
118 }
119 } else if (inUVSet == 1) {
120 if (hasCustomShadedMain || meshHasUV1) {
121 addInterpolationParameter("qt_varTexCoord1", "vec2");
122 if (m_hasMorphing)
123 vertex().append(" qt_vertUV1 = qt_getTargetTex0(qt_vertUV1);");
124 vertex() << " qt_varTexCoord1 = qt_vertUV1;\n";
125 fragment() <<" vec2 qt_texCoord1 = qt_varTexCoord1;\n";
126 } else {
127 vertex() << " vec2 qt_varTexCoord1 = vec2(0.0);\n";
128 fragment() << " vec2 qt_texCoord1 = vec2(0.0);\n";
129 }
130 }
131 }
132
134 {
136 addInterpolationParameter("qt_varTexCoordLightmap", "vec2");
137 vertex() << " qt_varTexCoordLightmap = qt_vertLightmapUV;\n";
138 fragment() <<" vec2 qt_texCoordLightmap = qt_varTexCoordLightmap;\n";
139 } else {
140 vertex() << " vec2 qt_varTexCoordLightmap = vec2(0.0);\n";
141 fragment() << " vec2 qt_texCoordLightmap = vec2(0.0);\n";
142 }
143 }
144
146 {
148 return;
149
151 generateWorldNormal(inKey);
152 QSSGStageGeneratorBase &activeGenerator(activeStage());
153 activeGenerator.addInclude("viewProperties.glsllib");
154 addInterpolationParameter("qt_var_object_to_camera", "vec3");
155
156 activeGenerator.append(" qt_var_object_to_camera = normalize( qt_local_model_world_position - qt_cameraPosition );");
157
158 // World normal cannot be relied upon in the vertex shader because of bump maps.
159 fragment().append(" vec3 environment_map_reflection = reflect( "
160 "normalize(qt_var_object_to_camera), qt_world_normal.xyz );");
161 fragment().append(" environment_map_reflection *= vec3( 0.5, 0.5, 0 );");
162 fragment().append(" environment_map_reflection += vec3( 0.5, 0.5, 1.0 );");
163 }
165 {
167 return;
168
170 activeStage().addUniform("qt_cameraPosition", "vec3");
171
172
173 fragment() << " vec3 qt_view_vector = normalize(qt_cameraPosition - qt_varWorldPos);\n";
174 }
175
176 // fragment shader expects varying vertex normal
177 // lighting in vertex pipeline expects qt_world_normal
178
179 // qt_world_normal in both vert and frag shader
181 {
183 return;
184
185 const bool meshHasNormal = hasAttributeInKey(QSSGShaderKeyVertexAttribute::Normal, inKey);
186
187 if (hasCustomShadedMain || meshHasNormal) {
188 addInterpolationParameter("qt_varNormal", "vec3");
190 } else {
192 fragment().append(" vec3 qt_varNormal = cross(dFdx(qt_varWorldPos), dFdy(qt_varWorldPos));");
193 }
194 fragment().append(" vec3 qt_world_normal = normalize(qt_varNormal);");
195 }
196
198 {
200 return;
201
202 addInterpolationParameter("qt_varObjectNormal", "vec3");
203 vertex().append(" qt_varObjectNormal = qt_vertNormal;");
204 fragment().append(" vec3 object_normal = normalize(qt_varObjectNormal);");
205 }
206
208 {
210 return;
211
212 activeStage().addUniform("qt_modelMatrix", "mat4");
213 addInterpolationParameter("qt_varWorldPos", "vec3");
215 if (!usesInstancing) {
216 if (m_hasSkinning)
217 vertex().append(" vec3 qt_local_model_world_position = qt_vertPosition.xyz;");
218 else
219 vertex().append(" vec3 qt_local_model_world_position = (qt_modelMatrix * qt_vertPosition).xyz;");
220 } else {
221 vertex().append(" vec3 qt_local_model_world_position = (qt_instancedModelMatrix * qt_vertPosition).xyz;");
222 }
223
224 assignOutput("qt_varWorldPos", "qt_local_model_world_position");
225 }
226
228 {
230 return;
231
232 addInterpolationParameter("qt_varDepth", "float");
233 vertex().append(" qt_varDepth = gl_Position.z / gl_Position.w;");
234 }
235
237 {
239 return;
240
241 activeStage().addUniform("qt_modelMatrix", "mat4");
242 addInterpolationParameter("qt_varShadowWorldPos", "vec3");
243
245 if (!usesInstancing) {
246 if (m_hasSkinning)
247 vertex().append(" vec4 qt_shadow_world_tmp = qt_vertPosition;");
248 else
249 vertex().append(" vec4 qt_shadow_world_tmp = qt_modelMatrix * qt_vertPosition;");
250 } else {
251 vertex().append(" vec4 qt_shadow_world_tmp = qt_instancedModelMatrix * qt_vertPosition;");
252 }
253 vertex().append(" qt_varShadowWorldPos = qt_shadow_world_tmp.xyz / qt_shadow_world_tmp.w;");
254 }
255
256 void generateVarTangentAndBinormal(const QSSGShaderDefaultMaterialKey &inKey, bool &genTangent, bool &genBinormal)
257 {
259 return;
260
261 const bool meshHasTangent = hasAttributeInKey(QSSGShaderKeyVertexAttribute::Tangent, inKey);
262 const bool meshHasBinormal = hasAttributeInKey(QSSGShaderKeyVertexAttribute::Binormal, inKey);
263
264 // I assume that there is no mesh having only binormal without tangent
265 // since it is an abnormal case
266 if (hasCustomShadedMain || meshHasTangent) {
267 addInterpolationParameter("qt_varTangent", "vec3");
269 fragment() << " vec3 qt_tangent = normalize(qt_varTangent);\n";
270
271 if (hasCustomShadedMain || meshHasBinormal) {
272 addInterpolationParameter("qt_varBinormal", "vec3");
274 fragment() << " vec3 qt_binormal = normalize(qt_varBinormal);\n";
275 genBinormal = true;
276 } else {
277 fragment() << " vec3 qt_binormal = vec3(0.0);\n";
278 }
279 genTangent = true;
280 } else {
281 fragment() << " vec3 qt_tangent = vec3(0.0);\n"
282 << " vec3 qt_binormal = vec3(0.0);\n";
283 }
284 }
286 {
288 return;
289
290 const bool meshHasColor = hasAttributeInKey(QSSGShaderKeyVertexAttribute::Color, inKey);
291
292 const bool vColorEnabled = defaultMaterialShaderKeyProperties.m_vertexColorsEnabled.getValue(inKey);
293 const bool usesVarColor = defaultMaterialShaderKeyProperties.m_usesVarColor.getValue(inKey);
295 const bool usesBlendParticles = defaultMaterialShaderKeyProperties.m_blendParticles.getValue(inKey);
296 if ((vColorEnabled && meshHasColor) || usesInstancing || usesBlendParticles || usesVarColor) {
297 addInterpolationParameter("qt_varColor", "vec4");
298 if (m_hasMorphing)
299 vertex().append(" qt_vertColor = qt_getTargetColor(qt_vertColor);");
300 vertex().append(" qt_varColor = qt_vertColor;");
301 fragment().append(" vec4 qt_vertColor = qt_varColor;\n");
302 } else {
303 fragment().append(" vec4 qt_vertColor = vec4(1.0);\n"); // must be 1,1,1,1 to not alter when multiplying with it
304 }
305 }
306
308
310
312
314
316
317 void addFunction(const QByteArray &functionName)
318 {
319 if (!m_addedFunctions.contains(functionName)) {
320 m_addedFunctions.push_back(functionName);
321 QByteArray includeName = "func" + functionName + ".glsllib";
322 addInclude(includeName);
323 }
324 }
325
327 {
329 }
330
331 void addConstantBufferParam(const QByteArray &cbName, const QByteArray &paramName, const QByteArray &type)
332 {
333 activeStage().addConstantBufferParam(cbName, paramName, type);
334 }
335
337 {
339 }
340
342 {
343 activeStage() << data;
344 return activeStage();
345 }
346
348
350 {
351 return const_cast<QSSGMaterialVertexPipeline *>(this)->activeStage().stage();
352 }
353
354 // Responsible for beginning all vertex and fragment generation (void main() { etc).
356 const QSSGShaderFeatures &inFeatureSet,
357 QSSGShaderLibraryManager &shaderLibraryManager);
358 // The fragment shader expects a floating point constant, qt_objectOpacity to be defined
359 // post this method.
360 void beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager);
361 // Output variables may be mangled in some circumstances so the shader generation system
362 // needs an abstraction
363 // mechanism around this.
364 void assignOutput(const QByteArray &inVarName, const QByteArray &inVarValueExpr);
365
366 // responsible for closing all vertex and fragment generation
367 void endVertexGeneration();
369
371 void addInterpolationParameter(const QByteArray &inParamName, const QByteArray &inParamType);
372
377};
378
380
381#endif
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qhash.h:818
Definition qlist.h:74
void push_back(parameter_type t)
Definition qlist.h:672
QSSGStageGeneratorBase * getStage(QSSGShaderGeneratorStage inStage)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int quint32
Definition qtypes.h:45
QVBoxLayout * layout
bool contains(const AT &t) const noexcept
Definition qlist.h:44
void append(const QByteArray &data)
QFlags< GenerationFlag > GenerationFlags
bool setCode(GenerationFlag inCode)
void generateShadowWorldPosition(const QSSGShaderDefaultMaterialKey &inKey)
void beginVertexGeneration(const QSSGShaderDefaultMaterialKey &inKey, const QSSGShaderFeatures &inFeatureSet, QSSGShaderLibraryManager &shaderLibraryManager)
void addIncoming(const QByteArray &name, const QByteArray &type)
void addDefinition(const QByteArray &name, const QByteArray &value=QByteArray())
void addUniform(const QByteArray &name, const QByteArray &type)
void addInclude(const QByteArray &name)
bool hasCode(GenerationFlag inCode)
QSSGStageGeneratorBase & vertex()
QSSGShaderMaterialAdapter * materialAdapter
void generateEnvMapReflection(const QSSGShaderDefaultMaterialKey &inKey)
void addUniformArray(const QByteArray &name, const QByteArray &type, quint32 size)
QSSGStageGeneratorBase & fragment()
void doGenerateVarTangent(const QSSGShaderDefaultMaterialKey &inKey)
void beginFragmentGeneration(QSSGShaderLibraryManager &shaderLibraryManager)
const QSSGShaderDefaultMaterialKeyProperties & defaultMaterialShaderKeyProperties
void generateVertexColor(const QSSGShaderDefaultMaterialKey &inKey)
void doGenerateVarBinormal(const QSSGShaderDefaultMaterialKey &inKey)
QSSGProgramGenerator * m_programGenerator
void addConstantBuffer(const QByteArray &name, const QByteArray &layout)
void addInterpolationParameter(const QByteArray &inParamName, const QByteArray &inParamType)
void doGenerateWorldNormal(const QSSGShaderDefaultMaterialKey &inKey)
~QSSGMaterialVertexPipeline()=default
void addConstantBufferParam(const QByteArray &cbName, const QByteArray &paramName, const QByteArray &type)
QSSGStageGeneratorBase & activeStage()
void generateVarTangentAndBinormal(const QSSGShaderDefaultMaterialKey &inKey, bool &genTangent, bool &genBinormal)
QSSGShaderGeneratorStage stage() const
bool hasAttributeInKey(QSSGShaderKeyVertexAttribute::VertexAttributeBits inAttr, const QSSGShaderDefaultMaterialKey &inKey)
void assignOutput(const QByteArray &inVarName, const QByteArray &inVarValueExpr)
QSSGProgramGenerator * programGenerator() const
void generateViewVector(const QSSGShaderDefaultMaterialKey &inKey)
void addOutgoing(const QByteArray &name, const QByteArray &type)
void addFunction(const QByteArray &functionName)
void generateWorldNormal(const QSSGShaderDefaultMaterialKey &inKey)
QHash< QByteArray, QByteArray > TStrTableStrMap
void generateWorldPosition(const QSSGShaderDefaultMaterialKey &inKey)
void generateUVCoords(quint32 inUVSet, const QSSGShaderDefaultMaterialKey &inKey)
Generates UV coordinates in shader code.
void generateLightmapUVCoords(const QSSGShaderDefaultMaterialKey &inKey)
TStrTableStrMap::const_iterator TParamIter
QSSGStageGeneratorBase & operator<<(const QByteArray &data)
bool getValue(QSSGDataView< quint32 > inDataStore) const
QSSGShaderGeneratorStage stage() const
virtual void addConstantBuffer(const QByteArray &name, const QByteArray &layout)
virtual void addConstantBufferParam(const QByteArray &cbName, const QByteArray &paramName, 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 addDefinition(const QByteArray &name, const QByteArray &value) final
virtual void append(const QByteArray &data)
virtual void addIncoming(const QByteArray &name, const QByteArray &type)
virtual void addInclude(const QByteArray &name) final