zoukankan      html  css  js  c++  java
  • Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用

    開始学习第4章 - 着色器的反射

    看完了1、2节,来记录一下。反射主要是利用了 Cubemap 立方体贴图。


    认识Cubemap

    立方体贴图。就如同名字所说。在一个立方体上有6张图。就这样觉得吧。


    假想一下 ,在一个艳丽的房间里。有一个表面是镜子的圆球。那这个圆球表面就反射了房间里面的全部东西。就是一个大号的凸镜。

    这是到网上找得一张图,非常直观的表达了我的意思……


    注意标题中说的,静态立方体贴图。为什么叫静态。由于这一次使用的立方体贴图是提前生成好的图片,而不是动态生成的。

    这又是什么意思呢?

    就拿上面图片中的场景来说,假设是静态的立方体贴图。那么当这个球在移动的时候。球上面显示的东西是不会变动的。

    现实生活中的话,球移动。球上面显示出来的内容应该也是要随之变动的。

    那么这里使用静态立方体贴图呢。是先学习立方体贴图的知识。后面会学习动态立方体贴图的。在书上是 4.6 这一节。


    创建Cubemap

    首先来创建一个立方体贴图,在Assets 中右键新建一个 Cubemap。


    搭建场景,加入一个Sphere 作为Camera 的容器。

    由于要借助 Camera 的 API 来生成Cubemap。

    转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

    以下是我搭建的场景。


    以下编写一个Unity编辑器插件来生成CubeMap。

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    
    public class GenerateStaticCubemap : ScriptableWizard 
    {
        public Transform renderPosition;
        public Cubemap cubemap;
    
        void OnizardUpdate()
        {
            helpString = "Select transform to render" + "from and cubemap to render into";
            if (renderPosition != null && cubemap != null)
            {
                isValid = true;
            }
            else
            {
                isValid = false;
            }
        }
    
        void OnWizardCreate()
        {
            //加入一个Camera,用来创建Cubemap的。

    GameObject go = new GameObject("CubemapCamera", typeof(Camera)); go.transform.position = renderPosition.position; go.transform.rotation = Quaternion.identity; go.camera.RenderToCubemap(cubemap); DestroyImmediate(go); } [MenuItem("CookBookShaders/Render Cubemap")] static void RenderCubemap() { ScriptableWizard.DisplayWizard("Render Cube", typeof(GenerateStaticCubemap), "Render"); } }


    由于是编辑器工具。所以要遵循unity的规定。把这个代码文件放在 名为 Editor 的目录中。自己新建一个即可。


    这个代码文件的核心就是

    go.camera.RenderToCubemap(cubemap);

    借助Camera 的 API。生成了一个 Cubemap。


    然后加入了一个菜单,作为入口。

    [MenuItem("CookBookShaders/Render Cubemap")]



    等unity 编译完毕后。菜单条就会出现我们自己加入的菜单。



    把刚才创建的 Cubemap 拖进来,把Sphere拖进来。


    点击 Render 就生成了 Cubemap。




    使用Cubemap

    上面创建好了立方体贴图,然后就能够使用了。

    仍然创建一个材质。一个 Shader。

    转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

    Shader 代码

    Shader "CookBookShaders/Cubemap" 
    {
    	Properties {
    		_MainTint("Diffuse Tint",Color)=(1,1,1,1)
    		_MainTex ("Base (RGB)", 2D) = "white" {}
    		_Cubemap("Cubemap",CUBE)=""{}
    		_ReflectionAmount("Reflection Amount",Range(0.01,1))=0.5
    	}
    	SubShader {
    		Tags { "RenderType"="Opaque" }
    		LOD 200
    		
    		CGPROGRAM
    		#pragma surface surf Lambert
    
    
    		float4 _MainTint;
    		sampler2D _MainTex;
    		samplerCUBE _Cubemap;
    		float _ReflectionAmount;
    
    
    		struct Input {
    			float2 uv_MainTex;
    			float3 worldRefl;
    		};
    
    		void surf (Input IN, inout SurfaceOutput o) 
    		{
    			half4 c = tex2D (_MainTex, IN.uv_MainTex)*_MainTint;
    			o.Emission=texCUBE(_Cubemap,IN.worldRefl).rgb *_ReflectionAmount;
    			o.Albedo = c.rgb;
    			o.Alpha = c.a;
    		}
    		ENDCG
    	} 
    	FallBack "Diffuse"
    }
    

    第一次使用立方体贴图。

    在Properties 块中。定义属性的使用类型是 CUBE。普通纹理是 2D。

    在SubShader 中,定义变量的时候注意用 samplerCUBE。普通纹理是 sampler2D。


    在 Input 结构体中,使用了 Unity的内置变量 worldRefl 。这个变量 提供了在着色器中使用的 世界反射变量。


    然后在 surf 函数中,使用 texCube 从Cubemap 中取纹素。

    texCUBE(_Cubemap,IN.worldRefl).rgb

    执行后的效果



    演示样例project下载:

    http://pan.baidu.com/s/1qYcNKxI


  • 相关阅读:
    卷积神经网络要点解析
    quicksork解析
    梳理知识点(一)
    高斯混合模型以及EM算法
    adaboost/gdbt/xgboos/random forestt的异同点
    Anki使用
    Markdown写作入门
    VBox复制虚拟机镜像后的操作
    Hadoop集群之vsftpd设置
    使用Oracle函数将银行归类,方便引用
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7372853.html
Copyright © 2011-2022 走看看