/// <summary> /// Initializes a new instance of the <see cref="ModelComponentRenderer" /> class. /// </summary> /// <param name="effectName">Name of the effect.</param> /// <exception cref="System.ArgumentNullException">effectName</exception> public ModelComponentRenderer(string effectName) { if (effectName != null) { EffectName = effectName; } meshesToRender = new FastList<RenderMesh>(); Callbacks = new ModelComponentRendererCallback(); skinningUpdater = new MeshSkinningUpdater(256); }
/// <summary> /// Initializes a new instance of the <see cref="RenderMesh" /> class. /// </summary> /// <param name="renderModel">The render model.</param> /// <param name="mesh">The mesh data.</param> /// <exception cref="System.ArgumentNullException">mesh</exception> public RenderMesh(RenderModel renderModel, Mesh mesh) { if (renderModel == null) throw new ArgumentNullException("renderModel"); if (mesh == null) throw new ArgumentNullException("mesh"); RenderModel = renderModel; Mesh = mesh; Enabled = true; parameterCollections = new FastListStruct<ParameterCollection>(8); previousParameterCollections = new FastListStruct<ParameterCollection>(8); UpdateMaterial(); // A RenderMesh is inheriting values from Mesh.Parameters // We are considering that Mesh.Parameters is not updated frequently (should be almost immutable) parameters = new ParameterCollection(); if (mesh.Parameters != null) { parameters.AddSources(mesh.Parameters); } }
public override void FillParameterCollections(ref FastListStruct<ParameterCollection> parameterCollections) { // Test common types to avoid struct enumerator boxing var localParameterCollectionsList = localParameterCollections as List<ParameterCollection>; if (localParameterCollectionsList != null) { foreach (var parameter in localParameterCollectionsList) { if (parameter != null) { parameterCollections.Add(parameter); } } } else { var localParameterCollectionsArray = localParameterCollections as ParameterCollection[]; if (localParameterCollectionsArray != null) { foreach (var parameter in localParameterCollectionsArray) { if (parameter != null) { parameterCollections.Add(parameter); } } } else { // Slow: enumerator will be boxed foreach (var parameter in localParameterCollections) { if (parameter != null) { parameterCollections.Add(parameter); } } } } }
/// <summary> /// Initializes a new instance of the <see cref="DynamicEffectCompiler" /> class. /// </summary> /// <param name="services">The services.</param> /// <param name="effectName">Name of the effect.</param> /// <param name="taskPriority">The task priority.</param> /// <exception cref="System.ArgumentNullException">services /// or /// effectName</exception> public DynamicEffectCompiler(IServiceRegistry services, string effectName, int taskPriority = 0) { if (services == null) throw new ArgumentNullException("services"); if (effectName == null) throw new ArgumentNullException("effectName"); Services = services; this.effectName = effectName; this.taskPriority = taskPriority; EffectSystem = Services.GetSafeServiceAs<EffectSystem>(); GraphicsDevice = Services.GetSafeServiceAs<IGraphicsDeviceService>().GraphicsDevice; parameterCollections = new FastListStruct<ParameterCollection>(8); // Default behavior for fallback effect: load effect with same name but empty compiler parameters ComputeFallbackEffect = (dynamicEffectCompiler, type, name, parameters) => { ParameterCollection usedParameters; var compilerParameters = new CompilerParameters { TaskPriority = -1 }; // We want high priority var effect = dynamicEffectCompiler.EffectSystem.LoadEffect(effectName, compilerParameters, out usedParameters).WaitForResult(); return new ComputeFallbackEffectResult(effect, usedParameters); }; }
public ShadowMapRenderer() { atlases = new FastListStruct <ShadowMapAtlasTexture>(16); }
/// <inheritdoc/> public override void ApplyDrawParameters(FastListStruct <LightDynamicEntry>?lightList, RenderDrawContext context, int viewIndex, ParameterCollection parameters, ref BoundingBoxExt boundingBox) { base.ApplyDrawParameters(lightList, context, viewIndex, parameters, ref boundingBox); ShadowGroup?.ApplyDrawParameters(context, parameters, lightList.HasValue ? lightList.Value : new FastListStruct <LightDynamicEntry>(8), ref boundingBox); }
public LightComponentForwardRenderer() { modelToLights = new Dictionary<RenderModel, RenderModelLights>(1024); directLightShaderGroupEntryKeys = new FastListStruct<LightForwardShaderFullEntryKey>(32); environmentLightShaderGroupEntryKeys = new FastListStruct<LightForwardShaderFullEntryKey>(32); directLightShaderGroupEntryKeysNoShadows = new FastListStruct<LightForwardShaderFullEntryKey>(32); parameterCollectionEntryPool = new PoolListStruct<LightParametersPermutationEntry>(16, CreateParameterCollectionEntry); //directLightGroup = new LightGroupRenderer("directLightGroups", LightingKeys.DirectLightGroups); //environmentLightGroup = new LightGroupRenderer("environmentLights", LightingKeys.EnvironmentLights); lightRenderers = new List<KeyValuePair<Type, LightGroupRendererBase>>(16); visibleLights = new List<LightComponent>(1024); visibleLightsWithShadows = new List<LightComponent>(1024); shaderEntries = new Dictionary<ObjectId, LightShaderPermutationEntry>(1024); directLightsPerModel = new List<LightEntry>(16); activeLightGroups = new Dictionary<Type, LightComponentCollectionGroup>(16); activeLightGroupsWithShadows = new Dictionary<Type, LightComponentCollectionGroup>(16); activeRenderers = new List<ActiveLightGroupRenderer>(16); lightParameterEntries = new Dictionary<ObjectId, LightParametersPermutationEntry>(32); // TODO: Make this pluggable RegisterLightGroupRenderer(typeof(LightDirectional), new LightDirectionalGroupRenderer()); RegisterLightGroupRenderer(typeof(LightSpot), new LightSpotGroupRenderer()); RegisterLightGroupRenderer(typeof(LightPoint), new LightPointGroupRenderer()); RegisterLightGroupRenderer(typeof(LightAmbient), new LightAmbientRenderer()); RegisterLightGroupRenderer(typeof(LightSkybox), new LightSkyboxRenderer()); }
public void ApplyViewParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct<LightDynamicEntry> currentLights) { }
/// <summary> /// Fills the parameter collections used by this instance. /// </summary> /// <param name="parameterCollections">The parameter collections.</param> public abstract void FillParameterCollections(ref FastListStruct<ParameterCollection> parameterCollections);
public void Initialize(Func <DataType, int> computeDataArrayExpectedSize) { this.computeDataArrayExpectedSize = computeDataArrayExpectedSize; dataArraysByDefinition = new Dictionary <object, int>(); dataArrays = new FastListStruct <DataArray>(8); }
public override void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { var boundingBox2 = (BoundingBox)boundingBox; bool shadowMapCreated = false; int lightIndex = 0; for (int i = 0; i < currentLights.Count; ++i) { var lightEntry = currentLights[i]; var light = lightEntry.Light; if (light.BoundingBox.Intersects(ref boundingBox2)) { var singleLightData = (LightSpotShadowMapShaderData)lightEntry.ShadowMapTexture.ShaderData; worldToShadowCascadeUV[lightIndex] = singleLightData.WorldToShadowCascadeUV; Matrix.Invert(ref singleLightData.WorldToShadowCascadeUV, out inverseWorldToShadowCascadeUV[lightIndex]); depthBiases[lightIndex] = singleLightData.DepthBias; offsetScales[lightIndex] = singleLightData.OffsetScale; depthRanges[lightIndex] = singleLightData.DepthRange; if (!shadowMapCreated) { shadowMapTexture = singleLightData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } shadowMapCreated = true; } lightIndex++; } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(worldToShadowCascadeUVsKey, worldToShadowCascadeUV); parameters.Set(inverseWorldToShadowCascadeUVsKey, inverseWorldToShadowCascadeUV); parameters.Set(depthRangesKey, depthRanges); parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
public void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { for (int lightIndex = 0; lightIndex < currentLights.Count; ++lightIndex) { var lightEntry = currentLights[lightIndex]; var singleLightData = (LightSpotShadowMapShaderData)lightEntry.ShadowMapTexture.ShaderData; worldToShadowCascadeUV[lightIndex] = singleLightData.WorldToShadowCascadeUV; depthBiases[lightIndex] = singleLightData.DepthBias; offsetScales[lightIndex] = singleLightData.OffsetScale; // TODO: should be setup just once at creation time if (lightIndex == 0) { shadowMapTexture = singleLightData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(worldToShadowCascadeUVsKey, worldToShadowCascadeUV); parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
public RenderModel(ModelComponent modelComponent) { RenderMeshesPerEffectSlot = new FastListStruct <FastListStruct <RenderMesh> >(4); ModelComponent = modelComponent; }
public RegisteredRenderProcessors(Type type, int instanceCount) { Type = type; Instances = new FastListStruct<KeyValuePair<VisibilityGroup, EntityProcessor>>(instanceCount); }
public override void ApplyViewParameters(FastListStruct <LightDynamicEntry>?lightList, RenderDrawContext context, int viewIndex, ParameterCollection parameters) { base.ApplyViewParameters(lightList, context, viewIndex, parameters); parameters.Set(ambientLightKey, AmbientColor[viewIndex]); }
public void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct<LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { }
public void ApplyViewParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct<LightDynamicEntry> currentLights) { for (int lightIndex = 0; lightIndex < currentLights.Count; ++lightIndex) { var lightEntry = currentLights[lightIndex]; var singleLightData = (LightDirectionalShadowMapShaderData)lightEntry.ShadowMapTexture.ShaderData; var splits = singleLightData.CascadeSplits; var matrices = singleLightData.WorldToShadowCascadeUV; int splitIndex = lightIndex * cascadeCount; for (int i = 0; i < splits.Length; i++) { cascadeSplits[splitIndex + i] = splits[i]; worldToShadowCascadeUV[splitIndex + i] = matrices[i]; } depthBiases[lightIndex] = singleLightData.DepthBias; offsetScales[lightIndex] = singleLightData.OffsetScale; // TODO: should be setup just once at creation time if (lightIndex == 0) { shadowMapTexture = singleLightData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f/shadowMapTextureSize; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(cascadeSplitsKey, cascadeSplits); parameters.Set(worldToShadowCascadeUVsKey, worldToShadowCascadeUV); parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
public virtual void ApplyViewParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights) { }
private void PrepareRenderMeshes(RenderModel renderModel, List <Mesh> meshes, ref FastListStruct <RenderMesh> renderMeshes, RenderItemCollection opaqueList, RenderItemCollection transparentList) { // Add new render meshes for (int i = renderMeshes.Count; i < meshes.Count; i++) { var renderMesh = new RenderMesh(renderModel, meshes[i]); renderMeshes.Add(renderMesh); } // Create the bounding frustum locally on the stack, so that frustum.Contains is performed with boundingBox that is also on the stack var frustum = new BoundingFrustum(ref ViewProjectionMatrix); var sceneCameraRenderer = Context.Tags.Get(SceneCameraRenderer.Current); var cullingMode = CullingModeOverride ?? (sceneCameraRenderer?.CullingMode ?? CameraCullingMode.None); for (int i = 0; i < renderMeshes.Count; i++) { var renderMesh = renderMeshes[i]; // Update the model hierarchy var modelViewHierarchy = renderModel.ModelComponent.Skeleton; modelViewHierarchy.UpdateRenderMesh(renderMesh); if (!renderMesh.Enabled || !renderMesh.UpdateMaterial()) { continue; } // Upload skinning blend matrices BoundingBoxExt boundingBox; skinningUpdater.Update(modelViewHierarchy, renderMesh, out boundingBox); // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ // Compute transformed AABB (by world) // TODO: CameraCullingMode should be pluggable // TODO: This should not be necessary. Add proper bounding boxes to gizmos etc. if (cullingMode == CameraCullingMode.Frustum && boundingBox.Extent != Vector3.Zero && !frustum.Contains(ref boundingBox)) { continue; } // Project the position // TODO: This could be done in a SIMD batch, but we need to figure-out how to plugin in with RenderMesh object var worldPosition = new Vector4(renderMesh.WorldMatrix.TranslationVector, 1.0f); Vector4 projectedPosition; Vector4.Transform(ref worldPosition, ref ViewProjectionMatrix, out projectedPosition); var projectedZ = projectedPosition.Z / projectedPosition.W; renderMesh.RasterizerState = renderMesh.IsGeometryInverted ? RasterizerStateForInvertedGeometry : RasterizerState; renderMesh.ForceRasterizer = ForceRasterizer; var list = renderMesh.HasTransparency ? transparentList : opaqueList; list.Add(new RenderItem(this, renderMesh, projectedZ)); } }
public void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { }
public override void ApplyViewParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights) { for (int lightIndex = 0; lightIndex < currentLights.Count; ++lightIndex) { var lightEntry = currentLights[lightIndex]; var singleLightData = (ShaderData)lightEntry.ShadowMapTexture.ShaderData; var splits = singleLightData.CascadeSplits; var lightWorldToShadowCascadeUVs = singleLightData.WorldToShadowCascadeUV; Vector2[] lightDepthRanges = singleLightData.DepthRange; int splitIndex = lightIndex * cascadeCount; for (int i = 0; i < splits.Length; i++) { int cascadeIndex = splitIndex + i; cascadeSplits[cascadeIndex] = splits[i]; worldToShadowCascadeUV[cascadeIndex] = lightWorldToShadowCascadeUVs[i]; inverseWorldToShadowCascadeUV[cascadeIndex] = Matrix.Invert(lightWorldToShadowCascadeUVs[i]); /////////////////////////////////////////////////// depthRanges[cascadeIndex] = lightDepthRanges[i]; /////////////////////////////////////////////////// } depthBiases[lightIndex] = singleLightData.DepthBias; offsetScales[lightIndex] = singleLightData.OffsetScale; // TODO: should be setup just once at creation time if (lightIndex == 0) { shadowMapTexture = singleLightData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(cascadeSplitsKey, cascadeSplits); parameters.Set(worldToShadowCascadeUVsKey, worldToShadowCascadeUV); parameters.Set(inverseWorldToShadowCascadeUVsKey, inverseWorldToShadowCascadeUV); /////////////////////////////////////////////////// parameters.Set(depthRangesKey, depthRanges); /////////////////////////////////////////////////// parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
internal static void PopulateLightsInRange(ref FastListStruct <LightDynamicEntry> allLights, LightShaderGroupDynamic.LightRange lightRange, ref FastListStruct <LightDynamicEntry> lightsInRange) { int lightsCount = lightRange.End - lightRange.Start; lightsInRange.EnsureCapacity(lightsCount); var lightsInRangeArray = lightsInRange.Items; for (int i = 0; i < lightsCount; i++) { lightsInRangeArray[i] = allLights[lightRange.Start + i]; } lightsInRange.Count = lightsCount; }
public override void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { var boundingBox2 = (BoundingBox)boundingBox; bool shadowMapCreated = false; int lightIndex = 0; for (int i = 0; i < currentLights.Count; ++i) { var lightEntry = currentLights[i]; if (lightEntry.Light.BoundingBox.Intersects(ref boundingBox2)) { var shaderData = (ShaderData)lightEntry.ShadowMapTexture.ShaderData; offsets[lightIndex] = shaderData.Offset; backfaceOffsets[lightIndex] = shaderData.BackfaceOffset; faceSizes[lightIndex] = shaderData.FaceSize; depthParameters[lightIndex] = shaderData.DepthParameters; depthBiases[lightIndex] = shaderData.DepthBias; viewMatrices[lightIndex] = shaderData.View; lightIndex++; // TODO: should be setup just once at creation time if (!shadowMapCreated) { shadowMapTexture = shaderData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } shadowMapCreated = true; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(viewKey, viewMatrices); parameters.Set(offsetsKey, offsets); parameters.Set(backfaceOffsetsKey, backfaceOffsets); parameters.Set(faceSizesKey, faceSizes); parameters.Set(depthParametersKey, depthParameters); parameters.Set(depthBiasesKey, depthBiases); }
public void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct<LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { var boundingBox2 = (BoundingBox)boundingBox; bool shadowMapCreated = false; int lightIndex = 0; for (int i = 0; i < currentLights.Count; ++i) { var lightEntry = currentLights[i]; var light = lightEntry.Light; if (light.BoundingBox.Intersects(ref boundingBox2)) { var singleLightData = (LightSpotShadowMapShaderData)lightEntry.ShadowMapTexture.ShaderData; worldToShadowCascadeUV[lightIndex] = singleLightData.WorldToShadowCascadeUV; depthBiases[lightIndex] = singleLightData.DepthBias; offsetScales[lightIndex] = singleLightData.OffsetScale; lightIndex++; if (!shadowMapCreated) { shadowMapTexture = singleLightData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } shadowMapCreated = true; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(worldToShadowCascadeUVsKey, worldToShadowCascadeUV); parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
public RegisteredRenderProcessors(Type type, int instanceCount) { Type = type; Instances = new FastListStruct <KeyValuePair <VisibilityGroup, EntityProcessor> >(instanceCount); }
public RenderModel(ModelComponent modelComponent) { RenderMeshesPerEffectSlot = new FastListStruct<FastListStruct<RenderMesh>>(4); ModelComponent = modelComponent; }
public void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct<LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { for (int lightIndex = 0; lightIndex < currentLights.Count; ++lightIndex) { var lightEntry = currentLights[lightIndex]; var singleLightData = (LightSpotShadowMapShaderData)lightEntry.ShadowMapTexture.ShaderData; worldToShadowCascadeUV[lightIndex] = singleLightData.WorldToShadowCascadeUV; depthBiases[lightIndex] = singleLightData.DepthBias; offsetScales[lightIndex] = singleLightData.OffsetScale; // TODO: should be setup just once at creation time if (lightIndex == 0) { shadowMapTexture = singleLightData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(worldToShadowCascadeUVsKey, worldToShadowCascadeUV); parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
/// <summary> /// Applies PerView lighting parameters. /// </summary> /// <param name="context"></param> /// <param name="viewIndex"></param> /// <param name="parameters"></param> public virtual void ApplyViewParameters(FastListStruct <LightDynamicEntry>?lightList, RenderDrawContext context, int viewIndex, ParameterCollection parameters) { }
private void PrepareRenderMeshes(RenderModel renderModel, List<Mesh> meshes, ref FastListStruct<RenderMesh> renderMeshes, RenderItemCollection opaqueList, RenderItemCollection transparentList) { // Add new render meshes for (int i = renderMeshes.Count; i < meshes.Count; i++) { var renderMesh = new RenderMesh(renderModel, meshes[i]); renderMeshes.Add(renderMesh); } // Create the bounding frustum locally on the stack, so that frustum.Contains is performed with boundingBox that is also on the stack var frustum = new BoundingFrustum(ref ViewProjectionMatrix); for (int i = 0; i < renderMeshes.Count; i++) { var renderMesh = renderMeshes[i]; // Update the model hierarchy var modelViewHierarchy = renderModel.ModelComponent.ModelViewHierarchy; modelViewHierarchy.UpdateRenderMesh(renderMesh); if (!renderMesh.Enabled) { continue; } // Upload skinning blend matrices BoundingBoxExt boundingBox; skinningUpdater.Update(modelViewHierarchy, renderMesh, out boundingBox); // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ // Compute transformed AABB (by world) // TODO: CullingMode should be pluggable // TODO: This should not be necessary. Add proper bounding boxes to gizmos etc. if (CullingMode == CullingMode.Frustum && boundingBox.Extent != Vector3.Zero && !frustum.Contains(ref boundingBox)) { continue; } // Project the position // TODO: This could be done in a SIMD batch, but we need to figure-out how to plugin in with RenderMesh object var worldPosition = new Vector4(renderMesh.WorldMatrix.TranslationVector, 1.0f); Vector4 projectedPosition; Vector4.Transform(ref worldPosition, ref ViewProjectionMatrix, out projectedPosition); var projectedZ = projectedPosition.Z / projectedPosition.W; renderMesh.RasterizerState = renderMesh.IsGeometryInverted ? RasterizerStateForInvertedGeometry : RasterizerState; renderMesh.UpdateMaterial(); var list = renderMesh.HasTransparency ? transparentList : opaqueList; list.Add(new RenderItem(this, renderMesh, projectedZ)); } }
/// <summary> /// Applies PerDraw lighting parameters. /// </summary> /// <param name="context"></param> /// <param name="viewIndex"></param> /// <param name="parameters"></param> /// <param name="boundingBox"></param> public virtual void ApplyDrawParameters(FastListStruct <LightDynamicEntry>?lightList, RenderDrawContext context, int viewIndex, ParameterCollection parameters, ref BoundingBoxExt boundingBox) { }
public LightShaderPermutationEntry() { DirectLightGroups = new FastListStruct<LightShaderGroup>(8); EnvironmentLights = new FastListStruct<LightShaderGroup>(8); PermutationLightGroups = new FastListStruct<LightShaderGroup>(2); DirectLightShaders = new ShaderSourceCollection(); EnvironmentLightShaders = new ShaderSourceCollection(); }
/// <summary> /// Fills the parameter collections used by this instance. /// </summary> /// <param name="parameterCollections">The parameter collections.</param> public abstract void FillParameterCollections(ref FastListStruct <ParameterCollection> parameterCollections);
public override void FillParameterCollections(ref FastListStruct<ParameterCollection> parameterCollections) { var material = Material; if (material != null && material.Parameters != null) { parameterCollections.Add(material.Parameters); } if (RenderModel.ModelComponent.Parameters != null) { parameterCollections.Add(RenderModel.ModelComponent.Parameters); } // TODO: Should we add RenderMesh.Parameters before ModelComponent.Parameters to allow user overiddes at component level? parameterCollections.Add(parameters); }
public override void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { var boundingBox2 = (BoundingBox)boundingBox; bool shadowMapCreated = false; int lightIndex = 0; for (int i = 0; i < currentLights.Count; ++i) { var lightEntry = currentLights[i]; if (lightEntry.Light.BoundingBox.Intersects(ref boundingBox2)) { var shaderData = (ShaderData)lightEntry.ShadowMapTexture.ShaderData; // Copy per-face data for (int j = 0; j < 6; j++) { worldToShadow[lightIndex * 6 + j] = shaderData.WorldToShadow[j]; inverseWorldToShadow[lightIndex * 6 + j] = Matrix.Invert(shaderData.WorldToShadow[j]); } depthBiases[lightIndex] = shaderData.DepthBias; offsetScales[lightIndex] = shaderData.OffsetScale; depthParameters[lightIndex] = shaderData.DepthParameters; lightIndex++; // TODO: should be setup just once at creation time if (!shadowMapCreated) { shadowMapTexture = shaderData.Texture; if (shadowMapTexture != null) { shadowMapTextureSize = new Vector2(shadowMapTexture.Width, shadowMapTexture.Height); shadowMapTextureTexelSize = 1.0f / shadowMapTextureSize; } shadowMapCreated = true; } } } parameters.Set(shadowMapTextureKey, shadowMapTexture); parameters.Set(shadowMapTextureSizeKey, shadowMapTextureSize); parameters.Set(shadowMapTextureTexelSizeKey, shadowMapTextureTexelSize); parameters.Set(worldToShadowKey, worldToShadow); parameters.Set(inverseWorldToShadowKey, inverseWorldToShadow); parameters.Set(depthParametersKey, depthParameters); parameters.Set(depthBiasesKey, depthBiases); parameters.Set(offsetScalesKey, offsetScales); }
public void ApplyDrawParameters(RenderDrawContext context, ParameterCollection parameters, FastListStruct <LightDynamicEntry> currentLights, ref BoundingBoxExt boundingBox) { var boundingBoxCasted = (BoundingBox)boundingBox; int lightIndex = 0; for (int i = 0; i < currentLights.Count; ++i) { var lightEntry = currentLights[i]; var light = lightEntry.Light; if (light.BoundingBox.Intersects(ref boundingBoxCasted)) { var spotLight = (LightSpot)light.Type; /* * // TODO: Just save the shaderdata struct directly within "LightDynamicEntry"? * var singleLightData = (LightSpotTextureProjectionShaderData)lightEntry.ShadowMapTexture.ShaderData; // TODO: This must not depend on the shadow map texture! * * worldToTextureUV[lightIndex] = singleLightData.WorldToTextureUV; * projectionTextureMipMapLevels[lightIndex] = singleLightData.ProjectiveTextureMipMapLevel; * projectiveTexture = singleLightData.ProjectiveTexture; */ // TODO: Move this to "Collect()" and use "LightSpotTextureProjectionShaderData", but IDK how! worldToTextureUV[lightIndex] = ComputeWorldToTextureUVMatrix(light); projectorPlaneMatrices[lightIndex] = ComputeProjectorPlaneMatrix(light); // We use the maximum number of mips instead of the actual number, // so things like video textures behave more consistently when changing the number of mip maps to generate. int maxMipMapCount = Texture.CountMips(lightParameters.ProjectionTexture.Width, lightParameters.ProjectionTexture.Height); float projectiveTextureMipMapLevel = (float)(maxMipMapCount - 1) * spotLight.MipMapScale; // "- 1" because the lowest mip level is 0, not 1. projectionTextureMipMapLevels[lightIndex] = projectiveTextureMipMapLevel; transitionAreas[lightIndex] = Math.Max(spotLight.TransitionArea, 0.001f); // Keep the value just above zero. This is to prevent some issues with the "smoothstep()" function on OpenGL and OpenGL ES. ++lightIndex; } } // TODO: Why is this set if it's already in the collection? // TODO: Does this get set once per group or something? parameters.Set(projectiveTextureKey, lightParameters.ProjectionTexture); parameters.Set(uvScale, lightParameters.UVScale); parameters.Set(uvOffset, lightParameters.UVOffset); parameters.Set(worldToProjectiveTextureUVsKey, worldToTextureUV); parameters.Set(projectorPlaneMatricesKey, projectorPlaneMatrices); parameters.Set(projectionTextureMipMapLevelsKey, projectionTextureMipMapLevels); parameters.Set(transitionAreasKey, transitionAreas); }
public void GlobalSetup() { lightNodes = new FastListStruct <LightClusterLinkedNode>(30 * 17 * 8); lightNodes2 = new FastListStruct <Vector3>(30 * 17 * 8); }