Silverlight C# 游戏开发:L8 材质和贴图

Silverlight C# 游戏开发:L8 材质和贴图,第1张

概述对于3D来说,主要的组成要素是:模型、灯光、摄像机,模型中的贴图部分不容忽视,贴图为模型带来生命力,在游戏开发当中非常重要,了解贴图的方式可以帮助我们作出,这一篇主要是说有关于贴图方面的内容。下面是今天的实例:   记得有一位朋友曾经说过,3D世界总会回归到2D当中,此话很有道理,无论我们怎么构建3D世界仍然还只是在面前的屏幕上显示,而这个就是典型的3D到2D,其实,我们都被欺骗了,所有看到的都不

对于3D来说,主要的组成要素是:模型、灯光、摄像机,模型中的贴图部分不容忽视,贴图为模型带来生命力,在游戏开发当中非常重要,了解贴图的方式可以帮助我们作出,这一篇主要是说有关于贴图方面的内容。下面是今天的实例:

 

记得有一位朋友曾经说过,3D世界总会回归到2D当中,此话很有道理,无论我们怎么构建3D世界仍然还只是在面前的屏幕上显示,而这个就是典型的3D到2D,其实,我们都被欺骗了,所有看到的都不是真正意义上的3D世界,是通过计算出来的结果,伟大的数学在这里发挥到了极致,就如Balder就是典型的通过计算的方式将3D控件渲染到Silverlight的平面上,只要对3D数学有一定的了解,都可以作出一个3D世界,说了这些有什么用呢?和贴图有很大的关系,大部分的开发者可能只是知道“贴”却对其原理一知半解,贴图的英文一般称之是Texture,贴图仅仅是另外一个子集下面的一个部分,而这个更大的集合是材质Material,要知道,世间万物并非仅仅只有纹理,它包含了诸如漫反射(diffuse)和反射(reflection)的属性,所以你仔细看某一个事物的时候,在不同的时空看到的结果不是一样。如果讨论3D世界,我想可能也非一时之事,今天咱们就之说说材质。

下面展示了一个3D世界中的典型材质赋予方式:

 

在Balder当中,Balder.Objects.GeometrIEs对象都带有Material属性,只要对这个属性进行设置即可。

  material = new Material();      Balder.Imaging.Image image = Runtime.Instance.ContentManager.Load<Balder.Imaging.Image>("/Balder_Studio;component/Res/map01.jpg");      material.DiffuseMap = new ImageMap(image) ;      material.DiffuseMapOpacity = 1;      material.Opacity = 1;      material.DoubleSIDed = true;                
上面的代码是创建一个基本的材质,然后从资源中读取一个贴图给Diffuse上,上次有位朋友问我如何在Balder中读取一个图片,其方式就是上面的方式,需要提醒的是,现在这种方法只能读取自身工程的文件,如果是外部的话,就会报错。

好吧,其实今天所有的核心就在上面的几行代码当中,下面仅仅是做了控制,现在我们弄一个UI控制界面,来 *** 作材质和贴图使我们更加直观。

 

为了方便起见,这次用上了属性绑定,界面的XAML如下:

  <UserControl         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"         xmlns:local="clr-namespace:Balder_Studio" x:Class="Balder_Studio.Lesson08"         mc:Ignorable="d"         d:DesignHeight="441" d:DesignWIDth="550">              <GrID>                      <GrID x:name="LayoutRoot" Background="White" d:IsLocked="True"/>             <StackPanel margin="12,8,0" HorizontalAlignment="left" Height="218" VerticalAlignment="top">                 <StackPanel margin="0" OrIEntation="Horizontal" Visibility="Collapsed">                     <TextBlock margin="0,9,0" FontSize="12" WIDth="118"><Run Text="贴图透明度"/></TextBlock>                     <SlIDer x:name="SlIDerOpacity" Value="1" WIDth="140" Maximum="1" LargeChange="0.2"/>                     <TextBlock x:name="TextValue" Text="{Binding Value, Elementname=SlIDerOpacity}" margin="0,0" FontSize="12" WIDth="71"/>                 </StackPanel>                 <StackPanel Height="28" OrIEntation="Horizontal" VerticalAlignment="Bottom">                     <TextBlock margin="0,0" FontSize="12" WIDth="118" Text="贴图"/>                     <ComboBox x:name="DiffuseMapSel" WIDth="140">                     </ComboBox>                     <button Content="清理贴图" WIDth="60" Click="button_Click_ClearDiffuseMap"></button>                 </StackPanel>                 <StackPanel margin="0" OrIEntation="Horizontal">                     <TextBlock margin="0,0" FontSize="12" WIDth="118"><Run Text="贴图"/><Run Text="透明度"/></TextBlock>                     <SlIDer x:name="SlIDerDOpacity" WIDth="140" Maximum="1" Value="1" LargeChange="0.2"/>                     <TextBlock Text="{Binding Value, Elementname=SlIDerDOpacity}" margin="0,0" FontSize="12" WIDth="71"/>                 </StackPanel>                 <StackPanel Height="28" OrIEntation="Horizontal" VerticalAlignment="Bottom">                     <TextBlock margin="0,0" FontSize="12" WIDth="118" Text="反射贴图"/>                     <ComboBox x:name="ReflectionMapSel" WIDth="140"/>                     <button Content="清理贴图" WIDth="60" Click="button_Click_ClearReflectionMap"></button>                 </StackPanel>                 <StackPanel margin="0" OrIEntation="Horizontal">                     <TextBlock margin="0,0" FontSize="12" WIDth="118"><Run Text="反射"/><Run Text="贴图"/><Run Text="透明度"/></TextBlock>                     <SlIDer x:name="SlIDerROpacity" WIDth="140" Maximum="1" Value="1" LargeChange="0.2"/>                     <TextBlock Text="{Binding Value, Elementname=SlIDerROpacity}" margin="0,0" FontSize="12" WIDth="71"/>                 </StackPanel>             </StackPanel>                  </GrID>     </UserControl>   

然后后台代码如下,做了简单的注释,相信各位高手会明白的。

后台代码 
      //////////////////////////////////////////////////          // Silvery Night          // Nowpaper原创Silverlight Balder3D文章,共同研究和探讨:)          //           // http://www.Nowpaper.net          // http://www.cnblogs.com/Nowpaper          //////////////////////////////////////////////////          using System;          using System.windows.Threading;          using System.windows.Controls;          using System.windows.Media;          using System.windows.Media.Imaging;          using Balder.Math;          using Balder.Objects.GeometrIEs;          using Balder.VIEw;          using Balder.lighting;          using Balder.Execution;          using System.windows;          using System.windows.Resources;          using Balder.Materials;          using Balder.Assets;          using System.windows.Data;          using System.Collections.Generic;                   namespace Balder_Studio          {              public partial class Lesson08 : UserControl              {                  //Heightmap                  Heightmap heightmap = new Heightmap();                  Camera camera = new Camera();                  //材质                  Material material = new Material();                  //贴图文件列表                  public List<string> ImageList = new List<string>()                  {                      "/Balder_Studio;component/Res/map01.jpg",                     "/Balder_Studio;component/Res/map02.jpg",                     "/Balder_Studio;component/Res/map03.jpg",                     "/Balder_Studio;component/Res/map04.jpg"                  };                  public Lesson08()                  {                      InitializeComponent();                               InitializeUILogic();                               //L1                      Game game = new Game() { WIDth = 600Height = 400 };                      game.Camera = camera;                      game.Camera.position = new Coordinate(100, 120, 150);                      game.Camera.Target = new Coordinate(0, 0, 0);                      game.Children.Add(new Omnilight()                      {                          position = new Coordinate(0, 100, 0),                         AmbIEnt = colors.transparent,                         specular = colors.transparent,                         Diffuse = colors.transparent,                         Strength = 0.55,                     });                      //L3                      Game_Axis axis_x = new Game_Axis(new Vertex(-300, 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);                      game.Children.Add(axis_x);                      game.Children.Add(axis_y);                      game.Children.Add(axis_z);                                                     heightmap.Dimension = new Dimension() { WIDth = 128Height = 128 };                      heightmap.LengthSegments = 2;                      heightmap.HeightSegments = 2;                      heightmap.InteractionEnabled = true;                               //L8                      //从位图中创建高度图                      CreateHeightmapFormBitmap(new Uri("/Balder_Studio;component/Res/heightmap.jpg", UriKind.relative));                      //通过ContentManager读取指定贴图                      Balder.Imaging.Image image = Runtime.Instance.ContentManager.Load<Balder.Imaging.Image>("/Balder_Studio;component/Res/map01.jpg");                      //漫反射贴图                      material.DiffuseMap = new ImageMap(image) ;                      //漫射贴图透明度                      material.DiffuseMapOpacity = 1;                      //材质透明度                      material.Opacity = 1;                      //双面材质                      material.DoubleSIDed = true;                      //将材质附上                      heightmap.Material = material;                               game.Children.Add(heightmap);                               LayoutRoot.Children.Add(game);                               this.KeyDown += new System.windows.input.KeyEventHandler(Lesson08_KeyDown);                              }                  //初始化UI                  private voID InitializeUILogic()                  {                                  foreach (var item in ImageList)                      {                          Image image = new Image() { WIDth = 128Height = 128 };                          Image image1 = new Image() { WIDth = 128Height = 128 };                          imageimage1.source = image.source = new BitmAPImage(new Uri(item, UriKind.relative));                          DiffuseMapSel.Items.Add(image);                          ReflectionMapSel.Items.Add(image1);                      }                      DiffuseMapSel.SelectionChanged += new SelectionChangedEventHandler(MapSel_SelectionChanged);                      ReflectionMapSel.SelectionChanged += new SelectionChangedEventHandler(MapSel_SelectionChanged);                      SlIDerOpacity.ValueChanged += new RoutedPropertyChangedEventHandler<double>(SlIDerOpacity_ValueChanged);                      SlIDerDOpacity.ValueChanged += new RoutedPropertyChangedEventHandler<double>(SlIDerOpacity_ValueChanged);                      SlIDerROpacity.ValueChanged += new RoutedPropertyChangedEventHandler<double>(SlIDerOpacity_ValueChanged);                  }                                   voID MapSel_SelectionChanged(object sender, SelectionChangedEventArgs e)                  {                      var comboBox = sender as ComboBox;                      if(comboBox.Selectedindex == -1)                          return;                      var filename = ImageList[comboBox.Selectedindex];                      Balder.Imaging.Image image;                      image = Runtime.Instance.ContentManager.Load<Balder.Imaging.Image>(filename);                      if (sender == DiffuseMapSel)                      {                          material.DiffuseMap = new ImageMap(image);                      }                      else                      {                          if (ReflectionMapSel == sender)                           {                              material.ReflectionMap = new ImageMap(image);                          }                      }                  }                                  voID SlIDerOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)                  {                      if (sender == SlIDerOpacity)                      {                          material.Opacity = e.NewValue;                      }                      else                      {                          if (sender == SlIDerDOpacity)                          {                              material.DiffuseMapOpacity = e.NewValue;                          }                          else                          {                              if (sender == SlIDerROpacity)                              {                                  material.ReflectionMapOpacity = e.NewValue;                              }                          }                      }                  }                                    voID Lesson08_KeyDown(object sender, System.windows.input.KeyEventArgs e)                  {                      switch (e.Key)                      {                          case System.windows.input.Key.W:                              {                                  var c = camera.Target - camera.position;                                  camera.position += c / 10;                                  camera.Target += c / 10;                              }                              break;                          case System.windows.input.Key.S:                              {                                  var c = camera.Target - camera.position;                                  camera.position -c / 10;                                  camera.Target -c / 10;                              }                              break;                      }                  }                                                      //从位图中创建高度图                  voID CreateHeightmapFormBitmap(Uri uri)                  {                      BitmAPImage bitmap = new BitmAPImage();                      //从资源中取得BitmapStream                      StreamResourceInfo sri = Application.GetResourceStream(uri);                      bitmap.SetSource(sri.Stream);                      //生成WriteableBitmap                      WriteableBitmap writeablebitmap = new WriteableBitmap(bitmap);                      //创建高度图数组                      float[,] HeightmapArray = new float[bitmap.PixelHeight, bitmap.PixelWIDth];                      //将数组拷贝到高度图数组                      for (int i = 0; i < bitmap.PixelHeight; i++)                      {                          for (int j = 0; j < bitmap.PixelWIDth; j++)                          {                              int index = bitmap.PixelWIDth * i + j;                              int pixel = writeablebitmap.Pixels[index];                              byte[] bytes = BitConverter.GetBytes(pixel);                              //计算:颜色越深则越低,颜色月浅则越高,50是最高的高度值                              HeightmapArray[i, j] = ((float)(bytes[0] + bytes[1] + bytes[2]) / 3) / 255 * 50;                          }                      }                      //赋值                      heightmap.HeightmapArray = HeightmapArray;                  }                           private voID button_Click_ClearDiffuseMap(object sender, RoutedEventArgs e)                  {                      heightmap.Material.DiffuseMap = null;                  }                           private voID button_Click_ClearReflectionMap(object sender, RoutedEventArgs e)                  {                      heightmap.Material.ReflectionMap = null;                  }              }          }        
好了,我们下面看看效果,使用上述代码实现即可,可以 点击直接下载工程浏览和测试,那么运行的预览效果如下:

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

下一篇我们介绍材质的应用,如何对模型进行贴图和更换贴图,以及贴图的属性,同时可能还结合Heightmap依据地理信息制作真实地图,那么下次再见。

总结

以上是内存溢出为你收集整理的Silverlight C# 游戏开发:L8 材质和贴图全部内容,希望文章能够帮你解决Silverlight C# 游戏开发:L8 材质和贴图所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1075146.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存