private bool SearchShadingGroup(RenderMesh renderMesh, int index, string groupName, int typeOffset, List <LightingUpdateInfo> finalList) { var mesh = renderMesh.Mesh; var constantBuffers = renderMesh.Effect.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; mesh.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; mesh.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; mesh.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; mesh.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; mesh.Parameters.Set(info.ColorKey, new Color3[member.Count]); info.Count = member.Count; break; case LightParamSemantic.Intensity: info.IntensityKey = (ParameterKey <float[]>)member.Param.Key; mesh.Parameters.Set(info.IntensityKey, new float[member.Count]); info.Count = member.Count; break; case LightParamSemantic.Decay: info.DecayKey = (ParameterKey <float[]>)member.Param.Key; mesh.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; mesh.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; mesh.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 mesh = renderMesh.Mesh; 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) { mesh.Parameters.Set(info.DirectionKey, arrayVector3, 0, lightCount); } if ((info.Semantic & LightParamSemantic.PositionVS) != 0) { mesh.Parameters.Set(info.PositionKey, arrayVector3, maxLights, 0, lightCount); } if ((info.Semantic & LightParamSemantic.DirectionWS) != 0) { mesh.Parameters.Set(info.DirectionKey, arrayVector3, 0, lightCount); } if ((info.Semantic & LightParamSemantic.PositionWS) != 0) { mesh.Parameters.Set(info.PositionKey, arrayVector3, maxLights, 0, lightCount); } if ((info.Semantic & LightParamSemantic.ColorWithGamma) != 0) { mesh.Parameters.Set(info.ColorKey, arrayColor3, 0, lightCount); } if ((info.Semantic & LightParamSemantic.Intensity) != 0) { mesh.Parameters.Set(info.IntensityKey, arrayFloat, 0, lightCount); } if ((info.Semantic & LightParamSemantic.Decay) != 0) { mesh.Parameters.Set(info.DecayKey, arrayFloat, maxLights, 0, lightCount); } if ((info.Semantic & LightParamSemantic.SpotBeamAngle) != 0) { mesh.Parameters.Set(info.SpotBeamAngleKey, arrayFloat, 2 * maxLights, 0, lightCount); } if ((info.Semantic & LightParamSemantic.SpotFieldAngle) != 0) { mesh.Parameters.Set(info.SpotFieldAngleKey, arrayFloat, 3 * maxLights, 0, lightCount); } if ((info.Semantic & LightParamSemantic.Count) != 0) { mesh.Parameters.Set(info.LightCountKey, lightCount); } } else { if ((info.Semantic & LightParamSemantic.Count) != 0) { mesh.Parameters.Set(info.LightCountKey, 0); } } }