本文主要是介绍C for Graphic:遮罩显示(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
模板缓冲一般用于遮罩渲染的功能,其原理很以前聊过(模板缓冲原理),就不再啰嗦了。
现在实现一个功能:使用一个长方体(或任意物体)遮罩渲染对象(比如一个球)。
首先在官网下载内置着色器,找到DefaultResourcesExtra中的Standard.shader,改造一下支持stencil操作,如下:
Shader "Standard-Stencil"
{Properties{_StencilVal("Stencil Value", int) = 1_StencilComp("Stencil CompFunction (Disable,0,Never,1,Less,2,Equal,3,LessEqual,4,Greater,5,NotEqual,6,GreaterEqual,7,Always,8)", int) = 3_StencilPass("StencilPassFunciton(Keep,0,Zero,1,Replace,2,IncrSat,3,DecrSat,4,Invert,5,IncrWrap,6,DecrWrap,7)", int) = 0[Enum(Less,0,Greater,1,LEqual,2,GEqual,3,Equal,4,NotEqual,5,Always,6)]_ZTest("ZTest",int) = 0[Enum(Off,0,Front,1,Back,2)]_Cull("Cull", int) = 2_Color("Color", Color) = (1,1,1,1)_MainTex("Albedo", 2D) = "white" {}_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5_Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0[Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0[Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0_MetallicGlossMap("Metallic", 2D) = "white" {}[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0[ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0_BumpScale("Scale", Float) = 1.0_BumpMap("Normal Map", 2D) = "bump" {}_Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02_ParallaxMap ("Height Map", 2D) = "black" {}_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0_OcclusionMap("Occlusion", 2D) = "white" {}_EmissionColor("Color", Color) = (0,0,0)_EmissionMap("Emission", 2D) = "white" {}_DetailMask("Detail Mask", 2D) = "white" {}_DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}_DetailNormalMapScale("Scale", Float) = 1.0_DetailNormalMap("Normal Map", 2D) = "bump" {}[Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0// Blending state[HideInInspector] _Mode ("__mode", Float) = 0.0[HideInInspector] _SrcBlend ("__src", Float) = 1.0[HideInInspector] _DstBlend ("__dst", Float) = 0.0[HideInInspector] _ZWrite ("__zw", Float) = 1.0}CGINCLUDE#define UNITY_SETUP_BRDF_INPUT MetallicSetupENDCGSubShader{Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }LOD 300// ------------------------------------------------------------------// Base forward pass (directional light, emission, lightmaps, ...)Pass{Name "FORWARD"Tags { "LightMode" = "ForwardBase" }Blend [_SrcBlend] [_DstBlend]ZWrite [_ZWrite]ZWrite [_ZTest]Stencil{Ref [_StencilVal]Comp [_StencilComp]Pass [_StencilPass]}Cull [_Cull]CGPROGRAM#pragma target 3.0// -------------------------------------#pragma shader_feature _NORMALMAP#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _EMISSION#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature ___ _DETAIL_MULX2#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF#pragma shader_feature _PARALLAXMAP#pragma multi_compile_fwdbase#pragma multi_compile_fog#pragma multi_compile_instancing// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.//#pragma multi_compile _ LOD_FADE_CROSSFADE#pragma vertex vertBase#pragma fragment fragBase#include "UnityStandardCoreForward.cginc"ENDCG}// ------------------------------------------------------------------// Additive forward pass (one light per pass)Pass{Name "FORWARD_DELTA"Tags { "LightMode" = "ForwardAdd" }Blend [_SrcBlend] OneFog { Color (0,0,0,0) } // in additive pass fog should be blackZWrite OffZTest LEqualCGPROGRAM#pragma target 3.0// -------------------------------------#pragma shader_feature _NORMALMAP#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF#pragma shader_feature ___ _DETAIL_MULX2#pragma shader_feature _PARALLAXMAP#pragma multi_compile_fwdadd_fullshadows#pragma multi_compile_fog// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.//#pragma multi_compile _ LOD_FADE_CROSSFADE#pragma vertex vertAdd#pragma fragment fragAdd#include "UnityStandardCoreForward.cginc"ENDCG}// ------------------------------------------------------------------// Shadow rendering passPass {Name "ShadowCaster"Tags { "LightMode" = "ShadowCaster" }ZWrite On ZTest LEqualCGPROGRAM#pragma target 3.0// -------------------------------------#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature _PARALLAXMAP#pragma multi_compile_shadowcaster#pragma multi_compile_instancing// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.//#pragma multi_compile _ LOD_FADE_CROSSFADE#pragma vertex vertShadowCaster#pragma fragment fragShadowCaster#include "UnityStandardShadow.cginc"ENDCG}// ------------------------------------------------------------------// Deferred passPass{Name "DEFERRED"Tags { "LightMode" = "Deferred" }CGPROGRAM#pragma target 3.0#pragma exclude_renderers nomrt// -------------------------------------#pragma shader_feature _NORMALMAP#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _EMISSION#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF#pragma shader_feature ___ _DETAIL_MULX2#pragma shader_feature _PARALLAXMAP#pragma multi_compile_prepassfinal#pragma multi_compile_instancing// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.//#pragma multi_compile _ LOD_FADE_CROSSFADE#pragma vertex vertDeferred#pragma fragment fragDeferred#include "UnityStandardCore.cginc"ENDCG}// ------------------------------------------------------------------// Extracts information for lightmapping, GI (emission, albedo, ...)// This pass it not used during regular rendering.Pass{Name "META"Tags { "LightMode"="Meta" }Cull OffCGPROGRAM#pragma vertex vert_meta#pragma fragment frag_meta#pragma shader_feature _EMISSION#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature ___ _DETAIL_MULX2#pragma shader_feature EDITOR_VISUALIZATION#include "UnityStandardMeta.cginc"ENDCG}}SubShader{Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }LOD 150// ------------------------------------------------------------------// Base forward pass (directional light, emission, lightmaps, ...)Pass{Name "FORWARD"Tags { "LightMode" = "ForwardBase" }Blend [_SrcBlend] [_DstBlend]ZWrite [_ZWrite]CGPROGRAM#pragma target 2.0#pragma shader_feature _NORMALMAP#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _EMISSION#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF// SM2.0: NOT SUPPORTED shader_feature ___ _DETAIL_MULX2// SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP#pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED#pragma multi_compile_fwdbase#pragma multi_compile_fog#pragma vertex vertBase#pragma fragment fragBase#include "UnityStandardCoreForward.cginc"ENDCG}// ------------------------------------------------------------------// Additive forward pass (one light per pass)Pass{Name "FORWARD_DELTA"Tags { "LightMode" = "ForwardAdd" }Blend [_SrcBlend] OneFog { Color (0,0,0,0) } // in additive pass fog should be blackZWrite OffZTest LEqualCGPROGRAM#pragma target 2.0#pragma shader_feature _NORMALMAP#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF#pragma shader_feature ___ _DETAIL_MULX2// SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP#pragma skip_variants SHADOWS_SOFT#pragma multi_compile_fwdadd_fullshadows#pragma multi_compile_fog#pragma vertex vertAdd#pragma fragment fragAdd#include "UnityStandardCoreForward.cginc"ENDCG}// ------------------------------------------------------------------// Shadow rendering passPass {Name "ShadowCaster"Tags { "LightMode" = "ShadowCaster" }ZWrite On ZTest LEqualCGPROGRAM#pragma target 2.0#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma skip_variants SHADOWS_SOFT#pragma multi_compile_shadowcaster#pragma vertex vertShadowCaster#pragma fragment fragShadowCaster#include "UnityStandardShadow.cginc"ENDCG}// ------------------------------------------------------------------// Extracts information for lightmapping, GI (emission, albedo, ...)// This pass it not used during regular rendering.Pass{Name "META"Tags { "LightMode"="Meta" }Cull OffCGPROGRAM#pragma vertex vert_meta#pragma fragment frag_meta#pragma shader_feature _EMISSION#pragma shader_feature _METALLICGLOSSMAP#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature ___ _DETAIL_MULX2#pragma shader_feature EDITOR_VISUALIZATION#include "UnityStandardMeta.cginc"ENDCG}}FallBack "VertexLit"//CustomEditor "StandardShaderGUI"
}
PS:本来想把CompareFunction和PassFunction做成Enum标签,结果发现shader的Enum标签不支持超过7个,算是新发现。
一般情况standard材质够场景制作了,这个材质赋予球体。
接下来按照以前的做法写一个StencilMaskShader
Shader "StencilDemo/StencilMaskShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{LOD 100Pass{Tags { "RenderType"="Opaque" }ColorMask 0Stencil{Ref 1Comp Always //(Disable,0,Never,1,Less,2,Equal,3,LessEqual,4,Greater,5,NotEqual,6,GreaterEqual,7,Always,8)Pass Replace //(Keep,0,Zero,1,Replace,2,IncrSat,3,DecrSat,4,Invert,5,IncrWrap,6,DecrWrap,7)}ZWrite OffZTest Off}}
}
这个用于立方体,置换立方体蒙版区域的stencilvalue,用于显示球体。设置好球体的renderqueue>立方体的renderqueue。效果如下:
因为模板测试位于图形流水线片段处理阶段,所以看到的效果就如同球体投影到平面上遮罩显示一样,我们想要立体感的话可以用两种方案。
一.填充立方体剖面
Shader "StencilDemo/ZTestUnlitShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{Tags { "RenderType"="Opaque+20" }LOD 100Pass{ZTest GreaterCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);return col;}ENDCG}}
}
这里设置渲染立方体剖面材质的renderqueue>球体renderqueue,同时设定ZTest Greater,这样就能显示出立方体被球体遮挡的区域,就能形成填充剖面。效果如下:
这个技术和以前切水果游戏一样,无非切水果的剖面纹理使用了相应的水果内部纹理。
PS:当然用Texture3D来进行填充剖面,也是很好的想法。
第二种方法性能要求高一点,但是也有很多应用的地方,后面有时间再写。
这篇关于C for Graphic:遮罩显示(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!