Hey everyone, I’ve been working on a custom deferred shading renderer inside of Unity similar to what Dolkar and Aieth have made here on the forums. I have been very unsuccessful though in terms of fixing a major flaw. I posted my issue in the scripting section but I think its better to post here as I assume most of that traffic has no idea of what I am proposing here.
All of the buffers display correctly, the lighting works but it doesn’t update past the first frame rendered to the screen. So when I press play it renders the first screen, and if I move an object or the camera nothing happens. I believe it has something to do with the Replacement shader funtions.
TL;DR → My issue is that the camera does not update what’s being rendered.
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);
}
}