【问题标题】:Adding normals to a list of vertices将法线添加到顶点列表
【发布时间】:2012-01-30 02:59:16
【问题描述】:

我在 C# 中使用 DirectX 9
我将所有顶点存储在一个列表(不是数组)中,因为我使用动态 LOD 算法,所以所有内容都是每帧计算的,所以我的顶点可能每帧都不同。

在我尝试添加法线和光照之前,一切正常。
我发现一旦将顶点添加到列表中,就无法编辑法线,因为它是结构而不是类的列表。所以它只会给出一个错误,比如“无法修改 blablaba 的返回值,因为它不是变量”
例如,如果我尝试这样做,它将无法正常工作 -

vertices[i].Normal = new Vector3(0, 1, 0);

在将顶点放入列表时必须添加法线,但在拥有完整网格之前无法计算法线。

所以我创建了一个新的自定义顶点类型,而不是把它变成一个结构,而是把它变成了一个类。这也不起作用,因为directx不会接受它,除非它是一个结构......

然后我尝试让它使用数组而不是顶点列表。这导致每秒少于一帧。我不得不使用 Array.Resize 每帧将数组的大小更改几百次,我猜它不喜欢那样。

你可能在想我应该把最终的列表变成一个数组,然后从那里计算法线。这不起作用,因为顶点不是以任何特定顺序添加的,所以我不知道哪些顶点靠近给定顶点以便能够计算法线。

那么,我如何存储我的顶点,以便在我构建网格后赋予它们法线?

【问题讨论】:

    标签: c# list directx normals


    【解决方案1】:

    C# 阻止您编写vertices[i].Normal = new Vector3(0, 1, 0),因为该表达式不会执行您想要的操作。与数组索引器不同,List<T> 索引器返回指定元素的 copy,并且因为顶点是结构体,所以复制了整个顶点,Normal 等等。您将更新顶点的临时副本,而不是列表中的实际顶点。

    解决方法是从列表中获取(副本)顶点,对其进行更新,然后将其放回(副本):

    var vertex = vertices[i];
    vertex.Normal = new Vector3(0, 1, 0); 
    vertices[i] = vertex;
    

    很遗憾,没有简单的方法可以避免这种重复复制。

    【讨论】:

    • 我完全不认为它会让我这样做,但它工作得非常好。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多