提交 a4e2e6c3 编写于 作者: H happyfire

- GPU Rasterizer working

上级 b5a78132
此差异已折叠。
此差异已折叠。
...@@ -123,26 +123,6 @@ NavMeshSettings: ...@@ -123,26 +123,6 @@ NavMeshSettings:
debug: debug:
m_Flags: 0 m_Flags: 0
m_NavMeshData: {fileID: 0} m_NavMeshData: {fileID: 0}
--- !u!1 &14700134 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 8164078558771037576, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
m_PrefabInstance: {fileID: 1559831303}
m_PrefabAsset: {fileID: 0}
--- !u!114 &14700138
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 14700134}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 275ec1cd091f7d54cb532cf4c552b27a, type: 3}
m_Name:
m_EditorClassIdentifier:
mesh: {fileID: 0}
DoubleSideRendering: 0
texture: {fileID: 0}
--- !u!1 &256726191 --- !u!1 &256726191
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -181,7 +161,7 @@ MeshRenderer: ...@@ -181,7 +161,7 @@ MeshRenderer:
m_RenderingLayerMask: 1 m_RenderingLayerMask: 1
m_RendererPriority: 0 m_RendererPriority: 0
m_Materials: m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 2100000, guid: f9f96ee2bf6b64945b16abad7a676453, type: 2}
m_StaticBatchInfo: m_StaticBatchInfo:
firstSubMesh: 0 firstSubMesh: 0
subMeshCount: 0 subMeshCount: 0
...@@ -239,12 +219,6 @@ MonoBehaviour: ...@@ -239,12 +219,6 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
mesh: {fileID: 0} mesh: {fileID: 0}
DoubleSideRendering: 0 DoubleSideRendering: 0
texture: {fileID: 0}
--- !u!4 &280443493 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
m_PrefabInstance: {fileID: 1225451993}
m_PrefabAsset: {fileID: 0}
--- !u!1 &666679034 --- !u!1 &666679034
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -261,7 +235,7 @@ GameObject: ...@@ -261,7 +235,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!114 &666679035 --- !u!114 &666679035
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -296,28 +270,8 @@ Transform: ...@@ -296,28 +270,8 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 1651153439} m_Father: {fileID: 1651153439}
m_RootOrder: 5 m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &708288525 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 8164078558771037576, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
m_PrefabInstance: {fileID: 1225451993}
m_PrefabAsset: {fileID: 0}
--- !u!114 &708288527
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 708288525}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 275ec1cd091f7d54cb532cf4c552b27a, type: 3}
m_Name:
m_EditorClassIdentifier:
mesh: {fileID: 0}
DoubleSideRendering: 0
texture: {fileID: 0}
--- !u!1 &963210794 --- !u!1 &963210794
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -357,7 +311,7 @@ MeshRenderer: ...@@ -357,7 +311,7 @@ MeshRenderer:
m_RenderingLayerMask: 1 m_RenderingLayerMask: 1
m_RendererPriority: 0 m_RendererPriority: 0
m_Materials: m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 2100000, guid: f9f96ee2bf6b64945b16abad7a676453, type: 2}
m_StaticBatchInfo: m_StaticBatchInfo:
firstSubMesh: 0 firstSubMesh: 0
subMeshCount: 0 subMeshCount: 0
...@@ -416,7 +370,6 @@ MonoBehaviour: ...@@ -416,7 +370,6 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
mesh: {fileID: 0} mesh: {fileID: 0}
DoubleSideRendering: 0 DoubleSideRendering: 0
texture: {fileID: 0}
--- !u!95 &963210800 --- !u!95 &963210800
Animator: Animator:
serializedVersion: 3 serializedVersion: 3
...@@ -436,71 +389,6 @@ Animator: ...@@ -436,71 +389,6 @@ Animator:
m_HasTransformHierarchy: 1 m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1 m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorControllerStateOnDisable: 0 m_KeepAnimatorControllerStateOnDisable: 0
--- !u!1001 &1225451993
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 1651153439}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_RootOrder
value: 4
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalPosition.x
value: 1.79
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalPosition.y
value: -2.93
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalPosition.z
value: 3
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -7635826562936255635, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: f9f96ee2bf6b64945b16abad7a676453, type: 2}
- target: {fileID: 919132149155446097, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_Name
value: rock
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ce694dbb0170d7e439cd892f9f151786, type: 3}
--- !u!1 &1297680259 --- !u!1 &1297680259
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -521,7 +409,7 @@ GameObject: ...@@ -521,7 +409,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!64 &1297680260 --- !u!64 &1297680260
MeshCollider: MeshCollider:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -613,7 +501,6 @@ MonoBehaviour: ...@@ -613,7 +501,6 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
mesh: {fileID: 0} mesh: {fileID: 0}
DoubleSideRendering: 0 DoubleSideRendering: 0
texture: {fileID: 0}
--- !u!95 &1297680265 --- !u!95 &1297680265
Animator: Animator:
serializedVersion: 3 serializedVersion: 3
...@@ -633,71 +520,6 @@ Animator: ...@@ -633,71 +520,6 @@ Animator:
m_HasTransformHierarchy: 1 m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1 m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorControllerStateOnDisable: 0 m_KeepAnimatorControllerStateOnDisable: 0
--- !u!1001 &1559831303
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 1651153439}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_RootOrder
value: 3
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalPosition.x
value: -1.98
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -7635826562936255635, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 09e62c4a29022d248a7454ef0dba37f3, type: 2}
- target: {fileID: 919132149155446097, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_Name
value: spot_triangulated_good
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
--- !u!1 &1651153438 --- !u!1 &1651153438
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -728,17 +550,10 @@ Transform: ...@@ -728,17 +550,10 @@ Transform:
- {fileID: 256726195} - {fileID: 256726195}
- {fileID: 1297680263} - {fileID: 1297680263}
- {fileID: 963210798} - {fileID: 963210798}
- {fileID: 1809435259}
- {fileID: 280443493}
- {fileID: 666679036} - {fileID: 666679036}
m_Father: {fileID: 1977655288} m_Father: {fileID: 1977655288}
m_RootOrder: 1 m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &1809435259 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 0b4771b06a3a8614b822c760aaba2a18, type: 3}
m_PrefabInstance: {fileID: 1559831303}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1825649040 --- !u!1 &1825649040
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -855,7 +670,6 @@ MonoBehaviour: ...@@ -855,7 +670,6 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
mesh: {fileID: 0} mesh: {fileID: 0}
DoubleSideRendering: 0 DoubleSideRendering: 0
texture: {fileID: 0}
--- !u!1 &1933767904 --- !u!1 &1933767904
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
fileFormatVersion: 2
guid: ef50ff8ef83643a42a03be5b19e5196d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
...@@ -55,6 +55,10 @@ namespace URasterizer ...@@ -55,6 +55,10 @@ namespace URasterizer
Vector4[] _tmpVector4s = new Vector4[3]; Vector4[] _tmpVector4s = new Vector4[3];
Vector3[] _tmpVector3s = new Vector3[3]; Vector3[] _tmpVector3s = new Vector3[3];
public String Name { get=>"CPU"; }
public Texture ColorTexture { get=>texture; }
public CPURasterizer(int w, int h, RenderingConfig config) public CPURasterizer(int w, int h, RenderingConfig config)
{ {
......
...@@ -80,14 +80,9 @@ namespace URasterizer ...@@ -80,14 +80,9 @@ namespace URasterizer
if(_rasterizer != _lastRasterizer){ if(_rasterizer != _lastRasterizer){
_lastRasterizer = _rasterizer; _lastRasterizer = _rasterizer;
if(_rasterizer == _cpuRasterizer){
rawImg.texture = _cpuRasterizer.texture; rawImg.texture = _rasterizer.ColorTexture;
_statsPanel.SetRasterizerType("CPU"); _statsPanel.SetRasterizerType(_rasterizer.Name);
}
else if(_rasterizer == _gpuRasterizer){
rawImg.texture = _gpuRasterizer.texture;
_statsPanel.SetRasterizerType("GPU Driven");
}
} }
var r = _rasterizer; var r = _rasterizer;
......
...@@ -4,9 +4,12 @@ namespace URasterizer ...@@ -4,9 +4,12 @@ namespace URasterizer
{ {
public interface IRasterizer public interface IRasterizer
{ {
string Name { get; }
void Clear(BufferMask mask); void Clear(BufferMask mask);
void Draw(RenderingObject ro, Camera camera); void Draw(RenderingObject ro, Camera camera);
Texture ColorTexture { get; }
void UpdateFrame(); void UpdateFrame();
FragmentShader CurrentFragmentShader { get; set; } FragmentShader CurrentFragmentShader { get; set; }
......
...@@ -7,6 +7,7 @@ namespace URasterizer ...@@ -7,6 +7,7 @@ namespace URasterizer
{ {
public Mesh mesh; public Mesh mesh;
public bool DoubleSideRendering; public bool DoubleSideRendering;
[HideInInspector, System.NonSerialized]
public Texture2D texture; public Texture2D texture;
//缓存避免在draw loop中从mesh copy //缓存避免在draw loop中从mesh copy
...@@ -23,7 +24,10 @@ namespace URasterizer ...@@ -23,7 +24,10 @@ namespace URasterizer
public ComputeBuffer VertexBuffer; public ComputeBuffer VertexBuffer;
public ComputeBuffer NormalBuffer; public ComputeBuffer NormalBuffer;
public ComputeBuffer OutBuffer; public ComputeBuffer TriangleBuffer;
public ComputeBuffer VertexOutBuffer;
public ComputeBuffer RenderTriangleBuffer;
private void Start() private void Start()
...@@ -47,23 +51,43 @@ namespace URasterizer ...@@ -47,23 +51,43 @@ namespace URasterizer
//为了能在运行时动态切换是否使用 GPU Driven Rasterizer, 这里同时把GPU使用的Compute Buffer创建出来 //为了能在运行时动态切换是否使用 GPU Driven Rasterizer, 这里同时把GPU使用的Compute Buffer创建出来
int vertexCnt = mesh.vertexCount; int vertexCnt = mesh.vertexCount;
VertexBuffer = new ComputeBuffer(vertexCnt, 3*sizeof(float)); VertexBuffer = new ComputeBuffer(vertexCnt, 3*sizeof(float));
VertexBuffer.name = "VertexBuffer";
VertexBuffer.SetData(MeshVertices); VertexBuffer.SetData(MeshVertices);
NormalBuffer = new ComputeBuffer(vertexCnt, 3*sizeof(float)); NormalBuffer = new ComputeBuffer(vertexCnt, 3*sizeof(float));
NormalBuffer.name = "NormalBuffer";
NormalBuffer.SetData(MeshNormals); NormalBuffer.SetData(MeshNormals);
//初始化三角形数组,每个三角形包含3个索引值
//注意这儿对调了v0和v1的索引,因为原来的 0,1,2是顺时针的,对调后是 1,0,2是逆时针的
//Unity Quard模型的两个三角形索引分别是 0,3,1,3,0,2 转换后为 3,0,1,0,3,2
int idxCnt = MeshTriangles.Length;
Vector3Int[] triangles = new Vector3Int[idxCnt/3];
for(int i=0; i < triangles.Length; ++i){
triangles[i].x = MeshTriangles[i*3+1];
triangles[i].y = MeshTriangles[i*3];
triangles[i].z = MeshTriangles[i*3+2];
}
TriangleBuffer = new ComputeBuffer(triangles.Length, 3*sizeof(uint));
TriangleBuffer.SetData(triangles);
OutBuffer = new ComputeBuffer(vertexCnt, 13*sizeof(float)); VertexOutBuffer = new ComputeBuffer(vertexCnt, 13*sizeof(float));
OutBuffer.name = "OutBuffer";
RenderTriangleBuffer = new ComputeBuffer(MeshTriangles.Length/3, sizeof(uint)*3, ComputeBufferType.Append);
} }
void OnDestroy() void OnDestroy()
{ {
VertexBuffer.Release(); VertexBuffer.Release();
VertexBuffer = null;
NormalBuffer.Release(); NormalBuffer.Release();
OutBuffer.Release(); NormalBuffer = null;
VertexOutBuffer.Release();
VertexOutBuffer = null;
TriangleBuffer.Release();
TriangleBuffer = null;
RenderTriangleBuffer.Release();
RenderTriangleBuffer = null;
} }
......
#pragma kernel VertexProcess #pragma kernel VertexProcess
#pragma kernel ClearFrame
#pragma kernel TriangleSetup
#pragma kernel RasterizeTriangle
struct OutBuf struct VertexOutBuf
{ {
float4 clipPos; float4 clipPos;
float3 worldPos; float3 worldPos;
...@@ -9,22 +12,343 @@ struct OutBuf ...@@ -9,22 +12,343 @@ struct OutBuf
float3 worldNormal; float3 worldNormal;
}; };
float4 ClearColor;
uint2 FrameBufferSize;
float4x4 matMVP; float4x4 matMVP;
float4x4 matModel; float4x4 matModel;
uint currentRenderTriangle;
StructuredBuffer<float3> vertexBuffer; StructuredBuffer<float3> vertexBuffer;
StructuredBuffer<float3> normalBuffer; StructuredBuffer<float3> normalBuffer;
RWStructuredBuffer<OutBuf> outBuffer; RWStructuredBuffer<VertexOutBuf> vertexOutBuffer;
StructuredBuffer<uint3> triangleBuffer; // All triangles of the mesh
AppendStructuredBuffer<uint3> renderTriangleBuffer; //triangles to render
ConsumeStructuredBuffer<uint3> renderCosumeBuffer;
RWTexture2D<float4> frameColorTexture;
[numthreads(32,24,1)]
void ClearFrame(uint3 id : SV_DispatchThreadID)
{
frameColorTexture[id.xy] = ClearColor;
}
[numthreads(768,1,1)] [numthreads(768,1,1)]
void VertexProcess (uint3 id : SV_DispatchThreadID) void VertexProcess (uint3 id : SV_DispatchThreadID)
{ {
float4 pos = float4(vertexBuffer[id.x].x, vertexBuffer[id.x].y, -vertexBuffer[id.x].z, 1.0f); float4 pos = float4(vertexBuffer[id.x].x, vertexBuffer[id.x].y, -vertexBuffer[id.x].z, 1.0f);
float3 normal = float3(normalBuffer[id.x].x, normalBuffer[id.x].y, -normalBuffer[id.x].z); float3 normal = float3(normalBuffer[id.x].x, normalBuffer[id.x].y, -normalBuffer[id.x].z);
outBuffer[id.x].clipPos = mul(matMVP, pos); vertexOutBuffer[id.x].clipPos = mul(matMVP, pos);
outBuffer[id.x].worldPos = mul(matModel, pos).xyz; vertexOutBuffer[id.x].worldPos = mul(matModel, pos).xyz;
outBuffer[id.x].objectNormal = normal; vertexOutBuffer[id.x].objectNormal = normal;
outBuffer[id.x].worldNormal = mul( (float3x3)matModel , normal); vertexOutBuffer[id.x].worldNormal = mul( (float3x3)matModel , normal);
}
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;
}
}
//三个顶点都不在三角形中则剔除
return true;
}
[numthreads(768,1,1)]
void TriangleSetup(uint3 id : SV_DispatchThreadID)
{
uint3 tri = triangleBuffer[id.x];
int idx0 = tri.x;
int idx1 = tri.y;
int idx2 = tri.z;
float4 v[3];
v[0] = vertexOutBuffer[idx0].clipPos;
v[1] = vertexOutBuffer[idx1].clipPos;
v[2] = vertexOutBuffer[idx2].clipPos;
if(Clipped(v)){
return;
}
//Perspective division, clip space to NDC
for (int k=0; k<3; k++)
{
v[k].x /= v[k].w;
v[k].y /= v[k].w;
v[k].z /= v[k].w;
}
//backface culling
float3 e01 = v[1].xyz - v[0].xyz;
float3 e02 = v[2].xyz - v[0].xyz;
float3 crossv = cross(e01, e02);
if (crossv.z < 0)
{
return;
}
//Viewport Transform, NDC to screen space
for (k = 0; k < 3; k++)
{
float4 vec = v[k];
vec.x = 0.5f * FrameBufferSize.x * (vec.x + 1.0f);
vec.y = 0.5f * FrameBufferSize.y * (vec.y + 1.0f);
//在硬件渲染中,NDC的z值经过硬件的透视除法之后就直接写入到depth buffer了,如果要调整需要在投影矩阵中调整
//由于我们是软件渲染,所以可以在这里调整z值。
//GAMES101约定的NDC是右手坐标系,z值范围是[-1,1],但n为1,f为-1,因此值越大越靠近n。
//为了可视化Depth buffer,将最终的z值从[-1,1]映射到[0,1]的范围,因此最终n为1, f为0。离n越近,深度值越大。
//由于远处的z值为0,因此clear时深度要清除为0,然后深度测试时,使用GREATER测试。
//(当然我们也可以在这儿反转z值,然后clear时使用float.MaxValue清除,并且深度测试时使用LESS_EQUAL测试)
//注意:这儿的z值调整并不是必要的,只是为了可视化时便于映射为颜色值。其实也可以在可视化的地方调整。
//但是这么调整后,正好和Unity在DirectX平台的Reverse z一样,让near plane附近的z值的浮点数精度提高。
vec.z = vec.z * 0.5f + 0.5f;
v[k] = vec;
}
//Screen space coordinates saved in clip pos
vertexOutBuffer[idx0].clipPos = v[0];
vertexOutBuffer[idx1].clipPos = v[1];
vertexOutBuffer[idx2].clipPos = v[2];
//triangle actually rendering append to this buffer
renderTriangleBuffer.Append(uint3(idx0, idx1, idx2));
}
float3 ComputeBarycentric2D(float x, float y, float4 v[3])
{
float c1 = (x * (v[1].y - v[2].y) + (v[2].x - v[1].x) * y + v[1].x * v[2].y - v[2].x * v[1].y) / (v[0].x * (v[1].y - v[2].y) + (v[2].x - v[1].x) * v[0].y + v[1].x * v[2].y - v[2].x * v[1].y);
float c2 = (x * (v[2].y - v[0].y) + (v[0].x - v[2].x) * y + v[2].x * v[0].y - v[0].x * v[2].y) / (v[1].x * (v[2].y - v[0].y) + (v[0].x - v[2].x) * v[1].y + v[2].x * v[0].y - v[0].x * v[2].y);
float c3 = (x * (v[0].y - v[1].y) + (v[1].x - v[0].x) * y + v[0].x * v[1].y - v[1].x * v[0].y) / (v[2].x * (v[0].y - v[1].y) + (v[1].x - v[0].x) * v[2].y + v[0].x * v[1].y - v[1].x * v[0].y);
return float3(c1, c2, c3);
}
[numthreads(32,24,1)]
void RasterizeTriangle(uint3 id : SV_DispatchThreadID)
{
uint3 tri = renderCosumeBuffer.Consume();// triangleBuffer[currentRenderTriangle]; //triangleBuffer
int idx0 = tri.x;
int idx1 = tri.y;
int idx2 = tri.z;
float4 v[3];
v[0] = vertexOutBuffer[idx0].clipPos;
v[1] = vertexOutBuffer[idx1].clipPos;
v[2] = vertexOutBuffer[idx2].clipPos;
//这个函数,每个像素都会执行,最好用一个buffer存所有的需要渲染的三角形的AABB,避免每次都在这儿计算
//Find out the bounding box of current triangle.
float minX = v[0].x;
float maxX = minX;
float minY = v[0].y;
float maxY = minY;
for(int i=1; i<3; ++i)
{
float x = v[i].x;
if(x < minX)
{
minX = x;
} else if(x > maxX)
{
maxX = x;
}
float y = v[i].y;
if(y < minY)
{
minY = y;
}else if(y > maxY)
{
maxY = y;
}
}
int minPX = floor(minX);
minPX = minPX < 0 ? 0 : minPX;
int maxPX = ceil(maxX);
maxPX = maxPX > FrameBufferSize.x ? FrameBufferSize.x : maxPX;
int minPY = floor(minY);
minPY = minPY < 0 ? 0 : minPY;
int maxPY = ceil(maxY);
maxPY = maxPY > FrameBufferSize.y ? FrameBufferSize.y : maxPY;
//判断当前像素是否在AABB中
if(id.x < minPX || id.x > maxPX || id.y < minPY || id.y > maxPY){
return;
}
int x = id.x;
int y = id.y;
//计算重心坐标
float3 c = ComputeBarycentric2D(x, y, v);
float alpha = c.x;
float beta = c.y;
float gamma = c.z;
if(alpha < 0 || beta < 0 || gamma < 0){
return;
}
//透视校正插值,z为透视校正插值后的view space z值
float z = 1.0f / (alpha / v[0].w + beta / v[1].w + gamma / v[2].w);
//zp为透视校正插值后的screen space z值
float zp = (alpha * v[0].z / v[0].w + beta * v[1].z / v[1].w + gamma * v[2].z / v[2].w) * z;
//深度测试(注意我们这儿的z值越大越靠近near plane,因此大值通过测试)
//if(zp >= depth_buf[index])
//depth_buf[index] = zp;
//透视校正插值
//float3 color_p = (alpha * t.Vertex0.Color / v[0].w + beta * t.Vertex1.Color / v[1].w + gamma * t.Vertex2.Color / v[2].w) * z;
//Vector2 uv_p = (alpha * t.Vertex0.Texcoord / v[0].w + beta * t.Vertex1.Texcoord / v[1].w + gamma * t.Vertex2.Texcoord / v[2].w) * z;
//Vector3 normal_p = (alpha * t.Vertex0.Normal / v[0].w + beta * t.Vertex1.Normal / v[1].w + gamma * t.Vertex2.Normal / v[2].w) * z;
//Vector3 worldPos_p = (alpha * t.Vertex0.WorldPos / v[0].w + beta * t.Vertex1.WorldPos / v[1].w + gamma * t.Vertex2.WorldPos / v[2].w) * z;
//Vector3 worldNormal_p = (alpha * t.Vertex0.WorldNormal / v[0].w + beta * t.Vertex1.WorldNormal / v[1].w + gamma * t.Vertex2.WorldNormal / v[2].w) * z;
//if (CurrentFragmentShader != null)
{
//FragmentShaderInputData input = new FragmentShaderInputData();
//input.Color = color_p;
//input.UV = uv_p;
//input.Texture = ro.texture;
//input.LocalNormal = normal_p;
//input.WorldPos = worldPos_p;
//input.WorldNormal = worldNormal_p;
frameColorTexture[id.xy] = float4(1,1,1,1);
}
} }
// void RasterizeTriangle(Triangle t, RenderingObject ro)
// {
// ProfileManager.BeginSample("Rasterizer.RasterizeTriangle");
// var v = _tmpVector4s;
// v[0] = t.Vertex0.Position;
// v[1] = t.Vertex1.Position;
// v[2] = t.Vertex2.Position;
// //Find out the bounding box of current triangle.
// float minX = v[0].x;
// float maxX = minX;
// float minY = v[0].y;
// float maxY = minY;
// for(int i=1; i<3; ++i)
// {
// float x = v[i].x;
// if(x < minX)
// {
// minX = x;
// } else if(x > maxX)
// {
// maxX = x;
// }
// float y = v[i].y;
// if(y < minY)
// {
// minY = y;
// }else if(y > maxY)
// {
// maxY = y;
// }
// }
// int minPX = Mathf.FloorToInt(minX);
// minPX = minPX < 0 ? 0 : minPX;
// int maxPX = Mathf.CeilToInt(maxX);
// maxPX = maxPX > _width ? _width : maxPX;
// int minPY = Mathf.FloorToInt(minY);
// minPY = minPY < 0 ? 0 : minPY;
// int maxPY = Mathf.CeilToInt(maxY);
// maxPY = maxPY > _height ? _height : maxPY;
// if(_config.MSAA == MSAALevel.Disabled)
// {
// // 遍历当前三角形包围中的所有像素,判断当前像素是否在三角形中
// // 对于在三角形中的像素,使用重心坐标插值得到深度值,并使用z buffer进行深度测试和写入
// for(int y = minPY; y < maxPY; ++y)
// {
// for(int x = minPX; x < maxPX; ++x)
// {
// //if(IsInsideTriangle(x, y, t)) //-->检测是否在三角形内比使用重心坐标检测要慢,因此先计算重心坐标,再检查3个坐标是否有小于0
// {
// //计算重心坐标
// var c = ComputeBarycentric2D(x, y, t);
// float alpha = c.x;
// float beta = c.y;
// float gamma = c.z;
// if(alpha < 0 || beta < 0 || gamma < 0){
// continue;
// }
// //透视校正插值,z为透视校正插值后的view space z值
// float z = 1.0f / (alpha / v[0].w + beta / v[1].w + gamma / v[2].w);
// //zp为透视校正插值后的screen space z值
// float zp = (alpha * v[0].z / v[0].w + beta * v[1].z / v[1].w + gamma * v[2].z / v[2].w) * z;
// //深度测试(注意我们这儿的z值越大越靠近near plane,因此大值通过测试)
// int index = GetIndex(x, y);
// if(zp >= depth_buf[index])
// {
// depth_buf[index] = zp;
// //透视校正插值
// ProfileManager.BeginSample("Rasterizer.RasterizeTriangle.AttributeInterpolation");
// Color color_p = (alpha * t.Vertex0.Color / v[0].w + beta * t.Vertex1.Color / v[1].w + gamma * t.Vertex2.Color / v[2].w) * z;
// Vector2 uv_p = (alpha * t.Vertex0.Texcoord / v[0].w + beta * t.Vertex1.Texcoord / v[1].w + gamma * t.Vertex2.Texcoord / v[2].w) * z;
// Vector3 normal_p = (alpha * t.Vertex0.Normal / v[0].w + beta * t.Vertex1.Normal / v[1].w + gamma * t.Vertex2.Normal / v[2].w) * z;
// Vector3 worldPos_p = (alpha * t.Vertex0.WorldPos / v[0].w + beta * t.Vertex1.WorldPos / v[1].w + gamma * t.Vertex2.WorldPos / v[2].w) * z;
// Vector3 worldNormal_p = (alpha * t.Vertex0.WorldNormal / v[0].w + beta * t.Vertex1.WorldNormal / v[1].w + gamma * t.Vertex2.WorldNormal / v[2].w) * z;
// ProfileManager.EndSample();
// if (CurrentFragmentShader != null)
// {
// FragmentShaderInputData input = new FragmentShaderInputData();
// input.Color = color_p;
// input.UV = uv_p;
// input.Texture = ro.texture;
// input.LocalNormal = normal_p;
// input.WorldPos = worldPos_p;
// input.WorldNormal = worldNormal_p;
// ProfileManager.BeginSample("Rasterizer.RasterizeTriangle.FragmentShader");
// frame_buf[index] = CurrentFragmentShader(input);
// ProfileManager.EndSample();
// }
// }
// }
// }
// }
// }
// ProfileManager.EndSample();
// }
...@@ -12,7 +12,7 @@ MonoBehaviour: ...@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5fa123a60a768444af03a384cb34a74, type: 3} m_Script: {fileID: 11500000, guid: d5fa123a60a768444af03a384cb34a74, type: 3}
m_Name: RenderingConfig m_Name: RenderingConfig
m_EditorClassIdentifier: m_EditorClassIdentifier:
ClearColor: {r: 0, g: 0, b: 0, a: 1} ClearColor: {r: 0.056692798, g: 0.41403675, b: 0.9245283, a: 0.24705882}
WireframeMode: 0 WireframeMode: 0
BackfaceCulling: 1 BackfaceCulling: 1
DisplayBuffer: 0 DisplayBuffer: 0
......
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{463dc408-4d10-7b51-7865-ada4f8fb4d91}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{08C43D46-104D-517B-7865-ADA4F8FB4D91}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{463dc408-4d10-7b51-7865-ada4f8fb4d91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {08C43D46-104D-517B-7865-ADA4F8FB4D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{463dc408-4d10-7b51-7865-ada4f8fb4d91}.Debug|Any CPU.Build.0 = 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
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
...@@ -14,6 +14,12 @@ EditorUserSettings: ...@@ -14,6 +14,12 @@ EditorUserSettings:
RecentlyUsedScenePath-2: RecentlyUsedScenePath-2:
value: 224247031146466e3f0f1f361531560a1305571f1e293524283b1429e7f2073be7e933a7f234362820 value: 224247031146466e3f0f1f361531560a1305571f1e293524283b1429e7f2073be7e933a7f234362820
flags: 0 flags: 0
RecentlyUsedScenePath-3:
value: 22424703114646680c031c2e153010231512162f3f6712353e3d2e30e7ee3168b0a923e7ee2e26
flags: 0
RecentlyUsedScenePath-4:
value: 22424703114646680c031c2e153010231512162f3f6712353e3d2e30e7ee3168b3a923e7ee2e26
flags: 0
vcSharedLogLevel: vcSharedLogLevel:
value: 0d5e400f0650 value: 0d5e400f0650
flags: 0 flags: 0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册