virtual void _Execute(HdTaskContext* ctx) override { // Try to extract render tags from the context in case // there are render tags passed to the graph that // we should be using while rendering the id buffer // XXX If this was a task (in the render graph) we could // just connect it to the render pass setup which receives // its rendertags from the viewer. if(_renderTags.empty()) { _GetTaskContextData(ctx, HdxTokens->renderTags, &_renderTags); } _renderPassState->Bind(); if(_renderTags.size()) { _renderPass->Execute(_renderPassState, _renderTags); } else { _renderPass->Execute(_renderPassState); } _renderPassState->Unbind(); }
void HdxShadowTask::_Execute(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // Extract the lighting context information from the task context GlfSimpleLightingContextRefPtr lightingContext; if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) { return; } if (_depthBiasEnable) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(_depthBiasSlopeFactor, _depthBiasConstantFactor); } else { glDisable(GL_POLYGON_OFFSET_FILL); } // XXX: Move conversion to sync time once Task header becomes private. glDepthFunc(HdConversions::GetGlDepthFunc(_depthFunc)); glEnable(GL_PROGRAM_POINT_SIZE); // Generate the actual shadow maps GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows(); for(size_t shadowId = 0; shadowId < shadows->GetNumLayers(); shadowId++) { // Bind the framebuffer that will store shadowId shadow map shadows->BeginCapture(shadowId, true); // Render the actual geometry in the collection _passes[shadowId]->Execute(_renderPassStates[shadowId], HdTokens->geometry); // Unbind the buffer and move on to the next shadow map shadows->EndCapture(shadowId); } // restore GL states to default glDisable(GL_PROGRAM_POINT_SIZE); glDisable(GL_POLYGON_OFFSET_FILL); }
void HdxSelectionTask::_Sync(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); SdfPath const& id = GetId(); HdSceneDelegate* delegate = GetDelegate(); HdRenderIndex& index = delegate->GetRenderIndex(); HdChangeTracker& changeTracker = index.GetChangeTracker(); HdDirtyBits bits = changeTracker.GetTaskDirtyBits(id); HdResourceRegistrySharedPtr const& resourceRegistry = index.GetResourceRegistry(); bool paramsChanged = bits & HdChangeTracker::DirtyParams; if (paramsChanged) { _GetSceneDelegateValue(HdTokens->params, &_params); } HdxSelectionTrackerSharedPtr sel; if (_GetTaskContextData(ctx, HdxTokens->selectionState, &sel)) { sel->Sync(&index); } if (sel && (paramsChanged || sel->GetVersion() != _lastVersion)) { _lastVersion = sel->GetVersion(); VtIntArray offsets; VtIntArray values; _hasSelection = sel->GetSelectionOffsetBuffer(&index, &offsets); if (!_selOffsetBar) { HdBufferSpecVector offsetSpecs; offsetSpecs.emplace_back(HdxTokens->hdxSelectionBuffer, HdTupleType { HdTypeInt32, 1 }); _selOffsetBar = resourceRegistry->AllocateSingleBufferArrayRange( /*role*/HdxTokens->selection, offsetSpecs); } if (!_selUniformBar) { HdBufferSpecVector uniformSpecs; uniformSpecs.emplace_back(HdxTokens->selColor, HdTupleType { HdTypeFloatVec4, 1 }); uniformSpecs.emplace_back(HdxTokens->selLocateColor, HdTupleType { HdTypeFloatVec4, 1 }); uniformSpecs.emplace_back(HdxTokens->selMaskColor, HdTupleType { HdTypeFloatVec4, 1 }); _selUniformBar = resourceRegistry->AllocateUniformBufferArrayRange( /*role*/HdxTokens->selection, uniformSpecs); } // // Uniforms // HdBufferSourceSharedPtrVector uniformSources; uniformSources.push_back(HdBufferSourceSharedPtr( new HdVtBufferSource(HdxTokens->selColor, VtValue(_params.selectionColor)))); uniformSources.push_back(HdBufferSourceSharedPtr( new HdVtBufferSource(HdxTokens->selLocateColor, VtValue(_params.locateColor)))); uniformSources.push_back(HdBufferSourceSharedPtr( new HdVtBufferSource(HdxTokens->selMaskColor, VtValue(_params.maskColor)))); resourceRegistry->AddSources(_selUniformBar, uniformSources); // // Offsets // HdBufferSourceSharedPtr offsetSource( new HdVtBufferSource(HdxTokens->hdxSelectionBuffer, VtValue(offsets))); resourceRegistry->AddSource(_selOffsetBar, offsetSource); } if (_params.enableSelection && _hasSelection) { (*ctx)[HdxTokens->selectionOffsets] = _selOffsetBar; (*ctx)[HdxTokens->selectionUniforms] = _selUniformBar; } else { (*ctx)[HdxTokens->selectionOffsets] = VtValue(); (*ctx)[HdxTokens->selectionUniforms] = VtValue(); } }
void HdxShadowTask::Sync(HdSceneDelegate* delegate, HdTaskContext* ctx, HdDirtyBits* dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); GLF_GROUP_FUNCTION(); // Extract the lighting context information from the task context GlfSimpleLightingContextRefPtr lightingContext; if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) { return; } GlfSimpleLightVector const glfLights = lightingContext->GetLights(); GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows(); HdRenderIndex &renderIndex = delegate->GetRenderIndex(); const bool dirtyParams = (*dirtyBits) & HdChangeTracker::DirtyParams; if (dirtyParams) { // Extract the new shadow task params from exec if (!_GetTaskParams(delegate, &_params)) { return; } } if (!renderIndex.IsSprimTypeSupported(HdPrimTypeTokens->simpleLight)) { return; } // Iterate through all lights and for those that have shadows enabled // and ensure we have enough passes to render the shadows. size_t passCount = 0; for (size_t lightId = 0; lightId < glfLights.size(); lightId++) { const HdStLight* light = static_cast<const HdStLight*>( renderIndex.GetSprim(HdPrimTypeTokens->simpleLight, glfLights[lightId].GetID())); if (!glfLights[lightId].HasShadow()) { continue; } // It is possible the light is nullptr for area lights converted to // simple lights, however they should not have shadows enabled. TF_VERIFY(light); // Extract the collection from the HD light VtValue vtShadowCollection = light->Get(HdLightTokens->shadowCollection); const HdRprimCollection &col = vtShadowCollection.IsHolding<HdRprimCollection>() ? vtShadowCollection.Get<HdRprimCollection>() : HdRprimCollection(); // Creates or reuses a pass with the right geometry that will be // used during Execute phase to draw the shadow maps. if (passCount < _passes.size()) { // Note here that we may want to sort the passes by collection // to invalidate fewer passes if the collections match already. // SetRprimCollection checks for identity changes on the collection // and no-ops in that case. _passes[passCount]->SetRprimCollection(col); } else { // Create a new pass if we didn't have enough already, HdRenderPassSharedPtr p = boost::make_shared<HdSt_RenderPass> (&renderIndex, col); _passes.push_back(p); } passCount++; } // Shrink down to fit to conserve resources // We may want hysteresis here if we find the count goes up and down // frequently. if (_passes.size() > passCount) { _passes.resize(passCount); } // Shrink down to fit to conserve resources if (_renderPassStates.size() > _passes.size()) { _renderPassStates.resize(_passes.size()); } // Ensure all passes have the right params set. if (dirtyParams) { TF_FOR_ALL(it, _renderPassStates) { _UpdateDirtyParams(*it, _params); } }
void HdxRenderTask::_Execute(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HD_MALLOC_TAG_FUNCTION(); HdRenderPassStateSharedPtr renderPassState; if (_setupTask) { // if _setupTask exists (for backward compatibility), use it renderPassState = _setupTask->GetRenderPassState(); } else { // otherwise, extract from TaskContext _GetTaskContextData(ctx, HdxTokens->renderPassState, &renderPassState); } if (not TF_VERIFY(renderPassState)) return; // Can't use GetTaskContextData because the lightingShader // is optional. VtValue lightingShader = (*ctx)[HdTokens->lightingShader]; // it's possible to not set lighting shader to HdRenderPassState. // Hd_DefaultLightingShader will be used in that case. if (lightingShader.IsHolding<HdLightingShaderSharedPtr>()) { renderPassState->SetLightingShader( lightingShader.Get<HdLightingShaderSharedPtr>()); } // Selection Setup // Note that selectionTask comes after renderTask, so that // it can access rprimIDs populated in RenderTask::_Sync. VtValue vo = (*ctx)[HdxTokens->selectionOffsets]; VtValue vu = (*ctx)[HdxTokens->selectionUniforms]; HdRenderPassShaderSharedPtr renderPassShader = renderPassState->GetRenderPassShader(); if (not vo.IsEmpty() and not vu.IsEmpty()) { HdBufferArrayRangeSharedPtr obar = vo.Get<HdBufferArrayRangeSharedPtr>(); HdBufferArrayRangeSharedPtr ubar = vu.Get<HdBufferArrayRangeSharedPtr>(); renderPassShader->AddBufferBinding( HdBindingRequest(HdBinding::SSBO, HdxTokens->selectionOffsets, obar, /*interleave*/false)); renderPassShader->AddBufferBinding( HdBindingRequest(HdBinding::UBO, HdxTokens->selectionUniforms, ubar, /*interleave*/true)); } else { renderPassShader->RemoveBufferBinding(HdxTokens->selectionOffsets); renderPassShader->RemoveBufferBinding(HdxTokens->selectionUniforms); } renderPassState->Bind(); // execute all render passes. TF_FOR_ALL(it, _passes) { (*it)->Execute(renderPassState); }
void HdxShadowTask::_Sync(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // Extract the lighting context information from the task context GlfSimpleLightingContextRefPtr lightingContext; if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) { return; } GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows(); _TaskDirtyState dirtyState; _GetTaskDirtyState(HdTokens->geometry, &dirtyState); // Check if the collection version has changed, if so, it means // that we should extract the new collections // from the lights in the render index, and then recreate the passes // required to render the shadow maps const bool collectionChanged = (_collectionVersion != dirtyState.collectionVersion); if ((dirtyState.bits & HdChangeTracker::DirtyParams) || collectionChanged) { _collectionVersion = dirtyState.collectionVersion; // Extract the new shadow task params from exec HdxShadowTaskParams params; if (!_GetSceneDelegateValue(HdTokens->params, ¶ms)) { return; } _depthBiasEnable = params.depthBiasEnable; _depthBiasConstantFactor = params.depthBiasConstantFactor; _depthBiasSlopeFactor = params.depthBiasSlopeFactor; _depthFunc = params.depthFunc; // XXX TODO: What to do about complexity? // We can now use the light information now // and create a pass for each _passes.clear(); _renderPassStates.clear(); HdSceneDelegate* delegate = GetDelegate(); const HdRenderIndex &renderIndex = delegate->GetRenderIndex(); // Extract the HD lights used to render the scene from the // task context, we will use them to find out what // lights are dirty and if we need to update the // collection for shadows mapping // XXX: This is inefficient, need to be optimized SdfPathVector sprimPaths = renderIndex.GetSprimSubtree( HdPrimTypeTokens->light, SdfPath::AbsoluteRootPath()); SdfPathVector lightPaths = HdxSimpleLightTask::ComputeIncludedLights( sprimPaths, params.lightIncludePaths, params.lightExcludePaths); HdxLightPtrConstVector lights; TF_FOR_ALL (it, lightPaths) { const HdxLight *light = static_cast<const HdxLight *>( renderIndex.GetSprim( HdPrimTypeTokens->light, *it)); if (light != nullptr) { lights.push_back(light); } } GlfSimpleLightVector const glfLights = lightingContext->GetLights(); TF_VERIFY(lights.size() == glfLights.size()); // Iterate through all lights and for those that have // shadows enabled we will extract the colection from // the render index and create a pass that during execution // it will be used for generating each shadowmap for (size_t lightId = 0; lightId < glfLights.size(); lightId++) { if (!glfLights[lightId].HasShadow()) { continue; } // Extract the collection from the HD light VtValue vtShadowCollection = lights[lightId]->Get(HdxLightTokens->shadowCollection); const HdRprimCollection &col = vtShadowCollection.IsHolding<HdRprimCollection>() ? vtShadowCollection.Get<HdRprimCollection>() : HdRprimCollection(); // Creates a pass with the right geometry that will be // use during Execute phase to draw the maps HdRenderPassSharedPtr p = boost::make_shared<HdRenderPass> (&delegate->GetRenderIndex(), col); HdRenderPassShaderSharedPtr renderPassShadowShader (new HdRenderPassShader(HdxPackageRenderPassShadowShader())); HdRenderPassStateSharedPtr renderPassState (new HdRenderPassState(renderPassShadowShader)); // Update the rest of the renderpass state parameters for this pass renderPassState->SetOverrideColor(params.overrideColor); renderPassState->SetWireframeColor(params.wireframeColor); renderPassState->SetLightingEnabled(false); // XXX : This can be removed when Hydra has support for // transparent objects. renderPassState->SetAlphaThreshold(1.0 /* params.alphaThreshold */); renderPassState->SetTessLevel(params.tessLevel); renderPassState->SetDrawingRange(params.drawingRange); renderPassState->SetCullStyle(params.cullStyle); _passes.push_back(p); _renderPassStates.push_back(renderPassState); } }