我们在设计和开发3D的时候最常用的就是灯光,它有的时候比摄像机还要重要,一些花哨漂亮的表现主要通过灯光实现,相比场景中只有一个的主要摄像机以外,灯光的类型和内容更加丰富,今天暂用小段时间一起研究一下Silverlight3D当中的灯光。下图是具体实现的预览效果:
在开始之前,需要了解一下基本的灯光类型,Balder3D里有三种灯光类型,分别是Omnilight、VIEwlight、Directionallight,如果玩过3Dmax的朋友应该是相当的熟悉,这些光的表现形式组合构成了游戏世界的绚丽多彩,没有光的世界大家可以通过最后程序实验一下,看看会如何呢。
Omnilight:也称泛光灯或者点光,比较清楚理解,它就是一个点发出的光源
VIEwlight:有了方向和目标,除了这个方向方位之内的都不会被照亮
Directionallight:是方向光,它是一个方向的照亮
具体内容可以参考下面的图片说明来理解他们,图片截取自3DMAX,资源来源于网络。
有一个好看的灯光,固然重要,但是我们要先学会如何控制它们,今次的代码比较多,涉及到了界面的 *** 作,我将Lesson05代码全部贴上,我的建议还是下载源文件看比较好一些:)
首先新建Lesson05这个控件,XAML代码如下:(下述代码使用Blend工具制作生成)
Lesson05.xaml<UserControl x:Class="Balder_Studio.Lesson05" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/Expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWIDth="400"> <GrID Background="White"> <GrID x:name="LayoutRoot"/> <StackPanel HorizontalAlignment="left" OrIEntation="Vertical" VerticalAlignment="top" WIDth="199" Height="132"> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" Text="X轴" WIDth="38" Height="14"/> <SlIDer Height="23" x:name="slIDer_axis_x" SmallChange="1" Maximum="100" LargeChange="10" margin="0" WIDth="100" Minimum="-100" /> <TextBlock x:name="axis_x" textwrapPing="Wrap" WIDth="38" Height="14" Text="0"/> </StackPanel> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" WIDth="38" Height="14"><Run Text="Y"/><Run Text="轴"/></TextBlock> <SlIDer Height="23" x:name="slIDer_axis_y" SmallChange="1" Maximum="100" LargeChange="10" margin="0" WIDth="100" Minimum="-100" /> <TextBlock x:name="axis_y" textwrapPing="Wrap" WIDth="38" Height="14" Text="0"/> </StackPanel> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" WIDth="38" Height="14"><Run Text="Z"/><Run Text="轴"/></TextBlock> <SlIDer Height="23" x:name="slIDer_axis_z" SmallChange="1" Maximum="100" LargeChange="10" margin="0" WIDth="100" Minimum="-100" /> <TextBlock x:name="axis_z" textwrapPing="Wrap" WIDth="38" Height="14" Text="0"/> </StackPanel> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" WIDth="38" Height="14" Text="亮度"/> <SlIDer Height="23" x:name="slIDer_Strength" Maximum="2" LargeChange="0.1" margin="0" WIDth="100" Value="1" /> <TextBlock x:name="StrengthText" WIDth="38" Height="14" Text="1"/> </StackPanel> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" WIDth="38" Height="14" Text="类型"/> <ComboBox x:name="lightType" WIDth="98"/> </StackPanel> </StackPanel> <StackPanel x:name="lightExSetting" HorizontalAlignment="left" OrIEntation="Vertical" VerticalAlignment="top" WIDth="199" Height="132" margin="198,-2,0" Visibility="Collapsed"> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" Text="偏移/方向X" WIDth="64" Height="14"/> <SlIDer Height="23" x:name="slIDer_axis_x1" SmallChange="1" Maximum="100" LargeChange="10" margin="0" WIDth="100" Minimum="-100" /> <TextBlock x:name="axis_x1" textwrapPing="Wrap" WIDth="38" Height="14" Text="0"/> </StackPanel> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" WIDth="64" Height="14"><Run Text="偏移/方向"/><Run Text="Y"/></TextBlock> <SlIDer Height="23" x:name="slIDer_axis_y1" SmallChange="1" Maximum="100" LargeChange="10" margin="0" WIDth="100" Minimum="-100" /> <TextBlock x:name="axis_y1" textwrapPing="Wrap" WIDth="38" Height="14" Text="0"/> </StackPanel> <StackPanel OrIEntation="Horizontal"> <TextBlock textwrapPing="Wrap" WIDth="64" Height="14"><Run FontFamily="Verdana, Arial, Arial Unicode MS, LucIDa Sans Unicode, LucIDa Grande" Text="偏移/方向"/><Run FontFamily="Verdana, LucIDa Grande" Text="Z"/></TextBlock> <SlIDer Height="23" x:name="slIDer_axis_z1" SmallChange="1" Maximum="100" LargeChange="10" margin="0" WIDth="100" Minimum="-100" /> <TextBlock x:name="axis_z1" textwrapPing="Wrap" WIDth="38" Height="14" Text="0"/> </StackPanel> <StackPanel OrIEntation="Horizontal" Visibility="Collapsed"> <TextBlock textwrapPing="Wrap" WIDth="38" Height="14" Text="亮度"/> <SlIDer Height="23" x:name="slIDer_Strength1" Maximum="1" LargeChange="0.1" margin="0" WIDth="100" Value="1" /> <TextBlock x:name="StrengthText1" WIDth="38" Height="14" Text="1"/> </StackPanel> </StackPanel> </GrID> </UserControl>Lesson05.xaml.cs代码如下,具体实现请参照 Lesson04的讲述
Lesson05.xaml.cs using System; using System.windows.Threading; using System.windows.Controls; using System.windows.Media; using Balder.Math; using Balder.Objects.GeometrIEs; using Balder.VIEw; using Balder.lighting; using Balder.Execution; namespace Balder_Studio { public partial class Lesson05 : UserControl { //选择的灯光 light _Selectedlight = null; public Lesson05() { InitializeComponent(); slIDer_axis_x.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_axis_ValueChanged); slIDer_axis_y.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_axis_ValueChanged); slIDer_axis_z.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_axis_ValueChanged); slIDer_Strength.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_axis_ValueChanged); slIDer_axis_x1.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_Offset_ValueChanged); slIDer_axis_y1.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_Offset_ValueChanged); slIDer_axis_z1.ValueChanged += new System.windows.RoutedPropertyChangedEventHandler<double>(slIDer_Offset_ValueChanged); Omnilight _Omnilight = new Omnilight(); VIEwlight _VIEwlight = new VIEwlight(); Directionallight _Directionallight = new Directionallight() {Direction=new Coordinate(-1,-1,0) }; //设定在同一个默认位置 _Omnilight.position = _VIEwlight.position = _Directionallight.position = new Coordinate(0, 0, 0); //最开始的时候都不会亮 _Omnilight.IsEnabled = _VIEwlight.IsEnabled = _Directionallight.IsEnabled = false; lightType.Items.Add(new TextBlock() { Text = "点光源", Tag = _Omnilight }); lightType.Items.Add(new TextBlock() { Text = "聚光源", Tag = _VIEwlight }); lightType.Items.Add(new TextBlock() { Text = "方向光", Tag = _Directionallight }); lightType.Selectedindex = 0; lightType.SelectionChanged += new SelectionChangedEventHandler(lightType_SelectionChanged); #region L1 - L4的代码 //L1 Game game = new Game() { WIDth = 600, Height = 400 }; game.Camera = new Camera(); game.Camera.position = new Coordinate(100, 120, 150); game.Camera.Target = new Coordinate(0, 0); #endregion game.Children.Add(_Omnilight); _Omnilight.IsEnabled = true; _Selectedlight = _Omnilight; game.Children.Add(_VIEwlight); game.Children.Add(_Directionallight); #region L1 - L4的代码 //L3 Game_Axis axis_x = new Game_Axis(new Vertex(-300, 0), new Vertex(300, colors.Red); Game_Axis axis_y = new Game_Axis(new Vertex(0, -300, new Vertex(0, 300, colors.Blue); Game_Axis axis_z = new Game_Axis(new Vertex(0, -300), 300), colors.Green); //L4 Balder.Objects.GeometrIEs.Geometry group = new Balder.Objects.GeometrIEs.Geometry() { name = "MeshGroup" }; group.InteractionEnabled = true; group.Children.Add(axis_x); group.Children.Add(axis_y); group.Children.Add(axis_z); //L2 Mesh Teapot = new Mesh(); Teapot.position = new Coordinate(0, 0); Teapot.Assetname = new Uri("/Balder_Studio;component/Res/teapot.ase", UriKind.relative); //L4 group.Children.Add(Teapot); group.Children.Add(new Box() { Dimension = new Coordinate(10, 20, 30), position = new Coordinate(100, 10, name = "MyBox" }); group.Children.Add(new Box() { Dimension = new Coordinate(10, 30, 10), position = new Coordinate(10, -100) }); game.Children.Add(group); LayoutRoot.Children.Add(game); #endregion } #region 控制灯光的界面事件 voID lightType_SelectionChanged(object sender, SelectionChangedEventArgs e) { //选择一个新的光源之时 if (_Selectedlight != null) _Selectedlight.IsEnabled = false; _Selectedlight = ((lightType.SelectedItem as TextBlock).Tag as light); _Selectedlight.IsEnabled = true; if (_Selectedlight is Omnilight) lightExSetting.Visibility = System.windows.Visibility.Collapsed; else lightExSetting.Visibility = System.windows.Visibility.Visible; } voID slIDer_axis_ValueChanged(object sender, System.windows.RoutedPropertyChangedEventArgs<double> e) { axis_z.Text = ((int)slIDer_axis_z.Value).ToString(); _Selectedlight.position.Z = slIDer_axis_z.Value; axis_y.Text = ((int)slIDer_axis_y.Value).ToString(); _Selectedlight.position.Y = slIDer_axis_y.Value; axis_x.Text = ((int)slIDer_axis_x.Value).ToString(); _Selectedlight.position.X = slIDer_axis_x.Value; StrengthText.Text = slIDer_Strength.Value.ToString(); _Selectedlight.Strength = slIDer_Strength.Value; } voID slIDer_Offset_ValueChanged(object sender, System.windows.RoutedPropertyChangedEventArgs<double> e) { axis_z1.Text = ((int)slIDer_axis_z1.Value).ToString(); axis_y1.Text = ((int)slIDer_axis_y1.Value).ToString(); axis_x1.Text = ((int)slIDer_axis_x1.Value).ToString(); if (_Selectedlight is VIEwlight) { var l = _Selectedlight as VIEwlight; l.XAngleOffset = slIDer_axis_x1.Value; l.YAngleOffset = slIDer_axis_y1.Value; l.ZAngleOffset = slIDer_axis_z1.Value; } else { var l = _Selectedlight as Directionallight; var X = slIDer_axis_x1.Value / slIDer_axis_x1.Maximum; var Y = slIDer_axis_y1.Value / slIDer_axis_y1.Maximum; var Z = slIDer_axis_z1.Value / slIDer_axis_z1.Maximum; l.Direction = new Coordinate(X, Y, Z); } } #endregion } }
我在其中加入了一些注释,希望有用:)细心的朋友可能会发现,这次没有讲解有关灯光颜色的问题,下次我专门写一篇有关颜色的部分,这样看起来更加直观,期望各位能够对Silverlight3D产生一些兴趣,加入这个开发方向上来。
好吧下一步让我们看看运行效果,同时附送本文章的源代码点击这里下载。
工程中如果缺少Balder.dll请在这里快速下载:SL4_Balder.rar
总结以上是内存溢出为你收集整理的Silverlight C# 游戏开发:L5 3D基本的灯光全部内容,希望文章能够帮你解决Silverlight C# 游戏开发:L5 3D基本的灯光所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)