I havent gotten to the starglow yet, but heres a massively flawed script that does offscreen particles and bloom on iOS, duct-taped together from mobilebloom and blurst’s example. It totally ignores depth for my purposes, but it should be possible to hack that back in.
Use the mobilebloom material in the bloom slot, and a fast additive/soft additive shader in the postblend slot. The particles should be tagged as layer 15, and the main camera set to ignore layer 15. There may be an extra unnecessary step at the end there because I was using it for AR and didnt want the video bloomed too. The bloom script doesnt need to be inline either, but I`m midway through tracking down a bug that seems to come from moving too many rendertextures around.
#pragma strict
function Awake () {
this.camera.depthTextureMode = DepthTextureMode.None;
}
public var intensity : float = 0.7f;
public var threshhold : float = 0.75f;
public var blurWidth : float = 1.0f;
public var downsampleset : int = 2;
public var postdownsampleFactor : int = 2;
public var extraBlurry : boolean = false;
public var postblend : Shader;
// image effects materials for internal use
public var bloomMaterial : Material = null;
private var blendMaterial:Material = null;
blendMaterial = new Material(postblend);
private var supported : boolean = true;
private var tempRtA : RenderTexture = null;
private var tempRtB : RenderTexture = null;
private var particlesRT : RenderTexture = null;
private var ParticlePost : RenderTexture = null;
function CreateBuffers () {
if (!tempRtA) {
tempRtA = new RenderTexture (Screen.width / 4, Screen.height / 4, 0);
tempRtA.hideFlags = HideFlags.DontSave;
}
if (!tempRtB) {
tempRtB = new RenderTexture (Screen.width / 4, Screen.height / 4, 0);
tempRtB.hideFlags = HideFlags.DontSave;
}
if (!particlesRT) {
particlesRT = new RenderTexture (Screen.width / downsampleset, Screen.height / downsampleset, 0);
particlesRT.hideFlags = HideFlags.DontSave;
}
if (!ParticlePost) {
ParticlePost = new RenderTexture (Screen.width / postdownsampleFactor, Screen.height / postdownsampleFactor, 0);
ParticlePost.hideFlags = HideFlags.DontSave;
}
}
function OnDisable () {
if (tempRtA) {
DestroyImmediate (tempRtA);
tempRtA = null;
}
if (tempRtB) {
DestroyImmediate (tempRtB);
tempRtB = null;
}
if (particlesRT) {
DestroyImmediate (particlesRT);
particlesRT = null;
}
if (ParticlePost) {
DestroyImmediate (ParticlePost);
ParticlePost = null;
}
}
function OnRenderImage (source :RenderTexture, destination:RenderTexture) {
CreateBuffers ();
//setup camera
var ppCamera:Camera = GetPPCamera();
ppCamera.CopyFrom(this.camera);
ppCamera.depthTextureMode = DepthTextureMode.None;
ppCamera.cullingMask |= (1 << 15);//set particle/bloom layer
ppCamera.targetTexture = particlesRT;
ppCamera.clearFlags = CameraClearFlags.SolidColor;
ppCamera.backgroundColor = Color.black;
ppCamera.Render();
// prepare data
bloomMaterial.SetVector ("_Parameter", Vector4 (0.0f, 0.0f, threshhold, intensity / (1.0f - threshhold)));
// ds blur
var oneOverW : float = 1.0f / (particlesRT.width * 1.0f);
var oneOverH : float = 1.0f / (particlesRT.height * 1.0f);
bloomMaterial.SetVector("_OffsetsA", Vector4(1.5f*oneOverW,1.5f*oneOverH,-1.5f*oneOverW,1.5f*oneOverH));
bloomMaterial.SetVector("_OffsetsB", Vector4(-1.5f*oneOverW,-1.5f*oneOverH,1.5f*oneOverW,-1.5f*oneOverH));
Graphics.Blit (particlesRT, tempRtB, bloomMaterial, 1);
oneOverW *= 4.0f * blurWidth;
oneOverH *= 4.0f * blurWidth;
bloomMaterial.SetVector("_OffsetsA", Vector4(1.5f*oneOverW,0.0f,-1.5f*oneOverW,0.0f));
bloomMaterial.SetVector("_OffsetsB", Vector4(0.5f*oneOverW,0.0f,-0.5f*oneOverW,0.0f));
Graphics.Blit (tempRtB, tempRtA, bloomMaterial, 2);
bloomMaterial.SetVector("_OffsetsA", Vector4(0.0f,1.5f*oneOverH,0.0f,-1.5f*oneOverH));
bloomMaterial.SetVector("_OffsetsB", Vector4(0.0f,0.5f*oneOverH,0.0f,-0.5f*oneOverH));
Graphics.Blit (tempRtA, tempRtB, bloomMaterial, 2);
if(extraBlurry) {
bloomMaterial.SetVector("_OffsetsA", Vector4(1.5f*oneOverW,0.0f,-1.5f*oneOverW,0.0f));
bloomMaterial.SetVector("_OffsetsB", Vector4(0.5f*oneOverW,0.0f,-0.5f*oneOverW,0.0f));
Graphics.Blit (tempRtB, tempRtA, bloomMaterial, 2);
bloomMaterial.SetVector("_OffsetsA", Vector4(0.0f,1.5f*oneOverH,0.0f,-1.5f*oneOverH));
bloomMaterial.SetVector("_OffsetsB", Vector4(0.0f,0.5f*oneOverH,0.0f,-0.5f*oneOverH));
Graphics.Blit (tempRtA, tempRtB, bloomMaterial, 2);
}
// bloomMaterial
bloomMaterial.SetTexture ("_Bloom", tempRtB);
Graphics.Blit (particlesRT, ParticlePost, bloomMaterial, 0);
//Add particles over this camera's view
Graphics.Blit(ParticlePost, source, blendMaterial);
//final composite
Graphics.Blit(source, destination);
}
private static var ppCameraGO:GameObject;
static function GetPPCamera():Camera
{
// Create the shader camera if it doesn’t exist yet
if(!ppCameraGO) {
ppCameraGO = new GameObject("Post Processing Camera", Camera);
ppCameraGO.camera.enabled = false;
ppCameraGO.hideFlags = HideFlags.HideAndDontSave;
}
return ppCameraGO.camera;
}