Search Unity

Compositing : it seems impossible?

Discussion in 'Shaders' started by ricecrispie60, Mar 30, 2015.

  1. ricecrispie60

    ricecrispie60

    Joined:
    May 6, 2014
    Posts:
    20
    I'll try to keep this short & to the point, please save my sanity shader forum ppl:

    Scenario: 2d style game made of sprites using Z postions to draw stuff infront, behind & inbetween each other.

    What i need: Draw certain objects with an image effect while maintaining their position in the scene.

    The problem: If I use render texture I have to draw on top of, or behind the rest of the scene : fail.
    If I use camera replacement shaders I have to duplicate every single shader in the scene into one stupid huge shader...and im just not that good with shaders - its not going to work.

    Am i missing something here? Every way I try to think this through keeps sending me back to the same problem of breaking my draw order & that trashes my graphics.
     
  2. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    you dont need to duplicate your shaders, you need to make a mask of what objects get effected by your image effect.
     
  3. ricecrispie60

    ricecrispie60

    Joined:
    May 6, 2014
    Posts:
    20
    Hi aubergine, thanks for you many helpful posts on this forum.

    I havent a clue on how I would make a mask in this context (if only this was photoshop). Also isn't it the scene that needs to be the mask & not the image effect objects?

    I hope im just not seeing the wood for the trees, could you point me in the right direction?
     
  4. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    I cant really post source code as i sell it in several of my assetstore packages such as blur per object, glow per object and pixelate per object.

    What you need to do is, grab a mask of which objects needs to get effected and composite the non affected objects and the affected objects via this mask through your image effect, just like photoshop indeed :)
     
  5. ricecrispie60

    ricecrispie60

    Joined:
    May 6, 2014
    Posts:
    20
    You know I think I was half way there with my enormous replacement shader & doing negative alpha but i wasn't trying to use another rendertexture as an image mask... like photoshop. Still seems that approach requires rendering most of my scene twice but let me think on it, thanks man.
     
  6. ricecrispie60

    ricecrispie60

    Joined:
    May 6, 2014
    Posts:
    20
    After a week of trying to get to grips with this I just have more questions, but i'll post some code too...

    I'm going to leave aside replacement shader 'fun' to produce a camera rendering an image ready to be composited as I think i'm there (not that there are any good examples of this either, but thanks to aubergine I seem to have that stuff working).

    Lets just deal with trying to overlay or underlay a couple of cameras while respecting the image effects stack on each camera.

    Heres the compositing script, i would class this code as working and broken at the same time:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. [ExecuteInEditMode]
    4. [RequireComponent (typeof(Camera))]
    5. public class simpleComposite : MonoBehaviour {
    6.  
    7.     public Camera otherCamera;
    8.     public Shader compositeShader;
    9.     public string setTexName;
    10.  
    11.     private RenderTexture otherRT;
    12.  
    13.     private Material mat;
    14.     // Use this for initialization
    15.     void Start () {
    16.         if (!otherCamera || !compositeShader ){
    17.             enabled = false;
    18.         }
    19.      
    20.     }
    21.  
    22.     void OnRenderImage (RenderTexture source, RenderTexture destination) {
    23.         otherRT = RenderTexture.GetTemporary(Screen.width, Screen.height, 16); //zero crashes unity??
    24.         otherCamera.targetTexture = otherRT;
    25.         mat.SetTexture( setTexName, otherRT);
    26.  
    27.         Graphics.Blit(source, destination, mat);
    28.         RenderTexture.ReleaseTemporary(otherRT);
    29.     }
    30.  
    31.     void OnDisable(){
    32.         cleanUp();
    33.     }
    34.  
    35.     void OnEnable(){
    36.         if(compositeShader && otherCamera){
    37.             mat = new Material(compositeShader);
    38.         } else {
    39.             enabled = false;
    40.         }
    41.     }
    42.  
    43.     void cleanUp(){
    44.         if(otherCamera){
    45.             otherCamera.targetTexture = null;
    46.         }
    47.  
    48.         if(otherRT){
    49.             //RenderTexture.ReleaseTemporary(otherRT); - throws errors re. releasing temporary rts
    50.             otherRT = null;
    51.         }
    52.  
    53.         if(mat){
    54.             DestroyImmediate(mat);
    55.         }
    56.  
    57.     }
    58.  
    59. }
    And heres the composite shader, also working & broken at the same time:
    Code (CSharp):
    1. Shader "Custom/simpleCompositeBlendOnto" {
    2.     Properties {
    3.         _MainTex ("_MainTex", 2D) = "" {}
    4.         _background ("_background Texture", 2D) = "" {}
    5.         }
    6.     SubShader {
    7.         Pass {
    8.              ZTest Always Cull Off ZWrite Off
    9.             CGPROGRAM
    10.             #pragma vertex vert
    11.             #pragma fragment frag
    12.  
    13.             #include "UnityCG.cginc"
    14.  
    15.             sampler2D _MainTex;
    16.             sampler2D _background;
    17.          
    18.             struct appdata_t {
    19.                 float4 vertex : POSITION;
    20.                 float2 texcoord : TEXCOORD0;
    21.             };
    22.  
    23.             struct v2f {
    24.                 float4 vertex : SV_POSITION;
    25.                 float2 texcoord : TEXCOORD0;
    26.             };
    27.  
    28.             v2f vert (appdata_t v)
    29.             {
    30.                 v2f o;
    31.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    32.                 o.texcoord = v.texcoord.xy;
    33.                 return o;
    34.             }
    35.  
    36.             fixed4 frag (v2f i) : SV_Target
    37.             {
    38.                 float4 mt = tex2D(_MainTex, i.texcoord);
    39.                 float4 bg = tex2D(_background, i.texcoord);
    40.              
    41.                 fixed4 output;
    42.                 output = lerp(bg,mt, mt.a);
    43.                 return output;
    44.             }
    45.             ENDCG
    46.  
    47.         }
    48.     }
    49.     Fallback Off
    50. }
    The problems:

    1. Its 'flakey' - The image flickers in edit mode like its fighting to show the composite result with not showing the compsite result.

    2. ***edit*** I was encoutering a strange verticle flip in one of the composite rendertextures here, but it seems it was a clash with unity image effects so can be disregarded.

    My basic question is am I doing this right? (obviously not).
     
    Last edited: Apr 6, 2015