Halo
Saya akan memberi tahu Anda cara membuat efek garis besar sederhana pada Lightweight Render Pipeline (LWRP) di Unity. Untuk melakukan ini, Anda memerlukan Unity versi 2018.3 dan lebih tinggi, serta LWRP versi 4.0.0 dan lebih tinggi.
Garis klasik terdiri dari shader dua arah, tetapi LWRP hanya mendukung shader single-pass. Untuk memperbaiki kekurangan ini di LWRP, menjadi mungkin untuk menambahkan pass kustom ke tahap rendering menggunakan antarmuka:
IAfterDepthPrePass IAfterOpaquePass IAfterOpaquePostProcess IAfterSkyboxPass IAfterTransparentPass IAfterRender
Persiapan
Kami akan membutuhkan dua shader.
Pertama saya akan menggunakan Warna Unlit. Sebagai gantinya, Anda dapat menggunakan yang lain, hal utama adalah menambahkan konstruksi Stensil ke shader.
Warna tidak terang Shader "Unlit/SimpleColor" { SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags { "LightMode" = "LightweightForward" } Stencil { Ref 2 Comp always Pass replace } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = TransformObjectToHClip(v.vertex.xyz); return o; } half4 frag (v2f i) : SV_Target { return half4(0.5h, 0.0h, 0.0h, 1.0h); } ENDHLSL } } }
Yang kedua adalah garis besar shader paling sederhana itu sendiri.
Garis besar sederhana Shader "Unlit/SimpleOutline" { SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Stencil { Ref 2 Comp notequal Pass keep } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; half4 _OutlineColor; v2f vert (appdata v) { v2f o; v.vertex.xyz += 0.2 * normalize(v.vertex.xyz); o.vertex = TransformObjectToHClip(v.vertex.xyz); return o; } half4 frag (v2f i) : SV_Target { return _OutlineColor; } ENDHLSL } } }
Tiket masuk kustom
Menulis custom pass dimulai dengan membuat MonoBehaviour yang biasa dan mengimplementasikan salah satu antarmuka yang disebutkan di atas. Kami menggunakan IAfterOpaquePass, karena garis besar hanya akan diterapkan pada objek buram.
public class OutlinePass : MonoBehaviour, IAfterOpaquePass { public ScriptableRenderPass GetPassToEnqueue(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorAttachmentHandle, RenderTargetHandle depthAttachmentHandle) {
Script ini harus ditambahkan ke kamera. Dan melalui itu kita akan mengatur interaksi bagian kita dengan logika permainan, tetapi lebih banyak tentang itu nanti.
Sekarang mari kita mulai menulis bagian itu sendiri. Untuk melakukan ini, buat kelas yang diwarisi dari ScriptableRenderPass
public class OutlinePassImpl : ScriptableRenderPass { public OutlinePassImpl() {
Di konstruktor, kami mendaftarkan nama bagian itu, membuat bahan dan pengaturan untuk menyaring objek yang terlihat setelah pendinginan. Dalam filter, kita hanya akan menetapkan objek buram, karena kita akan menambahkan pass kita setelah pass buram.
Fungsi Execute adalah fungsi render untuk lewat. Di dalamnya, kami membuat pengaturan untuk rendering, mengatur materi yang dibuat dalam konstruktor, dan merender semua objek yang terlihat yang memenuhi filter yang dibuat.
OutlinePassImpl yang ternyata pada saya public class OutlinePassImpl : ScriptableRenderPass { private Material outlineMaterial; private FilterRenderersSettings m_OutlineFilterSettings; private int OutlineColorId; public OutlinePassImpl(Color outlineColor) {
Sekarang mari kita tambahkan kelas OutlinePass. Di sini semuanya sangat sederhana untuk membuat turunan dari kelas OutlinePassImpl dan melalui tautan Anda dapat berinteraksi dengan pass pengguna dalam mode runtime. Misalnya, untuk mengubah warna outline.
OutlinePass yang ternyata padaku public class OutlinePass : MonoBehaviour, IAfterOpaquePass { public Color OutlineColor; private OutlinePassImpl outlinePass; public ScriptableRenderPass GetPassToEnqueue(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorAttachmentHandle, RenderTargetHandle depthAttachmentHandle) { return outlinePass ?? (outlinePass = new OutlinePassImpl(OutlineColor)); } }
Sekarang atur adegan untuk tes.
- Buat Bahan dari SimpleColor Shader
- Buat kubus dan gantung bahan di atasnya.
- Tambahkan skrip OutlinePass ke kamera dan atur warnanya.
- Dan klik mainkan
Garis besar hanya akan terlihat di Tampilan Game.
Inilah hasilnya yang harus diperoleh.

Bonus: lampu latar teman-musuh
Menggunakan pengaturan untuk memfilter objek yang terlihat, Anda dapat menentukan lapisan atau membuat lapisan untuk menerapkan bagian ini ke objek atau kelompok objek tertentu dan mengaitkannya dengan logika permainan.
Ubah pass kita sehingga semua objek dengan layer "Friend" memiliki garis hijau, dan dengan layer "Enemy" berwarna merah.
OutlinePass dan OutlinePassImpl public class OutlinePass : MonoBehaviour, IAfterOpaquePass { [System.Serializable] public class OutlineData { public Color Color; public LayerMask Layer; } public List<OutlineData> outlineDatas = new List<OutlineData>(); private OutlinePassImpl outlinePass; public ScriptableRenderPass GetPassToEnqueue(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorAttachmentHandle, RenderTargetHandle depthAttachmentHandle) { return outlinePass ?? (outlinePass = new OutlinePassImpl(outlineDatas)); } } public class OutlinePassImpl : ScriptableRenderPass { private Material[] outlineMaterial; private FilterRenderersSettings[] m_OutlineFilterSettings; public OutlinePassImpl(List<OutlinePass.OutlineData> outlineDatas) { RegisterShaderPassName("LightweightForward"); outlineMaterial = new Material[outlineDatas.Count]; m_OutlineFilterSettings = new FilterRenderersSettings[outlineDatas.Count]; Shader outlineShader = Shader.Find("Unlit/SimpleOutline"); int OutlineColorId = Shader.PropertyToID("_OutlineColor"); for (int i = 0; i < outlineDatas.Count; i++) { OutlinePass.OutlineData outline = outlineDatas[i]; Material material = CoreUtils.CreateEngineMaterial(outlineShader); material.SetColor(OutlineColorId, outline.Color); outlineMaterial[i] = material; m_OutlineFilterSettings[i] = new FilterRenderersSettings(true) { renderQueueRange = RenderQueueRange.opaque, layerMask = outline.Layer }; } } public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData) { Camera camera = renderingData.cameraData.camera; SortFlags sortFlags = renderingData.cameraData.defaultOpaqueSortFlags; DrawRendererSettings drawSettings = CreateDrawRendererSettings(camera, sortFlags, RendererConfiguration.None, renderingData.supportsDynamicBatching); for (int i = 0; i < outlineMaterial.Length; i++) { drawSettings.SetOverrideMaterial(outlineMaterial[i], 0); context.DrawRenderers(renderingData.cullResults.visibleRenderers, ref drawSettings, m_OutlineFilterSettings[i]); } } }
Di tempat kejadian, tambahkan layer "Teman" dan "Musuh", duplikat kubus beberapa kali, tetapkan layer-layer itu ke "Teman" atau "Musuh", atur Outline Pass dan jalankan.

Dan inilah yang kita dapatkan.

Kesimpulan
Render baru di Unity berkembang sangat baik, yang membuat membuat efek menarik menjadi sangat mudah.
Semoga artikel ini bermanfaat untuk dibaca. Jika ada yang punya pertanyaan, sampai jumpa di komentar.