我正在按照这个教程烘焙着色器到一个纹理贴图here,它工作得很好。我只是在标准着色器上应用它时遇到了一些问题。
这是他们使用顶点/碎片创建的展开着色器(我认为它们负责将顶点渲染到uv空间):
v2f vert (appdata v)
{
v2f o;
v.vertex = float4(v.uv.xy, 0.0, 1.0);
o.vertex = mul(UNITY_MATRIX_P, v.vertex);
//o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f IN) : SV_Target
{
//here is where you would put the shader code you want to bake
//for now I will just do a noise
float f = fbm(IN.uv + fbm(5*IN.uv, 4), 4);
fixed4 color = fixed4(f,f,1,1);
return color;
}我想这样做,但在表面着色器上。你们能帮我吗?
发布于 2020-10-22 18:23:45
您有两个选择。如果现在还不算太晚的话...
选项1:更改表面着色器中生成的代码
选项2:使用顶点修改器和抵消UnityObjectToClipPos(v.vertex);
统一表面着色器也只是顶点和碎片着色器,就像上面的代码片段一样。如果你创建一个着色器作为一个表面着色器,你告诉unity哪些预定义的函数要与编译后的代码一起使用,比如"surface surf Standard fullforwardshadows“,如果你点击编译后的着色器,你可以随时查看生成的代码。在那里,您可以看到一个带有顶点和碎片部分的长着色器。它有点乱七八糟的#ifelse,并且在你的机器上运行的代码最终只是一小部分。可以手动清理它,只更改您想要更改的特定部分,即添加自定义顶点着色器。由于这是耗时和容易出错的,unity有很多标准着色器的可定制性。
选项2:其中一个是顶点修改器杂注使用vertex:vert可以指定要在顶点着色器中调用的自定义顶点函数,以修改顶点位置。(请参见:here中的法线挤出)不幸的是,unity直接将UnityObjectToClipPos(v.vertex);包装在顶点修改器函数之后。因此,如果执行从对象空间到uv空间单位的变换,则会自动将uv坐标转换为剪辑空间,就好像它是对象空间坐标一样,从而导致无意义。你可以做的就是用mul(transpose(UNITY_MATRIX_IT_MV), v.vertex);来抵消这一点,得到的乘法是:P_V_M*t(t(inv(MV)=P,这样你就可以欺骗顶点修改器来充当覆盖。请记住,位置也用于其他操作,阴影等。如果你想有更多的控制,跳过这个不必要的双重乘法,你可以这样做
选项2:您始终可以从表面着色器生成代码并更改顶点函数。例如,您可以手动删除对UnityObjectToClipPos(v.vertex);的调用。
注意:我在UV-Space操作中遇到的一个问题是,裁剪空间取决于您使用的图形api。无论是像OpenGL还是Directx,你可能需要在float4(v.uv.xy, 0.0, 1.0);中将z坐标设置为-1.0或0.0。根据构建目标的不同,这也可能会发生变化。
编辑:以下是曲面着色器的顶点修改器示例:
#pragma surface surf Standard fullforwardshadows vertex:vert
void vert (inout appdata_full v) {
v.vertex = float4(v.texcoord.xy, 0.0, 1.0);
//or float4(v.texcoord.xy, -1.0, 1.0);
v.vertex = mul(transpose(UNITY_MATRIX_IT_MV), v.vertex);
}https://stackoverflow.com/questions/61098655
复制相似问题