浏览代码

WIP: New attempt to update to renderpass API. Branched from OnTileDeferred, since renderpass appears to be a work in progress still.

/main
Filip Iliescu 7 年前
当前提交
9f641209
共有 10 个文件被更改,包括 407 次插入303 次删除
  1. 567
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/OnTileDeferredRenderPipeline.cs
  2. 36
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/Internal-DeferredReflections.shader
  3. 35
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/LightingTemplate.hlsl
  4. 4
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/Skybox-Cubed.shader
  5. 6
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/Standard.shader
  6. 6
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/StandardSpecular.shader
  7. 2
      Assets/TestScenes/MobileDeferredTest/OnTileDeferredDemo/OnTileDeferredDemoScene.unity
  8. 2
      Assets/TestScenes/MobileDeferredTest/OnTileDeferredPipeline.asset
  9. 42
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/FinalPass.shader
  10. 10
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/FinalPass.shader.meta

567
Assets/ScriptableRenderPipeline/MobileRenderPipeline/OnTileDeferredRenderPipeline.cs


private static ComputeBuffer s_LightDataBuffer = null;
private static int s_GBufferAlbedo;
private static int s_GBufferSpecRough;
private static int s_GBufferNormal;
private static int s_GBufferEmission;
private static int s_GBufferZ;
private static RenderPassAttachment s_GBufferAlbedo;
private static RenderPassAttachment s_GBufferSpecRough;
private static RenderPassAttachment s_GBufferNormal;
private static RenderPassAttachment s_GBufferEmission;
private static RenderPassAttachment s_GBufferZ;
private static RenderPassAttachment s_CameraTarget;
#if !(UNITY_EDITOR || UNITY_STANDALONE)
private static int s_GBufferRedF32;
#endif
private static RenderPassAttachment s_GBufferRedF32;
private static int s_CameraTarget;
private static int s_CameraDepthTexture;
// private static int s_GBufferAlbedo;
// private static int s_GBufferSpecRough;
// private static int s_GBufferNormal;
// private static int s_GBufferEmission;
// private static int s_GBufferZ;
// private static int s_CameraTarget;
// private static int s_CameraDepthTexture;
//
// // write depth to red color buffer if on mobile so we can read it back
// // cannot read depth buffer directly in shader on iOS
// #if !(UNITY_EDITOR || UNITY_STANDALONE)
// private static int s_GBufferRedF32;
// #endif
private Material m_DirectionalDeferredLightingMaterial;
private Material m_FiniteDeferredLightingMaterial;

public void Build()
{
s_GBufferAlbedo = Shader.PropertyToID ("_CameraGBufferTexture0");
s_GBufferSpecRough = Shader.PropertyToID ("_CameraGBufferTexture1");
s_GBufferNormal = Shader.PropertyToID ("_CameraGBufferTexture2");
s_GBufferEmission = Shader.PropertyToID ("_CameraGBufferTexture3");
s_GBufferAlbedo = new RenderPassAttachment(RenderTextureFormat.ARGB32);
s_GBufferSpecRough = new RenderPassAttachment(RenderTextureFormat.ARGB32);
s_GBufferNormal = new RenderPassAttachment(RenderTextureFormat.ARGB2101010);
s_GBufferEmission = new RenderPassAttachment(RenderTextureFormat.ARGBHalf);
s_GBufferRedF32 = new RenderPassAttachment(RenderTextureFormat.RFloat);
s_GBufferZ = new RenderPassAttachment(RenderTextureFormat.Depth);
s_CameraTarget = new RenderPassAttachment(RenderTextureFormat.ARGB32);
#if !(UNITY_EDITOR || UNITY_STANDALONE)
s_GBufferRedF32 = Shader.PropertyToID ("_CameraVPDepth");
#endif
s_GBufferEmission.Clear(new Color(0.0f, 0.0f, 0.0f, 0.0f), 1.0f, 0);
s_GBufferZ.Clear(new Color(), 1.0f, 0);
s_CameraTarget.BindSurface(BuiltinRenderTextureType.CameraTarget, false, true);
s_GBufferZ = Shader.PropertyToID ("_CameraGBufferZ"); // used while rendering into G-buffer+
s_CameraDepthTexture = Shader.PropertyToID ("_CameraDepthTexture"); // copy of that for later sampling in shaders
s_CameraTarget = Shader.PropertyToID ("_CameraTarget");
// s_GBufferAlbedo = Shader.PropertyToID ("_CameraGBufferTexture0");
// s_GBufferSpecRough = Shader.PropertyToID ("_CameraGBufferTexture1");
// s_GBufferNormal = Shader.PropertyToID ("_CameraGBufferTexture2");
// s_GBufferEmission = Shader.PropertyToID ("_CameraGBufferTexture3");
//
// #if !(UNITY_EDITOR || UNITY_STANDALONE)
// s_GBufferRedF32 = Shader.PropertyToID ("_CameraVPDepth");
// #endif
//
// s_GBufferZ = Shader.PropertyToID ("_CameraGBufferZ"); // used while rendering into G-buffer+
// s_CameraDepthTexture = Shader.PropertyToID ("_CameraDepthTexture"); // copy of that for later sampling in shaders
// s_CameraTarget = Shader.PropertyToID ("_CameraTarget");
m_BlitMaterial = new Material (finalPassShader) { hideFlags = HideFlags.HideAndDontSave };

m_CubeReflTexArray.NewFrame();
}
public void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras)
{
foreach (var camera in cameras) {

m_ShadowMgr.UpdateCullingParameters(ref cullingParams);
var cullResults = CullResults.Cull (ref cullingParams, context);
NewFrame ();
UpdateShadowConstants (camera, cullResults);
m_ShadowMgr.RenderShadows( m_FrameId, context, cullResults, cullResults.visibleLights );
m_ShadowMgr.SyncData();
m_ShadowMgr.BindResources( context );
context.SetupCameraProperties(camera);
ExecuteRenderLoop(camera, cullResults, context);
}

void ExecuteRenderLoop(Camera camera, CullResults cullResults, ScriptableRenderContext loop)
{
NewFrame ();
using (RenderPass rp = new RenderPass (loop, camera.pixelWidth, camera.pixelHeight, 1, new[] {
s_GBufferAlbedo,
s_GBufferSpecRough,
s_GBufferNormal,
s_GBufferEmission,
s_GBufferRedF32,
s_CameraTarget
}, s_GBufferZ)) {
UpdateShadowConstants (camera, cullResults);
// GBuffer pass
using (new RenderPass.SubPass (rp, new[] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission, s_GBufferRedF32 }, null)) {
using (var cmd = new CommandBuffer { name = "Create G-Buffer" }) {
cmd.EnableShaderKeyword ("UNITY_HDR_ON");
m_ShadowMgr.RenderShadows( m_FrameId, loop, cullResults, cullResults.visibleLights );
m_ShadowMgr.SyncData();
m_ShadowMgr.BindResources( loop );
loop.ExecuteCommandBuffer (cmd);
}
loop.SetupCameraProperties(camera);
RenderGBuffer(cullResults, camera, loop);
// render opaque objects using Deferred pass
var settings = new DrawRendererSettings (cullResults, camera, new ShaderPassName ("Gbuffer Pass")) {
sorting = { flags = SortFlags.CommonOpaque },
rendererConfiguration = RendererConfiguration.PerObjectLightmaps
};
// try to use framebuffer fetch on tiled GPUs
#if UNITY_EDITOR || UNITY_STANDALONE
CopyDepthAfterGBuffer(loop);
#endif
RenderLighting (camera, cullResults, loop);
settings.inputFilter.SetQueuesOpaque ();
settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
loop.DrawRenderers (ref settings);
}
loop.DrawSkybox (camera);
//Lighting Pass
using (new RenderPass.SubPass(rp, new[] { s_GBufferEmission }, new[] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission, s_GBufferRedF32 }, true))
{
using (var cmd = new CommandBuffer { name = "Deferred Lighting and Reflections Pass"} )
{
RenderLightsDeferred (camera, cullResults, cmd, loop);
RenderReflections (camera, cmd, cullResults, loop);
RenderForward (cullResults, camera, loop, false);
loop.ExecuteCommandBuffer(cmd);
}
}
loop.SetupCameraProperties (camera);
//skybox
using (new RenderPass.SubPass (rp, new[] { s_GBufferEmission }, null, true)) {
loop.DrawSkybox (camera);
}
// present frame buffer.
FinalPass(loop);
//Single Pass Forward Transparencies
using (new RenderPass.SubPass(rp, new[] { s_GBufferEmission }, new[] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission, s_GBufferRedF32 }, true))
{
using (var cmd = new CommandBuffer { name = "Forwward Lighting Setup"} )
{
// bind depth surface for editor grid/gizmo/selection rendering
if (camera.cameraType == CameraType.SceneView)
{
var cmd = CommandBufferPool.Get();
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, new RenderTargetIdentifier(s_CameraDepthTexture));
loop.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
SetupLightShaderVariables (cullResults, camera, loop, cmd);
loop.ExecuteCommandBuffer(cmd);
var settings = new DrawRendererSettings(cullResults, camera, new ShaderPassName("ForwardSinglePass"))
{
sorting = { flags = SortFlags.CommonTransparent },
rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe,
};
settings.inputFilter.SetQueuesTransparent();
loop.DrawRenderers (ref settings);
}
}
//Final pass
loop.SetupCameraProperties (camera);
using (new RenderPass.SubPass(rp, new[] { s_CameraTarget }, new[] { s_GBufferEmission }))
{
var cmd = new CommandBuffer { name = "FinalPass" };
cmd.DrawProcedural(new Matrix4x4(), m_BlitMaterial, 0, MeshTopology.Triangles, 3);
loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// void ExecuteRenderLoop(Camera camera, CullResults cullResults, ScriptableRenderContext loop)
// {
// RenderGBuffer(cullResults, camera, loop);
//
// // try to use framebuffer fetch on tiled GPUs
// #if UNITY_EDITOR || UNITY_STANDALONE
// CopyDepthAfterGBuffer(loop);
// #endif
//
// RenderLighting (camera, cullResults, loop);
//
// loop.DrawSkybox (camera);
//
// RenderForward (cullResults, camera, loop, false);
//
// loop.SetupCameraProperties (camera);
//
// // present frame buffer.
// FinalPass(loop);
//
//// // bind depth surface for editor grid/gizmo/selection rendering
//// if (camera.cameraType == CameraType.SceneView)
//// {
//// var cmd = CommandBufferPool.Get();
//// cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, new RenderTargetIdentifier(s_CameraDepthTexture));
//// loop.ExecuteCommandBuffer(cmd);
//// CommandBufferPool.Release(cmd);
//// }
// }
//
// static void SetupGBuffer(int width, int height, CommandBuffer cmd)
// {
// var format10 = RenderTextureFormat.ARGB32;
// if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB2101010))
// format10 = RenderTextureFormat.ARGB2101010;
// var formatHDR = RenderTextureFormat.DefaultHDR;
//
// //@TODO: cleanup, right now only because we want to use unmodified Standard shader that encodes emission differently based on HDR or not,
// // so we make it think we always render in HDR
// cmd.EnableShaderKeyword ("UNITY_HDR_ON");
//
// cmd.GetTemporaryRT(s_GBufferAlbedo, width, height, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
// cmd.GetTemporaryRT(s_GBufferSpecRough, width, height, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
// cmd.GetTemporaryRT(s_GBufferNormal, width, height, 0, FilterMode.Point, format10, RenderTextureReadWrite.Linear);
// cmd.GetTemporaryRT(s_GBufferEmission, width, height, 0, FilterMode.Point, formatHDR, RenderTextureReadWrite.Linear);
// cmd.GetTemporaryRT(s_CameraDepthTexture, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
// cmd.GetTemporaryRT(s_CameraTarget, width, height, 0, FilterMode.Point, formatHDR, RenderTextureReadWrite.Default, 1, true); // rtv/uav
//
// #if UNITY_EDITOR || UNITY_STANDALONE
// cmd.GetTemporaryRT(s_GBufferZ, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
//
// var colorMRTs = new RenderTargetIdentifier[4] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission };
// cmd.SetRenderTarget(colorMRTs, new RenderTargetIdentifier(s_GBufferZ));
//
// #else
// cmd.GetTemporaryRT(s_GBufferZ, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
// cmd.GetTemporaryRT(s_GBufferRedF32, width, height, 24, FilterMode.Point, RenderTextureFormat.RFloat);
//
// var colorMRTs = new RenderTargetIdentifier[5] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission, s_GBufferRedF32 };
// cmd.SetRenderTarget(colorMRTs, new RenderTargetIdentifier(s_GBufferZ));
//
// #endif
//
// cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0));
//
// }
//
// static void RenderGBuffer(CullResults cull, Camera camera, ScriptableRenderContext loop)
// {
// // setup GBuffer for rendering
// var cmd = CommandBufferPool.Get ("Create G-Buffer");
// SetupGBuffer(camera.pixelWidth, camera.pixelHeight, cmd);
// loop.ExecuteCommandBuffer(cmd);
// CommandBufferPool.Release(cmd);
//
// // render opaque objects using Deferred pass
// var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("Deferred"))
// {
// sorting = {flags = SortFlags.CommonOpaque},
// rendererConfiguration = RendererConfiguration.PerObjectLightmaps
// };
//
// settings.inputFilter.SetQueuesOpaque();
// settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
// loop.DrawRenderers(ref settings);
// }
//
// void RenderLighting (Camera camera, CullResults inputs, ScriptableRenderContext loop)
// {
// var cmd = CommandBufferPool.Get ("Lighting");
//
// // Use framebuffer fetch if available
// #if UNITY_EDITOR || UNITY_STANDALONE
// cmd.SetRenderTarget (new RenderTargetIdentifier (s_GBufferEmission), new RenderTargetIdentifier (s_GBufferZ));
// #endif
//
// RenderLightsDeferred (camera, inputs, cmd, loop);
//
// // TODO: UNITY_BRDF_PBS1 writes out alpha 1 to our emission alpha. Should preclear emission alpha after gbuffer pass in case this ever changes
// RenderReflections (camera, cmd, inputs, loop);
//
// loop.ExecuteCommandBuffer (cmd);
// CommandBufferPool.Release(cmd);
// }
//
// void RenderForward(CullResults cull, Camera camera, ScriptableRenderContext loop, bool opaquesOnly)
// {
// CommandBuffer cmd = CommandBufferPool.Get ("ForwardSetup");
//
// SetupLightShaderVariables (cull, camera, loop);
//
// loop.ExecuteCommandBuffer (cmd);
// CommandBufferPool.Release(cmd);
//
// var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("ForwardSinglePass"))
// {
// sorting = { flags = opaquesOnly ? SortFlags.CommonOpaque : SortFlags.CommonTransparent }
// };
// settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
// if (opaquesOnly)
// settings.inputFilter.SetQueuesOpaque();
// else
// settings.inputFilter.SetQueuesTransparent();
//
// loop.DrawRenderers (ref settings);
//
// }
//
// static void CopyDepthAfterGBuffer(ScriptableRenderContext loop)
// {
// var cmd = CommandBufferPool.Get ("Copy depth");
// cmd.CopyTexture(new RenderTargetIdentifier(s_GBufferZ), new RenderTargetIdentifier(s_CameraDepthTexture));
// loop.ExecuteCommandBuffer(cmd);
// CommandBufferPool.Release(cmd);
// }
//
// void FinalPass(ScriptableRenderContext loop)
// {
// var cmd = CommandBufferPool.Get ("FinalPass");
// cmd.Blit(s_GBufferEmission, BuiltinRenderTextureType.CameraTarget, m_BlitMaterial, 0);
// loop.ExecuteCommandBuffer(cmd);
// CommandBufferPool.Release(cmd);
// }
// Utilites
static Matrix4x4 GetFlipMatrix()
{
Matrix4x4 flip = Matrix4x4.identity;

return GetFlipMatrix() * camera.worldToCameraMatrix;
}
static Matrix4x4 CameraToWorld(Camera camera)
{
return camera.cameraToWorldMatrix * GetFlipMatrix();
}
static Matrix4x4 CameraProjection(Camera camera)
{
return camera.projectionMatrix * GetFlipMatrix();
}
Matrix4x4 PerspectiveCotanMatrix(float cotangent, float zNear, float zFar )
{
float deltaZ = zNear - zFar;
var m = Matrix4x4.zero;
m.m00 = cotangent; m.m01 = 0.0f; m.m02 = 0.0f; m.m03 = 0.0f;
m.m10 = 0.0f; m.m11 = cotangent; m.m12 = 0.0f; m.m13 = 0.0f;
m.m20 = 0.0f; m.m21 = 0.0f; m.m22 = (zFar + zNear) / deltaZ; m.m23 = 2.0f * zNear * zFar / deltaZ;
m.m30 = 0.0f; m.m31 = 0.0f; m.m32 = -1.0f; m.m33 = 0.0f;
return m;
}
float GetCotanHalfSpotAngle (float spotAngle)
{
const float degToRad = (float)(Mathf.PI / 180.0);
var cs = Mathf.Cos(0.5f * spotAngle * degToRad);
var ss = Mathf.Sin(0.5f * spotAngle * degToRad);
return cs / ss; //cothalfspotangle
}
// Shadows
void UpdateShadowConstants(Camera camera, CullResults inputs)
{
m_FrameId.frameCount++;
// get the indices for all lights that want to have shadows
m_ShadowRequests.Clear();
m_ShadowRequests.Capacity = inputs.visibleLights.Count;
int lcnt = inputs.visibleLights.Count;
for (int i = 0; i < lcnt; ++i)
{
VisibleLight vl = inputs.visibleLights[i];
if (vl.light.shadows != LightShadows.None && vl.light.GetComponent<AdditionalShadowData>().shadowDimmer > 0.0f)
m_ShadowRequests.Add(i);
}
// pass this list to a routine that assigns shadows based on some heuristic
uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
// update the visibleLights with the shadow information
m_ShadowIndices.Clear();
for (uint i = 0; i < shadowRequestCount; i++)
{
m_ShadowIndices.Add(shadowRequests[i], shadowDataIndices[i]);
}
}
// Reflections
void RenderReflections(Camera camera, CommandBuffer cmd, CullResults cullResults, ScriptableRenderContext loop)
{
var probes = cullResults.visibleReflectionProbes;

}
}
void UpdateShadowConstants(Camera camera, CullResults inputs)
{
m_FrameId.frameCount++;
// get the indices for all lights that want to have shadows
m_ShadowRequests.Clear();
m_ShadowRequests.Capacity = inputs.visibleLights.Count;
int lcnt = inputs.visibleLights.Count;
for (int i = 0; i < lcnt; ++i)
{
VisibleLight vl = inputs.visibleLights[i];
if (vl.light.shadows != LightShadows.None && vl.light.GetComponent<AdditionalShadowData>().shadowDimmer > 0.0f)
m_ShadowRequests.Add(i);
}
// pass this list to a routine that assigns shadows based on some heuristic
uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
// update the visibleLights with the shadow information
m_ShadowIndices.Clear();
for (uint i = 0; i < shadowRequestCount; i++)
{
m_ShadowIndices.Add(shadowRequests[i], shadowDataIndices[i]);
}
}
static void SetupGBuffer(int width, int height, CommandBuffer cmd)
{
var format10 = RenderTextureFormat.ARGB32;
if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB2101010))
format10 = RenderTextureFormat.ARGB2101010;
var formatHDR = RenderTextureFormat.DefaultHDR;
//@TODO: cleanup, right now only because we want to use unmodified Standard shader that encodes emission differently based on HDR or not,
// so we make it think we always render in HDR
cmd.EnableShaderKeyword ("UNITY_HDR_ON");
cmd.GetTemporaryRT(s_GBufferAlbedo, width, height, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
cmd.GetTemporaryRT(s_GBufferSpecRough, width, height, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
cmd.GetTemporaryRT(s_GBufferNormal, width, height, 0, FilterMode.Point, format10, RenderTextureReadWrite.Linear);
cmd.GetTemporaryRT(s_GBufferEmission, width, height, 0, FilterMode.Point, formatHDR, RenderTextureReadWrite.Linear);
cmd.GetTemporaryRT(s_CameraDepthTexture, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(s_CameraTarget, width, height, 0, FilterMode.Point, formatHDR, RenderTextureReadWrite.Default, 1, true); // rtv/uav
#if UNITY_EDITOR || UNITY_STANDALONE
cmd.GetTemporaryRT(s_GBufferZ, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
var colorMRTs = new RenderTargetIdentifier[4] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission };
cmd.SetRenderTarget(colorMRTs, new RenderTargetIdentifier(s_GBufferZ));
#else
cmd.GetTemporaryRT(s_GBufferZ, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(s_GBufferRedF32, width, height, 24, FilterMode.Point, RenderTextureFormat.RFloat);
var colorMRTs = new RenderTargetIdentifier[5] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission, s_GBufferRedF32 };
cmd.SetRenderTarget(colorMRTs, new RenderTargetIdentifier(s_GBufferZ));
#endif
cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0));
}
static void RenderGBuffer(CullResults cull, Camera camera, ScriptableRenderContext loop)
{
// setup GBuffer for rendering
var cmd = CommandBufferPool.Get ("Create G-Buffer");
SetupGBuffer(camera.pixelWidth, camera.pixelHeight, cmd);
loop.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
// render opaque objects using Deferred pass
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("Deferred"))
{
sorting = {flags = SortFlags.CommonOpaque},
rendererConfiguration = RendererConfiguration.PerObjectLightmaps
};
settings.inputFilter.SetQueuesOpaque();
settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
loop.DrawRenderers(ref settings);
}
void RenderLighting (Camera camera, CullResults inputs, ScriptableRenderContext loop)
{
var cmd = CommandBufferPool.Get ("Lighting");
// Use framebuffer fetch if available
#if UNITY_EDITOR || UNITY_STANDALONE
cmd.SetRenderTarget (new RenderTargetIdentifier (s_GBufferEmission), new RenderTargetIdentifier (s_GBufferZ));
#endif
RenderLightsDeferred (camera, inputs, cmd, loop);
// TODO: UNITY_BRDF_PBS1 writes out alpha 1 to our emission alpha. Should preclear emission alpha after gbuffer pass in case this ever changes
RenderReflections (camera, cmd, inputs, loop);
loop.ExecuteCommandBuffer (cmd);
CommandBufferPool.Release(cmd);
}
void RenderSpotlight(VisibleLight light, CommandBuffer cmd, MaterialPropertyBlock properties, bool renderAsQuad, bool intersectsNear, bool deferred)
{
float range = light.range;

}
}
Matrix4x4 PerspectiveCotanMatrix(float cotangent, float zNear, float zFar )
{
float deltaZ = zNear - zFar;
var m = Matrix4x4.zero;
m.m00 = cotangent; m.m01 = 0.0f; m.m02 = 0.0f; m.m03 = 0.0f;
m.m10 = 0.0f; m.m11 = cotangent; m.m12 = 0.0f; m.m13 = 0.0f;
m.m20 = 0.0f; m.m21 = 0.0f; m.m22 = (zFar + zNear) / deltaZ; m.m23 = 2.0f * zNear * zFar / deltaZ;
m.m30 = 0.0f; m.m31 = 0.0f; m.m32 = -1.0f; m.m33 = 0.0f;
return m;
}
float GetCotanHalfSpotAngle (float spotAngle)
{
const float degToRad = (float)(Mathf.PI / 180.0);
var cs = Mathf.Cos(0.5f * spotAngle * degToRad);
var ss = Mathf.Sin(0.5f * spotAngle * degToRad);
return cs / ss; //cothalfspotangle
}
static void DepthOnlyForForwardOpaques(CullResults cull, Camera camera, ScriptableRenderContext loop)
{
var cmd = CommandBufferPool.Get ("Forward Opaques - Depth Only");
cmd.SetRenderTarget(new RenderTargetIdentifier(s_GBufferZ));
loop.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
// render opaque objects using Deferred pass
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("DepthOnly"))
{
sorting = { flags = SortFlags.CommonOpaque }
};
settings.inputFilter.SetQueuesOpaque();
loop.DrawRenderers(ref settings);
}
static void CopyDepthAfterGBuffer(ScriptableRenderContext loop)
{
var cmd = CommandBufferPool.Get ("Copy depth");
cmd.CopyTexture(new RenderTargetIdentifier(s_GBufferZ), new RenderTargetIdentifier(s_CameraDepthTexture));
loop.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
void FinalPass(ScriptableRenderContext loop)
{
var cmd = CommandBufferPool.Get ("FinalPass");
cmd.Blit(s_GBufferEmission, BuiltinRenderTextureType.CameraTarget, m_BlitMaterial, 0);
loop.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
void RenderForward(CullResults cull, Camera camera, ScriptableRenderContext loop, bool opaquesOnly)
{
SetupLightShaderVariables (cull, camera, loop);
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("ForwardSinglePass"))
{
sorting = { flags = opaquesOnly ? SortFlags.CommonOpaque : SortFlags.CommonTransparent }
};
settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
if (opaquesOnly)
settings.inputFilter.SetQueuesOpaque();
else
settings.inputFilter.SetQueuesTransparent();
loop.DrawRenderers (ref settings);
}
static Matrix4x4 CameraToWorld(Camera camera)
{
return camera.cameraToWorldMatrix * GetFlipMatrix();
}
static Matrix4x4 CameraProjection(Camera camera)
{
return camera.projectionMatrix * GetFlipMatrix();
}
private void InitializeLightData()
{
for (int i = 0; i < k_MaxLights; i++)

}
}
private void SetupLightShaderVariables(CullResults cull, Camera camera, ScriptableRenderContext context)
private void SetupLightShaderVariables(CullResults cull, Camera camera, ScriptableRenderContext context, CommandBuffer cmd)
{
int totalLightCount = cull.visibleLights.Count;
InitializeLightData();

s_LightDataBuffer.SetData(lightData);
CommandBuffer cmd = CommandBufferPool.Get ("SetupShaderConstants");
cmd.SetGlobalMatrix("g_mViewToWorld", viewToWorld);
cmd.SetGlobalMatrix("g_mWorldToView", viewToWorld.inverse);
cmd.SetGlobalMatrix("g_mScrProjection", projscr);

cmd.SetGlobalFloat ("_useLegacyCookies", UseLegacyCookies?1.0f:0.0f);
cmd.SetGlobalFloat ("_transparencyShadows", TransparencyShadows ? 1.0f : 0.0f);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}
}

36
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/Internal-DeferredReflections.shader


return max(max(p - aabbMax, aabbMin - p), half3(0.0, 0.0, 0.0));
}
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
void frag (unity_v2f_deferred i,
in half4 gbuffer0 : SV_Target0,
in half4 gbuffer1 : SV_Target1,
in half4 gbuffer2 : SV_Target2,
out half4 outEmission : SV_Target3,
in float linearDepth : SV_Target4)
#else
#endif
#ifndef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
OnChipDeferredFragSetup(i, uv, viewPos, worldPos, 0.0);
#else
OnChipDeferredFragSetup(i, uv, viewPos, worldPos, linearDepth);
#endif
float depth = UNITY_READ_FRAMEBUFFER_INPUT(4, i.pos);
OnChipDeferredFragSetup(i, uv, viewPos, worldPos, depth);
#ifndef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
// unpack Gbuffer
half4 gbuffer0 = tex2D (_CameraGBufferTexture0, uv);
half4 gbuffer1 = tex2D (_CameraGBufferTexture1, uv);
half4 gbuffer2 = tex2D (_CameraGBufferTexture2, uv);
#endif
half4 gbuffer0 = UNITY_READ_FRAMEBUFFER_INPUT(0, i.pos);
half4 gbuffer1 = UNITY_READ_FRAMEBUFFER_INPUT(1, i.pos);
half4 gbuffer2 = UNITY_READ_FRAMEBUFFER_INPUT(2, i.pos);
UnityStandardData data = UnityStandardDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2);
float3 eyeVec = normalize(worldPos - _WorldSpaceCameraPos);

half3 distance = distanceFromAABB(worldPos, unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
half falloff = saturate(1.0 - length(distance)/blendDistance);
half4 ret = half4(rgb*falloff, 1-falloff);
// UNITY_BRDF_PBS1 writes out alpha 1 to our emission alpha. TODO: Should preclear emission alpha after gbuffer pass in case this ever changes
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
outEmission = ret;
#else
return ret;
#endif
// UNITY_BRDF_PBS1 writes out alpha 1 to our emission alpha. TODO: Should preclear emission alpha after gbuffer pass in case this ever changes
return half4(rgb*falloff, 1-falloff);
}
ENDCG

35
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/LightingTemplate.hlsl


#define CUBEMAPFACE_POSITIVE_Z 4
#define CUBEMAPFACE_NEGATIVE_Z 5
sampler2D _CameraGBufferTexture0;
sampler2D _CameraGBufferTexture1;
sampler2D _CameraGBufferTexture2;
UNITY_DECLARE_FRAMEBUFFER_INPUT_HALF(0);
UNITY_DECLARE_FRAMEBUFFER_INPUT_HALF(1);
UNITY_DECLARE_FRAMEBUFFER_INPUT_HALF(2);
UNITY_DECLARE_FRAMEBUFFER_INPUT_FLOAT(3);
UNITY_DECLARE_FRAMEBUFFER_INPUT_FLOAT(4);
// from LightDefinitions.cs.hlsl
#define SPOT_LIGHT (0)

{
i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
float2 uv = i.uv.xy / i.uv.w;
// read depth and reconstruct world position
// if we have framebuffer fetch, its expected depth was passed in the parameter from the framebuffer so no need to fetch
#ifndef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
#endif
depth = Linear01Depth (depth);

outCookieColor = colorCookie;
}
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
half4 CalculateLight (unity_v2f_deferred i, inout half4 gbuffer0, inout half4 gbuffer1, inout half4 gbuffer2, inout float vpDepth)
#else
#endif
{
float3 wpos;
float2 uv;

UnityLight light;
UNITY_INITIALIZE_OUTPUT(UnityLight, light);
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
OnChipDeferredCalculateLightParams (i, wpos, uv, light.dir, atten, fadeDist, colorCookie, vpDepth);
#else
OnChipDeferredCalculateLightParams (i, wpos, uv, light.dir, atten, fadeDist, colorCookie, 0.0);
#endif
float depth = UNITY_READ_FRAMEBUFFER_INPUT(3, i.pos);
OnChipDeferredCalculateLightParams (i, wpos, uv, light.dir, atten, fadeDist, colorCookie, depth);
#if defined (POINT_COOKIE) || defined (DIRECTIONAL_COOKIE) || defined (SPOT)
light.color = _LightColor.rgb * colorCookie.rgb * atten;

#ifndef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
// unpack Gbuffer
half4 gbuffer0 = tex2D (_CameraGBufferTexture0, uv);
half4 gbuffer1 = tex2D (_CameraGBufferTexture1, uv);
half4 gbuffer2 = tex2D (_CameraGBufferTexture2, uv);
#endif
half4 gbuffer0 = UNITY_READ_FRAMEBUFFER_INPUT(0, i.pos);
half4 gbuffer1 = UNITY_READ_FRAMEBUFFER_INPUT(1, i.pos);
half4 gbuffer2 = UNITY_READ_FRAMEBUFFER_INPUT(2, i.pos);
UnityStandardData data = UnityStandardDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2);
float3 eyeVec = normalize(wpos-_WorldSpaceCameraPos);

4
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/Skybox-Cubed.shader


return o;
}
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
half4 frag (v2f i) : SV_Target3
#else
#endif
{
half4 tex = texCUBE (_Tex, i.texcoord);
half3 c = DecodeHDR (tex, _Tex_HDR);

6
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/Standard.shader


#include "UnityStandardForwardMobile.cginc"
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
half4 fragForward(VertexOutputForwardNew i) : SV_Target3
#else
half4 fragForward(VertexOutputForwardNew i) : SV_Target
#endif
half4 fragForward(VertexOutputForwardNew i) : SV_Target
{
return singlePassForward(i);
}

6
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/StandardSpecular.shader


#include "UnityStandardForwardMobile.cginc"
#ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
half4 fragForward(VertexOutputForwardNew i) : SV_Target3
#else
half4 fragForward(VertexOutputForwardNew i) : SV_Target
#endif
half4 fragForward(VertexOutputForwardNew i) : SV_Target
{
return singlePassForward(i);
}

2
Assets/TestScenes/MobileDeferredTest/OnTileDeferredDemo/OnTileDeferredDemoScene.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.36947274, g: 0.28027457, b: 0.32616237, a: 1}
m_IndirectSpecularColor: {r: 0.36931214, g: 0.280012, b: 0.3258571, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

2
Assets/TestScenes/MobileDeferredTest/OnTileDeferredPipeline.asset


m_QuadMesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
m_BoxMesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultSpotCookie: {fileID: 2800000, guid: 41e2109a383fc40ac81d1676de863fa2, type: 3}
finalPassShader: {fileID: 4800000, guid: 5590f54ad211f594da4e687b698f2258, type: 3}
finalPassShader: {fileID: 4800000, guid: bea92191e4f0645319306e59a11ceba2, type: 3}
deferredShader: {fileID: 4800000, guid: eeee2c879e4754d958204f0816f646c7, type: 3}
deferredReflectionShader: {fileID: 4800000, guid: eabc0a21ba0ff47268d9a58c92b8b40b,
type: 3}

42
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/FinalPass.shader


// Final compositing pass, just does gamma conversion for now.
Shader "SRP/FinalPass-Mobile"
{
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.5
#pragma multi_compile __ UNITY_COLORSPACE_GAMMA
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV_POSITION;
};
UNITY_DECLARE_FRAMEBUFFER_INPUT_HALF(0);
v2f vert(uint id : SV_VertexID)
{
v2f o;
o.vertex.x = (id & 1) != 0 ? 3 : -1;
o.vertex.y = (id & 2) != 0 ? -3 : 1;
o.vertex.z = 0;
o.vertex.w = 1;
return o;
}
half4 frag (v2f i) : SV_Target
{
return UNITY_READ_FRAMEBUFFER_INPUT(0, i.vertex);
}
ENDCG
}
} Fallback Off
}

10
Assets/ScriptableRenderPipeline/MobileRenderPipeline/Shaders/FinalPass.shader.meta


fileFormatVersion: 2
guid: bea92191e4f0645319306e59a11ceba2
timeCreated: 1500345256
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存