我有一个着色器,应该进行两次遍历,一次渲染一次背面。请参见下面的着色器代码:
Shader "Custom/Geometry/Wireframe"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[PowerSlider(3.0)]
_WireframeVal ("Wireframe width", Range(0., 0.34)) = 0.05
_FrontColor ("Front color", color) = (1., 1., 1., 1.)
_BackColor ("Back color", color) = (1., 1., 1., 1.)
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
Cull Back
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#include "UnityCG.cginc"
struct v2g {
float4 pos : SV_POSITION;
};
struct g2f {
float4 pos : SV_POSITION;
float3 bary : TEXCOORD0;
};
v2g vert(appdata_base v) {
v2g o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
[maxvertexcount(3)]
void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
g2f o;
o.pos = IN[0].pos;
o.bary = float3(1., 0., 0.);
triStream.Append(o);
o.pos = IN[1].pos;
o.bary = float3(0., 0., 1.);
triStream.Append(o);
o.pos = IN[2].pos;
o.bary = float3(0., 1., 0.);
triStream.Append(o);
}
float _WireframeVal;
fixed4 _FrontColor;
fixed4 frag(g2f i) : SV_Target {
if(!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
discard;
return _FrontColor;
}
ENDCG
}
Pass
{
Cull Front
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#include "UnityCG.cginc"
struct v2g {
float4 pos : SV_POSITION;
};
struct g2f {
float4 pos : SV_POSITION;
float3 bary : TEXCOORD0;
};
v2g vert(appdata_base v) {
v2g o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
[maxvertexcount(3)]
void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
g2f o;
o.pos = IN[0].pos;
o.bary = float3(1., 0., 0.);
triStream.Append(o);
o.pos = IN[1].pos;
o.bary = float3(0., 0., 1.);
triStream.Append(o);
o.pos = IN[2].pos;
o.bary = float3(0., 1., 0.);
triStream.Append(o);
}
float _WireframeVal;
fixed4 _BackColor;
fixed4 frag(g2f i) : SV_Target {
if(!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
discard;
return _BackColor;
}
ENDCG
}
}
}
但是我遇到的问题是代码中的第二遍从未执行过。因为当我为反向传递设置颜色时,该颜色永远不会在网格物体上可见,因此将着色器(材质)应用于该颜色。
此外,如果我交换通行证,以便后通证在前通证之前到来,则会出现相反的问题。
编辑
在此处看到应用了材质的网格物体正面的图片,以及在使用材质的同一网格物体背面的图片:
正面:
返回:
这是我第一次尝试制作这样的着色器,因此非常感谢所有帮助!
答案 0 :(得分:0)
Shader "Custom/Geometry/Wireframe"
{<<<<<<<<<<<<
Properties
{
这使它对我有用
不幸的是,着色器没有自动完成功能,因此很容易错过这样的错误,但是您的代码在编辑器中给了我以下错误:
Parse error: syntax error unexpected '{' 3
(第三行的括号)
shader is not supported on this gpu
(由语法错误引起)
去掉支架可以解决问题!
Shader "Custom/NewSurfaceShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
[PowerSlider(3.0)]
_WireframeVal("Wireframe width", Range(0., 0.34)) = 0.05
_FrontColor("Front color", color) = (1., 1., 1., 1.)
_BackColor("Back color", color) = (1., 1., 1., 1.)
}
SubShader
{
Tags { "RenderType" = "Opaque" }
Pass
{
Cull Back
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#include "UnityCG.cginc"
struct v2g {
float4 pos : SV_POSITION;
};
struct g2f {
float4 pos : SV_POSITION;
float3 bary : TEXCOORD0;
};
v2g vert(appdata_base v) {
v2g o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
[maxvertexcount(3)]
void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
g2f o;
o.pos = IN[0].pos;
o.bary = float3(1., 0., 0.);
triStream.Append(o);
o.pos = IN[1].pos;
o.bary = float3(0., 0., 1.);
triStream.Append(o);
o.pos = IN[2].pos;
o.bary = float3(0., 1., 0.);
triStream.Append(o);
}
float _WireframeVal;
fixed4 _FrontColor;
fixed4 frag(g2f i) : SV_Target {
if (!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
discard;
return _FrontColor;
}
ENDCG
}
Pass
{
Cull Front
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#include "UnityCG.cginc"
struct v2g {
float4 pos : SV_POSITION;
};
struct g2f {
float4 pos : SV_POSITION;
float3 bary : TEXCOORD0;
};
v2g vert(appdata_base v) {
v2g o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
[maxvertexcount(3)]
void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
g2f o;
o.pos = IN[0].pos;
o.bary = float3(1., 0., 0.);
triStream.Append(o);
o.pos = IN[1].pos;
o.bary = float3(0., 0., 1.);
triStream.Append(o);
o.pos = IN[2].pos;
o.bary = float3(0., 1., 0.);
triStream.Append(o);
}
float _WireframeVal;
fixed4 _BackColor;
fixed4 frag(g2f i) : SV_Target {
if (!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
discard;
return _BackColor;
}
ENDCG
}
}
}