Hey everyone. I decided to tackle a custom renderer, and while you might be thinking, “Unity 5 is around the corner, why on earth would you do that”? Well I plan to extend it to tiled deferred render and have a rendering pipeline that I have full control over. It seems the old, drop the built-in shaders into the resource folder and make changes doesnt work with Unity 5. I don’t have control over shadow maps. And I really really want to make my own BRDF system ![]()
For those of you who are not familiar with custom rendering it essentially what Jove 2.0 and Dolkar are doing here on the Unity forums. Creating a custom renderer in Unity allows for the easy use of Unity of course with the bonus of full access to how everything is rendered.
Here is the current code I have. So far it works, kinda. I have 3 issues. The last two are minute and you don’t have to worry as I am bound to figure it out. So for now my biggest concern is the issue below.
TL;DR : When I move the camera around, it does not update what’s being rendered.
Just to show you that it does function and that I’m excited about the potential use of it, here is a super basic diffuse, ambient and specular I made in about 1.5 minutes:
Example Image
EDIT: I added some of my BRDF code to it and it works nicely, still haven’t found a fix yet for the camera not updating…
BRDF

(Sorry for the messy code)
Rendering Code
using UnityEngine;
using System.Collections;
public class DeferredShading : MonoBehaviour
{
Camera originalCamera;
Camera renderingCamera;
public static RenderTexture[] RTs;
public Shader GBufferShader;
public Shader DirectionalLightShader;
public Light MainLight;
[Range(0, 10)]
public float LightIntensity = 1.0f;
public Color LightColor = Color.white;
private RenderBuffer[] colorBuffers;
private RenderBuffer depthBuffer;
private Material DirectionalLightMaterial;
private Material GBufferMat;
void Awake()
{
originalCamera = camera;
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if(!GBufferMat)
{
GBufferMat = new Material(GBufferShader);
GBufferMat.SetTexture("_MainTex", RTs[0]);
GBufferMat.SetTexture("_NormalTexture", RTs[1]);
GBufferMat.SetTexture("_DepthTexture", RTs[1]);
GBufferMat.SetTexture("_SpecColor", RTs[2]);
source = RTs[0];
Graphics.Blit(RTs[0], destination, GBufferMat);
Graphics.Blit(RTs[1], destination, GBufferMat);
Graphics.Blit(RTs[2], destination, GBufferMat);
}
if(!DirectionalLightMaterial)
{
DirectionalLightMaterial = new Material(DirectionalLightShader);
DirectionalLighting(source, destination);
}
}
void OnEnable()
{
CreateCamera();
}
void CreateCamera()
{
ReformCameras();
CreateBuffers();
}
void OnPostRender()
{
renderingCamera.SetTargetBuffers(colorBuffers, depthBuffer);
renderingCamera.RenderWithShader(GBufferShader, "");
}
void OnGUI()
{
//GUI.DrawTexture(new Rect(0, 0, RTs[0].width, RTs[0].height), RTs[0], ScaleMode.StretchToFill, false);
}
public void DirectionalLighting (RenderTexture Input, RenderTexture Output)
{
DirectionalLightMaterial.SetFloat("_LightIntensity", LightIntensity);
DirectionalLightMaterial.SetColor("_LightColor", LightColor);
DirectionalLightMaterial.SetVector("_LightDirection", MainLight.transform.forward * 1.0f);
DirectionalLightMaterial.SetTexture("_MainTex", RTs[0]);
DirectionalLightMaterial.SetTexture("_NormalTexture", RTs[1]);
Graphics.Blit(Input, Output, DirectionalLightMaterial);
}
void ReformCameras()
{
renderingCamera = new GameObject("RenderingCamera").AddComponent<Camera>();
renderingCamera.enabled = false;
renderingCamera.transform.parent = transform;
renderingCamera.transform.localPosition = Vector3.zero;
renderingCamera.transform.localRotation = Quaternion.identity;
originalCamera.renderingPath = RenderingPath.VertexLit;
originalCamera.cullingMask = 0;
originalCamera.clearFlags = CameraClearFlags.Depth;
originalCamera.backgroundColor = Color.black;
renderingCamera.renderingPath = RenderingPath.VertexLit;
renderingCamera.clearFlags = CameraClearFlags.SolidColor;
renderingCamera.farClipPlane = originalCamera.farClipPlane;
renderingCamera.fieldOfView = originalCamera.fieldOfView;
}
void CreateBuffers ()
{
RTs = new RenderTexture[] {
RenderTexture.GetTemporary(Screen.width, Screen.height, 32, RenderTextureFormat.Default),
RenderTexture.GetTemporary(Screen.width, Screen.height, 32, RenderTextureFormat.Default),
RenderTexture.GetTemporary(Screen.width, Screen.height, 32, RenderTextureFormat.Default) };
colorBuffers = new RenderBuffer[] { RTs[0].colorBuffer, RTs[1].colorBuffer, RTs[2].colorBuffer };
depthBuffer = RTs[1].depthBuffer;
}
void OnDisable()
{
Destroy(renderingCamera.gameObject);
}
}

