当前位置:网站首页>Flat shading with unity
Flat shading with unity
2022-06-30 13:52:00 【Return of different dimensions】
use Unity Realization Flat Shading
To achieve flat shading , Make every triangle smooth , We can start with the normal vector of the pixel , Let the normal of each pixel be equal to the normal of the triangle , Instead of interpolation from three vertex normals . To find the plane normal , You can take advantage of the ddx and ddy function , Separate calculation tangent and binormal vector , Finally, cross product normal:
float3 dpdx = ddx(i.worldPos);
float3 dpdy = ddy(i.worldPos);
i.normal = normalize(cross(dpdy, dpdx));

besides , We can also use geometry shader, Modify the vertex directly normal, Again fragment shader:
[maxvertexcount(3)]
void MyGeometryProgram (
triangle InterpolatorsVertex i[3],
inout TriangleStream<InterpolatorsVertex> stream
) {
float3 p0 = i[0].worldPos.xyz;
float3 p1 = i[1].worldPos.xyz;
float3 p2 = i[2].worldPos.xyz;
float3 triangleNormal = normalize(cross(p1 - p0, p2 - p0));
i[0].normal = triangleNormal;
i[1].normal = triangleNormal;
i[2].normal = triangleNormal;
stream.Append(i[0]);
stream.Append(i[1]);
stream.Append(i[2]);
}
Next , We want to add a line frame to the triangular surface on the basis of plane shading . So intuitively , Additional wireframe shading is required closer to the points on the edges of the triangle , The points inside the triangle are unaffected . Here we can judge with the help of the barycentric coordinates of the triangle , A point on the edge of a triangle , Its center of gravity coordinates (x,y,z) One of them must be 0. We started with geometry shader Add the attribute of barycentric coordinates in :
[maxvertexcount(3)]
void MyGeometryProgram (
triangle InterpolatorsVertex i[3],
inout TriangleStream<InterpolatorsVertex> stream
) {
...
i[0].barycentricCoordinates = float2(1, 0);
i[1].barycentricCoordinates = float2(0, 1);
i[2].barycentricCoordinates = float2(0, 0);
...
}
Only... Is used here float2 To represent the center of gravity coordinates , Because the barycentric coordinates have this property :x+y+z=1.
With the center of gravity coordinates , We can use it to draw wireframes . First , You can take the minimum value in the center of gravity coordinates , Represents the nearest distance from a point in a triangle to an edge , Then it is directly used to calculate the color :
float3 albedo = GetAlbedo(i);
float3 barys;
barys.xy = i.barycentricCoordinates;
barys.z = 1 - barys.x - barys.y;
float minBary = min(barys.x, min(barys.y, barys.z));
return albedo * minBary;

The prototype is here , But there are too many black places , The reason is that the minimum and maximum values in the barycentric coordinates are only 1/3, It has to be at the center of gravity . therefore , This range needs to be adjusted , We can use smoothstep function , Darken the shading of only a small part of the points , Then smooth transition to normal color :
float3 albedo = GetAlbedo(i);
float3 barys;
barys.xy = i.barycentricCoordinates;
barys.z = 1 - barys.x - barys.y;
float minBary = min(barys.x, min(barys.y, barys.z));
minBary = smoothstep(0, 0.1, minBary);
return albedo * minBary;

It looks good . But the beauty is , The width of the wireframe varies , It's easy to understand , After all, the area of screen space that a triangle can cover is different , A triangle covering a large area , The center of gravity coordinates change more slowly , That is to say, it is possible to change the barycentric coordinates from 0 Change to 0.1. that , Is there any way to unify the width of the triangle's wireframe ? This requires us to take into account the rate of change of the center of gravity coordinates . The smaller the rate of change , The lower the threshold to darken the wireframe . Speaking of the rate of change , We thought of what we mentioned before ddx and ddy function :
float3 albedo = GetAlbedo(i);
float3 barys;
barys.xy = i.barycentricCoordinates;
barys.z = 1 - barys.x - barys.y;
float minBary = min(barys.x, min(barys.y, barys.z));
// Equivalent to float delta = fwidth(minBary);
float delta = abs(ddx(minBary)) + abs(ddy(minBary));
minBary = smoothstep(0, delta, minBary);
return albedo * minBary;

We can also further adjust smoothstep Parameters of , To control the width of the wireframe :
minBary = smoothstep(delta, 2 * delta, minBary);

We noticed that , At this time, there are obvious sawtooth in some places . This is because we take the minimum value of the barycentric coordinates first , And then take the derivative , But this may be discontinuous . So we need to adjust the order , First of all, the coordinates of the center of gravity are xyz Derivation :
float3 albedo = GetAlbedo(i);
float3 barys;
barys.xy = i.barycentricCoordinates;
barys.z = 1 - barys.x - barys.y;
float3 deltas = fwidth(barys);
barys = smoothstep(deltas, 2 * deltas, barys);
float minBary = min(barys.x, min(barys.y, barys.z));
return albedo * minBary;

Effect grouping . Then finally , We expose some adjustable parameters , So we can adjust our performance at any time :
float3 albedo = GetAlbedo(i);
float3 barys;
barys.xy = i.barycentricCoordinates;
barys.z = 1 - barys.x - barys.y;
float3 deltas = fwidth(barys);
float3 smoothing = deltas * _WireframeSmoothing;
float3 thickness = deltas * _WireframeThickness;
barys = smoothstep(thickness, thickness + smoothing, barys);
float minBary = min(barys.x, min(barys.y, barys.z));
return lerp(_WireframeColor, albedo, minBary);
So we can adjust the color of the wireframe , Smoothness of transition , And the width of the wireframe itself :

If you think my article is helpful , Welcome to my WeChat official account. :Game_Develop_Forever
Reference
边栏推荐
- With the development of industrial Internet, the landing and application of the Internet has become wider
- Why can't the database table be written into data
- 第四批入围企业公示——年度TOP100智能网联供应商评选
- [deep anatomy of C language] storage principle of float variable in memory & comparison between pointer variable and "zero value"
- 【观察】智能产业加速,为何AI算力要先行?
- 想請教一下,我在佛山,到哪裏開戶比較好?手機開戶是安全麼?
- 目录相关命令
- The independent station is Web3.0. The national "14th five year plan" requires enterprises to build digital websites!
- visualstudio 和sql
- 深度长文探讨Join运算的简化和提速
猜你喜欢

【科学文献计量】外文文献及中文文献关键词的挖掘与可视化

Tencent two sides: @bean and @component are used on the same class. What happens?

ABAP toolbox v1.0 (with implementation ideas)

Optimization of unit test efficiency: why test programs? What are the benefits of testing?

How can I protect my private key?

Read all the knowledge points about enterprise im in one article

编程实战赛来啦!B站周边、高级会员等好礼送你啦!
![[deep anatomy of C language] storage principle of float variable in memory & comparison between pointer variable and](/img/3d/5d7fafba4ff7903afbd51d6d58dcdf.png)
[deep anatomy of C language] storage principle of float variable in memory & comparison between pointer variable and "zero value"

Step by step | help you easily submit Google play data security form

Kaniko official documents - build images in kubernetes
随机推荐
More than 20 years after Hong Kong's return, Tupu digital twin Hong Kong Zhuhai Macao Bridge has shocked
There is no utf8 option for creating tables in Navicat database.
2022-06-23 sail soft part formula and SQL generation (month and quarter retrieval)
今日睡眠质量记录80分
发生QQ大规模盗号事件,暴露出什么网络安全问题?
Basic syntax of unity script (2) -record time in unity
Simple understanding of the difference between get request and post submission
WTM major updates, multi tenancy and single sign on
想请教一下,我在佛山,到哪里开户比较好?手机开户是安全么?
Rk356x u-boot Institute (command section) 3.2 usage of help command
JS converts an array to a two-dimensional array based on the same value
一篇文章读懂关于企业IM的所有知识点
This article explains the concepts of typed array, arraybuffer, typedarray, DataView, etc
STM32 porting the fish component of RT thread Standard Edition
ERROR: Cannot uninstall ‘PyYAML‘. It is a distutils installed project and thus we cannot accurately
How can c write an SQL parser
All the abnormal knowledge you want is here
Write, append, read, and copy of golang files: examples of using bufio packages
DNS resolution home network access public DNS practice
[Title brushing] coco, who likes bananas