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

我们在设计和开发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,0,-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, Arial, Arial Unicode MS, Lucida Sans Unicode, 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, 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, 0), new Vertex(300, 0, 0), Colors.Red);
            Game_Axis axis_y = new Game_Axis(new Vertex(0, -300, 0), new Vertex(0, 300, 0), Colors.Blue);
            Game_Axis axis_z = new Game_Axis(new Vertex(0, 0, -300), new Vertex(0, 0, 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, 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, 0), Name = "MyBox" });
            group.Children.Add(new Box() { Dimension = new Coordinate(10, 30, 10), Position = new Coordinate(10, 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游戏开发博客:深蓝色右手

posted on 2010-11-24 13:05 nowpaper 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/nowpaper/archive/2010/11/24/1886439.html

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

  1. Silverlight C# 游戏开发:L2 自定义模型导入

    Balder的Geometries里提供了很多的已有的模型,比如立方体.圆柱等等,但是我们在开发游戏的时候大多情况下都是使用3D设计工具制作自定义的3D模型,而本篇则介绍的是如何导入显示一个自定义的3 ...

  2. Silverlight C# 游戏开发:Silverlight开发环境

    Silverlight C# 游戏开发:Silverlight开发环境 所谓工欲善其事必先利其器,没有好的工具也没有办法做事,我以前曾经想学习C++以外的程序语言,当时有java和C#来选择,当时考虑 ...

  3. Silverlight C# 游戏开发:方向键的组合,八方向实现

    Silverlight C# 游戏开发:方向键的组合,八方向实现 在游戏中,有一种情况是斜向移动,就是同时按下两个方向,形成斜线操作,在Win32GDI开发中,可以通过在逻辑循环里加入键盘状态判断取得 ...

  4. Silverlight C# 游戏开发:资源的处理,图像算法(二)

    Silverlight C# 游戏开发:资源的处理,图像算法(二) 也许说,图像算法很过时,那是许久以前的做法,可是作为Silverlight来说,我认为非常有用,这些有趣的处理就像是在Web上实现了 ...

  5. Silverlight C# 游戏开发:面向对象在游戏中的实例(一)

    本系列所有代码都是使用Microsoft Visual Studio 2008开发,为基于Silverlight的游戏开发技术,如果您看完之后觉得不错,回复顶一下,万分感激:) 今天,我将带来一个非常 ...

  6. Silverlight C# 游戏开发:关于精灵for Silverlight容器

    Silverlight C# 游戏开发:关于精灵for Silverlight容器 说明:素材来源于网络,版权归版权所有人所有 游戏中的精灵非常常用,spirit这个小玩意具体谁发明的不得而知,从游戏 ...

  7. Silverlight C# 游戏开发:Flyer06小小的改进让游戏更有趣

    Silverlight C# 游戏开发:Flyer06小小的改进让游戏更有趣 今天这套主题,仅仅是通过改进让游戏更加有趣,游戏中的细节永远是耐人寻味,有的游戏团队为此付诸努力甚至成为整个项目的成功关键 ...

  8. 3D Math Primer for Graphics and Game Development -- 图形与游戏开发(3D数学基础) (简介)...

    3D Math Primer for Graphics and Game Development //z 2014-04-28 13:18:20 L.247'38500 BG57IV3@XCL T20 ...

  9. Silverlight C# 游戏开发:项目开发实例和小技巧索引

    Silverlight C# 游戏开发:项目开发实例和小技巧索引 相比于技术文章而言,本索引中包含的都是独立的项目,争取按照每个独立的项目开发来编写系列,全部为原创,开发过程可能语无伦次,可能相当幼稚 ...

最新文章

  1. outlook qr码在哪里_明日方舟兑换码在哪里输入 附1200合成玉兑换码
  2. 梯度下降(BGD)、随机梯度下降(SGD)、Mini-batch Gradient Descent、带Mini-batch的SGD
  3. SQL Server数据库表锁定原理以及如何解除表的锁定转
  4. Postgis常用函数
  5. java try finally connectoin close_Java I/O流详解
  6. 人脸检测的harr检测函数
  7. PAT_B_1057_Java(20分)
  8. 了解下广告计费模式CPC、CPA和CPM
  9. 买彩票,也要了解一些数学知识
  10. Delphi窗体部分属性
  11. labeltool标注工具使用说明
  12. rk3399 rt5640 录音调试记录
  13. 校园网认证破解教程(某数字科技学院)
  14. 使用Python+百度AI把文字转成语音
  15. 串联滞后校正网络的作用_以下关于串联滞后校正的描述正确的是( )。
  16. 邓凡平WIFI学习笔记1:netd
  17. 基于stm32的减速直流电机PID算法控制
  18. 院士大牛们一年N篇7点以上SCI的诀窍
  19. 常用的PostMethod及getMethod请求
  20. 在线纯音听力测试软件,纯音听力测试

热门文章

  1. Unable to instantiate default tuplizer
  2. 使用消息中间件时,如何保证消息不丢失且仅仅被消费一次
  3. 使用com.alibaba.fastjson.JSONObject构造简单的JSON数据
  4. MyBatis多表查询(一对一,一对多,多对多)
  5. PostgreSQL常用SQL
  6. Exploit开发系列教程-Exploitme2 (Stack cookies SEH)
  7. 实战HTML5与CSS3 第一篇】初探水深,美丽的导航,绚丽的图片爆炸!!
  8. Linux下第一次使用MySQL数据库,设置密码
  9. D3.js以及通用JS(JavaScript)读取并解析server端JSON的注意事项
  10. 运用大数据助力大发展