当前位置:网站首页>Using tessellation in unity
Using tessellation in unity
2022-07-24 01:39:00 【Return of different dimensions】
stay Unity Use in Tessellation
Tessellation It's modern GPU An optional part of a programmable pipeline . It provides Hull shader and Domain shader For customization .

A complete hull shader It's like this :
[UNITY_domain("tri")]
[UNITY_outputcontrolpoints(3)]
[UNITY_outputtopology("triangle_cw")]
[UNITY_partitioning("integer")]
[UNITY_patchconstantfunc("MyPatchConstantFunction")]
TessellationControlPoint MyHullProgram (
InputPatch<TessellationControlPoint, 3> patch,
uint id : SV_OutputControlPointID
) {
return patch[id];
}
UNITY_domain("tri") Property indicates that the shader Is to deal with triangles .UNITY_outputcontrolpoints Attribute indicates the number of control points output , Here is a triangle patch The number of output vertices is 3 individual .UNITY_outputtopology Property indicates the winding order of the output triangle .UNITY_partitioning Attributes are used to tell GPU The way to subdivide triangles , Yes integer ,fractional_odd And so on .UNITY_patchconstantfunc Attributes are used to tell GPU, Which function to use to subdivide each patch. Different patch The result of subdivision may be different , This means that the function is not executed once at each control point , But in each patch Last time .
So let's take a look at patch constant function The appearance of , This function receives a message containing 3 A triangle of points patch, Output a file called TessellationFactors Data structure of , The data structure defines the subdivision coefficients of the three sides of the triangle , And the subdivision coefficient inside the triangle :
struct TessellationFactors {
float edge[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
TessellationFactors MyPatchConstantFunction (InputPatch<VertexData, 3> patch) {
TessellationFactors f;
f.edge[0] = 1;
f.edge[1] = 1;
f.edge[2] = 1;
f.inside = 1;
return f;
}
next , Let's take a look domain shader, Its purpose is to set the corresponding vertex attributes for the subdivided vertices , It's like an ordinary vertex , Before completion vertex shader What should have been done .
[UNITY_domain("tri")]
InterpolatorsVertex MyDomainProgram (
TessellationFactors factors,
OutputPatch<TessellationControlPoint, 3> patch,
float3 barycentricCoordinates : SV_DomainLocation
) {
VertexData data;
#define MY_DOMAIN_PROGRAM_INTERPOLATE(fieldName) data.fieldName = \
patch[0].fieldName * barycentricCoordinates.x + \
patch[1].fieldName * barycentricCoordinates.y + \
patch[2].fieldName * barycentricCoordinates.z;
MY_DOMAIN_PROGRAM_INTERPOLATE(vertex)
MY_DOMAIN_PROGRAM_INTERPOLATE(normal)
MY_DOMAIN_PROGRAM_INTERPOLATE(tangent)
MY_DOMAIN_PROGRAM_INTERPOLATE(uv)
return MyVertexProgram(data);
}
The center of gravity coordinates are introduced here , It is convenient for us to interpolate attributes . Macros are also defined here to reduce redundant code .
So we have a complete tessellation technological process , But the effect at this time is as if nothing happened :

The reason is simple , Namely patch const function The returned subdivision parameters are 1, We only have one side factor Adjust ( I.e. modification f.edge[0] Value ), Let's see 2~3 The effect of :


It can be seen that , There are more control points on one side , And there is also a control point inside the triangle , These control points are connected with the original three vertices of the triangle , Formed the subdivided triangle . Look at the inside of regulation factor The effect of ( I.e. modification f.inside Value ), Also from 2 Change to 3:


You can see ,2 There is a control point inside ,3 At that time, there appeared inside 3 Control points , this 3 Control points form a triangle . At this time, the law is still not obvious , Let's see 4 and 5 The situation of :


At this time, the law is more obvious ,4 The time is when there will be 4 Control points ,3 One forms a triangle , also 1 One will appear inside the triangle ;5 There will be 6 Control points , The inside of the triangle will be nested to form a triangle . And so on , When factor=2k+1 when , Internal will appear 3k Control points ; When factor=2k when , Internal will appear 3(k-1) + 1 Control points .
However, in practice, it regulates segmentation factor In the process of , We find that the change is completely discontinuous . Suppose we want to achieve a smooth transition of subdivision , What to do ?
At this time, we can modify the subdivision method , This can be done by setting [UNITY_partitioning("fractional_odd")] Realization , The effect is as follows :

Last , Let's consider how to choose the right segmentation factor. obviously , We want objects closer to us , The more details are displayed , Objects farther away from us , The less detail is displayed . We can use the information of screen space to judge . Transform objects into screen space , Calculate the distance between vertices , The greater the distance , The closer it is to us , Need more segmentation factor:
float4 p0 = UnityObjectToClipPos(cp0.vertex);
float4 p1 = UnityObjectToClipPos(cp1.vertex);
float edgeLength = distance(p0.xy / p0.w, p1.xy / p1.w);
return edgeLength * _ScreenParams.y / _TessellationEdgeLength;
There's another way to think about it , Is to take the midpoint of each side of the triangle , Calculate its distance from the camera , Adjust tessellation based on distance factor:
float3 p0 = mul(unity_ObjectToWorld, float4(cp0.vertex.xyz, 1)).xyz;
float3 p1 = mul(unity_ObjectToWorld, float4(cp1.vertex.xyz, 1)).xyz;
float edgeLength = distance(p0, p1);
float3 edgeCenter = (p0 + p1) * 0.5;
float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos);
return edgeLength / (_TessellationEdgeLength * viewDistance);
The final effect is as follows :

If you think my article is helpful , Welcome to my WeChat official account. :Game_Develop_Forever
Reference
边栏推荐
猜你喜欢

Precautions for using XXL job

Hcip network type, PPP session, data link layer protocol

Hcip day 5 notes

Introduction and environment construction of little bear sect

Notes - record a dynamic datasource please check the setting of primary problem solving

2022 global developer salary exposure: China ranks 19th, with an average annual salary of $23790
![[pumpkin Book ml] (task3) decision tree (updating)](/img/4c/fc7157518ad729400d605b811323de.png)
[pumpkin Book ml] (task3) decision tree (updating)

Code reading methods and best practices

Non boost ASIO notes: UDP UART socketcan multicast UDS

Draw a two coordinate diagram with MATLAB (the simplest in the whole network)
随机推荐
Arm architecture and programming 2 -- arm architecture (based on Baiwen arm architecture and programming tutorial video)
[pumpkin Book ml] (task3) decision tree (updating)
医院综合布线
[cloud native kubernetes] deployment advanced resource object management under kubernetes cluster
vantUI,Axiso,常见问题及使用:
HCIP第一天笔记
Hcip day 12 notes
Hcip experiment
How to finally generate a file from saveastextfile in spark
Hospital generic cabling
Topological sorting & critical path
Three document usage
jenkins多任務並發構建
MySQL Basics (operators, sorting and paging, multi table queries, functions)
Arm architecture and programming 7 -- exceptions and interrupts (based on Baiwen arm architecture and programming tutorial video)
基于强化空间注意力的视网膜网络(ESA-Unet)
Database paradigm and schema decomposition
20220723 record an unexplained shutdown of SAP Oracle monitoring service
医院网络安全架构
Interview question: what are the differences between ArrayList and LinkedList