浏览代码

Prepare for deferred rendering

Add FinalPass (for gamma correction), create init buffer and clear
buffer function, prepare deferred renderer buffer. Deferreded pass not
implemented yet
/main
sebastienlagarde 8 年前
当前提交
4984a6d0
共有 13 个文件被更改,包括 371 次插入43 次删除
  1. 264
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 7
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/DisneyGGX.shader
  3. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/DisneyGGX.hlsl
  4. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl
  5. 16
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/TemplateDisneyGGX.hlsl
  6. 5
      Assets/ScriptableRenderLoop/ShaderLibrary/API/Validate.hlsl
  7. 12
      Assets/ScriptableRenderLoop/ShaderLibrary/Color.hlsl
  8. 24
      Assets/ScriptableRenderLoop/ShaderLibrary/Filtering.hlsl
  9. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess.meta
  10. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/API/Validate.hlsl.meta
  11. 49
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader
  12. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader.meta

264
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


namespace UnityEngine.ScriptableRenderLoop
{
// This HDRenderLoop assume linear lighting. Don't work with gamma.
public class HDRenderLoop : ScriptableRenderLoop
{
[MenuItem("Renderloop/CreateHDRenderLoop")]

AssetDatabase.CreateAsset(instance, "Assets/HDRenderLoop.asset");
}
public class GBufferManager
{
public const int MaxGbuffer = 8;
public void SetBufferDescription(int index, string stringID, RenderTextureFormat inFormat, RenderTextureReadWrite inSRGBWrite)
{
ID[index] = Shader.PropertyToID(stringID);
RTID[index] = new RenderTargetIdentifier(ID[index]);
format[index] = inFormat;
sRGBWrite[index] = inSRGBWrite;
}
public void InitGBuffers(CommandBuffer cmd)
{
for (int index = 0; index < gbufferCount; index++)
{
cmd.GetTemporaryRT(ID[index], -1, -1, 0, FilterMode.Point, format[index], sRGBWrite[index]);
}
}
public RenderTargetIdentifier[] GetGBuffers(CommandBuffer cmd)
{
var colorMRTs = new RenderTargetIdentifier[gbufferCount];
for (int index = 0; index < gbufferCount; index++)
{
colorMRTs[index] = RTID[index];
}
return colorMRTs;
}
public int gbufferCount { get; set; }
int[] ID = new int[MaxGbuffer];
RenderTargetIdentifier[] RTID = new RenderTargetIdentifier[MaxGbuffer];
RenderTextureFormat[] format = new RenderTextureFormat[MaxGbuffer];
RenderTextureReadWrite[] sRGBWrite = new RenderTextureReadWrite[MaxGbuffer];
}
public const int MaxLights = 32;
static private ComputeBuffer m_punctualLightList;
public const int MAX_LIGHTS = 1024;
Material m_DeferredMaterial;
Material m_FinalPassMaterial;
GBufferManager gbufferManager = new GBufferManager();
static private int s_CameraColorBuffer;
static private int s_CameraDepthBuffer;
static private ComputeBuffer s_punctualLightList;
void OnEnable()
{

void ClearComputeBuffers()
{
if (m_punctualLightList != null)
m_punctualLightList.Release();
if (s_punctualLightList != null)
s_punctualLightList.Release();
}
void Rebuild()

// m_ShadowPass = new ShadowRenderPass (m_ShadowSettings);
m_punctualLightList = new ComputeBuffer(MAX_LIGHTS, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualLightData)));
gbufferManager.gbufferCount = 4;
gbufferManager.SetBufferDescription(0, "_CameraGBufferTexture0", RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); // Store diffuse color => sRGB
gbufferManager.SetBufferDescription(1, "_CameraGBufferTexture1", RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
gbufferManager.SetBufferDescription(2, "_CameraGBufferTexture2", RenderTextureFormat.ARGB2101010, RenderTextureReadWrite.Linear); // Store normal => higher precision
gbufferManager.SetBufferDescription(3, "_CameraGBufferTexture3", RenderTextureFormat.ARGB2101010, RenderTextureReadWrite.Linear);
s_CameraColorBuffer = Shader.PropertyToID("_CameraColorBuffer");
s_CameraDepthBuffer = Shader.PropertyToID("_CameraDepthBuffer");
s_punctualLightList = new ComputeBuffer(MaxLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualLightData)));
// Shader deferredMaterial = Shader.Find("Hidden/Unity/DeferredShading") as Shader;
// m_DeferredMaterial = new Material(deferredMaterial);
// m_DeferredMaterial.hideFlags = HideFlags.HideAndDontSave;
Shader finalPassShader = Shader.Find("Hidden/Unity/FinalPass") as Shader;
m_FinalPassMaterial = new Material(finalPassShader);
m_FinalPassMaterial.hideFlags = HideFlags.HideAndDontSave;
// m_ShadowPass = new ShadowRenderPass (m_ShadowSettings);
m_punctualLightList.Release();
s_punctualLightList.Release();
if (m_DeferredMaterial) DestroyImmediate(m_DeferredMaterial);
if (m_FinalPassMaterial) DestroyImmediate(m_FinalPassMaterial);
}
void InitAndClearBuffer(Camera camera, RenderLoop renderLoop)
{
// We clear only the depth buffer, no need to clear the various color buffer as we overwrite them.
// Clear depth/stencil and init buffers
{
var cmd = new CommandBuffer();
cmd.name = "InitGBuffers and clear Depth/Stencil";
// Init buffer
// With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).
// Also we manage ourself the HDR format, here allocating fp16 directly.
// With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
// These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly
cmd.GetTemporaryRT(s_CameraColorBuffer, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default);
cmd.GetTemporaryRT(s_CameraDepthBuffer, -1, -1, 24, FilterMode.Point, RenderTextureFormat.Depth);
gbufferManager.InitGBuffers(cmd);
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(true, false, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// Clear HDR target
{
var cmd = new CommandBuffer();
cmd.name = "Clear HDR target";
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// Clear GBuffers
{
var cmd = new CommandBuffer();
cmd.name = "Clear GBuffer";
// Write into the Camera Depth buffer
cmd.SetRenderTarget(gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
// Clear everything
// TODO: Clear is not required for color as we rewrite everything, will save performance.
cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// END TEMP
}
void RenderGBuffer(CullResults cull, Camera camera, RenderLoop renderLoop)
{
// setup GBuffer for rendering
var cmd = new CommandBuffer();
cmd.name = "GBuffer Pass";
cmd.SetRenderTarget(gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
// render opaque objects into GBuffer
DrawRendererSettings settings = new DrawRendererSettings(cull, camera, new ShaderPassName("GBuffer"));
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;
settings.inputCullingOptions.SetQueuesOpaque();
renderLoop.DrawRenderers(ref settings);
}
void RenderDeferredLighting(CullResults cull, Camera camera, RenderLoop renderLoop)
{
// setup GBuffer for rendering
var cmd = new CommandBuffer();
cmd.name = "Deferred Ligthing Pass";
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
void RenderForward(CullResults cullResults, Camera camera, RenderLoop renderLoop)
{
// setup GBuffer for rendering
var cmd = new CommandBuffer();
cmd.name = "Forward Pass";
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
DrawRendererSettings settings = new DrawRendererSettings(cullResults, camera, new ShaderPassName("Forward"));
settings.rendererConfiguration = RendererConfiguration.ConfigureOneLightProbePerRenderer | RendererConfiguration.ConfigureReflectionProbesProbePerRenderer;
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;
renderLoop.DrawRenderers(ref settings);
}
void FinalPass(RenderLoop renderLoop)
{
CommandBuffer cmd = new CommandBuffer();
cmd.name = "FinalPass";
// Resolve our HDR texture to CameraTarget.
cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
//---------------------------------------------------------------------------------------------------------------------------------------------------

int punctualLightCount = 0;
List<PunctualLightData> lights = new List<PunctualLightData>();
for (int lightIndex = 0; lightIndex < Math.Min(activeLights.Length, MAX_LIGHTS); lightIndex++)
for (int lightIndex = 0; lightIndex < Math.Min(activeLights.Length, MaxLights); lightIndex++)
Matrix4x4 lightToWorld = light.localToWorld;
PunctualLightData l = new PunctualLightData();
l.positionWS = light.light.transform.position;

punctualLightCount++;
}
}
m_punctualLightList.SetData(lights.ToArray());
s_punctualLightList.SetData(lights.ToArray());
Shader.SetGlobalBuffer("g_punctualLightList", m_punctualLightList);
Shader.SetGlobalBuffer("g_punctualLightList", s_punctualLightList);
Shader.SetGlobalInt("g_punctualLightCount", punctualLightCount);
}

*/
}
/*
void RenderDeferredLighting(Camera camera, CullingInputs inputs, RenderLoop loop)
{
var props = new MaterialPropertyBlock();
var cmd = new CommandBuffer();
cmd.SetRenderTarget(new RenderTargetIdentifier(kGBufferEmission), new RenderTargetIdentifier(kGBufferZ));
foreach (var cl in inputs.culledLights)
{
bool renderAsQuad = (cl.flags & VisibleLightFlags.IntersectsNearPlane) != 0 || (cl.flags & VisibleLightFlags.IntersectsFarPlane) != 0 || (cl.lightType == LightType.Directional);
Vector3 lightPos = cl.localToWorld.GetColumn(3);
float range = cl.range;
cmd.DisableShaderKeyword("POINT");
cmd.DisableShaderKeyword("POINT_COOKIE");
cmd.DisableShaderKeyword("SPOT");
cmd.DisableShaderKeyword("DIRECTIONAL");
cmd.DisableShaderKeyword("DIRECTIONAL_COOKIE");
//cmd.EnableShaderKeyword ("UNITY_HDR_ON");
switch (cl.lightType)
{
case LightType.Point:
cmd.EnableShaderKeyword("POINT");
break;
case LightType.Spot:
cmd.EnableShaderKeyword("SPOT");
break;
case LightType.Directional:
cmd.EnableShaderKeyword("DIRECTIONAL");
break;
}
props.SetFloat("_LightAsQuad", renderAsQuad ? 1 : 0);
props.SetVector("_LightPos", new Vector4(lightPos.x, lightPos.y, lightPos.z, 1.0f / (range * range)));
props.SetVector("_LightColor", cl.finalColor);
Debug.Log("Light color : " + cl.finalColor.ToString());
props.SetMatrix("_WorldToLight", cl.worldToLocal);
///@TODO: cleanup, remove this from Internal-PrePassLighting shader
//DeferredPrivate::s_LightMaterial->SetTexture (ShaderLab::Property ("_LightTextureB0"), builtintex::GetAttenuationTexture ());
if (renderAsQuad)
{
cmd.DrawMesh(m_QuadMesh, Matrix4x4.identity, m_DeferredMaterial, 0, 0, props);
}
else
{
var matrix = Matrix4x4.TRS(lightPos, Quaternion.identity, new Vector3(range, range, range));
cmd.DrawMesh(m_PointLightMesh, matrix, m_DeferredMaterial, 0, 0, props);
}
}
loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
*/
public override void Render(Camera[] cameras, RenderLoop renderLoop)
{
// Set Frame constant buffer

{
{
// Set camera constant buffer
// TODO...

UpdatePunctualLights(cullResults.culledLights);
DrawRendererSettings settings = new DrawRendererSettings (cullResults, camera, new ShaderPassName("Forward"));
settings.rendererConfiguration = RendererConfiguration.ConfigureOneLightProbePerRenderer | RendererConfiguration.ConfigureReflectionProbesProbePerRenderer;
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;
InitAndClearBuffer(camera, renderLoop);
RenderGBuffer(cullResults, camera, renderLoop);
RenderForward(cullResults, camera, renderLoop);
FinalPass(renderLoop);
renderLoop.DrawRenderers (ref settings);
renderLoop.Submit ();
}

7
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/DisneyGGX.shader


// forward pass
Pass
{
Name "FORWARD"
Name "Forward" // Name is not used
Tags { "LightMode" = "Forward" }
Blend [_SrcBlend] [_DstBlend]

ENDCG
}
Name "GBuffer"
Tags { "LightMode" = "Deferred" }
Name "GBuffer" // Name is not used
Tags { "LightMode" = "GBuffer" }
CGPROGRAM
#pragma target 5.0

8
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/DisneyGGX.hlsl


output.diffuseColor = data.diffuseColor;
output.occlusion = data.occlusion;
output.fresnel0 = data.specularColor;
output.roughness = SmoothnessToRoughness(data.smoothness);
output.fresnel0 = data.specularColor;
output.perceptualRoughness = SmoothnessToPerceptualRoughness(data.smoothness);
output.perceptualRoughness = SmoothnessToPerceptualRoughness(data.smoothness);
output.roughness = PerceptualRoughnessToRoughness(output.perceptualRoughness);
return output;
}

output.perceptualRoughness = inGBuffer1.a;
output.normalWS = UnpackNormalCartesian(inGBuffer2.rgb);
output.roughness = PerceptualRoughnessToRoughness(output.perceptualRoughness);
return output;

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl


// UNITY_SHADER_NO_UPGRADE
// CAUTION:
// Currently the shaders compiler always include regualr Unity shaderVariables, so I get a conflict here were UNITY_SHADER_VARIABLES_INCLUDED is already define, this need to be fixed.
// As I haven't change the variables name yet, I simply don't define anything, and I put the transform function at the end of the file outside the guard header.

16
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/TemplateDisneyGGX.hlsl


// Forward
struct Attributes
{
float4 positionOS : POSITION;
half3 normalOS : NORMAL;
float3 positionOS : POSITION;
float3 normalOS : NORMAL;
half4 tangentOS : TANGENT;
float4 tangentOS : TANGENT;
};
struct Varyings

float4 interpolators[5] : TEXCOORD0;
};
// Function to pack data to use as few interpolator as possible, the ShaderGraph should generate this functions
// Function to pack data to use as few interpolator as possible, the ShaderGraph should generate these functions
PackedVaryings PackVaryings(Varyings input)
{
PackedVaryings output;

Varyings output;
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow step transform to clip space + instancing matrix)
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow steps transform to clip space + instancing matrix)
output.positionHS = TransformWorldToHClip(output.positionWS);
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);

// #ifdef _TANGENT_TO_WORLD
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
float3x3 tangentToWorld = CreateTangentToWorld(normalWS, tangentWS.xyz, tangentWS.w);

// #else
// output.tangentToWorld[0].xyz = 0;
// output.tangentToWorld[1].xyz = 0;
// output.tangentToWorld[2].xyz = normalWS;
// #endif
output.tangentToWorld[0].w = 0;
output.tangentToWorld[1].w = 0;

5
Assets/ScriptableRenderLoop/ShaderLibrary/API/Validate.hlsl


// Upgrade NOTE: replaced 'defined in' with 'defined (in)'
// Wait for a fix from Trunk
/*
REQUIRE_DEFINED(UNITY_UV_STARTS_AT_TOP)
REQUIRE_DEFINED(UNITY_UV_STARTS_AT_TOP)
*/

12
Assets/ScriptableRenderLoop/ShaderLibrary/Color.hlsl


return pow(c.rgb, float3(2.2, 2.2, 2.2));
}
float3 Gamma22ToLinear(float3 c)
float4 Gamma22ToLinear(float4 c)
{
return float4(Gamma22ToLinear(c.rgb), c.a);
}

return pow(c.rgb, float3(0.454545454545455, 0.454545454545455, 0.454545454545455));
}
float3 LinearToGamma22(float3 c)
float4 LinearToGamma22(float4 c)
{
return float4(LinearToGamma22(c.rgb), c.a);
}

float4 SRGBToLinear(float4 c)
{
return float4(SRGBToLinear(c), c.a);
return float4(SRGBToLinear(c.rgb), c.a);
}
float3 LinearToSRGB(float3 c)

float4 LinearToSRGB(float4 c)
{
return float4(LinearToSRGB(c), c.a);
return float4(LinearToSRGB(c.rgb), c.a);
}
// TODO: Seb - To verify and refit!

return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);
}
float3 FastSRGBToLinear(float3 c)
float4 FastSRGBToLinear(float4 c)
{
return float4(FastSRGBToLinear(c.rgb), c.a);
}

float4 FastLinearToSRGB(float4 c)
{
return float4(FastLinearToSRGB(c), c.a);
return float4(FastLinearToSRGB(c.rgb), c.a);
}
//-----------------------------------------------------------------------------

24
Assets/ScriptableRenderLoop/ShaderLibrary/Filtering.hlsl


result += tex.SampleLevel(linearSampler, float2(texPos3.x, texPos3.y), 0.0f) * w3.x * w3.y;
return result;
}
}
/*
// manual tri-linearly interpolated texture fetch
// not really needed: used hard-wired texture interpolation
vec4 manualTexture3D( sampler3D samp, vec3 p ){
vec3 qa = p*uvMapSize + vec3(0.5);
vec3 qi = floor(qa);
qa -= qi;
qi -= vec3(0.5);
return
mix( mix( mix( texture3D( samp, (qi+vec3(0.0,0.0,0.0))*oneOverUvMapSize ),
texture3D( samp, (qi+vec3(1.0,0.0,0.0))*oneOverUvMapSize ), qa.x ),
mix( texture3D( samp, (qi+vec3(0.0,1.0,0.0))*oneOverUvMapSize ),
texture3D( samp, (qi+vec3(1.0,1.0,0.0))*oneOverUvMapSize ), qa.x ), qa.y ),
mix( mix( texture3D( samp, (qi+vec3(0.0,0.0,1.0))*oneOverUvMapSize ),
texture3D( samp, (qi+vec3(1.0,0.0,1.0))*oneOverUvMapSize ), qa.x ),
mix( texture3D( samp, (qi+vec3(0.0,1.0,1.0))*oneOverUvMapSize ),
texture3D( samp, (qi+vec3(1.0,1.0,1.0))*oneOverUvMapSize ), qa.x ), qa.y ), qa.z );
}
*/

9
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess.meta


fileFormatVersion: 2
guid: 8a352e0cb2a42fd4ba968b628ec4bc10
folderAsset: yes
timeCreated: 1474641822
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/ShaderLibrary/API/Validate.hlsl.meta


fileFormatVersion: 2
guid: 30ba55673585a6e4f9afd796eb8b170e
timeCreated: 1474895361
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

49
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader


// Final compositing pass, just does gamma correction for now.
Shader "Hidden/Unity/FinalPass"
{
Properties { _MainTex ("Texture", any) = "" {} }
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma target 5.0
#include "../../../ShaderLibrary/Color.hlsl"
#include "../ShaderVariables.hlsl"
sampler2D _MainTex;
uniform float4 _MainTex_ST;
struct Attributes {
float3 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.vertex = TransformWorldToHClip(input.vertex);
output.texcoord = input.texcoord.xy;
return output;
}
fixed4 Frag(Varyings input) : SV_Target
{
float4 c = tex2D(_MainTex, input.texcoord);
// Gamma correction
return LinearToSRGB(c);
}
ENDCG
}
}
Fallback Off
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader.meta


fileFormatVersion: 2
guid: 59e008f014898b14cbdfb3195e16e5f5
timeCreated: 1474641824
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存