zoukankan      html  css  js  c++  java
  • [小明学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 的颜色做加法加到顶点的颜色上,合成最后的输出到显卡缓存的色彩,也就是我们最后看到的颜色.

    • 效果图

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

  • 相关阅读:
    面向对象编程(OOP)、面向组件编程(COP)、面向方面编程(AOP)和面向服务编程(SOP)
    编程思想、软件工程思想、模块内变化时对其他模块的影响
    读林锐《软件工程思想》------讲述软件开发和做程序员的道理
    编程思想的理解(POP,OOP,SOA,AOP)
    javascript alert乱码的解决方法
    curl说明
    手机号正则表达式精简
    织梦自定义表单 在线报名 在线预约听语音
    Html Mailto标签详细使用方法
    织梦DedeCMS提示信息框的修改,修改ShowMsg方法函数
  • 原文地址:https://www.cnblogs.com/WongSiuming/p/4997430.html
Copyright © 2011-2022 走看看