当前位置:网站首页>[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 !
边栏推荐
- 有关并行的两个重要定律
- cgo+gSoap+onvif学习总结:9、go和c进行socket通信进行onvif协议处理
- What is the difference between strong reference, soft reference, weak reference and virtual reference?
- Robot framework official tutorial (I) getting started
- 【Markdown语法高级】让你的博客更精彩(四:设置字体样式以及颜色对照表)
- 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
- 只会“点点点”,凭什么让开发看得起你?
- Exceptions about configuring Postgres parameters
- 2022, the average salary of the soft tester, after reading it, I was instantly cool
- [golang] golang implements the string interception function substr
猜你喜欢

How to convert word to markdown text

Nodejs ctf 基础
](/img/fd/e12f43e23e6ec76c2b44ce7813e204.png)
运算放大器 —— 快速复苏笔记[贰](应用篇)

Selenium automated test (this one is enough) - self study

Depth first search and breadth first search of Graphs

Lanqiao cup provincial training camp - stack and recursion

stream流

使用Prometheus+Grafana实时监控服务器性能

How to choose sentinel vs. hystrix current limiting?

Two important laws about parallelism
随机推荐
Performance test summary (I) -- basic theory
Blue Bridge Cup provincial match training camp - Calculation of date
Ctfshow ThinkPHP topic 1
Paging query of employee information of black maredge takeout
什么是云原生,云原生技术为什么这么火?
What is the difference between strong reference, soft reference, weak reference and virtual reference?
How to choose sentinel vs. hystrix current limiting?
Leetcode 112. 路径总和
Neo4j installation tutorial
Fiddler抓包工具总结
HDU 3351:Seinfeld
Video playback | how to become an excellent reviewer of international journals in the field of Geoscience and ecology?
【Golang】golang实现sha256加密函数
性能测试总结(一)---基础理论篇
ctfshow ThinkPHP专题 1
哈希——1. 两数之和——有人白天相爱,有人夜里看海,有人力扣第一题都做不出来
系统管理员需知的 16 个 iptables 使用技巧
Leetcode 112. path sum
Best practice | using Tencent cloud AI character recognition to realize enterprise qualification certificate recognition
Directional crawling Taobao product name and price (teacher Songtian)