Shader "Custom/Selected Object" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Emission ("EmissionColor", Color) = (0.5, 0.5, 0.5, 1)
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_Mode ("Blend Mode", Range(0,3)) = 0
_ZWrite ("ZWrite", Int) = 0
_SrcBlend ("SrcBlend", Int) = 0
_DstBlend ("DstBlend", Int) = 0
_Cutoff ("Alpha Cutoff", Float) = 0.05
}
SubShader{
//Behind other geometry
Pass
{
ZTest GEqual
ZWrite [_ZWrite]
Blend [_SrcBlend] [_DstBlend]
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float2 uv : TEXCOORD0;
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 viewDir : TEXCOORD1;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = UnityObjectToWorldNormal(v.normal);
o.viewDir = normalize(UnityWorldSpaceViewDir(o.pos));
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 frag(v2f i) : SV_Target
{
//Note you have to normalize these again since they are being interpolated between vertices
float rim = 1 - dot(normalize(i.normal), normalize(i.viewDir));
fixed4 rimLight = lerp(half4(.95, .95, .95, 1), half4(0.65, 0.65, .95, 1), rim);
fixed4 t = tex2D(_MainTex, i.uv);
clip(t.a < 0.2);
return t * rimLight;
}
ENDCG
}
ZTest Less
ZWrite On
Blend [_SrcBlend][_DstBlend]
//Front geometry
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
// And generate the shadow pass with instancing support
#pragma surface surf Standard fullforwardshadows addshadow alphatest:_Cutoff //alpha:blend //keepalpha
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
#pragma multi_compile __ EMISSIVE_ON
sampler2D _MainTex;
fixed4 _Emission;
fixed4 _Color;
//float _Mode;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
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;
#if EMISSIVE_ON //Glowing
o.Emission = _Emission;
#endif
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Instanced/InstancedSurfaceShader"
}
Этот шейдер применяется к объекту, который выбрал пользователь.Он добавляет проход для рисования частей объекта, которые могут быть закрыты, например, рентгеновский эффект.Шейдер включается во время выполнения и работает должным образом, если начальный шейдер является стандартным шейдером Unity.
Проблема : я делаю шейдер вместо стандартного шейдера, чтобывключить создание экземпляров графического процессора.При свопинге с инстансированного шейдера эффект отрисовывается только после того, как объект полностью прошел свой окклюдер.
Кажется, что ZTest GEqual
терпит неудачу, если объект полностью не закрывает закрывающий объект.На изображениях выше эффект, видимый на втором, также должен быть виден на первом, где объект закрыт.
Тот факт, что он работает нормально со стандартным шейдером, заставляет меня поверить, что проблема заключается в том, что я упустил из инстансированного шейдера, здесь:
Shader "Custom/Instanced/InstancedSurfaceShader - Glow" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Emission ("EmissionColor", Color) = (1, 1, 1, 1)
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_Mode ("Blend Mode", Range(0,3)) = 0
_Cutoff("Alpha Cutoff", Float) = 0.05
}
SubShader {
ZTest Less
ZWrite On
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
// And generate the shadow pass with instancing support
#pragma surface surf Standard fullforwardshadows addshadow alphatest:_Cutoff
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
// Enable instancing for this shader
#pragma multi_compile_instancing
// Config maxcount. See manual page.
// #pragma instancing_options
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
fixed4 _Emission;
half _Glossiness;
half _Metallic;
// Declare instanced properties inside a cbuffer.
// Each instanced property is an array of by default 500(D3D)/128(GL) elements. Since D3D and GL imposes a certain limitation
// of 64KB and 16KB respectively on the size of a cubffer, the default array size thus allows two matrix arrays in one cbuffer.
// Use maxcount option on #pragma instancing_options directive to specify array size other than default (divided by 4 when used
// for GL).
// https://docs.unity3d.com/Manual/GPUInstancing.html
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color) // Make _Color an instanced property (i.e. an array)
#define _Color_arr Props
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) * UNITY_ACCESS_INSTANCED_PROP(_Color_arr, _Color);
o.Albedo = c.rgb;
o.Emission = _Emission;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Instanced/InstancedSurfaceShader"
}
А вот фрагмент кодаэто непосредственно влияет на материал / шейдер во время переключения шейдера:
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = -1;
Что в экземпляре шейдера может вызывать различный эффект рентгеновского шейдера?