浏览代码

fptl: first stab at directional light support (directional shadows not yet working in scene view)

/main
vlad-andreev 8 年前
当前提交
21b003b8
共有 3 个文件被更改,包括 123 次插入39 次删除
  1. 97
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  2. 58
      Assets/ScriptableRenderLoop/fptl/Internal-DeferredShading.shader
  3. 7
      Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs

97
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


using UnityEngine.Rendering;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace UnityEngine.ScriptableRenderLoop

static private ComputeBuffer m_convexBoundsBuffer;
static private ComputeBuffer m_aabbBoundsBuffer;
static private ComputeBuffer lightList;
static private ComputeBuffer m_dirLightList;
Matrix4x4[] g_matWorldToShadow = new Matrix4x4[MAX_LIGHTS * MAX_SHADOWMAP_PER_LIGHTS];
Vector4[] g_vDirShadowSplitSpheres = new Vector4[MAX_DIRECTIONAL_SPLIT];
Vector4[] g_vShadow3x3PCFTerms = new Vector4[4];
public const int gMaxNumDirLights = 2;
public const float gFltMax = 3.402823466e+38F;
const int MAX_LIGHTS = 10;

if (lightList != null)
lightList.Release();
if (m_dirLightList != null)
m_dirLightList.Release();
}
void Rebuild()

m_aabbBoundsBuffer = new ComputeBuffer(2 * gMaxNumLights, 3 * sizeof(float));
m_convexBoundsBuffer = new ComputeBuffer(gMaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
m_lightDataBuffer = new ComputeBuffer(gMaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightData)));
m_dirLightList = new ComputeBuffer(gMaxNumDirLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLight)));
lightList = new ComputeBuffer(LightDefinitions.NR_LIGHT_MODELS * 1024 * 1024, sizeof(uint)); // enough list memory for a 4k x 4k display

m_DeferredMaterial.SetBuffer("g_dirLightData", m_dirLightList);
m_DeferredReflectionMaterial.SetBuffer("g_vLightData", m_lightDataBuffer);
m_BuildPerTileLightListShader.SetBuffer(kGenListPerTileKernel, "g_vBoundsBuffer", m_aabbBoundsBuffer);

m_DeferredMaterial.SetTexture("_pointCookieTextures", m_cubeCookieTexArray.GetTexCache());
m_DeferredReflectionMaterial.SetTexture("_reflCubeTextures", m_cubeReflTexArray.GetTexCache());
g_matWorldToShadow = new Matrix4x4[MAX_LIGHTS * MAX_SHADOWMAP_PER_LIGHTS];
g_vDirShadowSplitSpheres = new Vector4[MAX_DIRECTIONAL_SPLIT];
g_vShadow3x3PCFTerms = new Vector4[4];
m_ShadowPass = new ShadowRenderPass(m_ShadowSettings);
}

m_convexBoundsBuffer.Release();
m_lightDataBuffer.Release();
lightList.Release();
m_dirLightList.Release();
}
static void SetupGBuffer(CommandBuffer cmd)

m_DeferredMaterial.SetBuffer("g_vLightData", m_lightDataBuffer);
m_DeferredReflectionMaterial.SetBuffer("g_vLightData", m_lightDataBuffer);
m_DeferredMaterial.SetBuffer("g_dirLightData", m_dirLightList);
var cmd = new CommandBuffer();
cmd.name = "DoTiledDeferredLighting";

cmd.SetGlobalMatrix("g_mWorldToView", viewToWorld.inverse);
cmd.SetGlobalMatrix("g_mScrProjection", scrProj);
cmd.SetGlobalMatrix("g_mInvScrProjection", incScrProj);
// Shadow constants
cmd.SetGlobalMatrixArray("g_matWorldToShadow", g_matWorldToShadow);
cmd.SetGlobalVectorArray("g_vDirShadowSplitSpheres", g_vDirShadowSplitSpheres);
cmd.SetGlobalVector("g_vShadow3x3PCFTerms0", g_vShadow3x3PCFTerms[0]);
cmd.SetGlobalVector("g_vShadow3x3PCFTerms1", g_vShadow3x3PCFTerms[1]);
cmd.SetGlobalVector("g_vShadow3x3PCFTerms2", g_vShadow3x3PCFTerms[2]);
cmd.SetGlobalVector("g_vShadow3x3PCFTerms3", g_vShadow3x3PCFTerms[3]);
//cmd.Blit (kGBufferNormal, (RenderTexture)null); // debug: display normals

cmd.SetComputeFloatParams(shadercs, name, data);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
void UpdateDirectionalLights(Camera camera, ActiveLight[] activeLights)
{
int dirLightCount = 0;
List<DirectionalLight> lights = new List<DirectionalLight>();
Matrix4x4 worldToView = camera.worldToCameraMatrix;
for (int nLight = 0; nLight < activeLights.Length; nLight++)
{
ActiveLight light = activeLights[nLight];
if (light.lightType == LightType.Directional)
{
Debug.Assert(dirLightCount < gMaxNumDirLights, "Too many directional lights.");
DirectionalLight l = new DirectionalLight();
float range = light.range;
Matrix4x4 lightToWorld = light.localToWorld;
Vector3 lightPos = lightToWorld.GetColumn(3);
Vector3 lightDir = lightToWorld.GetColumn(2); // Z axis in world space
// represents a left hand coordinate system in world space
Vector3 vx = lightToWorld.GetColumn(0); // X axis in world space
Vector3 vy = lightToWorld.GetColumn(1); // Y axis in world space
Vector3 vz = lightDir; // Z axis in world space
vx = worldToView.MultiplyVector(vx);
vy = worldToView.MultiplyVector(vy);
vz = worldToView.MultiplyVector(vz);
l.uShadowLightIndex = (uint)nLight;
l.vLaxisX = vx;
l.vLaxisY = vy;
l.vLaxisZ = vz;
l.vCol = new Vec3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
l.fLightIntensity = light.light.intensity;
lights.Add(l);
dirLightCount++;
}
}
m_dirLightList.SetData(lights.ToArray());
m_DeferredMaterial.SetInt("g_nDirLights", dirLightCount);
}
void UpdateShadowConstants(ActiveLight[] activeLights, ref ShadowOutput shadow)
{
int nNumLightsIncludingTooMany = 0;

Vector4[] g_vLightShadowIndex_vLightParams = new Vector4[MAX_LIGHTS];
Vector4[] g_vLightFalloffParams = new Vector4[MAX_LIGHTS];
Matrix4x4[] g_matWorldToShadow = new Matrix4x4[MAX_LIGHTS * MAX_SHADOWMAP_PER_LIGHTS];
Vector4[] g_vDirShadowSplitSpheres = new Vector4[MAX_DIRECTIONAL_SPLIT];
for (int nLight = 0; nLight < activeLights.Length; nLight++)
{

Debug.Log("SUCCESS! Found " + nNumLightsIncludingTooMany + " runtime lights which is within the supported number of lights, " + MAX_LIGHTS + ".\n\n");
}
}
// Send constants to shaders
Shader.SetGlobalMatrixArray("g_matWorldToShadow", g_matWorldToShadow);
Shader.SetGlobalVectorArray("g_vDirShadowSplitSpheres", g_vDirShadowSplitSpheres);
Vector4 g_vShadow3x3PCFTerms0 = new Vector4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
Vector4 g_vShadow3x3PCFTerms1 = new Vector4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
Vector4 g_vShadow3x3PCFTerms2 = new Vector4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
Vector4 g_vShadow3x3PCFTerms3 = new Vector4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms0", g_vShadow3x3PCFTerms0);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms1", g_vShadow3x3PCFTerms1);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms2", g_vShadow3x3PCFTerms2);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms3", g_vShadow3x3PCFTerms3);
g_vShadow3x3PCFTerms[0] = new Vector4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
g_vShadow3x3PCFTerms[1] = new Vector4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
g_vShadow3x3PCFTerms[2] = new Vector4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
g_vShadow3x3PCFTerms[3] = new Vector4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
}
int GenerateSourceLightBuffers(Camera camera, CullResults inputs)

loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
UpdateDirectionalLights(camera, cullResults.culledLights);
DoTiledDeferredLighting(camera, loop, camera.cameraToWorldMatrix, projscr, invProjscr, lightList);

58
Assets/ScriptableRenderLoop/fptl/Internal-DeferredShading.shader


uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform float g_flipVertical; // giant temp hack, see DoTiledDeferredLighting()
Texture2D _CameraDepthTexture;
Texture2D _CameraGBufferTexture0;
Texture2D _CameraGBufferTexture1;
Texture2D _CameraGBufferTexture2;
//UNITY_DECLARE_TEX2D(_LightTextureB0);
sampler2D _LightTextureB0;
UNITY_DECLARE_TEX2DARRAY(_spotCookieTextures);
UNITY_DECLARE_TEXCUBEARRAY(_pointCookieTextures);
StructuredBuffer<uint> g_vLightList;
StructuredBuffer<SFiniteLightData> g_vLightData;
uniform uint g_nDirLights;
//---------------------------------------------------------------------------------------------------------------------------------------------------------
// TODO: clean up.. -va

CBUFFER_END
//---------------------------------------------------------------------------------------------------------------------------------------------------------
Texture2D _CameraDepthTexture;
Texture2D _CameraGBufferTexture0;
Texture2D _CameraGBufferTexture1;
Texture2D _CameraGBufferTexture2;
//UNITY_DECLARE_TEX2D(_LightTextureB0);
sampler2D _LightTextureB0;
UNITY_DECLARE_TEX2DARRAY(_spotCookieTextures);
UNITY_DECLARE_TEXCUBEARRAY(_pointCookieTextures);
StructuredBuffer<uint> g_vLightList;
StructuredBuffer<SFiniteLightData> g_vLightData;
StructuredBuffer<DirectionalLight> g_dirLightData;
float GetLinearDepth(float3 vP)
{
Vec3 var = 1.0;

if ((shadowMapCenter.x < 0.0f) || (shadowMapCenter.x > 1.0f) || (shadowMapCenter.y < 0.0f) || (shadowMapCenter.y > 1.0f))
return 1.0f;
float objDepth = saturate(1.001f - vPositionTextureSpace.z);
float objDepth = saturate(257.0 / 256.0 - vPositionTextureSpace.z);
float4 v20Taps;
v20Taps.x = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xy, objDepth)).x; // 1 1

float flShadowScalar = 1.0;
int shadowSplitIndex = 0;
/*if (type == DIRECTIONAL_LIGHT)
if (type == DIRECTIONAL_LIGHT)
else */if (type == SPHERE_LIGHT)
else if (type == SPHERE_LIGHT)
{
float3 absPos = abs(vPositionToLightDirWs);
shadowSplitIndex = (vPositionToLightDirWs.z > 0) ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;

float3 c = ExecuteLightList(pixCoord, offs);
return float4(c, 1.0);
return float4(c,1.0);
return float4(pow(c, 1 / 2.2), 1.0);
return float4(pow(c,1/2.2),1.0);
#endif
}

float3 vPositionWs = mul(g_mViewToWorld, float4(vP, 1));
for (int i = 0; i < g_nDirLights; i++)
{
DirectionalLight lightData = g_dirLightData[i];
float atten = 1;
float shadowScalar = SampleShadow(DIRECTIONAL_LIGHT, vPositionWs, 0, lightData.uShadowLightIndex);
atten *= shadowScalar;
UnityLight light;
light.color.xyz = lightData.vCol.xyz * atten;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.vLaxisZ).xyz;
ints += UNITY_BRDF_PBS(data.diffuseColor, data.specularColor, oneMinusReflectivity, data.smoothness, data.normalWorld, vWSpaceVDir, light, ind);
// ints += LambertTerm(data.normalWorld, lightDir) * light.vCol;
}
// we need this outer loop for when we cannot assume a wavefront is 64 wide
// since in this case we cannot assume the lights will remain sorted by type
// during processing in lightlist_cs.hlsl

light.dir.xyz = mul((float3x3) g_mViewToWorld, vL).xyz; //unity_CameraToWorld
ints += UNITY_BRDF_PBS (data.diffuseColor, data.specularColor, oneMinusReflectivity, data.smoothness, data.normalWorld, vWSpaceVDir, light, ind);
++l; uIndex = l<uNrLights ? FetchIndex(offs, l) : 0;
uLgtType = l<uNrLights ? g_vLightData[uIndex].uLightType : 0;

7
Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs


public float fLightIntensity;
public Vec3 vLaxisX;
public int iSliceIndex;
public uint uShadowLightIndex;
public Vec3 vLaxisY;
public float fPad0;

public static int SPOT_LIGHT = 0;
public static int SPHERE_LIGHT = 1;
public static int BOX_LIGHT = 2;
public static int DIRECTIONAL_LIGHT = 3;
// direct lights and reflection probes for now
public static int NR_LIGHT_MODELS = 2;
// direct lights and reflection probes for now
public static int NR_LIGHT_MODELS = 2;
public static int DIRECT_LIGHT = 0;
public static int REFLECTION_LIGHT = 1;

正在加载...
取消
保存