我正在尝试将多个子着色器添加到一个着色器中。一个子着色器只是标准的 Unity 表面着色器,第二个子着色器是我从网上找到的某个地方修改的透明轮廓。这是我到目前为止的代码:
Shader "Custom/MetallicOutline" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
// Added this : Ben Hoffman
[Space(10)][Header(xxxxxxxxxxxxxxxx)][Header((Outline))]_OutlineWidth("Width", Float) = 0.5
_OutlineWidthControl("Width Control", 2D) = "white" {}
[Space(8)][Toggle(ENABLE_OPO)] _EOPO("Enable Outline Offset", Float) = 0
_OutlineOffset("Outline Offset", Vector) = (0,0,0)
[Space(8)]_OutlineColor("Color", Color) = (0,0,0,1)
[Space(8)]_OutlineNoiseIntensity("Noise Intensity", Range(0, 1)) = 0
[MaterialToggle] _DynamicNoiseOutline("Dynamic Noise Outline", Float) = 0
_OutlineOpacity("Outline Opacity", Range(0, 1)) = 1
}
SubShader {
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Lambert
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
SubShader {
Tags {
"RenderType" = "Opaque"
}
Pass {
Name "Outline"
Tags {
"Queue" = "Transparent"
}
//ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Front
Stencil {
Ref[_RefVal]
Comp[_Compa]
Pass[_Oper]
Fail[_Oper]
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_shadowcaster
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma only_renderers d3d9 d3d11 glcore gles3 metal d3d11_9x xboxone ps4 switch
#pragma target 3.0
#pragma shader_feature ENABLE_OPO
uniform sampler2D _Texture; uniform float4 _Texture_ST;
uniform float4 _OutlineColor;
uniform fixed _Transparent;
uniform float _OutlineNoiseIntensity;
uniform fixed _DynamicNoiseOutline;
uniform fixed _TexturePatternStyle;
uniform sampler2D _OutlineWidthControl; uniform float4 _OutlineWidthControl_ST;
uniform float _OutlineWidth;
uniform float3 _OutlineOffset;
// Transparency options
uniform float _OutlineOpacity;
struct VertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord0 : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0;
float4 projPos : TEXCOORD1;
UNITY_FOG_COORDS(2)
};
VertexOutput vert(VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.uv0 = v.texcoord0;
UNITY_SETUP_INSTANCE_ID(v);
float3 viDir = normalize(_WorldSpaceCameraPos.xyz - o.pos.xyz);
float4 viDirVP = mul(UNITY_MATRIX_VP, float4(viDir.xyz, 1));
float4 node_9780 = _Time;
float node_5371_ang = node_9780.g;
float node_5371_spd = 0.002;
float node_5371_cos = cos(node_5371_spd*node_5371_ang);
float node_5371_sin = sin(node_5371_spd*node_5371_ang);
float2 node_5371_piv = float2(0.5,0.5);
float2 node_5371 = (mul(o.uv0 - node_5371_piv,float2x2(node_5371_cos, -node_5371_sin, node_5371_sin, node_5371_cos)) + node_5371_piv);
float2 _DynamicNoiseOutline_var = lerp(o.uv0, node_5371, _DynamicNoiseOutline);
float2 node_7493_skew = _DynamicNoiseOutline_var + 0.2127 + _DynamicNoiseOutline_var.x*0.3713*_DynamicNoiseOutline_var.y;
float2 node_7493_rnd = 4.789*sin(489.123*(node_7493_skew));
float node_7493 = frac(node_7493_rnd.x*node_7493_rnd.y*(1 + node_7493_skew.x));
float4 _OutlineWidthControl_var = tex2Dlod(_OutlineWidthControl,float4(TRANSFORM_TEX(o.uv0, _OutlineWidthControl),0.0,0));
o.pos = UnityObjectToClipPos(float4(v.vertex.xyz + v.normal*(lerp(1.0,node_7493,_OutlineNoiseIntensity)*(clamp(_OutlineWidth,0.0,1000.0)*0.01)*_OutlineWidthControl_var.rgb),1));
#ifdef ENABLE_OPO
o.pos.xyz = o.pos.xyz - _OutlineOffset.xyz*viDirVP.xyz*0.1;
#endif
UNITY_TRANSFER_FOG(o,o.pos);
o.projPos = ComputeScreenPos(o.pos);
COMPUTE_EYEDEPTH(o.projPos.z);
return o;
}
fixed4 frag(VertexOutput i) : COLOR{
float2 sceneUVs = (i.projPos.xy / i.projPos.w);
float2 _TexturePatternStyle_var = lerp(i.uv0, float2((sceneUVs.x * 2 - 1)*(_ScreenParams.r / _ScreenParams.g), sceneUVs.y * 2 - 1).rg, _TexturePatternStyle);
float4 _Texture_var = tex2D(_Texture,TRANSFORM_TEX(_TexturePatternStyle_var, _Texture));
clip(lerp(1.0, _Texture_var.a, _Transparent) - 0.0);
// Set the opacity of the outline
fixed4 col = fixed4(_OutlineColor.rgb, 0);
col.a = _OutlineOpacity;
return col;
} // End frag
ENDCG
} // End outline pass
}
FallBack "Diffuse"
}
我知道大纲的逻辑肯定有效。代码中高于另一个 SubShader 的任何 SubShader 都会被渲染,而另一个则不会。
有谁知道为什么会这样?
我遇到了完全相同的问题。 我通过将第二个子着色器中的通道移动到第一个子着色器中(就在第一个通道的正下方(并删除第二个子着色器来修复它。
我对 Unity 很陌生,但我认为这是因为 Unity 只加载了一个子着色器。 不同的子着色器可能旨在让您能够灵活地处理不同的情况或平台,但一次只有一个子着色器处于活动状态。 尝试将两个通道放入同一个子着色器中,看看是否可以解决您的问题。