• Unity3D学习笔记12——渲染纹理


    1. 概述

    在文章《Unity3D学习笔记11——后处理》中论述了后处理是帧缓存(Framebuffer)技术实现之一;而另外一个帧缓存技术实现就是渲染纹理了。通常来说,我们渲染的场景会直接显示到屏幕的颜色缓冲区,但其实纹理和屏幕一样都是二维的,通过把场景渲染到纹理,可以实现很多特别的三维应用场景。三维渲染引擎中,通常给相机封装一个渲染目标(Render Target)的接口,如果不设置,就渲染到屏幕;如果将其设置成一个纹理对象,就渲染到纹理。

    2. 详论

    一个渲染纹理的例子是镜面效果。镜面效果的原理是,在正常渲染场景之外,额外再离屏渲染一张纹理图,渲染的内容是镜面面前的场景;然后,将这个渲染纹理传递到镜面物体上,左右颠倒绘制出来。

    案例非常简单,甚至不需要脚本。首先我们创建一个quad网格作为镜面,并且在镜面前放置一些三维物体:
    imglink1

    然后创建一张渲染纹理:
    imglink2

    接着在场景中创建渲染到纹理的相机。将相机的渲染目标设置成刚刚创建的渲染纹理,同时也应该调整相机的位置和旋转,使其于观察方向相反:
    imglink4

    修改镜面物体上的材质,使其调用的Shader为:

    Shader "Custom/Mirrior"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" }
            LOD 100
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
       
                #include "UnityCG.cginc"
    
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                struct v2f
                {
                    float2 uv : TEXCOORD0;    
                    float4 vertex : SV_POSITION;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
    
                v2f vert (appdata v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
    				o.uv = v.uv;
                    o.uv.x = 1 - o.uv.x;
             
                    return o;
                }
    
                fixed4 frag (v2f i) : SV_Target
                {
                    // sample the texture
                    fixed4 col = tex2D(_MainTex, i.uv);         
                    return col;
                }
                ENDCG
            }
        }
    }
    

    Shader的内容非常简单,给Shader传入渲染纹理,给横向的纹理坐标取反,最后得到一个左右颠倒的效果图:
    imglink3

    3. 问题

    大部分介绍渲染纹理的文章,基本上都是这个案例。但是我觉得这个只是略具意思而已。

    1. 单从案例本身来说,渲染纹理需要相机的支持,但相机的位置和旋转影像最终镜面的效果。当然我们可以根据实际的效果来调整,但最好根据镜面的成像原理算出合理的参数。
    2. 渲染纹理实际上是通过相机把场景又给渲染了一遍。渲染批次加倍,所以渲染纹理往往是比较耗费性能的。有时需要控制一些物体进入镜面,一些物体不用进入,那么就要用到Unity的Layer(图层)设置了。

    代码地址

  • 相关阅读:
    2022北京营养健康展会/北京健康生活展/北京养生健康展会
    【人生苦短,我学 Python】(1)初识 Python
    学习ASP.NET Core Blazor编程系列六——初始化数据
    人工智能AI风口已开:如何赋予UI设计与视频剪辑新生命
    程序员学习的5个国外网站推荐
    MySQL基础架构详解
    『牛客|每日一题』N皇后问题
    java springboot基于微信小程序的社区疫情管理系统uniapp 小程序
    表单修饰符、过滤器、内置指令和自定义指令
    你的模型是最好的还是最幸运的?选择最佳模型时如何避免随机性
  • 原文地址:https://www.cnblogs.com/charlee44/p/16607487.html