• [小明学Shader]7.环境映射和Cubemap


    对于金属状、玻璃状物体,它们的表面能映射出周围环境。如果碰上这类的物体,用上我们本篇的 shader,就能让这种物体显得更加的逼真。

    • 制作Cubemap

    写Shader之前呢,要用到一个Cubemap,可以用Unity的编辑器生成.代码如下:

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    
    public class GenerateCubeMap : ScriptableWizard {
    
        public Transform renderformPosition;
        public Cubemap cubeMap;
    
        void OnWizardUpdate(){
            helpString="Select transform to render from and cubemap to render int o";
            isValid = (renderformPosition != null) && (cubeMap != null);
        }
    
        void OnWizardCreate(){
            GameObject go = new GameObject ("CubeMap Camera", typeof(Camera));
            go.transform.position = renderformPosition.position;
            go.transform.rotation = renderformPosition.rotation;
    
            go.camera.RenderToCubemap (cubeMap);
            DestroyImmediate (go);
        }
    
        [MenuItem("Tool/Render to CubeMap")]
        static void RenderCubeMap(){
            ScriptableWizard.DisplayWizard("render cubemap",typeof(GenerateCubeMap),("Render"));
        }
    }

    这个脚本为菜单栏创建了一个Wizard,用来创建需要的Cubemap.在创建脚本的位置,可以右键创建一个Cubemap,然后通过对打开的Wizard窗口赋值,即可得到目标位置的Cubemap.

    • 创建环境映射Shader

    环境映射的Shader需要在Properties中增加一个CUBE属性,然后在Input中增加类型为float3 的worldRefl.

    Shader "Cutom/11.27/2"{
        Properties{
            _MainTex("Base(RGB)",2D)="white"{}
            _Cubemap("Cube Map",CUBE)=""{}
        }
        
        SubShader{
            Tags{"RenderType"="Opaque"}
            LOD 200
            
            CGPROGRAM
            #pragma surface surf Lambert
            
            sampler2D _MainTex;
            samplerCUBE _Cubemap;
            
            struct Input{
                float2 uv_MainTex;
                float3 worldRefl;
            };
            
            void surf(Input In,inout SurfaceOutput o){
                fixed4 c=tex2D(_MainTex,In.uv_MainTex);
                o.Albedo=c.rgb;
                
                fixed4 refcol=texCUBE(_Cubemap,In.worldRefl);
                refcol*=c.a;
                o.Emission=refcol.rgb;
                o.Alpha=refcol.a;
            }
            
            ENDCG
        }
    }

    将Cubemap上的点设定alpha值,然后将输出的Emission设定为Cubemap相应的值即可.这个 shader 代码,主要是用到了 texCUBE 这个 Unity 内置的方法,这个方法第1个参数是我们的 cubemap 文件,第2个参数是 unity 内置的基于世界坐标系的反射方向,在 Unity 渲染物体的时候,如果我们有 Input 结构需要这个东西,只要在 Input 结构中写上 worldRefl就可以, unity 会帮助把物体某个点的反射方向作为参数送如 shader,我们只要使用就可以。texCUBE 取出的值,我们把它放置到 SurfaceOutput 的 Emission 变量里面,出了 surf()这个方法后,光照方程会被运行, Emission 的值会在此过程保持,最后出了光照方程后( Unity在光照方程中主要计算某个点的光照颜色), Unity 会把 Emission 的颜色做加法加到顶点的颜色上,合成最后的输出到显卡缓存的色彩,也就是我们最后看到的颜色.

    • 效果图

    虽然看起来很想透明的玻璃球,但这是一个镜子球的效果,我们看到的是反射的样子.

  • 相关阅读:
    July 22nd 2017 Week 29th Saturday
    July 21st 2017 Week 29th Friday
    社交类APP原型模板分享——QQ
    专访UI中国认证设计师卤大湿 | 一位UI大师关于UI设计的思考
    第十届Mockplus ▪ UXPA用户体验西南赛区决赛成功举行
    【附案例】UI交互设计不会做?设计大神带你开启动效灵感之路
    旅游类APP原型模板分享——爱彼迎
    有了这款自动标注/切图神器,攻城狮终于可以省心了
    设计师升职加薪必须知道的10个设计网站
    官网类原型模板分享——Apple
  • 原文地址:https://www.cnblogs.com/WongSiuming/p/4997430.html
Copyright © 2020-2023  润新知