unity 中Deferred Lighting (延迟光照)

4 篇文章 0 订阅
2 篇文章 0 订阅

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
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值