I’m trying to implement my lighting system with the help of command buffers, but i can’t get the screen buffer in forward rendering mode.
Using BuiltinRenderTextureType.CurrentActive or BuiltinRenderTextureType.CameraTarget as a source when bliting does not help, i just get a white texture. Though if i use CameraTarget when making a “grab” blit, it works. I don’t get it.
How to do it without unnecessary copy via command buffer blit?
I also would like to use screen buffer’s depth texture, but it is not copied when making a “grab” blit, why? i have to render the scene depth separately by setting the camera in depth rendering mode, which i would like to avoid
CachedCamera.depthTextureMode = DepthTextureMode.Depth;
So here is the algorithm which uses command buffers to render some custom lights
private void ConfigureCommandBuffer(CommandBuffer commandBuffer)
{
if (commandBuffer == null) return;
//var simpleLightTexPropID = Shader.PropertyToID("_MainTex");
//var simpleLightTexRtID = new RenderTargetIdentifier(simpleLightTexPropID);
var overrideTexPropID = Shader.PropertyToID("_Overlay");
var overrideRtID = new RenderTargetIdentifier(overrideTexPropID);
var simpleLightPropID = Shader.PropertyToID("_SimpleLightAndGlobalTransitions");
var simpleLightRtID = new RenderTargetIdentifier(simpleLightPropID);
var screenTexPropID = Shader.PropertyToID("_MainTex");
var screenRtID = new RenderTargetIdentifier(screenTexPropID);
//render fake light on top of source(screen in this case)
DrawRenderers(commandBuffer, FakeLights);
commandBuffer.GetTemporaryRT(overrideTexPropID, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
commandBuffer.GetTemporaryRT(simpleLightPropID, -1, -1, 24, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
commandBuffer.GetTemporaryRT(screenTexPropID, -1, -1, 24, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
commandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, screenRtID);
//render override lights + transitions
commandBuffer.SetRenderTarget(overrideRtID, BuiltinRenderTextureType.Depth);
//clear before rendering to it
commandBuffer.ClearRenderTarget(false, true, Color.clear);
//render
DrawRenderers(commandBuffer, OverrideLights);
//render fake light as override light(into rgba)
DrawRenderers(commandBuffer, FakeLights);
commandBuffer.SetRenderTarget(simpleLightRtID, BuiltinRenderTextureType.Depth);
//clear color on simple light rt
commandBuffer.ClearRenderTarget(false, true, Color.clear);
//render simple light(into rgb) and global transition(into a)
DrawRenderers(commandBuffer, SimpleLights);
commandBuffer.SetGlobalColor("_GlobalLightColor", GlobalColor);
commandBuffer.SetGlobalTexture(overrideTexPropID, overrideRtID);
commandBuffer.SetGlobalTexture(simpleLightPropID, simpleLightRtID);
commandBuffer.Blit(screenRtID, BuiltinRenderTextureType.CameraTarget, Material,
(int)StandardImageEffect.BlendModes.LightAsPostprocess);
commandBuffer.ReleaseTemporaryRT(overrideTexPropID);
commandBuffer.ReleaseTemporaryRT(simpleLightPropID);
commandBuffer.ReleaseTemporaryRT(screenTexPropID);
}
Here are the problems with it
First:
commandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, screenTexPropID);
I would like to get rid of this line, because why would i need to make a copy of a screen buffer, when it is already there, somewhere, i don’t know how to get it and BuiltinRenderTextureType doesn’t seem to support it either, if you know, please give me a hint.
Also, copying the screen buffer like that works, i get the correct image, but when i try to blit directly from it(second blit), i just get a white texture.
I mean, if i change this line
commandBuffer.Blit(screenTexPropID, BuiltinRenderTextureType.CameraTarget, Material,
(int)StandardImageEffect.BlendModes.LightAsPostprocess);
to this line
commandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.CameraTarget, Material,
(int)StandardImageEffect.BlendModes.LightAsPostprocess);
i get a white texture, not the screen buffer’s image, why is that?
Second:
if i try to use the depth buffer from screenRtID, like that
commandBuffer.SetRenderTarget(overrideRtID, screenRtID);//second argument is the depth buffer
it doesn’t work, the depth texture is black in the frame debugger, as if the depth was not copied when doing blit from screen to temporary render texture, this line show how i try to use the depth from screen buffer’s copy
commandBuffer.SetRenderTarget(overrideRtID, screenRtID);
and i have to render the scene depth separately, and use it like this
commandBuffer.SetRenderTarget(overrideRtID, BuiltinRenderTextureType.Depth);
and it works, yes, but at the cost of additional rendering of depth, just because i cant get the depth from screen buffer directly.
All the problems could be solved if i could get the screen buffer as a RenderTargetIdentifier, so, how to do it?