Sliverlight3D Shader教程1——环境光照
这篇文章其实就是XNA Shader编程教程1-环境光照在silverlight上的实现,有了Silverlight 5 3D的帮助,代码只需稍作修改就可以实现浏览器上的Web 3D。其中的原理在XNA中已经解释得很清楚,所以文中只贴出相关代码,与Silverlight 5有关的知识可参见本网站的其他文章。
首先,从Silverlight Toolkit中的Silverlight 3d Application模板生成了一个默认项目,我命名为SL1_AmbientLight。然后移除项目中的VertexPositionColorNormal.cs,导入僵尸模型Object.x,将XNA Shader编程教程1-环境光照源代码项目中的Shader.fx的内容复制到此项目中的CustomEffect.slfx中,替换原有的内容。
将Cube.cs重命名为MyModel.cs,并对代码进行如下的修改:
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Silverlight3dApp { public class MyModel { #region 字段 readonly Scene scene; readonly GraphicsDevice graphicsDevice; readonly Model model; readonly SilverlightEffect effect; readonly SilverlightEffectParameter projectionParameter; readonly SilverlightEffectParameter viewParameter; readonly SilverlightEffectParameter worldParameter; readonly SilverlightEffectParameter ambientIntensityParameter; readonly SilverlightEffectParameter ambientColorParameter; #endregion #region 属性 public Matrix World { set{ worldParameter.SetValue(value);} } public Matrix Projection { set { projectionParameter.SetValue (value ); } } public Matrix View { set { viewParameter.SetValue(value); } } public float AmbientIntensity { set { ambientIntensityParameter.SetValue(value); } } public Vector4 AmbientColor { set { ambientColorParameter.SetValue(value); } } #endregion #region 初始化 public MyModel(Scene scene) { this.scene = scene; this.graphicsDevice = scene.GraphicsDevice; this.effect = scene.ContentManager.Load<silverlighteffect>("CustomEffect"); this.model = scene.ContentManager.Load<Model>("Object"); // 缓存effect参数 worldParameter = effect.Parameters["World"]; viewParameter = effect.Parameters["View"]; projectionParameter = effect.Parameters["Projection"]; ambientColorParameter = effect.Parameters["AmbientColor"]; ambientIntensityParameter = effect.Parameters["AmbientIntensity"]; } #endregion #region 方法 public void Draw() { foreach (var pass in effect.CurrentTechnique.Passes) { // Apply pass pass.Apply(); // 所用的僵尸模型只有一个,这个ModelMesh只有一个ModelMeshPart ModelMeshPart meshPart = model.Meshes[0].MeshParts[0]; // 设置顶点缓存和索引缓存 graphicsDevice.SetVertexBuffer(meshPart.VertexBuffer, meshPart.VertexOffset); graphicsDevice.Indices = meshPart.IndexBuffer; // 绘制模型 graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount); } } #endregion } }
将Scene.cs的代码修改为如下所示:
using System; using System.Windows.Controls; using System.Windows.Graphics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; namespace Silverlight3dApp { public class Scene : IDisposable { #region 字段 readonly DrawingSurface _drawingSurface; readonly ContentManager contentManager; readonly MyModel model; float aspectRatio; double rotateCamera = 0.0f; #endregion #region 属性 public ContentManager ContentManager { get { return contentManager; } } public GraphicsDevice GraphicsDevice { get { return GraphicsDeviceManager.Current.GraphicsDevice; } } #endregion #region 初始化 public Scene(DrawingSurface drawingSurface) { _drawingSurface = drawingSurface; // 注册控件大小改变的事件更新长宽比 _drawingSurface.SizeChanged += _drawingSurface_SizeChanged; // 获取content manager用于访问素材管道 contentManager = new ContentManager(null) { RootDirectory = "Content" }; // 初始化模型 model = new MyModel(this); model.AmbientIntensity = 1.0f; model.AmbientColor = new Vector4(0f,100f,0f,255f); model.World = Matrix.Identity; } #endregion #region 方法 void _drawingSurface_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e) { aspectRatio = (float)(_drawingSurface.ActualWidth / _drawingSurface.ActualHeight); } public void Draw() { // 清除后备缓存 GraphicsDeviceManager.Current.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(0.2f, 0.2f, 0.2f, 1.0f), 1.0f, 0); // 计算视矩阵和投影矩阵 rotateCamera += 30f / 1000.0; Matrix view = Matrix.CreateLookAt(new Vector3(5.0f * (float)Math.Cos(rotateCamera), 2, 5.0f * (float)Math.Sin(rotateCamera)), new Vector3(0, 2, 0), Vector3.Up); Matrix projection = Matrix.CreatePerspectiveFieldOfView(0.85f, aspectRatio, 0.01f, 1000.0f); // 更新shader中的矩阵变量 model.View = view; model.Projection = projection; // 绘制模型 model.Draw(); } public void Dispose() { _drawingSurface.SizeChanged -= _drawingSurface_SizeChanged; } #endregion } }
运行程序,得到的结果与XNA Shader编程教程1-环境光照是相同的。你可以对照两个程序的源代码,看看是如何进行移植的。
文件下载(已下载 2211 次)
发布时间:2012/8/20 下午11:20:49 阅读次数:7731