当前位置:网站首页>Cartoon rendering - average normal stroke
Cartoon rendering - average normal stroke
2022-07-02 09:03:00 【Ink pool Ivory】
【01】 Cartoon rendering from scratch - Stroke article ]
Recently learning rendering , I also learned when I started Back facing Stroke method , However, the cube is seriously fragmented , Just skip .
After reading this article, I learned how to average normals , The author saves the average normal to the tangent data of the model , It is also mentioned that you can convert to tangent space and then save to color or uv On . Because he only made the scheme of saving tangent data , I just want to try the scheme of using tangent space normals , Only when you write it out can you understand it well .
Slightly modify the author's tools , Save the grid locally .
《UnityShader Introduction to topic 》 Normal mapping related chapters of this book , Referred to the TBN matrix , stay C# Achieve it , And similar to the normal map, the numerical range is processed to [0,1].
Tools : Model average normal writes vertex color
[MenuItem("Tools/ Model average normal writes vertex color ")]
public static void WriteToColor()
{
MeshFilter[] meshFilters = Selection.activeGameObject.GetComponentsInChildren<MeshFilter>();
foreach (var meshFilter in meshFilters)
{
Mesh mesh = Object.Instantiate(meshFilter.sharedMesh);
ToColor(mesh);
AssetDatabase.CreateAsset(mesh, "Assets/" + meshFilter.name + "New.mesh");
}
SkinnedMeshRenderer[] skinMeshRenders = Selection.activeGameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (var skinMeshRender in skinMeshRenders)
{
Mesh mesh = Object.Instantiate(skinMeshRender.sharedMesh);
ToColor(mesh);
AssetDatabase.CreateAsset(mesh, "Assets/" + skinMeshRender.name + "New.mesh");
}
}
private static void ToColor(Mesh mesh)
{
var averageNormalHash = new Dictionary<Vector3, Vector3>();
for (var j = 0; j < mesh.vertexCount; j++)
{
if (!averageNormalHash.ContainsKey(mesh.vertices[j]))
{
averageNormalHash.Add(mesh.vertices[j], mesh.normals[j]);
}
else
{
averageNormalHash[mesh.vertices[j]] =
(averageNormalHash[mesh.vertices[j]] + mesh.normals[j]).normalized;
}
}
var averageNormals = new Vector3[mesh.vertexCount];
for (var j = 0; j < mesh.vertexCount; j++)
{
averageNormals[j] = averageNormalHash[mesh.vertices[j]];
// Go to tangent space And set it to [0,1] Range
var mNormal = mesh.normals[j];
var mTangent = mesh.tangents[j];
var mBinormal = Vector3.Cross(mNormal, new Vector3(mTangent.x, mTangent.y, mTangent.z)) * mTangent.w;
// Construction is by column , Here you need to press line
Matrix4x4 matrix = new Matrix4x4(new Vector3(mTangent.x, mTangent.y, mTangent.z).normalized, mBinormal.normalized, mNormal.normalized, Vector4.zero);
Matrix4x4 tmatrix = Matrix4x4.Transpose(matrix);
//[-1,1]=>[0,2]=>[0,1]
averageNormals[j] = (tmatrix.MultiplyVector(averageNormals[j]).normalized + Vector3.one) / 2.0f;
}
var colors = new Color[mesh.vertexCount];
for (var j = 0; j < mesh.vertexCount; j++)
{
colors[j] = new Color(averageNormals[j].x, averageNormals[j].y, averageNormals[j].z, 0);
}
mesh.colors = colors;
}
stay Shader It's similar , Transpose the matrix , It is the matrix from tangent space to model space
v2f vert(appdata v)
{
v2f o;
float4 pos = UnityObjectToClipPos(v.vertex);
TANGENT_SPACE_ROTATION;
float3 anormal = v.colors.rgb * 2 - 1;
// Transpose here ( The inverse ) once , because rotation Is the matrix from model space to tangent space
anormal = normalize(mul(transpose(rotation), anormal));
float3 viewNormal = mul((float3x3)UNITY_MATRIX_IT_MV, anormal.xyz);
float3 ndcNormal = normalize(TransformViewToProjection(viewNormal.xyz)) ;// Transform normals to NDC Space
float aspect = _ScreenParams.x / _ScreenParams.y;// Find the screen aspect ratio
ndcNormal.x /= aspect;
//pos.w It's about distance It will be removed after cutting , Zoom in and out , But we hope the trace in the distance is as big , So take it back , Avoid being eliminated
pos.xy += 0.01 * _OutlineScale * ndcNormal.xy * pos.w;
o.vertex = pos;
return o;
}
TANGENT_SPACE_ROTATION; You will get the model space to tangent space matrix rotation, Another transpose is tangent to model .
anormal Is the average normal in the restored model space
In order to be on the screen , No matter far or near, the stroke size remains the same , That is, to restore “ Perspective division ” To deal with , take w Multiply the weight back .
in addition , We found the extended x The incremental , After viewport transformation , It will be adjusted according to the screen resolution , The horizontal screen becomes larger and the vertical screen smaller , Therefore, it is also necessary to eliminate this influence .
边栏推荐
猜你喜欢
随机推荐
[flask] ORM one-to-one relationship
Qunhui NAS configuring iSCSI storage
MYSQL安装出现问题(The service already exists)
Move a string of numbers backward in sequence
WSL安装、美化、网络代理和远程开发
zipkin 简单使用
Web技术发展史
Qt的拖动事件
Gocv boundary fill
D interface and domain problems
QT qtimer class
ORA-12514问题解决方法
Minecraft模组服开服
使用IBM MQ远程连接时报错AMQ 4043解决思路
Luogu greedy part of the backpack line segment covers the queue to receive water
Using recursive functions to solve the inverse problem of strings
C # save web pages as pictures (using WebBrowser)
Minecraft插件服开服
Sqli labs level 12
统计字符串中各类字符的个数









