Unity CommandBuffer.SetViewProjectionMatrixes & CommandBuffer.DrawMesh 测试对Shader中默认的MVP设置


记录、备忘用

因为我之前看:CommandBuffer.DrawMesh的第二个矩阵的参数设置写着://Transformation matrix to use. 所以我以为是MVP的矩阵。

但是测试之后我发现我理解错了。

运来是 本地转换到世界坐标的变换矩阵,它就不能写类似: Transformations Local to world matrix to use吗?这样描述多好理解。

为何要测试这个呢?因为CommandBuffer刚用不久,然后急着实现某些功能,我就暂时跳过了CommandBuffer因为注释描述不够准确的问题,昨天用CommandBuffer.DrawMesh去绘制实现SSSM(屏幕空间阴影)的RT(这里没去用Camera.RenderWithShader)功能。

但是因为我觉得,Unity官方肯定不会连LocalToWorld的矩阵都不给设置吧,这多蛋疼,想象就知道是自己的使用姿势不对,所以现在回过头来测试。

虽然MVP矩阵通过CommandBuffer.SetViewProjectionMatrixes,与DrawMesh 算是设置对了但是_ProjectionParams.w但不是1/far的值,我估计是否这样用法的人很少,没人踩过这个坑?
很有可能是因为CommandBuffer.SetViewProjectionMatrixes并没有对_ProjectionParams更新,那么其他的变量也是极有可能也是没有更新的,所以用CommandBuffer来SetViewProjectionMatrixes后渲染处理还是妥妥的用回自定义的矩阵来处理

CSharp

using UnityEngine;
using UnityEngine.Rendering;
// jave.lin 2020.04.15 测试 CommandBuffer.SetViewProjectionMatrices 与测试 CommandBuffer.DrawMesh 配合使用设置Unity内置变换矩阵
public class CmdBuffSetViewProjTesting : MonoBehaviour
{
    public Camera cam;                  // 用于观察的Camera
    public Camera hidenCam;             // 用于类似RT渲染用的Camera,看看能否指定M,V,P各个矩阵
    public Material mat;                // 绘制用的材质
    public GameObject cubeHolder;       // Cube的LocalToWorldMatrix的挂点对象
    public bool withCubeHolder = true;  // 是否使用Cube挂点
    public bool setViewProj = true;     // 是否设置CommandBuffer.SetViewProjectionMatrices

    private CommandBuffer cmdBuff;
    private Mesh mesh;

    private void Start()
    {
        cmdBuff = new CommandBuffer();
        cmdBuff.name = "[Testing CmdBuff Set V P & DrawMesh]";

        var cubeGO = GameObject.CreatePrimitive(PrimitiveType.Cube);
        mesh = cubeGO.GetComponent<MeshFilter>().mesh;
        Destroy(cubeGO);
    }

    private void OnRenderObject()
    {
        cmdBuff.Clear();
        if (setViewProj)
        {
            cmdBuff.SetViewProjectionMatrices(hidenCam.worldToCameraMatrix, GL.GetGPUProjectionMatrix(hidenCam.projectionMatrix, false));
        }
        if (withCubeHolder)
        { // 所以DrawMesh的第二个Matrix4x4就是L2W的矩阵
            // 从CommandBuffer的API可以看到各个DrawXXX()中的Matrix的注释都是一样的,说明都是LocalToWorldMatrix。
            cmdBuff.DrawMesh(mesh, cubeHolder.transform.localToWorldMatrix, mat);
        }
        else
        {
            cmdBuff.DrawMesh(mesh, Matrix4x4.identity, mat);
        }

        Graphics.ExecuteCommandBuffer(cmdBuff);
    }
}

Shader

// jave.lin 2020.04.15 - 测试 CommandBuffer.SetViewProjectionMatrixes 与 CommandBuffer.DrawMesh 的MVP设置
Shader "Custom/CmdBuffDrawShader" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        _MainColor ("Color", Color) = (1,1,1,1)
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            struct appdata {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _MainColor;
            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 {
                fixed4 col = tex2D(_MainTex, i.uv);
                return col * _MainColor;
            }
            ENDCG
        }
    }
}

配置参数:

在这里插入图片描述

HidenCamera的Camera.enable = false

在这里插入图片描述

HidenCameraCamera.enable = false的,这样就不影响Main Camera的渲染。

Main Camera的视角

在这里插入图片描述

HidenCamera的视角

在这里插入图片描述

留意HidenCamera是朝着太阳的,视口可以看到太阳,Main Camera 是看不到的。

运行效果

在这里插入图片描述

看看实时的调整挂点对象,与HidenCamera

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值