Beispiel #1
0
        public override void Extract()
        {
            var objectInfoDataHolder    = RootRenderFeature.RenderData.GetData(_objectInfoPropertyKey);
            var blendMatricesDataHolder = RootRenderFeature.RenderData.GetData(_blendMatricesPropertyKey);

            foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences)
            {
                var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference);
                if (!(objectNode.RenderObject is RenderMesh renderMesh))
                {
                    continue;
                }

                blendMatricesDataHolder[objectNodeReference] = renderMesh.BlendMatrices;    // This is for our skinned models.

                if (!(renderMesh.Source is ModelComponent modelComponent))
                {
                    continue;
                }

                var objectInfoData = new ObjectInfoData(modelComponent.RenderGroup);
                objectInfoDataHolder[objectNodeReference] = objectInfoData;

#if DEBUG
                // This is only for debugging purposes, it can be removed.
                if (_isFirstRun)
                {
                    System.Diagnostics.Debug.WriteLine($"Entity: {modelComponent.Entity.Name} - renderGrp: {objectInfoData.RenderGroup}");
                }
#endif
            }
#if DEBUG
            _isFirstRun = false;
#endif
        }
        /// <inheritdoc/>
        public override void Extract()
        {
            var modelObjectInfo = RootRenderFeature.RenderData.GetData(renderObjectInfoKey);

            foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences)
            {
                var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference);
                var renderMesh = objectNode.RenderObject as RenderMesh;
                if (renderMesh == null)
                {
                    continue;
                }

                int meshIndex      = 0;
                var modelComponent = renderMesh.Source as ModelComponent;
                if (modelComponent == null)
                {
                    continue;
                }

                for (int i = 0; i < modelComponent.Model.Meshes.Count; i++)
                {
                    if (modelComponent.Model.Meshes[i] == renderMesh.Mesh)
                    {
                        meshIndex = i;
                        break;
                    }
                }

                modelObjectInfo[objectNodeReference] = new PickingObjectInfo(RuntimeIdHelper.ToRuntimeId(modelComponent), meshIndex, renderMesh.Mesh.MaterialIndex);
            }
        }
Beispiel #3
0
        public override void Extract()
        {
            var objectInfoDataHolder    = RootRenderFeature.RenderData.GetData(_objectInfoPropertyKey);
            var blendMatricesDataHolder = RootRenderFeature.RenderData.GetData(_blendMatricesPropertyKey);

            foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences)
            {
                var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference);
                if (!(objectNode.RenderObject is RenderMesh renderMesh))
                {
                    continue;
                }

                blendMatricesDataHolder[objectNodeReference] = renderMesh.BlendMatrices;    // This is for our skinned models.

                int meshIndex = 0;
                if (!(renderMesh.Source is ModelComponent modelComponent))
                {
                    continue;
                }

                for (int i = 0; i < modelComponent.Model.Meshes.Count; i++)
                {
                    if (modelComponent.Model.Meshes[i] == renderMesh.Mesh)
                    {
                        meshIndex = i;
                        break;
                    }
                }

                // RuntimeIdHelper.ToRuntimeId is how Stride does it for its 'Picking' scene.
                // We should probably change this to use something more appropriate for our data.
                var modelCompId    = RuntimeIdHelper.ToRuntimeId(modelComponent);
                var objectInfoData = new ObjectInfoData((uint)modelCompId, (ushort)meshIndex, (ushort)renderMesh.Mesh.MaterialIndex);
                objectInfoDataHolder[objectNodeReference] = objectInfoData;

#if DEBUG
                // This is only for debugging purposes, it can be removed.
                if (_isFirstRun)
                {
                    System.Diagnostics.Debug.WriteLine($"Entity: {modelComponent.Entity.Name} - modelCompId: {objectInfoData.ModelComponentId} - meshIndex: {objectInfoData.MeshIndex} - matIndex: {objectInfoData.MaterialIndex}");
                }
#endif
            }
#if DEBUG
            _isFirstRun = false;
#endif
        }
        public override void Extract()
        {
            var renderModelObjectInfo = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey);

            foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences)
            {
                var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference);
                var renderMesh = (RenderMesh)objectNode.RenderObject;

                Color4 highlightColor;

                var isHighlighted =
                    MaterialHighlightColors.TryGetValue(renderMesh.MaterialPass.Material, out highlightColor) ||
                    MeshHighlightColors.TryGetValue(renderMesh.Mesh, out highlightColor) ||
                    MaterialsHighlightedForModel.Contains(renderMesh.MaterialPass.Material) && ModelHighlightColors.TryGetValue(renderMesh.RenderModel.ModelComponent, out highlightColor);

                renderModelObjectInfo[objectNodeReference] = highlightColor;
            }
        }
        /// <inheritdoc/>
        public override void Prepare(RenderDrawContext context)
        {
            foreach (var view in RenderSystem.Views)
            {
                var viewFeature = view.Features[RootRenderFeature.Index];

                RenderViewLightData renderViewData;
                if (!renderViewDatas.TryGetValue(view.LightingView ?? view, out renderViewData) || viewFeature.Layouts.Count == 0)
                {
                    continue;
                }

                // Find a PerView layout from an effect in normal state
                ViewResourceGroupLayout firstViewLayout = null;
                foreach (var viewLayout in viewFeature.Layouts)
                {
                    // Only process view layouts in normal state
                    if (viewLayout.State != RenderEffectState.Normal)
                    {
                        continue;
                    }

                    var viewLighting = viewLayout.GetLogicalGroup(viewLightingKey);
                    if (viewLighting.Hash != ObjectId.Empty)
                    {
                        firstViewLayout = viewLayout;
                        break;
                    }
                }

                // Nothing found for this view (no effects in normal state)
                if (firstViewLayout == null)
                {
                    continue;
                }

                var viewIndex = renderViews.IndexOf(view);

                var viewParameterLayout = renderViewData.ViewParameterLayout;
                var viewParameters      = renderViewData.ViewParameters;
                var firstViewLighting   = firstViewLayout.GetLogicalGroup(viewLightingKey);

                // Prepare layout (should be similar for all PerView)
                if (firstViewLighting.Hash != renderViewData.ViewLayoutHash)
                {
                    renderViewData.ViewLayoutHash = firstViewLighting.Hash;

                    // Generate layout
                    viewParameterLayout = renderViewData.ViewParameterLayout = new ParameterCollectionLayout();
                    viewParameterLayout.ProcessLogicalGroup(firstViewLayout, ref firstViewLighting);

                    viewParameters.UpdateLayout(viewParameterLayout);
                }

                // Compute PerView lighting
                foreach (var directLightGroup in shaderPermutation.DirectLightGroups)
                {
                    directLightGroup.ApplyViewParameters(context, viewIndex, viewParameters);
                }
                foreach (var environmentLight in shaderPermutation.EnvironmentLights)
                {
                    environmentLight.ApplyViewParameters(context, viewIndex, viewParameters);
                }

                // Update PerView
                foreach (var viewLayout in viewFeature.Layouts)
                {
                    // Only process view layouts in normal state
                    if (viewLayout.State != RenderEffectState.Normal)
                    {
                        continue;
                    }

                    var viewLighting = viewLayout.GetLogicalGroup(viewLightingKey);
                    if (viewLighting.Hash == ObjectId.Empty)
                    {
                        continue;
                    }

                    if (viewLighting.Hash != firstViewLighting.Hash)
                    {
                        throw new InvalidOperationException("PerView Lighting layout differs between different RenderObject in the same RenderView");
                    }

                    var resourceGroup = viewLayout.Entries[view.Index].Resources;

                    // Update resources
                    resourceGroup.UpdateLogicalGroup(ref viewLighting, viewParameters);
                }

                // PerDraw
                Dispatcher.ForEach(viewFeature.RenderNodes, () => prepareThreadLocals.Value, (renderNodeReference, locals) =>
                {
                    var renderNode = RootRenderFeature.GetRenderNode(renderNodeReference);

                    // Ignore fallback effects
                    if (renderNode.RenderEffect?.State != RenderEffectState.Normal)
                    {
                        return;
                    }

                    var drawLayout = renderNode.RenderEffect?.Reflection?.PerDrawLayout;
                    if (drawLayout == null)
                    {
                        return;
                    }

                    var drawLighting = drawLayout.GetLogicalGroup(drawLightingKey);
                    if (drawLighting.Hash == ObjectId.Empty)
                    {
                        return;
                    }

                    // First time, let's build layout
                    if (drawLighting.Hash != locals.DrawLayoutHash)
                    {
                        locals.DrawLayoutHash = drawLighting.Hash;

                        // Generate layout
                        var drawParameterLayout = new ParameterCollectionLayout();
                        drawParameterLayout.ProcessLogicalGroup(drawLayout, ref drawLighting);

                        locals.DrawParameters.UpdateLayout(drawParameterLayout);
                    }

                    // TODO: Does this ever fail?
                    Debug.Assert(drawLighting.Hash == locals.DrawLayoutHash, "PerDraw Lighting layout differs between different RenderObject in the same RenderView");

                    // Compute PerDraw lighting
                    foreach (var directLightGroup in shaderPermutation.DirectLightGroups)
                    {
                        directLightGroup.ApplyDrawParameters(context, viewIndex, locals.DrawParameters, ref renderNode.RenderObject.BoundingBox);
                    }
                    foreach (var environmentLight in shaderPermutation.EnvironmentLights)
                    {
                        environmentLight.ApplyDrawParameters(context, viewIndex, locals.DrawParameters, ref renderNode.RenderObject.BoundingBox);
                    }

                    // Update resources
                    renderNode.Resources.UpdateLogicalGroup(ref drawLighting, locals.DrawParameters);
                });
            }
        }
        /// <param name="context"></param>
        /// <inheritdoc/>
        public override void PrepareEffectPermutations(RenderThreadContext context)
        {
            var renderEffects            = RootRenderFeature.RenderData.GetData(renderEffectKey);
            int effectSlotCount          = ((RootEffectRenderFeature)RootRenderFeature).EffectPermutationSlotCount;
            var renderViewObjectInfoData = RootRenderFeature.RenderData.GetData(renderViewObjectInfoKey);

            var shadowMapEffectSlot = ShadowMapRenderStage != null ? ((RootEffectRenderFeature)RootRenderFeature).GetEffectPermutationSlot(ShadowMapRenderStage) : EffectPermutationSlot.Invalid;

            foreach (var view in RenderSystem.Views)
            {
                if (view.GetType() != typeof(RenderView))
                {
                    continue;
                }

                RenderViewLightData renderViewData;
                if (!renderViewDatas.TryGetValue(view, out renderViewData))
                {
                    continue;
                }

                var viewFeature = view.Features[RootRenderFeature.Index];

                foreach (var renderPerViewNodeReference in viewFeature.ViewObjectNodes)
                {
                    var renderPerViewNode = RootRenderFeature.GetViewObjectNode(renderPerViewNodeReference);

                    var renderMesh = (RenderMesh)renderPerViewNode.RenderObject;

                    if (!renderMesh.Material.IsLightDependent)
                    {
                        continue;
                    }

                    var staticObjectNode = renderMesh.StaticObjectNode;

                    for (int i = 0; i < effectSlotCount; ++i)
                    {
                        // Don't apply lighting for shadow casters
                        if (i == shadowMapEffectSlot.Index)
                        {
                            continue;
                        }

                        var staticEffectObjectNode = staticObjectNode * effectSlotCount + i;
                        var renderEffect           = renderEffects[staticEffectObjectNode];

                        // Skip effects not used during this frame
                        if (renderEffect == null || !renderEffect.IsUsedDuringThisFrame(RenderSystem))
                        {
                            continue;
                        }

                        var renderModel      = renderMesh.RenderModel;
                        var modelComponent   = renderModel.ModelComponent;
                        var isShadowReceiver = renderMesh.IsShadowReceiver && modelComponent.IsShadowReceiver;

                        // TODO GRAPHICS REFACTOR: Shader permutations can be collected per-object. Only parameter permutations need to be per-view-object.
                        var renderObjectInfo = PreparePermutationEntryForRendering(renderViewData, isShadowReceiver, ref modelComponent.BoundingBox, modelComponent.Entity.Group, i);
                        renderObjectInfo.ApplyEffectPermutations(renderEffect);
                        renderViewObjectInfoData[renderPerViewNodeReference] = renderObjectInfo;

                        if (renderObjectInfo == null)
                        {
                            continue;
                        }

                        renderEffect.EffectValidator.ValidateParameter(LightingKeys.DirectLightGroups, renderObjectInfo.ShaderPermutationEntry.DirectLightShaders);
                        renderEffect.EffectValidator.ValidateParameter(LightingKeys.EnvironmentLights, renderObjectInfo.ShaderPermutationEntry.EnvironmentLightShaders);
                    }
                }
            }
        }
Beispiel #7
0
 public RenderNodeFeatureReference(RootRenderFeature rootRenderFeature, RenderNodeReference renderNode, RenderObject renderObject)
 {
     RootRenderFeature = rootRenderFeature;
     RenderNode        = renderNode;
     RenderObject      = renderObject;
 }