diff options
| author | yum <yum.food.vr@gmail.com> | 2025-07-28 00:07:13 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-07-28 00:07:36 -0700 |
| commit | 62a3a05cb79143e882ac54fa98b146d154b7a1e1 (patch) | |
| tree | b150b755f124993ed7aa8177579d14612f929110 /Scripts | |
| parent | f8a7d3fda6abef2923b0fa8f7021b9d0646ed8d5 (diff) | |
Add CRT pipeline script
Diffstat (limited to 'Scripts')
| -rw-r--r-- | Scripts/LinearPipeline.asset | 382 | ||||
| -rw-r--r-- | Scripts/LinearPipeline.asset.meta | 8 | ||||
| -rw-r--r-- | Scripts/LinearPipeline.cs | 154 | ||||
| -rw-r--r-- | Scripts/LinearPipeline.cs.meta | 11 |
4 files changed, 555 insertions, 0 deletions
diff --git a/Scripts/LinearPipeline.asset b/Scripts/LinearPipeline.asset new file mode 100644 index 0000000..c266faa --- /dev/null +++ b/Scripts/LinearPipeline.asset @@ -0,0 +1,382 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3} + m_Name: LinearPipeline + m_EditorClassIdentifier: + serializedUdonProgramAsset: {fileID: 11400000, guid: 72e2a1c3acce634458f16dca729f28c4, + type: 2} + udonAssembly: + assemblyError: + sourceCsScript: {fileID: 11500000, guid: 864067451b3c52048ac1ad1bc1f730e0, type: 3} + scriptVersion: 2 + compiledVersion: 2 + behaviourSyncMode: 1 + hasInteractEvent: 0 + scriptID: -8087597915593885420 + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: + - Name: fieldDefinitions + Entry: 7 + Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition, + UdonSharp.Editor]], mscorlib + - Name: comparer + Entry: 7 + Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String, + mscorlib]], mscorlib + - Name: + Entry: 8 + Data: + - Name: + Entry: 12 + Data: 5 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: sourceInput + - Name: $v + Entry: 7 + Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: sourceInput + - Name: <UserType>k__BackingField + Entry: 7 + Data: 3|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.Texture, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 3 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 4|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 2 + - Name: + Entry: 7 + Data: 5|UnityEngine.HeaderAttribute, UnityEngine.CoreModule + - Name: header + Entry: 1 + Data: Pipeline Assets + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: 6|UnityEngine.TooltipAttribute, UnityEngine.CoreModule + - Name: tooltip + Entry: 1 + Data: The initial texture to start the pipeline with. + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: effectMaterials + - Name: $v + Entry: 7 + Data: 7|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: effectMaterials + - Name: <UserType>k__BackingField + Entry: 7 + Data: 8|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.Material[], UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 8 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 9|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 10|UnityEngine.TooltipAttribute, UnityEngine.CoreModule + - Name: tooltip + Entry: 1 + Data: The materials to apply in sequence. The order matters. + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: pipelineOutputs + - Name: $v + Entry: 7 + Data: 11|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: pipelineOutputs + - Name: <UserType>k__BackingField + Entry: 7 + Data: 12|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.RenderTexture[], UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 12 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 13|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 14|UnityEngine.TooltipAttribute, UnityEngine.CoreModule + - Name: tooltip + Entry: 1 + Data: The RenderTextures to store the output of each step. MUST be the same + size as the materials array. + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: runOnStart + - Name: $v + Entry: 7 + Data: 15|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: runOnStart + - Name: <UserType>k__BackingField + Entry: 7 + Data: 16|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Boolean, mscorlib + - Name: + Entry: 8 + Data: + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 16 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 17|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 2 + - Name: + Entry: 7 + Data: 18|UnityEngine.HeaderAttribute, UnityEngine.CoreModule + - Name: header + Entry: 1 + Data: Execution Mode + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: 19|UnityEngine.TooltipAttribute, UnityEngine.CoreModule + - Name: tooltip + Entry: 1 + Data: If true, the pipeline will run once when the world loads. + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: runContinuously + - Name: $v + Entry: 7 + Data: 20|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: runContinuously + - Name: <UserType>k__BackingField + Entry: 9 + Data: 16 + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 16 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 21|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 22|UnityEngine.TooltipAttribute, UnityEngine.CoreModule + - Name: tooltip + Entry: 1 + Data: If true, the pipeline will run every frame. Use with caution, can be + performance-intensive. + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: diff --git a/Scripts/LinearPipeline.asset.meta b/Scripts/LinearPipeline.asset.meta new file mode 100644 index 0000000..a148130 --- /dev/null +++ b/Scripts/LinearPipeline.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3e835c1538a20974aa1dfd2fe5e736d9 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LinearPipeline.cs b/Scripts/LinearPipeline.cs new file mode 100644 index 0000000..33b1fef --- /dev/null +++ b/Scripts/LinearPipeline.cs @@ -0,0 +1,154 @@ +/* + Udon# Linear Pipeline Controller + + This script manages a linear chain of image effects. It takes a source texture + and processes it through a sequence of materials, storing the result of each + step in a corresponding RenderTexture. + + Setup: + 1. Create an empty GameObject in your scene. + 2. Add an UdonBehaviour component to it. + 3. Create this Udon# script in your project and assign it to the UdonBehaviour. + 4. Create all the Materials and RenderTextures you need for your pipeline. + 5. In the Inspector, assign the Source Input, Materials, and Output RenderTextures. + - The size of the Effect Materials and Pipeline Outputs arrays MUST be the same. + - The order of materials and textures in the arrays determines the pipeline order. + 6. Choose your desired execution mode (Run On Start, Run Continuously). +*/ + +using UdonSharp; +using UnityEngine; +using VRC.SDKBase; + +[UdonBehaviourSyncMode(BehaviourSyncMode.None)] +public class LinearPipeline : UdonSharpBehaviour +{ + [Header("Pipeline Assets")] + [Tooltip("The initial texture to start the pipeline with.")] + public Texture sourceInput; + + [Tooltip("The materials to apply in sequence. The order matters.")] + public Material[] effectMaterials; + + [Tooltip("The RenderTextures to store the output of each step. MUST be the same size as the materials array.")] + public RenderTexture[] pipelineOutputs; + + [Header("Execution Mode")] + [Tooltip("If true, the pipeline will run once when the world loads.")] + public bool runOnStart = true; + + [Tooltip("If true, the pipeline will run every frame. Use with caution, can be performance-intensive.")] + public bool runContinuously = false; + + void Start() + { + _ConfigurePipeline(); + + if (runOnStart) + { + _RunPipeline(); + } + } + + void Update() + { + if (runContinuously) + { + _RunPipeline(); + } + } + + /// <summary> + /// Configure materials for the pipeline. + /// </summary> + void _ConfigurePipeline() + { + if (effectMaterials == null || effectMaterials.Length == 0) + { + Debug.LogError("[LinearUdonPipeline] No Effect Materials have been assigned!", this); + return; + } + + if (pipelineOutputs == null || pipelineOutputs.Length == 0) + { + Debug.LogError("[LinearUdonPipeline] No Pipeline Outputs have been assigned!", this); + return; + } + + if (effectMaterials.Length != pipelineOutputs.Length) + { + Debug.LogError("[LinearUdonPipeline] The number of materials does not match the number of output textures!", this); + return; + } + + // Configure materials - set _MainTex to appropriate source + for (int i = 0; i < effectMaterials.Length; i++) + { + if (effectMaterials[i] != null) + { + if (i == 0) + { + // First material uses the source input + effectMaterials[i].SetTexture("_MainTex", sourceInput); + } + else + { + // Subsequent materials use the previous output as input + effectMaterials[i].SetTexture("_MainTex", pipelineOutputs[i - 1]); + } + } + } + } + + /// <summary> + /// This public method can be called by other Udon scripts or UI events to run the pipeline. + /// </summary> + public void _RunPipeline() + { + // --- Pre-flight Checks --- + if (sourceInput == null) + { + Debug.LogError("[LinearUdonPipeline] Source Input is not assigned!", this); + return; + } + + if (effectMaterials == null || effectMaterials.Length == 0) + { + Debug.LogError("[LinearUdonPipeline] No Effect Materials have been assigned!", this); + return; + } + + if (pipelineOutputs == null || pipelineOutputs.Length == 0) + { + Debug.LogError("[LinearUdonPipeline] No Pipeline Outputs have been assigned!", this); + return; + } + + if (effectMaterials.Length != pipelineOutputs.Length) + { + Debug.LogError("[LinearUdonPipeline] The number of materials does not match the number of output textures!", this); + return; + } + + // --- Run Pipeline --- + + // 1. First Blit: From the main source to the first texture in our chain. + VRCGraphics.Blit(sourceInput, pipelineOutputs[0], effectMaterials[0], -1); + + // 2. Loop through the rest of the chain. + for (int i = 1; i < effectMaterials.Length; i++) + { + // The source for this step is the output from the previous step. + Texture sourceForThisStep = pipelineOutputs[i - 1]; + + // The destination is the current output texture. + RenderTexture destForThisStep = pipelineOutputs[i]; + + // The material for this step. + Material materialForThisStep = effectMaterials[i]; + + VRCGraphics.Blit(sourceForThisStep, destForThisStep, materialForThisStep, -1); + } + } +} + diff --git a/Scripts/LinearPipeline.cs.meta b/Scripts/LinearPipeline.cs.meta new file mode 100644 index 0000000..4f4cb17 --- /dev/null +++ b/Scripts/LinearPipeline.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 864067451b3c52048ac1ad1bc1f730e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |
