Silverlight C# 游戏开发:L5 3D基本的灯光

简介:

我们在设计和开发3D的时候最常用的就是灯光,它有的时候比摄像机还要重要,一些花哨漂亮的表现主要通过灯光实现,相比场景中只有一个的主要摄像机以外,灯光的类型和内容更加丰富,今天暂用小段时间一起研究一下Silverlight3D当中的灯光。下图是具体实现的预览效果:

在开始之前,需要了解一下基本的灯光类型,Balder3D里有三种灯光类型,分别是OmniLight、ViewLight、DirectionalLight,如果玩过3Dmax的朋友应该是相当的熟悉,这些光的表现形式组合构成了游戏世界的绚丽多彩,没有光的世界大家可以通过最后程序实验一下,看看会如何呢。

OmniLight:也称泛光灯或者点光,比较清楚理解,它就是一个点发出的光源

ViewLight:有了方向和目标,除了这个方向方位之内的都不会被照亮

DirectionalLight:是方向光,它是一个方向的照亮

具体内容可以参考下面的图片说明来理解他们,图片截取自3DMAX,资源来源于网络。

 

有一个好看的灯光,固然重要,但是我们要先学会如何控制它们,今次的代码比较多,涉及到了界面的操作,我将Lesson05代码全部贴上,我的建议还是下载源文件看比较好一些:)

首先新建Lesson05这个控件,XAML代码如下:(下述代码使用Blend工具制作生成)

Lesson05.xaml
 
 
  1. <UserControl x:Class="Balder_Studio.Lesson05" 
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  6. mc:Ignorable="d" 
  7. d:DesignHeight="300" d:DesignWidth="400"> 
  8.  
  9. <Grid Background="White"> 
  10. <Grid x:Name="LayoutRoot"/> 
  11. <StackPanel HorizontalAlignment="Left" Orientation="Vertical" VerticalAlignment="Top" Width="199" Height="132"> 
  12. <StackPanel Orientation="Horizontal"> 
  13. <TextBlock TextWrapping="Wrap" Text="X轴" Width="38" Height="14"/> 
  14. <Slider Height="23" x:Name="slider_axis_x" SmallChange="1" Maximum="100" LargeChange="10" Margin="0" Width="100" Minimum="-100" /> 
  15. <TextBlock x:Name="axis_x" TextWrapping="Wrap" Width="38" Height="14" Text="0"/> 
  16. </StackPanel> 
  17. <StackPanel Orientation="Horizontal"> 
  18. <TextBlock TextWrapping="Wrap" Width="38" Height="14"><Run Text="Y"/><Run Text="轴"/></TextBlock> 
  19. <Slider Height="23" x:Name="slider_axis_y" SmallChange="1" Maximum="100" LargeChange="10" Margin="0" Width="100" Minimum="-100" /> 
  20. <TextBlock x:Name="axis_y" TextWrapping="Wrap" Width="38" Height="14" Text="0"/> 
  21. </StackPanel> 
  22. <StackPanel Orientation="Horizontal"> 
  23. <TextBlock TextWrapping="Wrap" Width="38" Height="14"><Run Text="Z"/><Run Text="轴"/></TextBlock> 
  24. <Slider Height="23" x:Name="slider_axis_z" SmallChange="1" Maximum="100" LargeChange="10" Margin="0" Width="100" Minimum="-100" /> 
  25. <TextBlock x:Name="axis_z" TextWrapping="Wrap" Width="38" Height="14" Text="0"/> 
  26. </StackPanel> 
  27. <StackPanel Orientation="Horizontal"> 
  28. <TextBlock TextWrapping="Wrap" Width="38" Height="14" Text="亮度"/> 
  29. <Slider Height="23" x:Name="slider_Strength" Maximum="2" LargeChange="0.1" Margin="0" Width="100" Value="1" /> 
  30. <TextBlock x:Name="StrengthText" Width="38" Height="14" Text="1"/> 
  31. </StackPanel> 
  32. <StackPanel Orientation="Horizontal"> 
  33. <TextBlock TextWrapping="Wrap" Width="38" Height="14" Text="类型"/> 
  34. <ComboBox x:Name="LightType" Width="98"/> 
  35. </StackPanel> 
  36. </StackPanel> 
  37. <StackPanel x:Name="LightExSetting" HorizontalAlignment="Left" Orientation="Vertical" VerticalAlignment="Top" Width="199" Height="132" Margin="198,0,-2,0" Visibility="Collapsed"> 
  38. <StackPanel Orientation="Horizontal"> 
  39. <TextBlock TextWrapping="Wrap" Text="偏移/方向X" Width="64" Height="14"/> 
  40. <Slider Height="23" x:Name="slider_axis_x1" SmallChange="1" Maximum="100" LargeChange="10" Margin="0" Width="100" Minimum="-100" /> 
  41. <TextBlock x:Name="axis_x1" TextWrapping="Wrap" Width="38" Height="14" Text="0"/> 
  42. </StackPanel> 
  43. <StackPanel Orientation="Horizontal"> 
  44. <TextBlock TextWrapping="Wrap" Width="64" Height="14"><Run Text="偏移/方向"/><Run Text="Y"/></TextBlock> 
  45. <Slider Height="23" x:Name="slider_axis_y1" SmallChange="1" Maximum="100" LargeChange="10" Margin="0" Width="100" Minimum="-100" /> 
  46. <TextBlock x:Name="axis_y1" TextWrapping="Wrap" Width="38" Height="14" Text="0"/> 
  47. </StackPanel> 
  48. <StackPanel Orientation="Horizontal"> 
  49. <TextBlock TextWrapping="Wrap" Width="64" Height="14"><Run FontFamily="Verdana, Arial, Arial Unicode MS, Lucida Sans Unicode, Lucida Grande" Text="偏移/方向"/><Run FontFamily="Verdana, Arial, Arial Unicode MS, Lucida Sans Unicode, Lucida Grande" Text="Z"/></TextBlock> 
  50. <Slider Height="23" x:Name="slider_axis_z1" SmallChange="1" Maximum="100" LargeChange="10" Margin="0" Width="100" Minimum="-100" /> 
  51. <TextBlock x:Name="axis_z1" TextWrapping="Wrap" Width="38" Height="14" Text="0"/> 
  52. </StackPanel> 
  53. <StackPanel Orientation="Horizontal" Visibility="Collapsed"> 
  54. <TextBlock TextWrapping="Wrap" Width="38" Height="14" Text="亮度"/> 
  55. <Slider Height="23" x:Name="slider_Strength1" Maximum="1" LargeChange="0.1" Margin="0" Width="100" Value="1" /> 
  56. <TextBlock x:Name="StrengthText1" Width="38" Height="14" Text="1"/> 
  57. </StackPanel> 
  58. </StackPanel> 
  59. </Grid> 
  60. </UserControl> 
  61.    
  62.  
Lesson05.xaml.cs代码如下,具体实现请参照 Lesson04的讲述
 
  1. Lesson05.xaml.cs   
  2. using System;  
  3. using System.Windows.Threading;  
  4. using System.Windows.Controls;  
  5. using System.Windows.Media;  
  6. using Balder.Math;  
  7. using Balder.Objects.Geometries;  
  8. using Balder.View;  
  9. using Balder.Lighting;  
  10. using Balder.Execution;  
  11.  
  12. namespace Balder_Studio  
  13. {  
  14. public partial class Lesson05 : UserControl  
  15. {  
  16. //选择的灯光  
  17. Light _SelectedLight = null;  
  18. public Lesson05()  
  19. {  
  20. InitializeComponent();   
  21. slider_axis_x.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);  
  22. slider_axis_y.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);  
  23. slider_axis_z.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);  
  24. slider_Strength.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);  
  25.  
  26. slider_axis_x1.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Offset_ValueChanged);  
  27. slider_axis_y1.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Offset_ValueChanged);  
  28. slider_axis_z1.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Offset_ValueChanged);  
  29.  
  30.  
  31. OmniLight _OmniLight = new OmniLight();  
  32. ViewLight _ViewLight = new ViewLight();  
  33. DirectionalLight _DirectionalLight = new DirectionalLight() {Direction=new Coordinate(-1,-1,0) };  
  34. //设定在同一个默认位置  
  35. _OmniLight.Position = _ViewLight.Position = _DirectionalLight.Position = new Coordinate(0, 0, 0);  
  36. //最开始的时候都不会亮  
  37. _OmniLight.IsEnabled = _ViewLight.IsEnabled = _DirectionalLight.IsEnabled = false;  
  38.  
  39. LightType.Items.Add(new TextBlock() { Text = "点光源"Tag = _OmniLight });  
  40. LightType.Items.Add(new TextBlock() { Text = "聚光源"Tag = _ViewLight });  
  41. LightType.Items.Add(new TextBlock() { Text = "方向光"Tag = _DirectionalLight });  
  42. LightType.SelectedIndex = 0;  
  43. LightType.SelectionChanged += new SelectionChangedEventHandler(LightType_SelectionChanged);  
  44.  
  45. #region L1 - L4的代码  
  46. //L1  
  47. Game game = new Game() { Width = 600Height = 400 };  
  48. game.Camera = new Camera();  
  49. game.Camera.Position = new Coordinate(100, 120, 150);  
  50. game.Camera.Target = new Coordinate(0, 0, 0);  
  51. #endregion  
  52. game.Children.Add(_OmniLight);  
  53. _OmniLight.IsEnabled = true;  
  54. _SelectedLight = _OmniLight;  
  55. game.Children.Add(_ViewLight);  
  56. game.Children.Add(_DirectionalLight);  
  57. #region L1 - L4的代码  
  58. //L3  
  59. Game_Axis axis_x = new Game_Axis(new Vertex(-300, 0, 0), new Vertex(300, 0, 0), Colors.Red);  
  60. Game_Axis axis_y = new Game_Axis(new Vertex(0, -300, 0), new Vertex(0, 300, 0), Colors.Blue);  
  61. Game_Axis axis_z = new Game_Axis(new Vertex(0, 0, -300), new Vertex(0, 0, 300), Colors.Green);  
  62. //L4  
  63. Balder.Objects.Geometries.Geometry group = new Balder.Objects.Geometries.Geometry() { Name = "MeshGroup" };  
  64. group.InteractionEnabled = true;  
  65. group.Children.Add(axis_x);  
  66. group.Children.Add(axis_y);  
  67. group.Children.Add(axis_z);  
  68. //L2  
  69. Mesh Teapot = new Mesh();  
  70. Teapot.Position = new Coordinate(0, 0, 0);  
  71.  
  72. Teapot.AssetName = new Uri("/Balder_Studio;component/Res/teapot.ase", UriKind.Relative);  
  73. //L4  
  74. group.Children.Add(Teapot);  
  75. group.Children.Add(new Box() { Dimension = new Coordinate(10, 20, 30), Position = new Coordinate(100, 10, 0), Name = "MyBox" });  
  76. group.Children.Add(new Box() { Dimension = new Coordinate(10, 30, 10), Position = new Coordinate(10, 10, -100) });  
  77. game.Children.Add(group);  
  78.  
  79. LayoutRoot.Children.Add(game);  
  80. #endregion  
  81.  
  82. }  
  83. #region 控制灯光的界面事件  
  84. void LightType_SelectionChanged(object sender, SelectionChangedEventArgs e)  
  85. {  
  86. //选择一个新的光源之时  
  87. if (_SelectedLight != null)  
  88. _SelectedLight.IsEnabled = false;  
  89. _SelectedLight = ((LightType.SelectedItem as TextBlock).Tag as Light);  
  90. _SelectedLight.IsEnabled = true;  
  91. if (_SelectedLight is OmniLight)  
  92. LightExSetting.Visibility = System.Windows.Visibility.Collapsed;  
  93. else  
  94. LightExSetting.Visibility = System.Windows.Visibility.Visible;  
  95.  
  96. }  
  97.  
  98. void slider_axis_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)  
  99. {  
  100. axis_z.Text = ((int)slider_axis_z.Value).ToString();  
  101. _SelectedLight.Position.Z = slider_axis_z.Value;  
  102. axis_y.Text = ((int)slider_axis_y.Value).ToString();  
  103. _SelectedLight.Position.Y = slider_axis_y.Value;  
  104. axis_x.Text = ((int)slider_axis_x.Value).ToString();  
  105. _SelectedLight.Position.X = slider_axis_x.Value;  
  106. StrengthText.Text = slider_Strength.Value.ToString();  
  107. _SelectedLight.Strength = slider_Strength.Value;  
  108. }  
  109. void slider_Offset_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)  
  110. {  
  111. axis_z1.Text = ((int)slider_axis_z1.Value).ToString();   
  112. axis_y1.Text = ((int)slider_axis_y1.Value).ToString();   
  113. axis_x1.Text = ((int)slider_axis_x1.Value).ToString();  
  114.  
  115. if (_SelectedLight is ViewLight)  
  116. {  
  117. var l = _SelectedLight as ViewLight;  
  118. l.XAngleOffset = slider_axis_x1.Value;  
  119. l.YAngleOffset = slider_axis_y1.Value;  
  120. l.ZAngleOffset = slider_axis_z1.Value;  
  121. }  
  122. else  
  123. {  
  124. var l = _SelectedLight as DirectionalLight;  
  125. var X = slider_axis_x1.Value / slider_axis_x1.Maximum;  
  126. var Y = slider_axis_y1.Value / slider_axis_y1.Maximum;  
  127. var Z = slider_axis_z1.Value / slider_axis_z1.Maximum;  
  128. l.Direction = new Coordinate(X, Y, Z);  
  129. }  
  130. }  
  131.  
  132. #endregion  
  133. }  
  134. }  
  135.  
  136.    
  137.  

我在其中加入了一些注释,希望有用:)细心的朋友可能会发现,这次没有讲解有关灯光颜色的问题,下次我专门写一篇有关颜色的部分,这样看起来更加直观,期望各位能够对Silverlight3D产生一些兴趣,加入这个开发方向上来。

好吧下一步让我们看看运行效果,同时附送本文章的源代码点击这里下载。

工程中如果缺少Balder.dll请在这里快速下载:SL4_Balder.rar



本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/712291

相关文章
|
3月前
|
存储 开发框架 .NET
【C#】C# 基础语法与游戏开发
【1月更文挑战第21天】【C#】C# 基础语法与游戏开发
|
3月前
|
存储 开发框架 .NET
【C#】认识C# (为了游戏开发 O(≧口≦)O)
【1月更文挑战第26天】【C#】认识C# (为了游戏开发 O(≧口≦)O)
|
前端开发 C#
silverlight,WPF动画终极攻略之番外 3D切换导航篇(Blend 4开发)
原文:silverlight,WPF动画终极攻略之番外 3D切换导航篇(Blend 4开发) 这篇介绍的是3D导航,点击图标,页面360°翻转的效果!有什么不足的欢迎大家指出来。 1.新建一个usercontrol,命名为menu. 2.按照下图设置一下属性。
1219 0