Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
n5
URasterizer
提交
632f3781
URasterizer
项目概览
n5
/
URasterizer
通知
21
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
URasterizer
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
632f3781
编写于
3月 14, 2022
作者:
H
happyfire
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
+ frustum culling for CPU Rasterizer
* fix clipped
上级
b72f4bac
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
1275 addition
and
661 deletion
+1275
-661
URasterizer/Assembly-CSharp.csproj
URasterizer/Assembly-CSharp.csproj
+608
-619
URasterizer/Assets/Samples/Scenes/TestScene01.unity
URasterizer/Assets/Samples/Scenes/TestScene01.unity
+479
-8
URasterizer/Assets/URasterizer/Codes/CPURasterizer.cs
URasterizer/Assets/URasterizer/Codes/CPURasterizer.cs
+148
-6
URasterizer/Assets/URasterizer/Codes/RenderingConfig.cs
URasterizer/Assets/URasterizer/Codes/RenderingConfig.cs
+1
-0
URasterizer/Assets/URasterizer/Codes/RenderingObject.cs
URasterizer/Assets/URasterizer/Codes/RenderingObject.cs
+1
-1
URasterizer/Assets/URasterizer/RenderingConfig.asset
URasterizer/Assets/URasterizer/RenderingConfig.asset
+2
-1
URasterizer/Assets/URasterizer/Shaders/URTriangleProcess.hlsl
...terizer/Assets/URasterizer/Shaders/URTriangleProcess.hlsl
+33
-20
URasterizer/URasterizer.sln
URasterizer/URasterizer.sln
+3
-6
未找到文件。
URasterizer/Assembly-CSharp.csproj
浏览文件 @
632f3781
此差异已折叠。
点击以展开。
URasterizer/Assets/Samples/Scenes/TestScene01.unity
浏览文件 @
632f3781
此差异已折叠。
点击以展开。
URasterizer/Assets/URasterizer/Codes/CPURasterizer.cs
浏览文件 @
632f3781
...
...
@@ -35,6 +35,7 @@ namespace URasterizer
//优化GC
Vector4
[]
_tmpVector4s
=
new
Vector4
[
3
];
Vector4
[]
_tmp8Vector4s
=
new
Vector4
[
8
];
Vector3
[]
_tmpVector3s
=
new
Vector3
[
3
];
public
String
Name
{
get
=>
"CPU"
;
}
...
...
@@ -173,6 +174,100 @@ namespace URasterizer
TransformTool
.
SetupViewProjectionMatrix
(
camera
,
Aspect
,
out
_matView
,
out
_matProjection
);
}
//在ClipSpace中,判断OBB顶点是否在视锥外部。输入v为clip space下OBB的8个顶点
//该函数使用的是保守视锥剔除算法,对于每个裁剪面都检查OBB的所有顶点是否在它外面,如果都在则剔除
//该算法是保守的,不会错误剔除掉不该剔除的OBB,但是可能有一些特殊位置的OBB剔除不掉,
//比如当OBB比较大且在视锥外,但是同时和左右近3个面相交,这样这3个面就无法成功判断剔除。
//这种情况一般是离镜头很近的大的墙体,可能会剔除不掉,造成性能问题。
//可参考:https://www.iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm
bool
CheckVerticesOutFrustumClipSpace
(
Vector4
[]
v
)
{
//left
int
cnt
=
0
;
for
(
int
i
=
0
;
i
<
8
;
++
i
){
var
w
=
v
[
i
].
w
>=
0
?
v
[
i
].
w
:
-
v
[
i
].
w
;
if
(
v
[
i
].
x
<
-
w
){
++
cnt
;
}
if
(
cnt
==
8
){
return
true
;
}
}
//right
cnt
=
0
;
for
(
int
i
=
0
;
i
<
8
;
++
i
){
var
w
=
v
[
i
].
w
>=
0
?
v
[
i
].
w
:
-
v
[
i
].
w
;
if
(
v
[
i
].
x
>
w
){
++
cnt
;
}
if
(
cnt
==
8
){
return
true
;
}
}
//bottom
cnt
=
0
;
for
(
int
i
=
0
;
i
<
8
;
++
i
){
var
w
=
v
[
i
].
w
>=
0
?
v
[
i
].
w
:
-
v
[
i
].
w
;
if
(
v
[
i
].
y
<
-
w
){
++
cnt
;
}
if
(
cnt
==
8
){
return
true
;
}
}
//top
cnt
=
0
;
for
(
int
i
=
0
;
i
<
8
;
++
i
){
var
w
=
v
[
i
].
w
>=
0
?
v
[
i
].
w
:
-
v
[
i
].
w
;
if
(
v
[
i
].
y
>
w
){
++
cnt
;
}
if
(
cnt
==
8
){
return
true
;
}
}
//near
cnt
=
0
;
for
(
int
i
=
0
;
i
<
8
;
++
i
){
var
w
=
v
[
i
].
w
>=
0
?
v
[
i
].
w
:
-
v
[
i
].
w
;
if
(
v
[
i
].
z
<
-
w
){
++
cnt
;
}
if
(
cnt
==
8
){
return
true
;
}
}
//far
cnt
=
0
;
for
(
int
i
=
0
;
i
<
8
;
++
i
){
var
w
=
v
[
i
].
w
>=
0
?
v
[
i
].
w
:
-
v
[
i
].
w
;
if
(
v
[
i
].
z
>
w
){
++
cnt
;
}
if
(
cnt
==
8
){
return
true
;
}
}
return
false
;
}
bool
FrustumCulling
(
Bounds
localAABB
,
Matrix4x4
mvp
)
{
var
v
=
_tmp8Vector4s
;
var
min
=
localAABB
.
min
;
min
.
z
=
-
min
.
z
;
var
max
=
localAABB
.
max
;
max
.
z
=
-
max
.
z
;
v
[
0
]
=
mvp
*
new
Vector4
(
min
.
x
,
min
.
y
,
min
.
z
,
1.0f
);
v
[
1
]
=
mvp
*
new
Vector4
(
min
.
x
,
min
.
y
,
max
.
z
,
1.0f
);
v
[
2
]
=
mvp
*
new
Vector4
(
min
.
x
,
max
.
y
,
min
.
z
,
1.0f
);
v
[
3
]
=
mvp
*
new
Vector4
(
min
.
x
,
max
.
y
,
max
.
z
,
1.0f
);
v
[
4
]
=
mvp
*
new
Vector4
(
max
.
x
,
min
.
y
,
min
.
z
,
1.0f
);
v
[
5
]
=
mvp
*
new
Vector4
(
max
.
x
,
min
.
y
,
max
.
z
,
1.0f
);
v
[
6
]
=
mvp
*
new
Vector4
(
max
.
x
,
max
.
y
,
min
.
z
,
1.0f
);
v
[
7
]
=
mvp
*
new
Vector4
(
max
.
x
,
max
.
y
,
max
.
z
,
1.0f
);
return
CheckVerticesOutFrustumClipSpace
(
v
);
}
public
void
DrawObject
(
RenderingObject
ro
)
{
ProfileManager
.
BeginSample
(
"CPURasterizer.DrawObject"
);
...
...
@@ -182,6 +277,11 @@ namespace URasterizer
_matModel
=
ro
.
GetModelMatrix
();
Matrix4x4
mvp
=
_matProjection
*
_matView
*
_matModel
;
if
(
_config
.
FrustumCulling
&&
FrustumCulling
(
mesh
.
bounds
,
mvp
)){
ProfileManager
.
EndSample
();
return
;
}
Matrix4x4
normalMat
=
_matModel
.
inverse
.
transpose
;
_verticesAll
+=
mesh
.
vertexCount
;
...
...
@@ -206,7 +306,7 @@ namespace URasterizer
var
normal
=
ro
.
MeshNormals
[
i
];
var
objNormal
=
new
Vector3
(
normal
.
x
,
normal
.
y
,
-
normal
.
z
);
vsOutput
[
i
].
objectNormal
=
objNormal
;
vsOutput
[
i
].
worldNormal
=
_matModel
*
objNormal
;
vsOutput
[
i
].
worldNormal
=
normalMat
*
objNormal
;
}
ProfileManager
.
EndSample
();
...
...
@@ -380,28 +480,70 @@ namespace URasterizer
//硬件实现时一般只对部分顶点z值在near,far之间的图元进行clipping操作,
//而部分顶点x,y值在x,y裁剪平面之间的图元则不进行裁剪,只是通过一个比viewport更大一些的guard-band区域进行整体剔除(相当于放大x,y的测试范围)
//这样x,y裁剪平面之间的图元最终在frame buffer上进行Scissor测试。
//此处的实现简化为只整体剔除,不做任何clipping操作。对于x,y裁剪没问题,虽然没扩大region,也可以最后在frame buffer上裁剪掉。
//此处的实现简化为只整体
的视锥
剔除,不做任何clipping操作。对于x,y裁剪没问题,虽然没扩大region,也可以最后在frame buffer上裁剪掉。
//对于z的裁剪由于没有处理,会看到整个三角形消失导致的边缘不齐整
//直接使用Clip space下的视锥剔除算法
bool
Clipped
(
Vector4
[]
v
)
{
//分别检查视锥体的六个面,如果三角形所有三个顶点都在某个面之外,则该三角形在视锥外,剔除
//由于NDC中总是满足-1<=Zndc<=1, 而当 w < 0 时,-w >= Zclip = Zndc*w >= w。所以此时clip space的坐标范围是[w,-w], 为了比较时更明确,将w取正
var
v0
=
v
[
0
];
var
w0
=
v0
.
w
>=
0
?
v0
.
w
:
-
v0
.
w
;
var
v1
=
v
[
1
];
var
w1
=
v1
.
w
>=
0
?
v1
.
w
:
-
v1
.
w
;
var
v2
=
v
[
2
];
var
w2
=
v2
.
w
>=
0
?
v2
.
w
:
-
v2
.
w
;
//left
if
(
v0
.
x
<
-
w0
&&
v1
.
x
<
-
w1
&&
v2
.
x
<
-
w2
){
return
true
;
}
//right
if
(
v0
.
x
>
w0
&&
v1
.
x
>
w1
&&
v2
.
x
>
w2
){
return
true
;
}
//bottom
if
(
v0
.
y
<
-
w0
&&
v1
.
y
<
-
w1
&&
v2
.
y
<
-
w2
){
return
true
;
}
//top
if
(
v0
.
y
>
w0
&&
v1
.
y
>
w1
&&
v2
.
y
>
w2
){
return
true
;
}
//near
if
(
v0
.
z
<
-
w0
&&
v1
.
z
<
-
w1
&&
v2
.
z
<
-
w2
){
return
true
;
}
//far
if
(
v0
.
z
>
w0
&&
v1
.
z
>
w1
&&
v2
.
z
>
w2
){
return
true
;
}
return
false
;
}
//Clipped_old的算法只检查顶点是否在视锥内。但是当三角形特别大,穿过视锥且所有顶点都在视锥外时,会错误认为是要剔除的 (false negative)
bool
Clipped_old
(
Vector4
[]
v
)
{
//Clip space使用GAMES101规范,右手坐标系,n为+1, f为-1
//裁剪(仅整体剔除)
//实际的硬件是在Clip space裁剪,所以此处我们也使用clip space
(当然由于我们不真正的裁剪,只是整体剔除,所以其实在NDC操作更方便)
//实际的硬件是在Clip space裁剪,所以此处我们也使用clip space
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
var
vertex
=
v
[
i
];
var
w
=
vertex
.
w
;
w
=
w
>=
0
?
w
:
-
w
;
//由于NDC中总是满足-1<=Zndc<=1, 而当 w < 0 时,-w >= Zclip = Zndc*w >= w。所以此时clip space的坐标范围是[w,-w], 为了比较时更明确,将w取正
w
=
w
>=
0
?
w
:
-
w
;
bool
inside
=
(
vertex
.
x
<=
w
&&
vertex
.
x
>=
-
w
&&
vertex
.
y
<=
w
&&
vertex
.
y
>=
-
w
&&
vertex
.
z
<=
w
&&
vertex
.
z
>=
-
w
);
if
(
inside
)
{
//不裁剪三角形,只要有任意一点在clip space中则三角形整体保留
//不裁剪三角形,只要有任意一点在clip space中则三角形整体保留
return
false
;
}
}
}
//三个顶点都不在三角形中则剔除
return
true
;
...
...
URasterizer/Assets/URasterizer/Codes/RenderingConfig.cs
浏览文件 @
632f3781
...
...
@@ -14,6 +14,7 @@ namespace URasterizer {
[
Header
(
"CPU Rasterizer ONLY Setting"
)]
public
bool
WireframeMode
=
false
;
public
bool
FrustumCulling
=
true
;
public
bool
BackfaceCulling
=
true
;
public
DisplayBufferType
DisplayBuffer
=
DisplayBufferType
.
Color
;
public
MSAALevel
MSAA
=
MSAALevel
.
Disabled
;
...
...
URasterizer/Assets/URasterizer/Codes/RenderingObject.cs
浏览文件 @
632f3781
...
...
@@ -83,7 +83,7 @@ namespace URasterizer
TriangleBuffer
=
new
ComputeBuffer
(
triangles
.
Length
,
3
*
sizeof
(
uint
));
TriangleBuffer
.
SetData
(
triangles
);
VertexOutBuffer
=
new
ComputeBuffer
(
vertexCnt
,
15
*
sizeof
(
float
));
VertexOutBuffer
=
new
ComputeBuffer
(
vertexCnt
,
15
*
sizeof
(
float
));
}
void
OnDestroy
()
...
...
URasterizer/Assets/URasterizer/RenderingConfig.asset
浏览文件 @
632f3781
...
...
@@ -17,10 +17,11 @@ MonoBehaviour:
RasterizerType
:
1
UseUnityNativeRendering
:
0
WireframeMode
:
0
FrustumCulling
:
1
BackfaceCulling
:
1
DisplayBuffer
:
0
MSAA
:
0
BilinearSample
:
1
FragmentShaderType
:
1
FragmentShaderType
:
0
VertexColors
:
{
fileID
:
11400000
,
guid
:
a126a2fdc8a60c54e8a3aadb7db4bb3a
,
type
:
2
}
ComputeShader
:
{
fileID
:
7200000
,
guid
:
caa96f337395ad9449e1be41546efcd6
,
type
:
3
}
URasterizer/Assets/URasterizer/Shaders/URTriangleProcess.hlsl
浏览文件 @
632f3781
bool
Clipped
(
float4
v
[
3
])
{
//Clip space使用GAMES101规范,右手坐标系,n为+1, f为-1
//裁剪(仅整体剔除)
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
float4
vertex
=
v
[
i
];
float
w
=
vertex
.
w
;
w
=
w
>=
0
?
w
:
-
w
;
//由于NDC中总是满足-1<=Zndc<=1, 而当 w < 0 时,-w >= Zclip = Zndc*w >= w。所以此时clip space的坐标范围是[w,-w], 为了比较时更明确,将w取正
bool
inside
=
(
vertex
.
x
<=
w
&&
vertex
.
x
>=
-
w
&&
vertex
.
y
<=
w
&&
vertex
.
y
>=
-
w
&&
vertex
.
z
<=
w
&&
vertex
.
z
>=
-
w
);
if
(
inside
)
{
//不裁剪三角形,只要有任意一点在clip space中则三角形整体保留
return
false
;
}
//分别检查视锥体的六个面,如果三角形所有三个顶点都在某个面之外,则该三角形在视锥外,剔除
//由于NDC中总是满足-1<=Zndc<=1, 而当 w < 0 时,-w >= Zclip = Zndc*w >= w。所以此时clip space的坐标范围是[w,-w], 为了比较时更明确,将w取正
float4
v0
=
v
[
0
];
float
w0
=
v0
.
w
>=
0
?
v0
.
w
:
-
v0
.
w
;
float4
v1
=
v
[
1
];
float
w1
=
v1
.
w
>=
0
?
v1
.
w
:
-
v1
.
w
;
float4
v2
=
v
[
2
];
float
w2
=
v2
.
w
>=
0
?
v2
.
w
:
-
v2
.
w
;
//left
if
(
v0
.
x
<
-
w0
&&
v1
.
x
<
-
w1
&&
v2
.
x
<
-
w2
){
return
true
;
}
//三个顶点都不在三角形中则剔除
return
true
;
//right
if
(
v0
.
x
>
w0
&&
v1
.
x
>
w1
&&
v2
.
x
>
w2
){
return
true
;
}
//bottom
if
(
v0
.
y
<
-
w0
&&
v1
.
y
<
-
w1
&&
v2
.
y
<
-
w2
){
return
true
;
}
//top
if
(
v0
.
y
>
w0
&&
v1
.
y
>
w1
&&
v2
.
y
>
w2
){
return
true
;
}
//near
if
(
v0
.
z
<
-
w0
&&
v1
.
z
<
-
w1
&&
v2
.
z
<
-
w2
){
return
true
;
}
//far
if
(
v0
.
z
>
w0
&&
v1
.
z
>
w1
&&
v2
.
z
>
w2
){
return
true
;
}
return
false
;
}
...
...
URasterizer/URasterizer.sln
浏览文件 @
632f3781
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{
08C43D46-104D-517B-7865-ADA4F8FB4D
91}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{
463dc408-4d10-7b51-7865-ada4f8fb4d
91}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{08C43D46-104D-517B-7865-ADA4F8FB4D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08C43D46-104D-517B-7865-ADA4F8FB4D91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08C43D46-104D-517B-7865-ADA4F8FB4D91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08C43D46-104D-517B-7865-ADA4F8FB4D91}.Release|Any CPU.Build.0 = Release|Any CPU
{463dc408-4d10-7b51-7865-ada4f8fb4d91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{463dc408-4d10-7b51-7865-ada4f8fb4d91}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录