unity 中Deferred Lighting (延迟光照)

Posted xiaogeformax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity 中Deferred Lighting (延迟光照)相关的知识,希望对你有一定的参考价值。

Deferred Lighting (延迟光照)

Deferred Lighting简介

这个是unity 圣典里面对于延迟光照的解释

Deferred Lighting is rendering path with the most lighting and shadow fidelity:

延迟光照是一种当前最高级的能实现光线和阴影保真的渲染路径

There’s no limit how many lights can affect any object.
对于能影响任何物体的光线数量没有上限
All lights are evaluated per-pixel. Which means that they all interact properly with normal maps etc.
完全采用以每像素的方式评估光线,这等于意味着全部将以正常贴图的方式正确的和物体交互
All lights can have Cookies.
所有光线都能拥有信息缓存
All lights can have Shadows.
所有的光线都能产生阴影
Deferred Lighting’s advantages 延迟光照的优点:

Lighting cost is proportional to light size on screen. Does not matter how many objects it shines on. Small lights = cheap!
光照的开销与屏幕的光线尺寸成正比,不用担心光线所照射的物品的数量,少量光线 等价于 廉价的花费
Consistency. All lighting for all lights is computed per-pixel; there are no lighting computations that break down on large triangles etc.
一致性,所有的光线的光照采用按像素为计算分割单位来计算。比如,不会有在大规模三角形情况下光照计算使计算性能发生崩溃的情况发生。
Disadvantages 缺点:

No real anti-aliasing support.
没有实时抗锯齿支持
Deferred Lighting can’t handle semi-transparent objects. Those are rendered using Forward Rendering.
延迟光照不能处理半透明物体,也不能用在哪些使用前向渲染的物体之上
Limited lighting model support (Blinn-Phong). All lighting is computed the same way; you can’t have drastically different lighting models on different objects.
有限的光照模式支持(Blinn-Phong)。所有光照以同样的方式计算,你不能够在不同的物体上采用完全不同的光照模式
No support for “receive shadows” flag and limited support light Culling Masks.
没有对接收阴影特征的支持和对光线遮罩剔除有限的支持

unity提供的全局纹理采样器

CameraDepthTexture 纹理采样 深度缓存 Depth
_CameraGBufferTexture0 纹理采样 漫反射 Diffuse
_CameraGBufferTexture1 纹理采样 镜面反射 Specular
_CameraGBufferTexture2 纹理采样 世界空间法线 World Space Normal
_CameraGBufferTexture3 纹理采样 (HDR)格式 Emission + lighting + lightmaps + reflection probes buffer

我们可以对下面几种采样进行对比,看出其中的效果。
左上角 Depth
左下角 Diffuse
右上角 世界空间法线
右下角 HDR

shader部分

我们这里的shader是放在摄像机上面的,同时需要将摄像机的RenderPath 设置为Deferred,同时我们需要给摄像机添加脚本

using UnityEngine;
using System.Collections;
using System.IO;

[ExecuteInEditMode]
public class DeferredLighting : MonoBehaviour

    [SerializeField] private Shader shader;

    private Material mat = null;

    private void OnEnable()
    
        if (mat == null)
        
            mat = new Material(shader);
        

        FindObjectOfType<Camera>().depthTextureMode = DepthTextureMode.DepthNormals;
    

    void OnRenderImage (RenderTexture source, RenderTexture destination)
    
        if (mat == null)
        
            Graphics.Blit(source, destination);
            return;
        

        Graphics.Blit(source, destination, mat);
    

上面的cs脚本是作用于摄像机来调节屏幕的,如果材质不可用,就用Graphics.Blit(source, destination);函数直接渲染到屏幕上,如果可以用,就用Graphics.Blit(source, destination, mat)渲染到mat材质上。

Shader "DeferredLighting"

    Properties
    
        _MainTex ("Texture", 2D) = "white" 
    
    SubShader
    
        Tags  "RenderType"="Opaque" 
        LOD 100
        ZWrite off
        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;

            uniform sampler2D _CameraDepthTexture;    //深度缓存 Depth
            uniform sampler2D _CameraGBufferTexture0; //漫反射 Diffuse
            uniform sampler2D _CameraGBufferTexture1; //镜面反射 Specular
            uniform sampler2D _CameraGBufferTexture2; //世界空间法线 World Space Normal
            uniform sampler2D _CameraGBufferTexture3; //(HDR)格式 Emission + lighting + lightmaps + reflection probes buffer.


            v2f vert (appdata v)
            
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            

            fixed4 frag (v2f i) : SV_Target
            
                if (i.uv.x < 0.5)
                
                    // Diffuse...
                    // 左下角
                    if (i.uv.y < 0.5)
                    
                        i.uv *= 2.0;
                        return tex2D(_CameraGBufferTexture0, i.uv);
                    
                    // Depth...
                    // 左上角
                    else
                    
                        i.uv.y -= 0.5;
                        i.uv *= 2.0;
                        return tex2D(_CameraDepthTexture, i.uv).r;
                    
                
                else 
                
                    i.uv.x -= 0.5;

                    // HDR
                    // 右下角
                    if (i.uv.y < 0.5)
                    
                        i.uv *= 2.0;
                        return tex2D(_CameraGBufferTexture3, i.uv);
                    
                    // 世界空间法线
                    // 右上角
                    else
                    
                        i.uv.y -= 0.5;
                        i.uv *= 2.0;
                        return tex2D(_CameraGBufferTexture2, i.uv);
                    
                
            
            ENDCG
        
    

以上是关于unity 中Deferred Lighting (延迟光照)的主要内容,如果未能解决你的问题,请参考以下文章

Unity渲染路径 Rendering Paths_1_Deferred Lighting 延时光照

Unity Lighting - Lighting overview 照明概述

unity4.6版本中,Lighting在哪里?

《Deferred Shading》

Unity12.2 通过Lighting Window设置相关参数

前Forward / 延时Deferred