前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Untiy Native Render Plugin在VR中的绘制

Untiy Native Render Plugin在VR中的绘制

作者头像
逍遥剑客
发布2018-05-21 11:28:13
1.7K0
发布2018-05-21 11:28:13
举报

官方的NativeRenderPlugin Sample只是画了一个屏幕空间的三角形, 怎么改成世界空间的呢? 以D3D11为例:

Native:

代码语言:javascript
复制
struct ConstantBuffer
{
    DirectX::XMMATRIX World;
    DirectX::XMMATRIX View;
    DirectX::XMMATRIX Projection;
} g_CB;
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API SetCameraMatrix(float vm[], float pm[])
{
    g_CB.View = XMLoadFloat4x4(&DirectX::XMFLOAT4X4(vm));
    g_CB.Projection = XMLoadFloat4x4(&DirectX::XMFLOAT4X4(pm));
}

由于DirectX Math已经是row major的, 所以不用转置了. Shader:

代码语言:javascript
复制
cbuffer MyCB : register(b0) 
{
    float4x4 worldMatrix;
    float4x4 viewMatrix;
    float4x4 projectionMatrix;
}
void VS (float3 pos : POSITION, float4 color : COLOR, out float4 ocolor : COLOR, out float4 opos : SV_Position) 
{
    opos = mul(float4(pos, 1), worldMatrix);
    opos = mul(opos, viewMatrix);
    opos = mul(opos, projectionMatrix);

    ocolor = color;
}

C#脚本这边有个细节, 就是投影矩阵需要转换一下, 不能直接取相机的:

代码语言:javascript
复制
    [DllImport("RenderingPlugin")]
    private static extern void SetCameraMatrix(float[] viewMatrix, float[] projectionMatrix);
    private static float[] MatrixToArray(Matrix4x4 _matrix)
    {
        float[] result = new float[16];

        for (int _row = 0; _row < 4; _row++)
        {
            for (int _col = 0; _col < 4; _col++)
            {
                result[_col + _row * 4] = _matrix[_row, _col];
            }
        }

        return result;
    }

    void OnPostRender()
    {
        // Set time for the plugin
        SetTimeFromUnity(Time.timeSinceLevelLoad);
        if (Camera.current != null)
        {
            var viewMatrix = Camera.current.worldToCameraMatrix;
            var projectionMatrix = GL.GetGPUProjectionMatrix(Camera.current.projectionMatrix, VRSettings.enabled);

            SetCameraMatrix(MatrixToArray(viewMatrix), MatrixToArray(projectionMatrix));
        }

        // Issue a plugin event with arbitrary integer identifier.
        // The plugin can distinguish between different
        // things it needs to do based on this ID.
        // For our simple plugin, it does not matter which ID we pass here.
        GL.IssuePluginEvent(GetRenderEventFunc(), 1);
    }

这个脚本挂到Camera上即可, OnPostRender会分别针对左右眼调用两次, 所以Native那边会产生两次绘制. 另外, Native这边也可以从视图矩阵中还原出眼睛位置:

代码语言:javascript
复制
        XMMATRIX invViewMatrix = XMMatrixInverse(nullptr, g_CB.View);
        XMVECTOR eyePos = XMMatrixTranspose(invViewMatrix).r[3];

参考资料

http://forum.unity3d.com/threads/native-c-plugin-in-world-space.196512/ https://github.com/obviousjim/ofxUnity/blob/master/UnityProject/Assets/UseRenderingPlugin.cs http://docs.unity3d.com/ScriptReference/Camera-projectionMatrix.html http://docs.unity3d.com/ScriptReference/Camera.Render.html https://forums.oculus.com/community/discussion/16313/native-rendering-plugin-with-oculus-rift http://forum.unity3d.com/threads/different-content-in-each-eye.332575/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年04月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档