Render to buffer object?

Hello,

I’ve had an attempt at reaction diffusion, the tuts around, still in webGL or openGL, refer to a buffer object, I tried to blag it with a render to texture and a camera pointing at the target, and I think it does work barely, it;s just the update is happening too fast I think:

That’s where I’ve got to, is there a better way to feed the out put of a shader into an input of another shader? And also can you control the amount at which it’s fed back/read?

Cheers

I’ve tried graphics.blit and been unsuccessful, I’m not sure if I have it right.

I’ve messes around with the OnRenderimage Call, I thought could pass it 2 separate public render textures, and have them feeding back from each other like so:

2951346--218824--BlitTest.JPG

But it looks like the RenderTexture source and RenderTexture destination in the OnRenderimage can’t be public?

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class BlitTest : MonoBehaviour
{
    public Material material;
    public RenderTexture source;
    public RenderTexture destination;
    // Postprocess the image
    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source, destination, material);
    }
}

Have I got my thinking wrong here? Is there a better way to do this?

Thank you in advance!

Anyone have any idea about the what the buffer tab equivalent in shader toy would be? Here’s the simplest versions: Shader - Shadertoy BETA and Shader - Shadertoy BETA

I’ve looked and experimented with Render Textures, OnRenderImage on the camera, blit and multi blit and swear I’m over complicating things. I think what is confusing me about this is writing and reading into same buffer at the same time, as in the shaderToy examples, I just ended up with feedback.

What’s the approach one should use when you have two shader’s outpus into one buffer? Closest thread I’ve seen knocking around is here: Multiple fragment outputs - Unity Engine - Unity Discussions But not sure that’s what I need in this case.

Any thoughts?

So I need to do a multi pass, not sure if I’ve set up the shader correctly, trying to go off of blur/bloom, the thing I can’t work out is the taps part in those shader, are they completely necessary for multipass?

// AlanZucconi.com: http://www.alanzucconi.com/?p=4539
using UnityEngine;
using System.Collections;

//[ExecuteInEditMode]
public class ShaderBlit : MonoBehaviour
{
    public Material material;
    public RenderTexture texture;
    private RenderTexture buffer;

    public Texture initialTexture; // first texture

    void Start ()
    {
        Graphics.Blit(initialTexture, texture);

        buffer = new RenderTexture(texture.width, texture.height, texture.depth, texture.format);
    }

    // Postprocess the image
    public void UpdateTexture()
    {
        Graphics.Blit(texture, buffer, material, 0);
        Graphics.Blit(buffer, texture, material, 1);
    }

    // Updates regularly
    private float lastUpdateTime = 0;
    public float updateInterval = 0.1f; // s
    public void Update ()
    {
        if (Time.time > lastUpdateTime + updateInterval)
        {
            UpdateTexture();
            lastUpdateTime = Time.time;
        }
    }
}
Shader "Test/MultiPasstest"
{
    Properties
    {
    _Color ("Color", Color) = (0,0,0,0)
    _MainTex ("Color (RGB) Alpha (A)", 2D) = "white"
    }
    CGINCLUDE

    #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
                float4 screenCoord : TEXCOORD1;
            };

             uniform float4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                o.color = v.color;
                o.uv = v.uv;
                //o.screenCoord.xy = ComputeScreenPos(o.vertex);
                return o;
            }

            sampler2D _MainTex;
            sampler2D _Texture2;

            float3 hash33(in float2 p)
        {
            float n = sin(dot(p, float2(41, 289)));   
            return frac(float3(2097152, 262144, 32768)*n);
        }

        // Serves no other purpose than to save having to write this out all the time. I could write a
        // "define," but I'm pretty sure this'll be inlined.
            float4 tx(in float2 p){ return tex2D(_MainTex, p); }

        // Weighted blur function. Pretty standard.
            float blur(in float2 p)
            { 
            // Used to move to adjoining pixels. - uv + float2(-1, 1)*px, uv + float2(1, 0)*px, etc.
            float3 e = float3(1, 0, -1);
            float2 px = 1./512.;
           
            // Weighted 3x3 blur, or a cheap and nasty Gaussian blur approximation.
            float res = 0.0;
            // Four corners. Those receive the least weight.
            res += tx(p + e.xx*px ).x + tx(p + e.xz*px ).x + tx(p + e.zx*px ).x + tx(p + e.zz*px ).x;
            // Four sides, which are given a little more weight.
            res += (tx(p + e.xy*px ).x + tx(p + e.yx*px ).x + tx(p + e.yz*px ).x + tx(p + e.zy*px ).x)*2.;
            // The center pixel, which we're giving the most weight to, as you'd expect.
            res += tx(p + e.yy*px ).x*4.;
            // Normalizing.
            return res/16.;    
           
            }

                fixed4 frag (v2f i) : SV_Target
            {
              float2 uv = i.uv; // Screen coordinates. Range: [0, 1]
              float2 pw = 1./1.; // Relative pixel width. Used for neighboring pixels, etc.
            // The blurred pixel. This is the result that's used in the "Image" tab. It's also reused
            // in the next frame in the reaction diffusion process (see below).
              float avgReactDiff = blur(uv);
            // The noise value. Because the result is blurred, we can get away with plain old static noise.
            // However, smooth noise, and various kinds of noise textures will work, too.
              float3 noise = hash33(uv + float2(53, 43)*_Time.y)*.6 + .2;

            // Used to move to adjoining pixels. - uv + float2(-1, 1)*px, uv + float2(1, 0)*px, etc.
              float3 e = float3(1, 0, -1);
           
            // Gradient epsilon value. The "1.5" figure was trial and error, but was based on the 3x3 blur radius.
              float2 pwr = pw*1.5;
              float2 lap = float2(tx(uv + e.xy*pwr).y - tx(uv - e.xy*pwr).y, tx(uv + e.yx*pwr).y - tx(uv - e.yx*pwr).y);//
           
            // Add some diffusive expansion, scaled down to the order of a pixel width.
              uv = uv + lap*pw*3.0;
           
            // Stochastic decay. Ie: A differention equation, influenced by noise.
            // You need the decay, otherwise things would keep increasing, which in this case means a white screen.
              float newReactDiff = tx(uv).x + (noise.z - 0.5)*0.0025 - 0.002;
           
            // Reaction-diffusion.
              newReactDiff += dot(tx(uv + (noise.xy-0.5)*pw).xy, float2(1, -1))*0.145;

              float iFrame = _Time.y;
            // Storing the reaction diffusion value in the X channel, and avgReactDiff (the blurred pixel value)
            // in the Y channel. However, for the first few frames, we add some noise. Normally, one frame would
            // be enough, but for some weird reason, it doesn't always get stored on the very first frame.
              if(iFrame>0.2) _Color.xy = clamp(float2(newReactDiff, avgReactDiff/.98), 0., 1.);
              else  _Color = (noise, 1.);
              return _Color;
            }

                fixed4 frag2 (v2f i) : SV_Target
            {
            // The screen coordinates.
            float2 uv = i.uv;
            // Read in the blurred pixel value. There's no rule that says you can't read in the
            // value in the "X" channel, but blurred stuff is easier to bump, that's all.
            float c = 1. - tex2D(_MainTex, uv).y;
            // Reading in the same at a slightly offsetted position. The difference between
            // "c2" and "c" is used to provide the highlighting.
            float c2 = 1. - tex2D(_MainTex, uv + .5/1.0).y;
            // Color the pixel by mixing two colors in a sinusoidal kind of pattern.
            //
            float pattern = -cos(uv.x*0.75*3.14159-0.9)*cos(uv.y*1.5*3.14159-0.75)*0.5 + 0.5;
            //
            // Blue and gold, for an abstract sky over a... wheat field look. Very artsy. :)
            float3 col = float3(c*1.5, pow(c, 2.25), pow(c, 6.));
            col = lerp(col, col.zyx, clamp(pattern-.2, 0., 1.) );
            // Extra color variations.
            //float3 col = mix(float3(c*1.2, pow(c, 8.), pow(c, 2.)), float3(c*1.3, pow(c, 2.), pow(c, 10.)), pattern );
            //float3 col = mix(float3(c*1.3, c*c, pow(c, 10.)), float3(c*c*c, c*sqrt(c), c), pattern );
            // Adding the highlighting. Not as nice as bump mapping, but still pretty effective.
            col += float3(.6, .85, 1.)*max(c2*c2 - c*c, 0.)*12.;
            // Apply a vignette and increase the brightness for that fake spotlight effect.
            col *= pow( 16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y) , .125)*1.15;
            // Fade in for the first few seconds.
            col *= smoothstep(0., 1., _Time.y/2.);
            // Done.
            _Color = float4(min(col, 1.), 1.);
            return _Color;
            }

            ENDCG

    SubShader{
        ZTest Always Cull Off ZWrite Off
        Fog{ Mode off }
        //Pass 0
        Pass{

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            ENDCG
            }
        //Pass 1
            Pass{

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag2
            ENDCG
            }
        }
}

Hey. Did you found a solution?