210 const auto &defaultMaterialShaderKeyProperties = layerData.getDefaultMaterialPropertyTable();
212 const bool blendParticles = defaultMaterialShaderKeyProperties.m_blendParticles.getValue(renderable.shaderDescription);
214 const auto &shaderPipeline =
shadersForCustomMaterial(ps, material, renderable, defaultMaterialShaderKeyProperties, featureSet);
216 if (shaderPipeline) {
218 const auto &modelNode = renderable.modelContext.model;
227 const auto entryPartA =
reinterpret_cast<quintptr>(&material);
229 const void *entryKey =
reinterpret_cast<const void *
>(entryPartA ^ entryPartB);
233 shaderPipeline->ensureCombinedMainLightsUniformBuffer(&dcd.ubuf);
234 char *ubufData = dcd.ubuf->beginFullDynamicBufferUpdateForCurrentFrame();
235 if (!alteredCamera) {
243 dcd.ubuf->endFullDynamicBufferUpdateForCurrentFrame();
247 bool instancing =
false;
248 if (!alteredCamera) {
252 instancing =
QSSGLayerRenderData::prepareInstancing(rhiCtx, &renderable, alteredCamera->getScalingCorrectDirection(), alteredCamera->getGlobalPos(), renderable.instancingLodMin, renderable.instancingLodMax);
264 ia = renderable.subset.rhi.ia;
267 int instanceBufferBinding = 0;
270 const quint32 stride = renderable.modelContext.model.instanceTable->stride();
271 QVarLengthArray<QRhiVertexInputBinding, 8> bindings;
272 std::copy(ia.inputLayout.cbeginBindings(),
273 ia.inputLayout.cendBindings(),
274 std::back_inserter(bindings));
276 instanceBufferBinding = bindings.size() - 1;
277 ia.inputLayout.setBindings(bindings.cbegin(), bindings.cend());
289 shaderPipeline->ub0LightDataOffset(),
290 shaderPipeline->ub0LightDataSize());
292 QVector<QShaderDescription::InOutVariable> samplerVars =
293 shaderPipeline->fragmentStage()->shader().description().combinedImageSamplers();
295 auto it = std::find_if(samplerVars.cbegin(), samplerVars.cend(),
297 if (
it == samplerVars.
cend())
298 samplerVars.append(
var);
301 int maxSamplerBinding = -1;
303 maxSamplerBinding =
qMax(maxSamplerBinding,
var.binding);
312 QBitArray samplerBindingsSpecified(maxSamplerBinding + 1);
315 samplerBindingsSpecified.setBit(shaderPipeline->bindingForTexture(
"qt_particleTexture"));
318 if (
QRhiTexture *boneTexture = layerData.getBonemapTexture(renderable.modelContext)) {
319 int binding = shaderPipeline->bindingForTexture(
"qt_boneTexture");
332 samplerBindingsSpecified.setBit(binding);
337 auto *targetsTexture = renderable.subset.rhi.targetsTexture;
338 if (targetsTexture) {
339 int binding = shaderPipeline->bindingForTexture(
"qt_morphTargetTexture");
349 samplerBindingsSpecified.setBit(binding);
357 int reflectionSampler = shaderPipeline->bindingForTexture(
"qt_reflectionMap");
360 QRhiTexture* reflectionTexture = layerData.getReflectionMapManager()->reflectionMapEntry(renderable.reflectionProbeIndex)->m_rhiPrefilteredCube;
361 if (reflectionSampler >= 0 && reflectionTexture) {
363 samplerBindingsSpecified.setBit(reflectionSampler);
365 }
else if (shaderPipeline->lightProbeTexture()) {
368 samplerBindingsSpecified.setBit(binding);
369 QPair<QSSGRenderTextureCoordOp, QSSGRenderTextureCoordOp> tiling = shaderPipeline->lightProbeTiling();
374 shaderPipeline->lightProbeTexture(),
sampler);
378 if (shaderPipeline->screenTexture()) {
381 if (screenTextureBinding >= 0 || screenTextureArrayBinding >= 0) {
390 if (screenTextureBinding >= 0) {
391 samplerBindingsSpecified.setBit(screenTextureBinding);
394 shaderPipeline->screenTexture(),
sampler);
396 if (screenTextureArrayBinding >= 0) {
397 samplerBindingsSpecified.setBit(screenTextureArrayBinding);
398 bindings.
addTexture(screenTextureArrayBinding,
400 shaderPipeline->screenTexture(),
sampler);
405 if (shaderPipeline->depthTexture()) {
408 if (depthTextureBinding >= 0 || depthTextureArrayBinding >= 0) {
412 if (depthTextureBinding >= 0) {
413 samplerBindingsSpecified.setBit(depthTextureBinding);
416 shaderPipeline->depthTexture(),
sampler);
418 if (depthTextureArrayBinding >= 0) {
419 samplerBindingsSpecified.setBit(depthTextureArrayBinding);
422 shaderPipeline->depthTexture(),
sampler);
427 if (shaderPipeline->ssaoTexture()) {
430 if (ssaoTextureBinding >= 0 || ssaoTextureArrayBinding >= 0) {
434 if (ssaoTextureBinding >= 0) {
435 samplerBindingsSpecified.setBit(ssaoTextureBinding);
438 shaderPipeline->ssaoTexture(),
sampler);
440 if (ssaoTextureArrayBinding >= 0) {
441 samplerBindingsSpecified.setBit(ssaoTextureArrayBinding);
444 shaderPipeline->ssaoTexture(),
sampler);
449 if (shaderPipeline->lightmapTexture()) {
452 samplerBindingsSpecified.setBit(binding);
457 shaderPipeline->lightmapTexture(),
sampler);
461 const int shadowMapCount = shaderPipeline->shadowMapCount();
462 for (
int i = 0;
i < shadowMapCount; ++
i) {
467 const QByteArray &
name(shadowMapProperties.shadowMapTextureUniformName);
468 if (shadowMapProperties.cachedBinding < 0)
469 shadowMapProperties.cachedBinding = shaderPipeline->bindingForTexture(
name);
470 if (shadowMapProperties.cachedBinding < 0)
472 samplerBindingsSpecified.setBit(shadowMapProperties.cachedBinding);
473 bindings.
addTexture(shadowMapProperties.cachedBinding,
480 while (renderableImage) {
482 const int samplerHint = int(renderableImage->m_mapType);
483 int samplerBinding = shaderPipeline->bindingForTexture(samplerName, samplerHint);
484 if (samplerBinding >= 0) {
486 if (samplerBinding >= 0 &&
texture) {
498 samplerBindingsSpecified.setBit(samplerBinding);
504 renderableImage = renderableImage->m_nextImage;
507 if (maxSamplerBinding >= 0) {
509 int customTexCount = shaderPipeline->extraTextureCount();
510 for (
int i = 0;
i < customTexCount; ++
i) {
512 const int samplerBinding = shaderPipeline->bindingForTexture(
t.name);
513 if (samplerBinding >= 0) {
514 samplerBindingsSpecified.setBit(samplerBinding);
529 if (!samplerBindingsSpecified.testBit(
var.binding)) {
540 bool srbChanged =
false;
541 if (!srb || bindings != dcd.bindings) {
542 srb = rhiCtxD->srb(bindings);
543 dcd.bindings = bindings;
548 renderable.rhiRenderData.mainPass.srb = srb;
550 renderable.rhiRenderData.reflectionPass.srb[cubeFaceIdx] = srb;
555 && dcd.renderTargetDescriptionHash == pipelineKey.extra.renderTargetDescriptionHash
556 && dcd.renderTargetDescription == pipelineKey.renderTargetDescription
560 renderable.rhiRenderData.mainPass.pipeline = dcd.pipeline;
562 renderable.rhiRenderData.reflectionPass.pipeline = dcd.pipeline;
565 renderable.rhiRenderData.mainPass.pipeline = rhiCtxD->pipeline(pipelineKey,
566 renderPassDescriptor,
568 dcd.pipeline = renderable.rhiRenderData.mainPass.pipeline;
570 renderable.rhiRenderData.reflectionPass.pipeline = rhiCtxD->pipeline(pipelineKey,
571 renderPassDescriptor,
573 dcd.pipeline = renderable.rhiRenderData.reflectionPass.pipeline;
576 dcd.renderTargetDescriptionHash = pipelineKey.extra.renderTargetDescriptionHash;
577 dcd.renderTargetDescription = pipelineKey.renderTargetDescription;