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 阅读次数:8552
