@@ -49,7 +49,10 @@ public class SoftRenderForm : Form {
49
49
PointLight pointLight ;
50
50
// 聚光灯
51
51
SpotLight spotLight ;
52
-
52
+
53
+ // 是否开启面剔除功能
54
+ bool cullingFaceOn = false ;
55
+ CullingFaceMode cullingFaceMode = CullingFaceMode . Back ;
53
56
54
57
// 屏幕宽高度(同时也作分辨率使用)
55
58
private int screenHeight = 500 , screenWidth = 500 ;
@@ -83,9 +86,9 @@ public SoftRenderForm() {
83
86
// 初始化所有光源
84
87
//directionalLight = new DirectionalLight(MainLightDirection, Color01.White);
85
88
//lights.Add(directionalLight);
86
- //pointLight = new PointLight(Vector3.Zero,7, new Color01(0,0, 1f,1f));
89
+ //pointLight = new PointLight(Vector3.Zero, 7, new Color01(0, 0, 1f, 1f));
87
90
//lights.Add(pointLight);
88
- spotLight = new SpotLight ( 45 , 7f , new Vector3 ( 0 , 0 , 1 ) , new Color01 ( 1 , 1 , 1 , 1 ) , new Vector3 ( 0 , 0 , - 3 ) ) ;
91
+ spotLight = new SpotLight ( 15f , 7f , new Vector3 ( 0 , 0 , 1 ) , new Color01 ( 1 , 1 , 1 , 1 ) , new Vector3 ( 0 , 0 , - 3 ) ) ;
89
92
lights . Add ( spotLight ) ;
90
93
91
94
// 开启深度测试
@@ -111,7 +114,7 @@ public SoftRenderForm() {
111
114
112
115
// 读取OBJ文件
113
116
SpaceShip = OBJLoader . LoadOBJ ( "../../enemry_spaceship.obj" ) ;
114
- //cube = OBJLoader.LoadOBJ("../../cube .obj");
117
+ //cube = OBJLoader.LoadOBJ("../../cube2 .obj");
115
118
cube = new Cube ( ) ;
116
119
sphere = OBJLoader . LoadOBJ ( "../../sphere.obj" ) ;
117
120
@@ -134,7 +137,7 @@ protected override void OnMouseDown(MouseEventArgs e) {
134
137
135
138
private void UpdateInput ( ) {
136
139
137
- float cameraSpeed = 2 .0f;
140
+ float cameraSpeed = 5 .0f;
138
141
if ( Input . Instance . isKeyDown ) {
139
142
switch ( Input . Instance . keyCode ) {
140
143
case Keys . Left :
@@ -613,11 +616,27 @@ public Vertex ScreenMapping(Vertex v) {
613
616
/// <param name="v1"></param>
614
617
/// <param name="v2"></param>
615
618
/// <param name="v3"></param>
616
- public void DrawPrimitive ( Vertex v1 , Vertex v2 , Vertex v3 , Matrix4x4 mvp ) {
619
+ public void DrawPrimitive ( Vertex v1 , Vertex v2 , Vertex v3 , Matrix4x4 mMatrix , Matrix4x4 vMatrix , Matrix4x4 pMatrix ) {
617
620
// 将各顶点作为列矩阵进行MVP变换
618
- v1 . pos = mvp * v1 . modelSpacePos ;
619
- v2 . pos = mvp * v2 . modelSpacePos ;
620
- v3 . pos = mvp * v3 . modelSpacePos ;
621
+ //v1.pos = mvp * v1.modelSpacePos;
622
+ //v2.pos = mvp * v2.modelSpacePos;
623
+ //v3.pos = mvp * v3.modelSpacePos;
624
+
625
+ // 先将顶点变换到观察空间下
626
+ Matrix4x4 mvMatrix = vMatrix * mMatrix ;
627
+ v1 . pos = mvMatrix * v1 . modelSpacePos ;
628
+ v2 . pos = mvMatrix * v2 . modelSpacePos ;
629
+ v3 . pos = mvMatrix * v3 . modelSpacePos ;
630
+
631
+ // 判断是否通过面剔除
632
+ if ( ! FaceCulling ( v1 , v2 , v3 ) && cullingFaceOn ) {
633
+ return ;
634
+ }
635
+
636
+ // 将所有顶点变换到裁剪空间下
637
+ v1 . pos = pMatrix * v1 . pos ;
638
+ v2 . pos = pMatrix * v2 . pos ;
639
+ v3 . pos = pMatrix * v3 . pos ;
621
640
622
641
// 判断有顶点是否应该被裁剪
623
642
if ( CVVCutting ( v1 . pos ) ||
@@ -644,7 +663,7 @@ public void DrawPrimitive(Vertex v1,Vertex v2,Vertex v3,Matrix4x4 mvp) {
644
663
/// <param name="triangle"></param>
645
664
/// <param name="mvp"></param>
646
665
/// <param name="drawMode">默认为连续三角形绘制</param>
647
- public void DrawElement ( Mesh mesh , Matrix4x4 mvp , SoftRenderDrawMode drawMode = SoftRenderDrawMode . Triangles ) {
666
+ public void DrawElement ( Mesh mesh , Matrix4x4 mMatrix , Matrix4x4 vMatrix , Matrix4x4 pMatrix , SoftRenderDrawMode drawMode = SoftRenderDrawMode . Triangles ) {
648
667
int [ ] triangle = mesh . triangles ;
649
668
Vertex [ ] vertices = mesh . vertices ;
650
669
if ( triangle . Length % 3 != 0 ) return ;
@@ -656,16 +675,16 @@ public void DrawElement(Mesh mesh,Matrix4x4 mvp,SoftRenderDrawMode drawMode= Sof
656
675
Vertex v2 = vertices [ triangle [ i + 1 ] ] ;
657
676
Vertex v3 = vertices [ triangle [ i + 2 ] ] ;
658
677
659
- DrawPrimitive ( v1 , v2 , v3 , mvp ) ;
678
+ DrawPrimitive ( v1 , v2 , v3 , mMatrix , vMatrix , pMatrix ) ;
660
679
}
661
680
break ;
662
681
case SoftRenderDrawMode . Triangles_FUN :
663
682
Vertex v_init = vertices [ triangle [ 0 ] ] ;
664
- for ( int i = 1 ; i < triangle . Length ; i += 2 ) {
665
- Vertex v2 = vertices [ triangle [ i + 1 ] ] ;
666
- Vertex v3 = vertices [ triangle [ i + 2 ] ] ;
683
+ for ( int i = 1 ; i + 1 < triangle . Length ; i += 2 ) {
684
+ Vertex v2 = vertices [ triangle [ i ] ] ;
685
+ Vertex v3 = vertices [ triangle [ i + 1 ] ] ;
667
686
668
- DrawPrimitive ( v_init , v2 , v3 , mvp ) ;
687
+ DrawPrimitive ( v_init , v2 , v3 , mMatrix , vMatrix , pMatrix ) ;
669
688
}
670
689
break ;
671
690
case SoftRenderDrawMode . TRIANGLE_STRIP :
@@ -674,14 +693,14 @@ public void DrawElement(Mesh mesh,Matrix4x4 mvp,SoftRenderDrawMode drawMode= Sof
674
693
Vertex vsecond = vertices [ triangle [ 1 ] ] ;
675
694
Vertex vthird = vertices [ triangle [ 2 ] ] ;
676
695
677
- DrawPrimitive ( vfirset , vsecond , vthird , mvp ) ;
696
+ DrawPrimitive ( vfirset , vsecond , vthird , mMatrix , vMatrix , pMatrix ) ;
678
697
679
698
for ( int i = 3 ; i < triangle . Length ; i ++ ) {
680
699
Vertex v1 = vertices [ triangle [ i - 2 ] ] ;
681
700
Vertex v2 = vertices [ triangle [ i - 1 ] ] ;
682
701
Vertex v3 = vertices [ triangle [ i ] ] ;
683
702
684
- DrawPrimitive ( v1 , v2 , v3 , mvp ) ;
703
+ DrawPrimitive ( v1 , v2 , v3 , mMatrix , vMatrix , pMatrix ) ;
685
704
}
686
705
687
706
break ;
@@ -720,6 +739,44 @@ public bool ZTest(int px,int py,float pz) {
720
739
721
740
#endregion
722
741
742
+
743
+ #region 面剔除测试
744
+
745
+ public bool FaceCulling ( Vertex v1 , Vertex v2 , Vertex v3 ) {
746
+ // v2指向v1的向量
747
+ Vector3 p1 = v2 . pos - v1 . pos ;
748
+ // v3指向v1的向量
749
+ Vector3 p2 = v3 . pos - v2 . pos ;
750
+
751
+ // 获得p1和p2的叉积
752
+ Vector3 normal = Vector3 . Cross ( p1 , p2 ) ;
753
+
754
+ // 获得视空间内从顶点望向观察方向的向量
755
+ Vector3 viewDir = - v1 . pos + Vector3 . Zero ;
756
+
757
+ // 如果该叉积结果和观察方向一致,那么说明该面面朝摄像机,即为逆时针,
758
+ // 否则说明该面背朝摄像机,为顺时针
759
+ switch ( cullingFaceMode ) {
760
+ case CullingFaceMode . Back :
761
+ if ( Vector3 . Dot ( normal , viewDir ) > 0 ) {
762
+ return true ;
763
+ }
764
+ break ;
765
+ case CullingFaceMode . Front :
766
+ if ( Vector3 . Dot ( normal , viewDir ) < 0 ) {
767
+ return true ;
768
+ }
769
+ break ;
770
+ case CullingFaceMode . All :
771
+ return true ;
772
+ }
773
+
774
+
775
+ return false ;
776
+ }
777
+
778
+ #endregion
779
+
723
780
#region 绘制更多图元
724
781
Mesh SpaceShip ;
725
782
Mesh cube ;
@@ -734,7 +791,7 @@ public void DrawMesh(Mesh mesh,Vector3 position,Vector3 scale,Vector3 rotation,S
734
791
Matrix4x4 projectionMatrix = camera . GetProjectionMatrix ( ) ;
735
792
736
793
// 构建MVP矩阵
737
- Matrix4x4 MVPMatrix = projectionMatrix * viewMatrix * modelMatrix ;
794
+ // Matrix4x4 MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
738
795
739
796
// 给每个顶点引用一份MVP矩阵
740
797
//foreach (int i in mesh.triangles) {
@@ -748,7 +805,7 @@ public void DrawMesh(Mesh mesh,Vector3 position,Vector3 scale,Vector3 rotation,S
748
805
mesh . pMatrix = projectionMatrix ;
749
806
750
807
751
- DrawElement ( mesh , MVPMatrix , softRenderDrawMode ) ;
808
+ DrawElement ( mesh , modelMatrix , viewMatrix , projectionMatrix , softRenderDrawMode ) ;
752
809
}
753
810
754
811
/// <summary>
@@ -761,7 +818,7 @@ public void DrawMesh(Mesh mesh,SoftRenderDrawMode drawMode=SoftRenderDrawMode.Tr
761
818
// 坐标/旋转与缩放
762
819
angel = ( angel + 1 ) % 720 ;
763
820
Vector3 rotation = new Vector3 ( angel , angel , angel ) ;
764
- Vector3 scale = new Vector3 ( 1 , 1 , 1 ) * 3 ;
821
+ Vector3 scale = new Vector3 ( 1 , 1 , 1 ) * 2 ;
765
822
Vector3 worldPosition = new Vector3 ( 0 , 0 , 0 ) ;
766
823
767
824
// 构建M矩阵
@@ -772,7 +829,7 @@ public void DrawMesh(Mesh mesh,SoftRenderDrawMode drawMode=SoftRenderDrawMode.Tr
772
829
Matrix4x4 projectionMatrix = camera . GetProjectionMatrix ( ) ;
773
830
774
831
// 构建MVP矩阵
775
- Matrix4x4 MVPMatrix = projectionMatrix * viewMatrix * modelMatrix ;
832
+ // Matrix4x4 MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
776
833
777
834
//// 给每个顶点引用一份MVP矩阵
778
835
//foreach (int i in mesh.triangles) {
@@ -786,7 +843,7 @@ public void DrawMesh(Mesh mesh,SoftRenderDrawMode drawMode=SoftRenderDrawMode.Tr
786
843
mesh . pMatrix = projectionMatrix ;
787
844
788
845
789
- DrawElement ( mesh , MVPMatrix , drawMode ) ;
846
+ DrawElement ( mesh , modelMatrix , viewMatrix , projectionMatrix , drawMode ) ;
790
847
}
791
848
792
849
#region 光照模型
0 commit comments