Shader中几何着色器的代码:
[maxvertexcount(30)]
void Gemo(triangle v2g IN[3], inout TriangleStream<g2f> triStream)
{
float3 pos = IN[0].pos.xyz;//获取模型空间下的顶点坐标
float3 worldPos = TransformObjectToWorld(pos);//将模型空间的顶点坐标转换成世界空间坐标
//-----实现草片的随机旋转-----
//草片绕z轴旋转
float3x3 facingRotationMatrix = AngleAxis3x3(Rand(pos.xyz) * TWO_PI, float3(0, 0, 1));
//草片绕-x轴旋转
float3x3 bendRotationMatrix = AngleAxis3x3(Rand(pos.zzx) * _BendRotationRandom * PI * 0.5, float3(-1, 0, 0));
//-----实现风-----
float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;
float2 windSample = (tex2Dlod(_WindDistortionMap, float4(uv, 0, 0)).xy * 2 - 1) * _WindStrength;
float3 wind = normalize(float3(windSample.x, windSample.y, 0));
float3x3 windRotation = AngleAxis3x3(PI * windSample, wind);
//-----实现交互-----
//1.得到玩家与草的模型顶点之间的距离
float3 dis = distance(_PlayerPos, worldPos);
//2.计算草的弯曲程度
float radius = saturate((1 - dis + _PushRadius) * _Strength);
float3 spheleDisp = normalize(worldPos.xyz - _PlayerPos.xyz);
//防止草的根部穿过地面
spheleDisp.y += 1;
spheleDisp *= radius;
spheleDisp = clamp(spheleDisp.xyz, -0.8, 0.8);
//-----实现草沿着副法线的y轴方向生长-----
float3 vNormal = IN[0].normal;//顶点法线方向
float4 vTangent = IN[0].tangent;//顶点切线方向
float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;//顶点副法线
//
float3x3 tangentToLocal = float3x3(
vTangent.x, vBinormal.x, vNormal.x,
vTangent.y, vBinormal.y, vNormal.y,
vTangent.z, vBinormal.z, vNormal.z
);
float3x3 tw = mul(tangentToLocal, windRotation);//
float3x3 twf = mul(tw, facingRotationMatrix);//草片绕z轴旋转
float3x3 transformationMatrix = mul(twf, bendRotationMatrix);//草绕-x轴旋转
float3x3 transformationMatrixFacing = mul(tangentToLocal, facingRotationMatrix);//草的最上部分的三角形顶点位移
//-----实现随机宽度和随机高度-----
float height = (Rand(pos.zyx) * 2 - 1) * _BladerHeightRandom + _BladeHeight;
float width = (Rand(pos.xzy) * 2 - 1) * _BladerWidthRandom + _BladeWidth;
float forward = Rand(pos.yyz) * _BladeForward;
if(IN[0].viewPos.z > -_LODDistance1)
{
//------for循环实现增加草的面数,为了让草可以弯曲-----
for(int i = 0; i < BLADE_SEGMENTSNEAR; i++)
{
float t = i / (float)BLADE_SEGMENTSNEAR;
float segmentHeight = height * t;//高度越来越高
float segmentWidth = width * (1 - t);
float segmentForward = pow(t, _BladeCurve) * forward;
float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;
float3 newPos = i == 0 ? pos : (spheleDisp + pos);
//添加三角形的三对对称顶点:1 最下面一对顶点 2 中间部分一对顶点 3上半部分一对顶点
triStream.Append(GenerateGrassVertex(newPos, segmentWidth, segmentHeight, segmentForward, float2(0, t),transformMatrix));
triStream.Append(GenerateGrassVertex(newPos, -segmentWidth, segmentHeight, segmentForward, float2(1, t),transformMatrix));
}
}
else if(IN[0].viewPos.z > -_LODDistance2)
{
//------for循环实现增加草的面数,为了让草可以弯曲-----
for(int i = 0; i < BLADE_SEGMENTSMIDDLE; i++)
{
float t = i / (float)BLADE_SEGMENTSMIDDLE;
float segmentHeight = height * t;//高度越来越高
float segmentWidth = width * (1 - t);
float segmentForward = pow(t, _BladeCurve) * forward;
float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;
float3 newPos = i == 0 ? pos : (spheleDisp + pos);
//添加三角形的三对对称顶点:1 最下面一对顶点 2 中间部分一对顶点 3上半部分一对顶点
triStream.Append(GenerateGrassVertex(newPos, segmentWidth, segmentHeight, segmentForward, float2(0, t),transformMatrix));
triStream.Append(GenerateGrassVertex(newPos, -segmentWidth, segmentHeight, segmentForward, float2(1, t),transformMatrix));
}
}
else
{
//------for循环实现增加草的面数,为了让草可以弯曲-----
for(int i = 0; i < BLADE_SEGMENTSNEARFAR; i++)
{
float t = i / (float)BLADE_SEGMENTSNEARFAR;
float segmentHeight = height * t;//高度越来越高
float segmentWidth = width * (1 - t);
float segmentForward = pow(t, _BladeCurve) * forward;
float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;
float3 newPos = i == 0 ? pos : (spheleDisp + pos);
//添加三角形的三对对称顶点:1 最下面一对顶点 2 中间部分一对顶点 3上半部分一对顶点
triStream.Append(GenerateGrassVertex(newPos, segmentWidth, segmentHeight, segmentForward, float2(0, t),transformMatrix));
triStream.Append(GenerateGrassVertex(newPos, -segmentWidth, segmentHeight, segmentForward, float2(1, t),transformMatrix));
}
}
//添加三角形的最上部分的顶点 只有一个
triStream.Append(GenerateGrassVertex(pos,0, height, forward, float2(0.5, 1),transformationMatrix));
}
C#部分就不太清除怎么写了。
由于几何着色器生成的小草是在原有的模型每个顶点位置处直接生成的,所以问题是 1:是每片小草叶子都需要用DrawMeshInstancedIndirect()函数优化吗?2.官方的例子是生成10万个小球,但是本例子中生成10个草皮,并且每个草皮上都覆盖好多小草实例,我应该实例化每个草皮还是所有草皮上的小草实例?
参考一下https://blog.csdn.net/wodownload2/article/details/104973269
您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~
如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~
ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632
非常感谢您使用有问必答服务,为了后续更快速的帮您解决问题,现诚邀您参与有问必答体验反馈。您的建议将会运用到我们的产品优化中,希望能得到您的支持与协助!
速戳参与调研>>>https://t.csdnimg.cn/Kf0y