首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TMesh -生成三维形状并计算法线

TMesh -生成三维形状并计算法线
EN

Stack Overflow用户
提问于 2021-11-16 16:20:32
回答 1查看 233关注 0票数 1

我试着理解3d是如何工作的,我已经创建了3d形状,例如多维数据集

我填写mesh.data.VertexBuffer.Verticesmesh.data.IndexBuffer。屏幕上一切看上去都很好,但阴影没有问题。

我不明白如何为顶点提供法线?我可以考虑三角形的法线,但我无法想象单个顶点。一个垂直线可以由多个三角形共享,是吗?例如,对于立方体,三面墙可以共用一个角线。

也许我的理解是错的。

问题是:

  1. ,对于立方体,应该像现在一样只有8点吗?在indexbuffer.
  2. Or中使用它们,我应该对每个三角形都有单独的点,即使它们和其他三角形点有相同的坐标,也能计算法线吗?例如,对于立方体,我应该有:

6 walls * 4 points = 24 points而不是我目前的8只?

更新

代码语言:javascript
运行
复制
unit UnitMain;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Viewport3D, System.Math.Vectors, FMX.Types3D,
  FMX.Controls3D, FMX.Objects3D, FMX.MaterialSources;

type
  TFormCube = class(TForm)
    Viewport3D1: TViewport3D;
    Camera1: TCamera;
    Light1: TLight;
    Mesh1: TMesh;
    LightMaterialSource1: TLightMaterialSource;
    LightMaterialSource2: TLightMaterialSource;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormCube: TFormCube;

implementation

{$R *.fmx}

procedure TFormCube.FormCreate(Sender: TObject);
Var idx: Integer;
begin
  Mesh1.Data.VertexBuffer.Length:= 8;

  Mesh1.Data.VertexBuffer.Vertices[0]:= Point3d(1, 1, 1);
  Mesh1.Data.VertexBuffer.Vertices[1]:= Point3d(1, -1, 1);
  Mesh1.Data.VertexBuffer.Vertices[2]:= Point3d(-1, -1, 1);
  Mesh1.Data.VertexBuffer.Vertices[3]:= Point3d(-1, 1, 1);

  Mesh1.Data.VertexBuffer.Vertices[4]:= Point3d(1, 1, -1);
  Mesh1.Data.VertexBuffer.Vertices[5]:= Point3d(1, -1, -1);
  Mesh1.Data.VertexBuffer.Vertices[6]:= Point3d(-1, -1, -1);
  Mesh1.Data.VertexBuffer.Vertices[7]:= Point3d(-1, 1, -1);

  Mesh1.Data.IndexBuffer.Length:= 8*2*3;


  //front
  idx:= 0;
  Mesh1.Data.IndexBuffer[idx + 0]:= 0;
  Mesh1.Data.IndexBuffer[idx + 1]:= 3;
  Mesh1.Data.IndexBuffer[idx + 2]:= 2;

  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 0;
  Mesh1.Data.IndexBuffer[idx + 1]:= 2;
  Mesh1.Data.IndexBuffer[idx + 2]:= 1;

  //right
  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 4;
  Mesh1.Data.IndexBuffer[idx + 1]:= 0;
  Mesh1.Data.IndexBuffer[idx + 2]:= 1;

  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 4;
  Mesh1.Data.IndexBuffer[idx + 1]:= 1;
  Mesh1.Data.IndexBuffer[idx + 2]:= 5;


  //back
  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 7;
  Mesh1.Data.IndexBuffer[idx + 1]:= 4;
  Mesh1.Data.IndexBuffer[idx + 2]:= 5;

  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 7;
  Mesh1.Data.IndexBuffer[idx + 1]:= 5;
  Mesh1.Data.IndexBuffer[idx + 2]:= 6;

  //left
  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 3;
  Mesh1.Data.IndexBuffer[idx + 1]:= 7;
  Mesh1.Data.IndexBuffer[idx + 2]:= 6;

  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 3;
  Mesh1.Data.IndexBuffer[idx + 1]:= 6;
  Mesh1.Data.IndexBuffer[idx + 2]:= 2;

  //top
  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 4;
  Mesh1.Data.IndexBuffer[idx + 1]:= 7;
  Mesh1.Data.IndexBuffer[idx + 2]:= 3;

  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 4;
  Mesh1.Data.IndexBuffer[idx + 1]:= 3;
  Mesh1.Data.IndexBuffer[idx + 2]:= 0;

  //bottom
  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 1;
  Mesh1.Data.IndexBuffer[idx + 1]:= 2;
  Mesh1.Data.IndexBuffer[idx + 2]:= 6;

  inc(idx, 3);
  Mesh1.Data.IndexBuffer[idx + 0]:= 1;
  Mesh1.Data.IndexBuffer[idx + 1]:= 6;
  Mesh1.Data.IndexBuffer[idx + 2]:= 5;
end;

end.

和dfm

代码语言:javascript
运行
复制
object FormCube: TFormCube
  Left = 0
  Top = 0
  Caption = 'Cube'
  ClientHeight = 823
  ClientWidth = 1166
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  OnCreate = FormCreate
  DesignerMasterStyle = 0
  object Viewport3D1: TViewport3D
    Align = Client
    Camera = Camera1
    Color = claBlack
    Size.Width = 1166.000000000000000000
    Size.Height = 823.000000000000000000
    Size.PlatformDefault = False
    UsingDesignCamera = False
    object Camera1: TCamera
      AngleOfView = 45.000000000000000000
      Position.X = -2.000000000000000000
      Position.Y = -2.000000000000000000
      Position.Z = -10.000000000000000000
      Width = 1.000000000000000000
      Height = 1.000000000000000000
      Depth = 1.000000000000000000
    end
    object Light1: TLight
      Color = claWhite
      LightType = Directional
      SpotCutOff = 180.000000000000000000
      Position.X = -9.222618103027344000
      Position.Y = 2.758471012115479000
      RotationAngle.Y = 21.211906433105470000
      Width = 1.000000000000000000
      Height = 1.000000000000000000
      Depth = 1.000000000000000000
      Quanternion = '(0,-0.184053480625153,0,-0.982916116714478)'
    end
    object Mesh1: TMesh
      Width = 1.000000000000000000
      Height = 1.000000000000000000
      Depth = 1.000000000000000000
      TwoSide = True
      MaterialSource = LightMaterialSource2
    end
    object LightMaterialSource1: TLightMaterialSource
      Diffuse = claRed
      Ambient = claBlue
      Emissive = claGreen
      Specular = claWhite
      Shininess = 30
      Left = 280
      Top = 168
    end
  end
  object LightMaterialSource2: TLightMaterialSource
    Diffuse = claWhite
    Ambient = xFF202020
    Emissive = claNull
    Specular = xFF606060
    Shininess = 30
    Left = 248
    Top = 256
  end
end
EN

回答 1

Stack Overflow用户

发布于 2021-11-16 21:07:15

看起来第二个选项是真的。

我认为这是浪费资源,需要更多的点数。

而不是8点,后者从第一个角度描述了qube good

我需要24积分(6 walls * 4 points = 24 points)。

在此基础上,通过乘积法得到简单的法线。

结果现在看起来很好,对于更复杂的形状也是如此。

结论与Blender 2.93一致,为立方体出口24分。

代码语言:javascript
运行
复制
<float_array id="Cube-mesh-positions-array" count="24">1 1 1 1 1 -1 1 -1 1 1 -1 -1 -1 1 1 -1 1 -1 -1 -1 1 -1 -1 -1</float_array>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69992685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档