浏览代码

script side buffer setup and stub single pass shader

/classicDeferredMobile
Filip Iliescu 8 年前
当前提交
a8cc1cc0
共有 2 个文件被更改,包括 125 次插入227 次删除
  1. 185
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/ClassicDeferred/ClassicDeferredPipeline.cs
  2. 167
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/ClassicDeferred/UnityStandardForwardMobile.cginc

185
Assets/ScriptableRenderPipeline/MobileRenderPipeline/ClassicDeferred/ClassicDeferredPipeline.cs


m_ShadowMgr = null;
}
}
// TODO: define this using LightDefintions.cs
public static int SPOT_LIGHT = 0;
public static int SPHERE_LIGHT = 1;
public static int BOX_LIGHT = 2;
public static int DIRECTIONAL_LIGHT = 3;
const int k_MaxLights = 10;
const int k_MaxShadowmapPerLights = 6;
const int k_MaxDirectionalSplit = 4;

Vector4[] m_Shadow3X3PCFTerms = new Vector4[4];
// arrays for shader data
private Vector4[] m_LightData = new Vector4[k_MaxLights]; // x:Light_type, y:ShadowIndex z:w:UNUSED
private Vector4[] m_LightAttenuations = new Vector4[k_MaxLights];
private Vector4[] m_LightSpotDirections = new Vector4[k_MaxLights];
private Vector4[] m_LightDirections = new Vector4[k_MaxLights];
private Matrix4x4[] m_LightMatrix = new Matrix4x4[k_MaxLights];
private Matrix4x4[] m_WorldToLightMatrix = new Matrix4x4[k_MaxLights];
[NonSerialized]
private int m_shadowBufferID;

// present frame buffer.
FinalPass(loop);
}
void RenderForward(CullResults cull, Camera camera, ScriptableRenderContext loop, bool opaquesOnly)
{
var cmd = new CommandBuffer { name = opaquesOnly ? "Prep Opaques Only Forward Pass" : "Prep Forward Pass" };
loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("ForwardBase"))
{
sorting = { flags = SortFlags.CommonOpaque }
};
settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
if (opaquesOnly) settings.inputFilter.SetQueuesOpaque();
else settings.inputFilter.SetQueuesTransparent();
loop.DrawRenderers(ref settings);
}
static Matrix4x4 GetFlipMatrix()

loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
void RenderForward(CullResults cull, Camera camera, ScriptableRenderContext loop, bool opaquesOnly)
{
SetupLightShaderVariables (cull, camera, loop);
/// <summary>
/// Light list construction
/// </summary>
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("ForwardSinglePass"))
{
sorting = { flags = SortFlags.CommonOpaque }
};
settings.rendererConfiguration = RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
if (opaquesOnly) settings.inputFilter.SetQueuesOpaque();
else settings.inputFilter.SetQueuesTransparent();
loop.DrawRenderers(ref settings);
}
m_LightPositions[i] = Vector4.zero;
m_LightData [i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
m_LightAttenuations[i] = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
m_LightSpotDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
m_LightDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
m_LightPositions[i] = Vector4.zero;
m_LightMatrix[i] = Matrix4x4.identity;
m_WorldToLightMatrix[i] = Matrix4x4.identity;
private void SetupLightShaderVariables(VisibleLight[] lights, int pixelLightCount, ScriptableRenderContext context)
private void SetupLightShaderVariables(CullResults cull, Camera camera, ScriptableRenderContext context)
int totalLightCount = pixelLightCount;
int totalLightCount = cull.visibleLights.Length;
VisibleLight currLight = lights[i];
if (currLight.lightType == LightType.Directional)
{
Vector4 dir = -currLight.localToWorld.GetColumn(2);
m_LightPositions[i] = new Vector4(dir.x, dir.y, dir.z, 0.0f);
}
else
{
Vector4 pos = currLight.localToWorld.GetColumn(3);
m_LightPositions[i] = new Vector4(pos.x, pos.y, pos.z, 1.0f);
}
VisibleLight light = cull.visibleLights [i];
Vector3 lightPos = light.localToWorld.GetColumn (3); //position
Vector3 lightDir = light.localToWorld.GetColumn (2); //z axis
float range = light.range;
float rangeSq = light.range * light.range;
var lightToWorld = light.localToWorld;
var worldToLight = lightToWorld.inverse;
m_WorldToLightMatrix[i] = worldToLight;
//postiions and directions
m_LightPositions [i] = new Vector4(lightPos.x, lightPos.y, lightPos.z, 1.0f / rangeSq);
m_LightDirections [i] = new Vector4(lightDir.x, lightDir.y, lightDir.z, 0.0f);
m_LightColors[i] = currLight.finalColor;
//shadow index
int shadowIdx;
float lightShadowNDXOrNot = m_ShadowIndices.TryGetValue(i, out shadowIdx ) ? (float) shadowIdx : -1.0f;
m_LightData[i].y = lightShadowNDXOrNot;
// color
m_LightColors [i] = light.finalColor;
if (light.lightType == LightType.Point) {
m_LightData[i].x = SPHERE_LIGHT;
//RenderPointLight (light, cmd, props, renderAsQuad, intersectsNear, true);
} else if (light.lightType == LightType.Spot) {
m_LightData[i].x = SPOT_LIGHT;
float chsa = GetCotanHalfSpotAngle (light.spotAngle);
// Setup Light Matrix
Matrix4x4 temp1 = Matrix4x4.Scale(new Vector3 (-.5f, -.5f, 1.0f));
Matrix4x4 temp2 = Matrix4x4.Translate( new Vector3 (.5f, .5f, 0.0f));
Matrix4x4 temp3 = PerspectiveCotanMatrix (chsa, 0.0f, range);
m_LightMatrix[i] = temp2 * temp1 * temp3 * worldToLight;
float rangeSq = currLight.range * currLight.range;
float quadAtten = (currLight.lightType == LightType.Directional) ? 0.0f : 25.0f / rangeSq;
} else if (light.lightType == LightType.Directional) {
m_LightData[i].x = DIRECTIONAL_LIGHT;
if (currLight.lightType == LightType.Spot)
{
Vector4 dir = currLight.localToWorld.GetColumn(2);
m_LightSpotDirections[i] = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);
// Setup Light Matrix
float scale = 1.0f / light.light.cookieSize;
Matrix4x4 temp1 = Matrix4x4.Scale(new Vector3 (scale, scale, 0.0f));
Matrix4x4 temp2 = Matrix4x4.Translate( new Vector3 (.5f, .5f, 0.0f));
m_LightMatrix[i] = temp2 * temp1 * worldToLight;
float spotAngle = Mathf.Deg2Rad * currLight.spotAngle;
float cosOuterAngle = Mathf.Cos(spotAngle * 0.5f);
float cosInneAngle = Mathf.Cos(spotAngle * 0.25f);
float angleRange = cosInneAngle - cosOuterAngle;
m_LightAttenuations[i] = new Vector4(cosOuterAngle,
Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
}
else
{
m_LightSpotDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
m_LightAttenuations[i] = new Vector4(-1.0f, 1.0f, quadAtten, rangeSq);
CommandBuffer cmd = new CommandBuffer() {name = "SetupShadowShaderConstants"};
cmd.SetGlobalVectorArray("globalLightPos", m_LightPositions);
cmd.SetGlobalVectorArray("globalLightColor", m_LightColors);
cmd.SetGlobalVectorArray("globalLightAtten", m_LightAttenuations);
cmd.SetGlobalVectorArray("globalLightSpotDir", m_LightSpotDirections);
cmd.SetGlobalFloat("globalLightData", (float)pixelLightCount);
CommandBuffer cmd = new CommandBuffer() {name = "SetupShaderConstants"};
cmd.SetGlobalVectorArray("gLightData", m_LightData);
cmd.SetGlobalVectorArray("gLightColor", m_LightColors);
cmd.SetGlobalVectorArray("gLightDirection", m_LightDirections);
cmd.SetGlobalVectorArray("gLightPos", m_LightPositions);
cmd.SetGlobalMatrixArray("gLightMatrix", m_LightMatrix);
cmd.SetGlobalMatrixArray("gWorldToLightMatrix", m_WorldToLightMatrix);
cmd.SetGlobalVector("gData", new Vector4(totalLightCount, 0, 0, 0));
//}
/*
void RenderForwardAddLight(Camera camera, CullResults inputs, CommandBuffer cmd, ScriptableRenderContext loop)
{
int lightCount = inputs.visibleLights.Length;
for (int lightNum = 0; lightNum < lightCount; lightNum++)
{
VisibleLight light = inputs.visibleLights[lightNum];
Vector4 lightInfo;
if (light.lightType == LightType.Directional)
{
Vector3 worldPos = light.localToWorld;
lightInfo = new Vector4 (worldPos.x, worldPos.y, worldPos.z, 1.0);
}
else {
Vector3 worldPos = -light.localToWorld;
lightInfo = new Vector4 (worldPos.x, worldPos.y, worldPos.z, 0.0);
}
var props = new MaterialPropertyBlock ();
props.SetVector ("_WorldSpaceLightPos0", lightInfo);
}
}
*/

167
Assets/ScriptableRenderPipeline/MobileRenderPipeline/ClassicDeferred/UnityStandardForwardMobile.cginc


float4 tex : TEXCOORD0;
half4 ambientOrLightmapUV : TEXCOORD1; // SH or Lightmap UV
half4 tangentToWorldAndParallax[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:empty]
//float4 posWorld : TEXCOORD3;
float4 posWorld : TEXCOORD8;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_TRANSFER_INSTANCE_ID(v, o);
o.posWorld = posWorld;
o.tex = TexCoords(v);
float3 normalWorld = UnityObjectToWorldNormal(v.normal);

return o;
}
//#include "LightingUtils.hlsl"
float GetLinearZFromSVPosW(float posW)
{
#if USE_LEFTHAND_CAMERASPACE
float linZ = posW;
#else
float linZ = -posW;
#endif
return linZ;
}
float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
float fSx = UNITY_MATRIX_P[0].x;
float fCx = UNITY_MATRIX_P[0].z;
float fSy = UNITY_MATRIX_P[1].y;
float fCy = UNITY_MATRIX_P[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
}
static FragmentCommonData gdata;
static float occlusion;
//half4 fragNoLight(VertexOutputForwardNew i) : SV_Target
//{
// float linZ = GetLinearZFromSVPosW(i.pos.w); // matching script side where camera space is right handed.
// float3 vP = GetViewPosFromLinDepth(i.pos.xy, linZ);
// float3 vPw = mul(g_mViewToWorld, float4(vP,1.0)).xyz;
// float3 Vworld = normalize(mul((float3x3) g_mViewToWorld, -vP).xyz); // not same as unity_CameraToWorld
//
//#ifdef _PARALLAXMAP
// half3 tangent = i.tangentToWorldAndParallax[0].xyz;
// half3 bitangent = i.tangentToWorldAndParallax[1].xyz;
// half3 normal = i.tangentToWorldAndParallax[2].xyz;
// float3 vDirForParallax = float3( dot(tangent, Vworld), dot(bitangent, Vworld), dot(normal, Vworld));
//#else
// float3 vDirForParallax = Vworld;
//#endif
// gdata = FragmentSetup(i.tex, -Vworld, vDirForParallax, i.tangentToWorldAndParallax, vPw); // eyeVec = -Vworld
//
// return OutputForward (float4(0.0,0.0,0.0,1.0), gdata.alpha); // figure out some alpha test stuff
//}
// todo: put this is LightDefinitions common file
#define MAX_LIGHTS 10
float3 EvalMaterial(UnityLight light, UnityIndirect ind)
{
return UNITY_BRDF_PBS(gdata.diffColor, gdata.specColor, gdata.oneMinusReflectivity, gdata.smoothness, gdata.normalWorld, -gdata.eyeVec, light, ind);
}
float4 gLightData[MAX_LIGHTS];
half4 gLightColor[MAX_LIGHTS];
float4 gLightPos[MAX_LIGHTS];
half4 gLightDirection[MAX_LIGHTS];
float4x4 gLightMatrix[MAX_LIGHTS];
float4x4 gWorldToLightMatrix[MAX_LIGHTS];
float4 gData;
float3 EvalIndirectSpecular(UnityLight light, UnityIndirect ind)
struct LightInput
return occlusion * UNITY_BRDF_PBS(gdata.diffColor, gdata.specColor, gdata.oneMinusReflectivity, gdata.smoothness, gdata.normalWorld, -gdata.eyeVec, light, ind);
}
float4 lightData;
half4 pos;
half4 color;
half4 lightDir;
float4x4 lightMat;
float4x4 worldToLightMat;
};
//#include "RegularForwardLightingTemplate.hlsl"
//#include "RegularForwardReflectionTemplate.hlsl"
uniform int g_numLights;
uniform int g_numReflectionProbes;
uniform float4x4 g_mViewToWorld;
uniform float4x4 g_mWorldToView; // used for reflection only
uniform float4x4 g_mScrProjection;
uniform float4x4 g_mInvScrProjection;
void GetCountAndStart(out uint start, out uint nrLights, bool reflection)
{
start = reflection==true ? g_numLights : 0; // offset by numLights entries
nrLights = reflection==true ? g_numReflectionProbes : g_numLights;
}
float3 ExecuteLightList(out uint numLightsProcessed, uint2 pixCoord, float3 vP, float3 vPw, float3 Vworld)
{
uint start = 0, numLights = 0;
GetCountAndStart(start, numLights, false);
numLightsProcessed = numLights; // mainly for debugging/heat maps
return float3(1, 0, 0);
//return ExecuteLightList(start, numLights, vP, vPw, Vworld);
}
float3 ExecuteReflectionList(out uint numReflectionProbesProcessed, uint2 pixCoord, float3 vP, float3 vNw, float3 Vworld, float smoothness)
{
uint start = 0, numReflectionProbes = 0;
GetCountAndStart(start, numReflectionProbes, true);
numReflectionProbesProcessed = numReflectionProbes; // mainly for debugging/heat maps
return float3(0, 1, 0);
//return ExecuteReflectionList(start, numReflectionProbes, vP, vNw, Vworld, smoothness);
}
#define INITIALIZE_LIGHT(light, lightIndex) \
light.lightData = gLightData[lightIndex]; \
light.pos = gLightPos[lightIndex]; \
light.color = gLightColor[lightIndex]; \
light.lightDir = gLightDirection[lightIndex]; \
light.lightMat = gLightMatrix[lightIndex]; \
light.worldToLightMat = gWorldToLightMatrix[lightIndex];
float linZ = GetLinearZFromSVPosW(i.pos.w); // matching script side where camera space is right handed.
float3 vP = GetViewPosFromLinDepth(i.pos.xy, linZ);
float3 vPw = mul(g_mViewToWorld, float4(vP,1.0)).xyz;
float3 Vworld = normalize(mul((float3x3) g_mViewToWorld, -vP).xyz); // not same as unity_CameraToWorld
half4 ret = half4(1, 0, 0, 0.5);
#ifdef _PARALLAXMAP
half3 tangent = i.tangentToWorldAndParallax[0].xyz;
half3 bitangent = i.tangentToWorldAndParallax[1].xyz;
half3 normal = i.tangentToWorldAndParallax[2].xyz;
float3 vDirForParallax = float3( dot(tangent, Vworld), dot(bitangent, Vworld), dot(normal, Vworld));
#else
float3 vDirForParallax = Vworld;
#endif
gdata = FragmentSetup(i.tex, -Vworld, vDirForParallax, i.tangentToWorldAndParallax, vPw); // eyeVec = -Vworld
uint2 pixCoord = ((uint2) i.pos.xy);
for (int lightIndex = 0; lightIndex < gData.x; ++lightIndex)
{
LightInput light;
INITIALIZE_LIGHT(light, lightIndex);
float atten = 1.0;
occlusion = Occlusion(i.tex.xy);
UnityGI gi = FragmentGI (gdata, occlusion, i.ambientOrLightmapUV, atten, DummyLight(), false);
uint numLightsProcessed = 0, numReflectionsProcessed = 0;
float3 res = 0;
// direct light contributions
res += ExecuteLightList(numLightsProcessed, pixCoord, vP, vPw, Vworld);
// specular GI
res += ExecuteReflectionList(numReflectionsProcessed, pixCoord, vP, gdata.normalWorld, Vworld, gdata.smoothness);
// diffuse GI
res += UNITY_BRDF_PBS (gdata.diffColor, gdata.specColor, gdata.oneMinusReflectivity, gdata.smoothness, gdata.normalWorld, -gdata.eyeVec, gi.light, gi.indirect).xyz;
res += UNITY_BRDF_GI (gdata.diffColor, gdata.specColor, gdata.oneMinusReflectivity, gdata.smoothness, gdata.normalWorld, -gdata.eyeVec, occlusion, gi);
//res = OverlayHeatMap(numLightsProcessed, res);
//UNITY_APPLY_FOG(i.fogCoord, res);
return OutputForward (float4(res,1.0), gdata.alpha);
ret += 0.01*light.color;
}
return ret;
}
#endif
正在加载...
取消
保存