private LightParametersPermutationEntry CreateParametersPermutationEntry(LightShaderPermutationEntry lightShaderPermutationEntry) { // TODO GRAPHICS REFACTOR to use Set*() instead of Set*Slow() we would need to pool data by LightShaderPermutationEntry (just like ParameterCollections) var parameterCollectionEntry = lightShaderPermutationEntry.ParameterCollectionEntryPool.Add(); parameterCollectionEntry.Clear(); var directLightGroups = parameterCollectionEntry.DirectLightGroupDatas; var environmentLights = parameterCollectionEntry.EnvironmentLightDatas; foreach (var directLightGroup in lightShaderPermutationEntry.DirectLightGroups) { directLightGroups.Add(directLightGroup.CreateGroupData()); } foreach (var environmentLightGroup in lightShaderPermutationEntry.EnvironmentLights) { environmentLights.Add(environmentLightGroup.CreateGroupData()); } foreach (var lightEntry in directLightsPerMesh) { directLightGroups[lightEntry.GroupIndex].AddLight(lightEntry.Light, lightEntry.Shadow); } foreach (var lightEntry in environmentLightsPerMesh) { environmentLights[lightEntry.GroupIndex].AddLight(lightEntry.Light, null); } return(parameterCollectionEntry); }
public LightParametersPermutationEntry(LightShaderPermutationEntry shaderPermutationEntry) { ShaderPermutationEntry = shaderPermutationEntry; Parameters = new ParameterCollection(); DirectLightGroupDatas = new List <LightShaderGroupData>(); EnvironmentLightDatas = new List <LightShaderGroupData>(); }
private void PreRenderMesh(RenderContext context, RenderMesh renderMesh) { var contextParameters = context.Parameters; RenderModelLights renderModelLights; if (!modelToLights.TryGetValue(renderMesh.RenderModel, out renderModelLights)) { contextParameters.Set(LightingKeys.DirectLightGroups, null); contextParameters.Set(LightingKeys.EnvironmentLights, null); return; } // TODO: copy shadow receiver info to mesh var isShadowReceiver = renderMesh.IsShadowReceiver; if (currentModelLightShadersPermutationEntry != renderModelLights.LightShadersPermutation || currentModelShadersParameters != renderModelLights.Parameters || currentShadowReceiver != isShadowReceiver) { currentModelLightShadersPermutationEntry = renderModelLights.LightShadersPermutation; currentModelShadersParameters = renderModelLights.Parameters; currentShadowReceiver = isShadowReceiver; if (currentShadowReceiver) { currentModelShadersParameters.Parameters.CopySharedTo(contextParameters); } else { currentModelShadersParameters.ParametersNoShadows.CopySharedTo(contextParameters); } } }
private LightShaderPermutationEntry CreateShaderPermutationEntry() { var shaderEntry = new LightShaderPermutationEntry(); // Direct Lights (with or without shadows) for (int i = 0; i < directLightShaderGroupEntryKeys.Count; i++) { var shaderGroupEntry = directLightShaderGroupEntryKeys.Items[i]; int lightCount = shaderGroupEntry.Key.LightCount; ILightShadowMapShaderGroupData shadowGroupData = null; if (shaderGroupEntry.ShadowRenderer != null) { // TODO: Cache ShaderGroupData shadowGroupData = shaderGroupEntry.ShadowRenderer.CreateShaderGroupData(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.ShadowType, lightCount); } // TODO: Cache LightShaderGroup var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], lightCount, shadowGroupData); shaderEntry.DirectLightGroups.Add(lightShaderGroup); shaderEntry.DirectLightShaders.Add(lightShaderGroup.ShaderSource); } // All Direct Lights for (int i = 0; i < directLightShaderGroupEntryKeysNoShadows.Count; i++) { var shaderGroupEntry = directLightShaderGroupEntryKeysNoShadows.Items[i]; // TODO: Cache LightShaderGroup var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null); shaderEntry.DirectLightGroupsNoShadows.Add(lightShaderGroup); shaderEntry.DirectLightShadersNoShadows.Add(lightShaderGroup.ShaderSource); } // All Environment lights for (int i = 0; i < environmentLightShaderGroupEntryKeys.Count; i++) { var shaderGroupEntry = environmentLightShaderGroupEntryKeys.Items[i]; // TODO: Cache LightShaderGroup var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(EnvironmentLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null); shaderEntry.EnvironmentLights.Add(lightShaderGroup); shaderEntry.EnvironmentLightShaders.Add(lightShaderGroup.ShaderSource); } return(shaderEntry); }
public RenderModelLights(LightShaderPermutationEntry lightShadersPermutation, LightParametersPermutationEntry parameters) { LightShadersPermutation = lightShadersPermutation; Parameters = parameters; }
private LightParametersPermutationEntry CreateParametersPermutationEntry(LightShaderPermutationEntry lightShaderPermutationEntry) { var parameterCollectionEntry = parameterCollectionEntryPool.Add(); parameterCollectionEntry.Clear(); var directLightGroups = parameterCollectionEntry.DirectLightGroupDatas; var directLightGroupsNoShadows = parameterCollectionEntry.DirectLightGroupsNoShadowDatas; var environmentLights = parameterCollectionEntry.EnvironmentLightDatas; foreach (var directLightGroup in lightShaderPermutationEntry.DirectLightGroups) { directLightGroups.Add(directLightGroup.CreateGroupData()); } foreach (var directLightGroupNoShadow in lightShaderPermutationEntry.DirectLightGroupsNoShadows) { directLightGroupsNoShadows.Add(directLightGroupNoShadow.CreateGroupData()); } foreach (var environmentLightGroup in lightShaderPermutationEntry.EnvironmentLights) { environmentLights.Add(environmentLightGroup.CreateGroupData()); } var parameters = parameterCollectionEntry.Parameters; var parametersNoShadows = parameterCollectionEntry.ParametersNoShadows; parameters.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShaders); parameters.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders); parametersNoShadows.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShadersNoShadows); parametersNoShadows.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders); foreach (var lightEntry in directLightsPerModel) { directLightGroups[lightEntry.GroupIndex].AddLight(lightEntry.Light, lightEntry.Shadow); directLightGroupsNoShadows[lightEntry.GroupIndexNoShadows].AddLight(lightEntry.Light, null); } foreach (var lightEntry in environmentLightsPerModel) { environmentLights[lightEntry.GroupIndex].AddLight(lightEntry.Light, null); } foreach (var lightGroup in directLightGroups) { lightGroup.ApplyParameters(parameters); } foreach (var lightGroup in directLightGroupsNoShadows) { lightGroup.ApplyParameters(parametersNoShadows); } foreach (var lightGroup in environmentLights) { lightGroup.ApplyParameters(parameters); lightGroup.ApplyParameters(parametersNoShadows); } return parameterCollectionEntry; }
private LightShaderPermutationEntry CreateShaderPermutationEntry() { var shaderEntry = new LightShaderPermutationEntry(); // Direct Lights (with or without shadows) for (int i = 0; i < directLightShaderGroupEntryKeys.Count; i++) { var shaderGroupEntry = directLightShaderGroupEntryKeys.Items[i]; int lightCount = shaderGroupEntry.Key.LightCount; ILightShadowMapShaderGroupData shadowGroupData = null; if (shaderGroupEntry.ShadowRenderer != null) { // TODO: Cache ShaderGroupData shadowGroupData = shaderGroupEntry.ShadowRenderer.CreateShaderGroupData(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.ShadowType, lightCount); } // TODO: Cache LightShaderGroup var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], lightCount, shadowGroupData); shaderEntry.DirectLightGroups.Add(lightShaderGroup); shaderEntry.DirectLightShaders.Add(lightShaderGroup.ShaderSource); } // All Direct Lights for (int i = 0; i < directLightShaderGroupEntryKeysNoShadows.Count; i++) { var shaderGroupEntry = directLightShaderGroupEntryKeysNoShadows.Items[i]; // TODO: Cache LightShaderGroup var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null); shaderEntry.DirectLightGroupsNoShadows.Add(lightShaderGroup); shaderEntry.DirectLightShadersNoShadows.Add(lightShaderGroup.ShaderSource); } // All Environment lights for (int i = 0; i < environmentLightShaderGroupEntryKeys.Count; i++) { var shaderGroupEntry = environmentLightShaderGroupEntryKeys.Items[i]; // TODO: Cache LightShaderGroup var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(EnvironmentLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null); shaderEntry.EnvironmentLights.Add(lightShaderGroup); shaderEntry.EnvironmentLightShaders.Add(lightShaderGroup.ShaderSource); } return shaderEntry; }
protected override void DrawCore(RenderContext context) { modelProcessor = SceneInstance.GetCurrent(context).GetProcessor<ModelProcessor>(); lightProcessor = SceneInstance.GetCurrent(context).GetProcessor<LightProcessor>(); // No light processors means no light in the scene, so we can early exit if (lightProcessor == null || modelProcessor == null) { return; } // Not in the context of a SceneCameraRenderer? just exit sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current); sceneCamera = context.Tags.Get(CameraComponentRenderer.Current); if (sceneCameraRenderer == null || sceneCamera == null) { return; } sceneCullingMask = sceneCameraRenderer.CullingMask; // Setup the callback on the ModelRenderer and shadow map LightGroupRenderer if (!isModelComponentRendererSetup) { // TODO: Check if we could discover declared renderers in a better way than just hacking the tags of a component var modelRenderer = ModelComponentRenderer.GetAttached(sceneCameraRenderer); if (modelRenderer == null) { return; } modelRenderer.Callbacks.PreRenderModel += PrepareRenderModelForRendering; modelRenderer.Callbacks.PreRenderMesh += PreRenderMesh; // TODO: Make this pluggable // TODO: Shadows should work on mobile platforms if (context.GraphicsDevice.Features.Profile >= GraphicsProfile.Level_10_0 && (Platform.Type == PlatformType.Windows || Platform.Type == PlatformType.WindowsStore || Platform.Type == PlatformType.Windows10)) { shadowMapRenderer = new ShadowMapRenderer(modelRenderer.EffectName); shadowMapRenderer.Renderers.Add(typeof(LightDirectional), new LightDirectionalShadowMapRenderer()); shadowMapRenderer.Renderers.Add(typeof(LightSpot), new LightSpotShadowMapRenderer()); } isModelComponentRendererSetup = true; } // Collect all visible lights CollectVisibleLights(); // Draw shadow maps if (shadowMapRenderer != null) shadowMapRenderer.Draw(context, visibleLightsWithShadows); // Prepare active renderers in an ordered list (by type and shadow on/off) CollectActiveLightRenderers(context); currentModelLightShadersPermutationEntry = null; currentModelShadersParameters = null; currentShadowReceiver = true; // Clear the cache of parameter entries lightParameterEntries.Clear(); parameterCollectionEntryPool.Clear(); // Clear association between model and lights modelToLights.Clear(); // Clear all data generated by shader entries foreach (var shaderEntry in shaderEntries) { shaderEntry.Value.ResetGroupDatas(); } }
private LightParametersPermutationEntry CreateParametersPermutationEntry(LightShaderPermutationEntry lightShaderPermutationEntry) { var parameterCollectionEntry = parameterCollectionEntryPool.Add(); parameterCollectionEntry.Clear(); var directLightGroups = parameterCollectionEntry.DirectLightGroupDatas; var directLightGroupsNoShadows = parameterCollectionEntry.DirectLightGroupsNoShadowDatas; var environmentLights = parameterCollectionEntry.EnvironmentLightDatas; foreach (var directLightGroup in lightShaderPermutationEntry.DirectLightGroups) { directLightGroups.Add(directLightGroup.CreateGroupData()); } foreach (var directLightGroupNoShadow in lightShaderPermutationEntry.DirectLightGroupsNoShadows) { directLightGroupsNoShadows.Add(directLightGroupNoShadow.CreateGroupData()); } foreach (var environmentLightGroup in lightShaderPermutationEntry.EnvironmentLights) { environmentLights.Add(environmentLightGroup.CreateGroupData()); } var parameters = parameterCollectionEntry.Parameters; var parametersNoShadows = parameterCollectionEntry.ParametersNoShadows; parameters.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShaders); parameters.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders); parametersNoShadows.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShadersNoShadows); parametersNoShadows.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders); foreach (var lightEntry in directLightsPerModel) { directLightGroups[lightEntry.GroupIndex].AddLight(lightEntry.Light, lightEntry.Shadow); directLightGroupsNoShadows[lightEntry.GroupIndexNoShadows].AddLight(lightEntry.Light, null); } foreach (var lightEntry in environmentLightsPerModel) { environmentLights[lightEntry.GroupIndex].AddLight(lightEntry.Light, null); } foreach (var lightGroup in directLightGroups) { lightGroup.ApplyParameters(parameters); } foreach (var lightGroup in directLightGroupsNoShadows) { lightGroup.ApplyParameters(parametersNoShadows); } foreach (var lightGroup in environmentLights) { lightGroup.ApplyParameters(parameters); lightGroup.ApplyParameters(parametersNoShadows); } return(parameterCollectionEntry); }
protected override void DrawCore(RenderContext context) { modelProcessor = SceneInstance.GetCurrent(context).GetProcessor <ModelProcessor>(); lightProcessor = SceneInstance.GetCurrent(context).GetProcessor <LightProcessor>(); // No light processors means no light in the scene, so we can early exit if (lightProcessor == null || modelProcessor == null) { return; } // Not in the context of a SceneCameraRenderer? just exit sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current); sceneCamera = context.Tags.Get(CameraComponentRenderer.Current); if (sceneCameraRenderer == null || sceneCamera == null) { return; } sceneCullingMask = sceneCameraRenderer.CullingMask; // Setup the callback on the ModelRenderer and shadow map LightGroupRenderer if (!isModelComponentRendererSetup) { // TODO: Check if we could discover declared renderers in a better way than just hacking the tags of a component var modelRenderer = ModelComponentRenderer.GetAttached(sceneCameraRenderer); if (modelRenderer == null) { return; } modelRenderer.Callbacks.PreRenderModel += PrepareRenderModelForRendering; modelRenderer.Callbacks.PreRenderMesh += PreRenderMesh; // TODO: Make this pluggable // TODO: Shadows should work on mobile platforms if (context.GraphicsDevice.Features.Profile >= GraphicsProfile.Level_10_0 && (Platform.Type == PlatformType.Windows || Platform.Type == PlatformType.WindowsStore || Platform.Type == PlatformType.Windows10)) { shadowMapRenderer = new ShadowMapRenderer(modelRenderer.EffectName); shadowMapRenderer.Renderers.Add(typeof(LightDirectional), new LightDirectionalShadowMapRenderer()); shadowMapRenderer.Renderers.Add(typeof(LightSpot), new LightSpotShadowMapRenderer()); } isModelComponentRendererSetup = true; } // Collect all visible lights CollectVisibleLights(); // Draw shadow maps if (shadowMapRenderer != null) { shadowMapRenderer.Draw(context, visibleLightsWithShadows); } // Prepare active renderers in an ordered list (by type and shadow on/off) CollectActiveLightRenderers(context); currentModelLightShadersPermutationEntry = null; currentModelShadersParameters = null; currentShadowReceiver = true; // Clear the cache of parameter entries lightParameterEntries.Clear(); parameterCollectionEntryPool.Clear(); // Clear association between model and lights modelToLights.Clear(); // Clear all data generated by shader entries foreach (var shaderEntry in shaderEntries) { shaderEntry.Value.ResetGroupDatas(); } }