private bool SearchShadingGroup(RenderMesh renderMesh, int index, string groupName, int typeOffset, List <LightingUpdateInfo> finalList)
        {
            var constantBuffers = renderMesh.Effect.Bytecode.Reflection.ConstantBuffers;
            var info            = new LightingUpdateInfo();

            LightParamSemantic foundParameterSemantic;
            var foundParam     = false;
            var lightTypeGuess = LightTypeGuess.None;

            UpdateLightingParameterSemantics(index, groupName);

            foreach (var constantBuffer in constantBuffers)
            {
                foreach (var member in constantBuffer.Members)
                {
                    if (lightingParameterSemantics.TryGetValue(member.Param.Key, out foundParameterSemantic))
                    {
                        info.Semantic = info.Semantic | foundParameterSemantic;
                        foundParam    = true;
                        switch (foundParameterSemantic)
                        {
                        case LightParamSemantic.PositionVS:
                            info.PositionKey = (ParameterKey <Vector3[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.PositionKey, new Vector3[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Point;
                            break;

                        case LightParamSemantic.DirectionVS:
                            info.DirectionKey = (ParameterKey <Vector3[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.DirectionKey, new Vector3[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Directional;
                            break;

                        case LightParamSemantic.PositionWS:
                            info.PositionKey = (ParameterKey <Vector3[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.PositionKey, new Vector3[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Point;
                            break;

                        case LightParamSemantic.DirectionWS:
                            info.DirectionKey = (ParameterKey <Vector3[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.DirectionKey, new Vector3[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Directional;
                            break;

                        case LightParamSemantic.ColorWithGamma:
                            info.ColorKey = (ParameterKey <Color3[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.ColorKey, new Color3[member.Count]);
                            info.Count = member.Count;
                            break;

                        case LightParamSemantic.Intensity:
                            info.IntensityKey = (ParameterKey <float[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.IntensityKey, new float[member.Count]);
                            info.Count = member.Count;
                            break;

                        case LightParamSemantic.Decay:
                            info.DecayKey = (ParameterKey <float[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.DecayKey, new float[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Point;
                            break;

                        case LightParamSemantic.SpotBeamAngle:
                            info.SpotBeamAngleKey = (ParameterKey <float[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.SpotBeamAngleKey, new float[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Spot;
                            break;

                        case LightParamSemantic.SpotFieldAngle:
                            info.SpotFieldAngleKey = (ParameterKey <float[]>)member.Param.Key;
                            renderMesh.Parameters.Set(info.SpotFieldAngleKey, new float[member.Count]);
                            info.Count     = member.Count;
                            lightTypeGuess = lightTypeGuess | LightTypeGuess.Spot;
                            break;

                        case LightParamSemantic.Count:
                            info.LightCountKey = (ParameterKey <int>)member.Param.Key;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }
            }
            if (foundParam)
            {
                switch (lightTypeGuess)
                {
                case LightTypeGuess.Directional:
                    info.Type = LightingUpdateType.Directional + typeOffset;
                    break;

                case LightTypeGuess.Point:
                    info.Type = LightingUpdateType.Point + typeOffset;
                    break;

                case LightTypeGuess.Spot:
                    info.Type = LightingUpdateType.Spot + typeOffset;
                    break;
                }
                if (lightTypeGuess != LightTypeGuess.None)
                {
                    info.Index = index;
                    finalList.Add(info);
                }
            }
            return(foundParam);
        }
        private void UpdateLightingParameters(LightingUpdateInfo info, ref RenderMesh renderMesh, ref Matrix viewMatrix, List <EntityLightShadow> lightsForMesh)
        {
            var maxLights = info.Count;

            if (maxLights > 0)
            {
                Matrix  worldView;
                Vector3 lightDir;
                Vector3 lightPos;
                Vector3 direction;
                Vector3 position;
                var     lightCount = 0;
                foreach (var light in lightsForMesh)
                {
                    if ((info.Semantic & LightParamSemantic.PositionDirectionVS) != 0)
                    {
                        if ((info.Semantic & LightParamSemantic.DirectionVS) != 0)
                        {
                            Matrix.Multiply(ref light.Entity.Transformation.WorldMatrix, ref viewMatrix, out worldView);
                            lightDir = light.Light.LightDirection;
                            Vector3.TransformNormal(ref lightDir, ref worldView, out direction);
                            arrayVector3[lightCount] = direction;
                        }
                        if ((info.Semantic & LightParamSemantic.PositionVS) != 0)
                        {
                            lightPos = light.Entity.Transformation.Translation;
                            Vector3.TransformCoordinate(ref lightPos, ref viewMatrix, out position);
                            arrayVector3[lightCount + maxLights] = position;
                        }
                    }
                    else if ((info.Semantic & LightParamSemantic.PositionDirectionWS) != 0)
                    {
                        if ((info.Semantic & LightParamSemantic.DirectionWS) != 0)
                        {
                            lightDir = light.Light.LightDirection;
                            Vector3.TransformNormal(ref lightDir, ref light.Entity.Transformation.WorldMatrix, out direction);
                            arrayVector3[lightCount] = direction;
                        }
                        if ((info.Semantic & LightParamSemantic.PositionWS) != 0)
                        {
                            lightPos = light.Entity.Transformation.Translation;
                            arrayVector3[lightCount + maxLights] = lightPos;
                        }
                    }
                    if ((info.Semantic & LightParamSemantic.ColorWithGamma) != 0)
                    {
                        //color.R = (float)Math.Pow(light.Light.Color.R, 2.2);
                        //color.G = (float)Math.Pow(light.Light.Color.G, 2.2);
                        //color.B = (float)Math.Pow(light.Light.Color.B, 2.2);
                        //arrayColor3[lightCount] = color;
                        arrayColor3[lightCount] = light.Light.Color;
                    }
                    if ((info.Semantic & LightParamSemantic.Intensity) != 0)
                    {
                        arrayFloat[lightCount] = light.Light.Intensity;
                    }
                    if ((info.Semantic & LightParamSemantic.Decay) != 0)
                    {
                        arrayFloat[lightCount + maxLights] = light.Light.DecayStart;
                    }
                    if ((info.Semantic & LightParamSemantic.SpotBeamAngle) != 0)
                    {
                        arrayFloat[lightCount + 2 * maxLights] = (float)Math.Cos(Math.PI * light.Light.SpotBeamAngle / 180);
                    }
                    if ((info.Semantic & LightParamSemantic.SpotFieldAngle) != 0)
                    {
                        arrayFloat[lightCount + 3 * maxLights] = (float)Math.Cos(Math.PI * light.Light.SpotFieldAngle / 180);
                    }

                    ++lightCount;
                    if (lightCount >= maxLights)
                    {
                        break;
                    }
                }

                if ((info.Semantic & LightParamSemantic.DirectionVS) != 0)
                {
                    renderMesh.Parameters.Set(info.DirectionKey, arrayVector3, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.PositionVS) != 0)
                {
                    renderMesh.Parameters.Set(info.PositionKey, arrayVector3, maxLights, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.DirectionWS) != 0)
                {
                    renderMesh.Parameters.Set(info.DirectionKey, arrayVector3, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.PositionWS) != 0)
                {
                    renderMesh.Parameters.Set(info.PositionKey, arrayVector3, maxLights, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.ColorWithGamma) != 0)
                {
                    renderMesh.Parameters.Set(info.ColorKey, arrayColor3, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.Intensity) != 0)
                {
                    renderMesh.Parameters.Set(info.IntensityKey, arrayFloat, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.Decay) != 0)
                {
                    renderMesh.Parameters.Set(info.DecayKey, arrayFloat, maxLights, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.SpotBeamAngle) != 0)
                {
                    renderMesh.Parameters.Set(info.SpotBeamAngleKey, arrayFloat, 2 * maxLights, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.SpotFieldAngle) != 0)
                {
                    renderMesh.Parameters.Set(info.SpotFieldAngleKey, arrayFloat, 3 * maxLights, 0, lightCount);
                }
                if ((info.Semantic & LightParamSemantic.Count) != 0)
                {
                    renderMesh.Parameters.Set(info.LightCountKey, lightCount);
                }
            }
            else
            {
                if ((info.Semantic & LightParamSemantic.Count) != 0)
                {
                    renderMesh.Parameters.Set(info.LightCountKey, 0);
                }
            }
        }