zoukankan      html  css  js  c++  java
  • Unity 自制Cubemap及使用

    Unity 自制Cubemap及使用

    首先,什么是Cubemap?

             Cubemap是一个由六个独立的正方形纹理组成的集合。通常被用来作为具有反射属性物体的反射源。类似与MAX里的HDR属性。

    如何创建自己的Cubemap

    1.                 我们需要创建一些元素来当做Cubemaps的光源。因此,我们需要在场景中放置一些几何平面。你可以使用一个建模软件,例如Maya或者Max,当然你也可以使用Unity自带的plane。哪一种方式都行,这无所谓。你的场景应该可以像这样:


    2. 场景中的物体如下所示:

      其中,Position是一个空对象,它将仅仅作为观察的位置将从该点观察到的环境信息渲染到我们的Cubemap上。





    实现



    1. 首先,我们需要创建一个新的脚本,但是由于我们想要一个弹出的编辑器窗口,因此我们必须把脚本放到一个叫做Editor的文件夹里。在你的Project面板中创建一个叫Editor的文件夹,然后再创建一个C#脚本,叫做GenerateStaticCubemap。


    2. 打开上述脚本,为了使用特定的函数,我们需要使用新的using指令:

    3.     using UnityEngine;
    4.     using UnityEditor;
    using System.Collections
    1. 为了让Unity认识到,这个脚本会是一个弹出的编辑器窗口,我们需要让GenerateStaticCubemap类继承ScriptableWizard类。这使得我们可以使用一些很好的底层函数。

    public class GenerateStaticCubemap : ScriptableWizard {



    1. 然后,我们需要添加一些新的变量来存储新的CubeMap以及它的位置(即上面提到的position空对象)。

    2. 第一个函数是Unity的内置函数OnWizardUpdate()。它在向导(wizard)第一次弹出或者当GUI被用户改变时(如拖进去某些对象,输入某些字符等)时被调用。因此,我们可以在这里检查用户已经向向导中填入我们需要的所有的资源。在这里,如果Cubemap或者它的位置(一个transform)没有被填充,那么就设置内置变量isValid为false,直到拿到所有资源。

    3. 当isValid变量为true时,向导将调用OnWizardCreate()函数。在这个函数里,我们将创建一个新的摄像机,然后把它放到之前设置的transform的位置上,再调用RenderToCubemap函数得到最终的Cubemap。

    4. 最后,我们需要从Unit编辑器的菜单栏打开这个向导。这需要MenuItem关键词。

                    
    public Transform renderPosition;
                   public Cubemap cubemap;
    9.                    void OnWizardUpdate() {
    10.                                 helpString = "Select transform to render" +
    11.                                                " from and cubemap to render into";
    12.                                 if (renderPosition != null && cubemap != null) {
    13.                                                isValid = true;
    14.                                 }
    15.                                 else {
    16.                                                isValid = false;
    17.                                 }
                   }
    19.                 void OnWizardCreate() {
    20.                                 GameObject go = new GameObject("CubeCam", typeof(Camera));
    21.   
    22.                                 go.transform.position = renderPosition.position;
    23.                                 go.transform.rotation = Quaternion.identity;
    24.   
    25.                                 go.camera.RenderToCubemap(cubemap);
    26.   
    27.                                 DestroyImmediate(go);
                   }
    29.                 [MenuItem("CookBook/Render Cubemap")]
    30.                 static void RenderCubemap() {
    31.                                 ScriptableWizard.DisplayWizard("Render CubeMap", typeof(GenerateStaticCubemap), "Render!");
                   }



    最后,整体代码如下:

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
     
    public class GenerateStaticCubemap : ScriptableWizard {
     
                   public Transform renderPosition;
                   public Cubemap cubemap;
     
                   void OnWizardUpdate() {
                                   helpString = "Select transform to render" +
                                                  " from and cubemap to render into";
                                   if (renderPosition != null && cubemap != null) {
                                                  isValid = true;
                                   }
                                   else {
                                                  isValid = false;
                                   }
                   }
     
                   void OnWizardCreate() {
                                   GameObject go = new GameObject("CubeCam", typeof(Camera));
     
                                   go.transform.position = renderPosition.position;
                                   go.transform.rotation = Quaternion.identity;
     
                                   go.camera.RenderToCubemap(cubemap);
     
                                   DestroyImmediate(go);
                   }
     
                   [MenuItem("CookBook/Render Cubemap")]
                   static void RenderCubemap() {
                                   ScriptableWizard.DisplayWizard("Render CubeMap", typeof(GenerateStaticCubemap), "Render!");
                   }
    }


    此时,回到Unity编辑器页面,点击一下Unity菜单栏(有时需要点击才会刷新)就会看到出现一个新的选项:CookBook/Render Cubemap,如下所示:

    点击它你将会打开一个向导界面,如下所示。它需要两个资源,一个是Render Position,这将决定观察位置(你可以理解成你将会在该位置放一面镜子,这里需要注意的是由于代码里设置的摄像机的rotation为初始值,这意味着摄像机将看向图中蓝色箭头所指方向),一个是Cubemap,可以理解成就是镜子反射的图像。我的例子中设置如下。

    点击Render!按钮后,查看你的Cubemap,就会看到类似下面这样的情景。

    可以发现,我们已经把图像渲染到了一个立方体里了。恭喜你,你已经完成了自己的一个Cubemap!你可以尝试在不同的场景中试验。

    解释

    还记得一开始我们继承了ScriptableWizard类,这是为了告诉Unity3D我们想要制作一个新的弹出窗口类型的用户编辑器,这也是为什么我们需要把脚本放到Editor文件夹里的原因。如果我们不这么做,Unity将不会把它识别为一个用户编辑器类型的脚本。

    接下来我们声明的参数是用于存储Cubemap的渲染位置,以及把新的渲染得到的Cubemap放到Project的哪里,例如上面的名为First的Cubemap就是我提前在工程文件下创建的一个Cubemap。有了这些我们就可以生成自己的Cubemap了。

    然后我们使用了OnWizardUpdate()函数,它是由ScriptableWizard类提供给我们的。同样的,isValid变量也是一个内置变量。它让我们可以方便的打开或者关闭向导下方的Create按钮(这里指的是Render!按钮)。这样可以防止用户使用空的transform或者Cubemap进行下面的操作。

    一旦我们确定用户提供了正确的数据,我们就可以进入到OnWizardCreate()函数了。这是Cubemap真正被创建的地方。它首先创建了一个新的GameObject构造器,并把它的类型创建为Camera。然后把它放到用户提供的transform的位置上。

    到了这里,我们剩下要做的就是把用户提供的Cubemap传递给RenderToCubemap函数,生成六张图片。

    最后,我们为向导创建了一个菜单选项,以便让用户可以从Unity顶部的菜单栏打开这个工具。除了需要[MenuItem("CookBook/Render Cubemap")]关键词以外,我们还需要将函数声明为static函数。



    至此,我们就完成了一个简单的工具,可以用于在Unity编辑器中直接生成Cubemaps!

     

  • 相关阅读:
    Zookeeper安装
    JDK安装(Linux)
    Zookeeper简介
    修改tomcat配置解决定时任务多次重复执行
    解决.net mvc session超时的问题
    C#- JSON的操作
    Android SharedPreferences的理解与使用
    大屏适配:flexible.js的源码及配置
    charles抓包工具,抓手机端https设置
    Sanic二十:Sanic 扩展之sanic-openapi生成接口文档之sanic-openapi支持的数据类型
  • 原文地址:https://www.cnblogs.com/muyouking/p/6441705.html
Copyright © 2011-2022 走看看