当前位置:网站首页>[TA frost wolf umay - "hundred people plan] Figure 3.3 surface subdivision and geometric shader large-scale grass rendering
[TA frost wolf umay - "hundred people plan] Figure 3.3 surface subdivision and geometric shader large-scale grass rendering
2022-07-24 11:27:00 【zczplus】
【TA- Frost Wolf _may-《 Hundred people plan 》】 graphics 3.3 Surface subdivision and geometry shaders Large scale grass rendering
- @[TOC](【TA- Frost Wolf _may-《 Hundred people plan 》】 graphics 3.3 Surface subdivision and geometry shaders Large scale grass rendering
- 3.3.1 Application of surface subdivision shader
- 3.3.2 Application of geometric shaders
- 3.3.3 TESS Input and output of
- 3.3.4 TESS technological process (Tessellation Shader )
- 3.3.5 GS Input and output
- Homework
【TA- Frost Wolf _may-《 Hundred people plan 》】 graphics 3.3 Surface subdivision and geometry shaders Large scale grass rendering
- @[TOC](【TA- Frost Wolf _may-《 Hundred people plan 》】 graphics 3.3 Surface subdivision and geometry shaders Large scale grass rendering
- 3.3.1 Application of surface subdivision shader
- 3.3.2 Application of geometric shaders
- 3.3.3 TESS Input and output of
- 3.3.4 TESS technological process (Tessellation Shader )
- 3.3.5 GS Input and output
- Homework
3.3.1 Application of surface subdivision shader
- The waves of the sea 、 The snow
- Combination with displacement mapping

3.3.2 Application of geometric shaders

Shader execution order

3.3.3 TESS Input and output of
- Input
Patch, It can be regarded as a collection of multiple vertices , Contains the attributes of each vertex , You can specify one Patch The number of vertices contained and their own attributes . - function
Subdivide the element ( It can be a triangle , Rectangle, etc ) - Output
Subdivided vertices
3.3.4 TESS technological process (Tessellation Shader )
- HULL Shader
- Determine the number of segments ( Set up Tessellation factor as well as Inside Tessellation factor)
- For the input Patch Change the parameters ( if necessary )
- Tessellation Primitive Generation
Subdivide - Domain Shader
Process the subdivided points , From center of gravity space to screen space
HULL Shader
Tessellation Factor
Used to decide how to divide an edge into several parts
equal_Spacing
fractional_even_spacing: The minimum value is 2
fractional_odd_spacing: The minimum value is 1
The last two parameters contain decimal parts , There are non equal length parts at both ends of the line , The function is to make the cut line segment smoother
Inner Tessellation Factor
Make a vertical line on the dividing point and generate an intersection , So as to get effective internal segmentation
3.3.5 GS Input and output
- Input : For element ( triangle , rectangular , Line, etc )
Depending on the element ,shader A different number of vertices will appear in the - The output is also an element , One or more , You need to build from the top , Order matters , At the same time, you need to define the maximum number of output vertices
Homework
Surface subdivision

Large area grass rendering

Generate grass according to the number of vertices , And you can change the orientation , length , Width , Color , And use the distorted texture to make the effect of wind .
Follow the link below , That's too much , All night , I almost understand the function of each piece of code . Add your own understanding of the code, and then record it later , It's convenient to find later .
Large area grass rendering tutorial ( The pure English course is super good , Maybe a ladder ?)
Tessellation Shader
Shader "Custom/100 learning/MyTessShader"
{
Properties
{
_TessellationUniform ("Tessellation Uniform", Range(1, 64)) = 1
}
SubShader
{
Tags {
"RenderType" = "Opaque"
}
Pass{
LOD 200
Name "FORWARD"
Tags{
"LightMode" = "ForwardBase"
}
CGPROGRAM
// Surface subdivision shaders contain hull shader and domain shader
// Plus Vertex shaders and fragment shaders
#pragma hull hullShader
#pragma domain domainShader
#pragma vertex tessVert
#pragma fragment frag
#include "UnityCG.cginc"
// Surface subdivision header file Including some auxiliary functions
#include "Tessellation.cginc"
#pragma target 5.0
sampler2D _MainTex;
float4 _MainTex_ST;
struct a2v{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
};
struct v2f{
float4 pos : SV_POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
};
// be applied to domain Function , Used to process coordinates
v2f vert (a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = v.normal;
o.tangent = v.tangent;
o.uv = v.uv;
return o;
}
#ifdef UNITY_CAN_COMPILE_TESSELLATION
struct tessVertex{
float4 vertex : INTERNALTESSPOS;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
};
// Different elements , The structure will be different be used for Hull Shader
struct outputPatchConstant{
float edge[3] : SV_TESSFACTOR;
float inside : SV_INSIDETESSFACTOR;
};
// Pass data from vertex shaders into surface subdivision shaders
tessVertex tessVert(a2v v){
tessVertex o;
o.vertex = v.vertex;
o.normal = v.normal;
o.tangent = v.tangent;
o.uv = v.uv;
return o;
}
float _TessellationUniform;
outputPatchConstant hsconst (InputPatch<tessVertex, 3> patch){
// Define surface subdivision parameters
outputPatchConstant o;
o.edge[0] = _TessellationUniform;
o.edge[1] = _TessellationUniform;
o.edge[2] = _TessellationUniform;
o.inside = _TessellationUniform;
return o;
}
// Determine the type of elements :quad / triangle
[UNITY_domain("tri")]
// Split edge The rules of :equal_spacing, fractional_odd, fractional_even
[UNITY_partitioning("fractional_odd")]
// Output triangle , For example, clockwise or counterclockwise It is related to back culling
[UNITY_outputtopology("triangle_cw")]
// One patch There are three points , But all three points share this function
[UNITY_patchconstantfunc("hsconst")]
// Different elements correspond to different control points
[UNITY_outputcontrolpoints(3)]
// Definition hullShader function
tessVertex hullShader (InputPatch<tessVertex, 3> patch, uint id : SV_OUTPUTCONTROLPOINTID){
return patch[id];
}
// Define the type of element : And hull shader In the same way
[UNITY_domain("tri")]
// bary Represents the coefficient under the center of gravity coordinate , Return the point under the center of gravity coordinate
v2f domainShader(outputPatchConstant tessFactors, const OutputPatch<tessVertex, 3> patch, float3 bary : SV_DOMAINLOCATION){
a2v v;
v.vertex = patch[0].vertex * bary.x + patch[1].vertex * bary.y + patch[2].vertex * bary.z;
v.tangent = patch[0].tangent * bary.x + patch[1].tangent * bary.y + patch[2].tangent * bary.z;
v.normal = patch[0].normal * bary.x + patch[1].normal * bary.y + patch[2].normal * bary.z;
v.uv = patch[0].uv * bary.x + patch[1].uv * bary.y + patch[2].uv * bary.z;
v2f o = vert (v);
return o;
}
#endif
fixed4 frag(v2f i):SV_Target{
return fixed4(1.0, 1.0, 1.0, 1.0);
}
ENDCG
}
}
FallBack Off
}
The grass Shader
Shader "Custom/100 learning/MyGrassShader"
{
Properties
{
[Header(Shading)]
// Color
_TopColor("Top Color", Color) = (1,1,1,1)
_BottomColor("Bottom Color", Color) = (1,1,1,1)
_TranslucentGain("Translucent Gain", Range(0,1)) = 0.5
// The width and height of the grass as well as Corresponding random adjustment threshold
_BladeWidth("Blade Width", Float) = 0.05
_BladeWidthRandom("Blade Width Random", Float) = 0.02
_BladeHeight("Blade Height", Float) = 0.5
_BladeHeightRandom("Blade Height Random", Float) = 0.3
// Random tilt threshold
_BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2
// Tessellation Shader relevant
_TessellationUniform("Tessellation Uniform", Range(1, 64)) = 1
// Add wind blown twisted texture
_WindDistortionMap("Wind Distortion Map", 2D) = "white" {
}
_WindFrequency("Wind Frequency", Vector) = (0.05, 0.05, 0, 0)
// Intensity of wind
_WindStrength("Wind Strength", Float) = 1
}
// CGINCLUDE Generally written in the book SubShader Outside Convenient for all SubShader share
CGINCLUDE
#include "UnityCG.cginc"
#include "Autolight.cginc"
#include "Tessellation.cginc"
// The function of this reference is the same as that of the above Tessellation As like as two peas
#include "Assets/100PersonPlan/Shader/CustomTessellation.cginc"
float _BendRotationRandom;
float _BladeHeight;
float _BladeHeightRandom;
float _BladeWidth;
float _BladeWidthRandom;
sampler2D _WindDistortionMap;
float4 _WindDistortionMap_ST;
float2 _WindFrequency;
float _WindStrength;
struct geometryOutput{
float4 pos : SV_POSITION;
#if UNITY_PASS_FORWARDBASE
// float3 normal : NORMAL;
float2 uv : TEXCOORD0;
// // unityShadowCoord4 is defined as a float4 in UnityShadowLibrary.cginc
// unityShadowCoord4 _ShadowCoord : TEXCOORD1;
#endif
};
// https://forum.unity.com/threads/am-i-over-complicating-this-random-function.454887/#post-2949326
// Returns a number in the 0...1 range.
float rand(float3 co){
return frac(sin(dot(co.xyz,float3(12.9898, 78.233, 53.539))) * 43758.5453);
}
// Construct a rotation matrix that rotates around the provided axis, sourced from:
// https://gist.github.com/keijiro/ee439d5e7388f3aafc5296005c8c3f33
float3x3 AngleAxis3x3(float angle, float3 axis){
float c, s;
// return sin and cos values of the given angle
sincos(angle, s, c);
float t = 1 - c;
float x = axis.x;
float y = axis.y;
float z = axis.z;
return float3x3(
t * x * x + c, t * x * y - s * z, t * x * z + s * y,
t * x * y + s * z, t * y * y + c, t * y * z - s * x,
t * x * z - s * y, t * y * z + s * x, t * z * z + c
);
}
// Because in CustomTessellation.cginc Has been defined in vertexInput vertexOutput as well as vert
// So the following three parts are omitted
// struct vertexInput{
// float4 vertex : POSITION;
// float3 normal : NORMAL;
// float4 tangent : TANGENT;
// };
// struct vertexOutput{
// float4 vertex : SV_POSITION;
// float3 normal : NORMAL;
// float4 tangent : TANGENT;
// };
// // Modify the vertex shader
// vertexOutput vert(vertexInput v){
// vertexOutput o;
// o.vertex = v.vertex;
// o.normal = v.normal;
// o.tangent = v.tangent;
// return o;
// }
geometryOutput VertexOutput(float3 pos, float2 uv){
geometryOutput o;
o.pos = UnityObjectToClipPos(pos);
o.uv = uv;
return o;
}
// The operation of transforming vertices Transferred to geometry shader in , therefore UnityObjectToClipPos Written in geo shader in
// There are two parameters in the function declaration section The first is input , Indicates receiving a triangle type , ( The interior contains three vertices )
// The second parameter means to output a triangles, And make use of geometryOutput To carry the data
[maxvertexcount(3)]
void geo(triangle vertexOutput IN[3], inout TriangleStream<geometryOutput> triStream){
geometryOutput o;
float3 pos = IN[0].vertex;
float3 vNormal = IN[0].normal;
float4 vTangent = IN[0].tangent;
float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;
// Used to convert between world space and tangent space
float3x3 tangentToLocal = float3x3(
vTangent.x, vBinormal.x, vNormal.x,
vTangent.y, vBinormal.y, vNormal.y,
vTangent.z, vBinormal.z, vNormal.z
);
// Randomly generate the rotation angle according to the current position , And specify the rotation as z Axis ( In tangent space )
float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0,0,1));
float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1,0,0));
// Use the position of the current point to sample the distorted texture , Instead of the texture coordinates of the given mesh , So as to achieve the effect of realistic wind
float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;
// Sample the distorted texture in combination with the strength of the wind Texture sampling range from 0 - 1 Turn into -1 - 1
float2 windSample = (tex2Dlod(_WindDistortionMap, float4 (uv, 0, 0)).xy * 2 - 1)* _WindStrength;
// Generate the axis of rotation
float3 wind = normalize(float3(windSample.x, windSample.y, 0));
// Generate rotation matrix
float3x3 windRotation = AngleAxis3x3(UNITY_PI * windSample, wind);
// Using translation matrix and rotation matrix to generate transformation matrix
float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);
// Use random numbers to generate the height and width of each piece of grass
float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;
float width = (rand(pos.xzy) * 2 -1) * _BladeWidthRandom + _BladeWidth;
// The processing of transforming points from model space to world space is extracted to the outside and becomes function calls
// The application of tangent change matrix becomes the transformation from tangent space to world space
triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(width, 0, 0)), float2(0, 0)));
triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(-width, 0, 0)), float2(1, 0)));
// In tangent coordinates , The direction pointing upwards is z Axis , So here's 1 Should be given z
triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(0, 0, height)), float2(0.5, 1)));
}
ENDCG
SubShader{
Cull Off
Pass{
Tags{
"RenderType" = "Opaque"
"lightMode" = "ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma hull hull
#pragma domain domain
#pragma geometry geo
#pragma fragment frag
#pragma target 4.6
#pragma multi_compile_fwdbase
#include "Lighting.cginc"
float4 _TopColor;
float4 _BottomColor;
float _TranslucentGain;
fixed4 frag(geometryOutput i, fixed facing : VFACE) : SV_Target{
return lerp(_BottomColor, _TopColor, i.uv.y);
}
ENDCG
}
}
FallBack Off
}
Add
After reading others' homework, I found that there are still many points that can be optimized , Then change !
边栏推荐
- Only "a little bit", why do developers look up to you?
- 链表——142. 环形链表 II
- 有关并行的两个重要定律
- This is the right way for developers to open artifact!
- 性能测试总结(一)---基础理论篇
- Tensor and numpy convert "suggested collection" to each other
- 黑马瑞吉外卖之员工信息分页查询
- [golang] golang implements the post request to send form type data function
- Depth first search and breadth first search of Graphs
- 运算放大器 —— 快速复苏笔记[贰](应用篇)
猜你喜欢

字符串——344.反转字符串
![MOS管 —— 快速复苏应用笔记(壹)[原理篇]](/img/a1/8427c9b1d0ea0cecce820816510045.png)
MOS管 —— 快速复苏应用笔记(壹)[原理篇]

How to convert word to markdown text

RRPN:Arbitrary-Oriented Scene Text Detection via Rotation Proposals

Sorting out the ideas of data processing received by TCP server, and the note of select: invalid argument error
What is cloud native? Why is cloud native technology so popular?

iMeta观点 | 短读长扩增子测序是否适用于微生物组功能的预测?

tcp 服务端接收数据处理思路梳理,以及select: Invalid argument报错 笔记

【C】 Understanding C language variable scope and life cycle from memory
什么是云原生,云原生技术为什么这么火?
随机推荐
[golang] golang implements sha256 encryption function
Lanqiao cup provincial training camp - commonly used STL
网络爬虫之短信验证
性能测试总结(一)---基础理论篇
What is the difference between strong reference, soft reference, weak reference and virtual reference?
Stm32+esp8266+mqtt protocol connects Alibaba cloud Internet of things platform
哈希——349. 两个数组的交集
Exceptions about configuring Postgres parameters
高频笔试题(蔚来)
Fiddler抓包工具总结
HCIP MGRE实验 第三天
Redis cluster setup
Pytorch learning -- using gradient descent method to realize univariate linear regression
Directional crawling Taobao product name and price (teacher Songtian)
How to access the code of online customer service system to your website
The U.S. Department of Homeland Security launched an investigation into the electronic communication records deleted by the secret service during the riots in the Capitol
JMeter if controller
JPS has no namenode and datanode reasons
Blue Bridge Cup provincial match training camp - Calculation of date
Performance test summary (I) -- basic theory