浏览代码

Combine distance and spot attenuation into a single uniform

/main
egomeh 6 年前
当前提交
8ef0ee06
共有 4 个文件被更改,包括 39 次插入48 次删除
  1. 4
      com.unity.render-pipelines.lightweight/CHANGELOG.md
  2. 54
      com.unity.render-pipelines.lightweight/LWRP/Passes/SetupLightweightConstanstPass.cs
  3. 3
      com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Input.hlsl
  4. 26
      com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Lighting.hlsl

4
com.unity.render-pipelines.lightweight/CHANGELOG.md


## [3.3.0-preview]
### Changed
- Light attenuation now matches that of baked GI.
- Change real-time attenuation to inverse square.
- Change attenuation for baked GI to inverse square, to match real-time attenuation.
- Small optimization in light attenuation shader code.
## [3.2.0-preview]
### Changed

54
com.unity.render-pipelines.lightweight/LWRP/Passes/SetupLightweightConstanstPass.cs


public static int _AdditionalLightCount;
public static int _AdditionalLightPosition;
public static int _AdditionalLightColor;
public static int _AdditionalLightDistanceAttenuation;
public static int _AdditionalLightAttenuation;
public static int _AdditionalLightSpotAttenuation;
public static int _LightIndexBuffer;

Vector4 k_DefaultLightPosition = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
Vector4 k_DefaultLightColor = Color.black;
Vector4 k_DefaultLightAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 1.0f);
Vector4 k_DefaultLightAttenuation = new Vector4(1.0f, 0.0f, 0.0f, 1.0f);
Vector4 k_DefaultLightSpotAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
Vector4[] m_LightDistanceAttenuations;
Vector4[] m_LightAttenuations;
Vector4[] m_LightSpotAttenuations;
private int maxVisibleLocalLights { get; set; }
private ComputeBuffer perObjectLightIndices { get; set; }

PerCameraBuffer._AdditionalLightCount = Shader.PropertyToID("_AdditionalLightCount");
PerCameraBuffer._AdditionalLightPosition = Shader.PropertyToID("_AdditionalLightPosition");
PerCameraBuffer._AdditionalLightColor = Shader.PropertyToID("_AdditionalLightColor");
PerCameraBuffer._AdditionalLightDistanceAttenuation = Shader.PropertyToID("_AdditionalLightDistanceAttenuation");
PerCameraBuffer._AdditionalLightAttenuation = Shader.PropertyToID("_AdditionalLightAttenuation");
PerCameraBuffer._AdditionalLightSpotAttenuation = Shader.PropertyToID("_AdditionalLightSpotAttenuation");
m_LightDistanceAttenuations = new Vector4[0];
m_LightAttenuations = new Vector4[0];
m_LightSpotAttenuations = new Vector4[0];
}
public void Setup(int maxVisibleLocalLights, ComputeBuffer perObjectLightIndices)

{
m_LightPositions = new Vector4[maxVisibleLocalLights];
m_LightColors = new Vector4[maxVisibleLocalLights];
m_LightDistanceAttenuations = new Vector4[maxVisibleLocalLights];
m_LightAttenuations = new Vector4[maxVisibleLocalLights];
m_LightSpotAttenuations = new Vector4[maxVisibleLocalLights];
void InitializeLightConstants(List<VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightDistanceAttenuation, out Vector4 lightSpotDir,
out Vector4 lightSpotAttenuation)
void InitializeLightConstants(List<VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir)
lightDistanceAttenuation = k_DefaultLightSpotAttenuation;
lightAttenuation = k_DefaultLightAttenuation;
lightSpotAttenuation = k_DefaultLightAttenuation;
// When no lights are visible, main light will be set to -1.
// In this case we initialize it to default values and return

// VisibleLight.finalColor already returns color in active color space
lightColor = lightData.finalColor;
lightColor.w = 0.0f;
// Directional Light attenuation is initialize so distance attenuation always be 1.0
if (lightData.lightType != LightType.Directional)

float fadeRangeSqr = (fadeStartDistanceSqr - lightRangeSqr);
float oneOverFadeRangeSqr = 1.0f / fadeRangeSqr;
float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr;
float quadAtten = 25.0f / lightRangeSqr;
lightDistanceAttenuation = new Vector4(quadAtten, oneOverFadeRangeSqr, lightRangeSqrOverFadeRangeSqr, 1.0f);
lightAttenuation.x = oneOverFadeRangeSqr;
lightAttenuation.y = lightRangeSqrOverFadeRangeSqr;
lightColor.w = 1.0f;
}
if (lightData.lightType == LightType.Spot)

float smoothAngleRange = Mathf.Max(0.001f, cosInnerAngle - cosOuterAngle);
float invAngleRange = 1.0f / smoothAngleRange;
float add = -cosOuterAngle * invAngleRange;
lightSpotAttenuation = new Vector4(invAngleRange, add, 0.0f);
lightAttenuation.z = invAngleRange;
lightAttenuation.w = add;
}
Light light = lightData.light;

if (m_MixedLightingSetup == MixedLightingSetup.None && lightData.light.shadows != LightShadows.None)
{
m_MixedLightingSetup = MixedLightingSetup.Subtractive;
lightDistanceAttenuation.w = 0.0f;
lightColor.w = 0.0f;
}
}
}

for (int i = 0; i < maxVisibleLocalLights; ++i)
InitializeLightConstants(lightData.visibleLights, -1, out m_LightPositions[i],
out m_LightColors[i],
out m_LightDistanceAttenuations[i],
out m_LightSpotDirections[i],
out m_LightSpotAttenuations[i]);
out m_LightAttenuations[i],
out m_LightSpotDirections[i]);
m_MixedLightingSetup = MixedLightingSetup.None;

void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData)
{
Vector4 lightPos, lightColor, lightDistanceAttenuation, lightSpotDir, lightSpotAttenuation;
Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir;
InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightDistanceAttenuation, out lightSpotDir, out lightSpotAttenuation);
InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir);
if (lightData.mainLightIndex >= 0)
{

}
}
cmd.SetGlobalVector(PerCameraBuffer._MainLightPosition, new Vector4(lightPos.x, lightPos.y, lightPos.z, lightDistanceAttenuation.w));
cmd.SetGlobalVector(PerCameraBuffer._MainLightPosition, new Vector4(lightPos.x, lightPos.y, lightPos.z, 1.0f)); // TODO: lightDistanceAttenuation.w));
cmd.SetGlobalVector(PerCameraBuffer._MainLightColor, lightColor);
}

{
InitializeLightConstants(lights, i, out m_LightPositions[localLightsCount],
out m_LightColors[localLightsCount],
out m_LightDistanceAttenuations[localLightsCount],
out m_LightSpotDirections[localLightsCount],
out m_LightSpotAttenuations[localLightsCount]);
out m_LightAttenuations[localLightsCount],
out m_LightSpotDirections[localLightsCount]);
localLightsCount++;
}
}

cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightPosition, m_LightPositions);
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightColor, m_LightColors);
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightDistanceAttenuation, m_LightDistanceAttenuations);
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightAttenuation, m_LightAttenuations);
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightSpotAttenuation, m_LightSpotAttenuations);
}
void SetShaderKeywords(CommandBuffer cmd, ref CameraData cameraData, ref LightData lightData, ref ShadowData shadowData)

3
com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Input.hlsl


half4 _AdditionalLightCount;
float4 _AdditionalLightPosition[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightColor[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightDistanceAttenuation[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightAttenuation[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightSpotAttenuation[MAX_VISIBLE_LIGHTS];
float4 _ScaledScreenParams;
CBUFFER_END

26
com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Lighting.hlsl


struct LightInput
{
float4 position;
half3 color;
half4 distanceAttenuation;
half4 color;
half4 distanceAndSpotAttenuation;
half4 spotAttenuation;
};
// Abstraction over Light shading data.

// Matches Unity Vanila attenuation
// Attenuation smoothly decreases to light range.
half DistanceAttenuation(half distanceSqr, half3 distanceAttenuation)
half DistanceAttenuation(half distanceSqr, half2 distanceAttenuation)
{
// We use a shared distance attenuation for additional directional and puctual lights
// for directional lights attenuation will be 1

// We can rewrite that to fit a MAD by doing
// distanceSqr * (1.0 / (fadeDistanceSqr - lightRangeSqr)) + (-lightRangeSqr / (fadeDistanceSqr - lightRangeSqr)
// distanceSqr * distanceAttenuation.y + distanceAttenuation.z
half smoothFactor = saturate(distanceSqr * distanceAttenuation.y + distanceAttenuation.z);
half smoothFactor = saturate(distanceSqr * distanceAttenuation.x + distanceAttenuation.y);
half SpotAttenuation(half3 spotDirection, half3 lightDirection, half4 spotAttenuation)
half SpotAttenuation(half3 spotDirection, half3 lightDirection, half2 spotAttenuation)
{
// Spot Attenuation with a linear falloff can be defined as
// (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle)

float distanceSqr = max(dot(posToLightVec, posToLightVec), FLT_MIN);
directionAndAttenuation.xyz = half3(posToLightVec * rsqrt(distanceSqr));
directionAndAttenuation.w = DistanceAttenuation(distanceSqr, lightInput.distanceAttenuation.xyz);
directionAndAttenuation.w *= SpotAttenuation(lightInput.spotDirection.xyz, directionAndAttenuation.xyz, lightInput.spotAttenuation);
directionAndAttenuation.w = DistanceAttenuation(distanceSqr, lightInput.distanceAndSpotAttenuation.xy);
directionAndAttenuation.w *= SpotAttenuation(lightInput.spotDirection.xyz, directionAndAttenuation.xyz, lightInput.distanceAndSpotAttenuation.zw);
return directionAndAttenuation;
}

// Cookies disabled for now due to amount of shader variants
//directionAndAttenuation.w *= CookieAttenuation(positionWS);
// directionAndAttenuation.w *= CookieAttenuation(positionWS);
return directionAndAttenuation;
}

// objects granularity level. We will only be able to do that when scriptable culling kicks in.
// TODO: Use StructuredBuffer on PC/Console and profile access speed on mobile that support it.
lightInput.position = _AdditionalLightPosition[lightIndex];
lightInput.color = _AdditionalLightColor[lightIndex].rgb;
lightInput.distanceAttenuation = _AdditionalLightDistanceAttenuation[lightIndex];
lightInput.color = _AdditionalLightColor[lightIndex];
lightInput.distanceAndSpotAttenuation = _AdditionalLightAttenuation[lightIndex];
lightInput.spotAttenuation = _AdditionalLightSpotAttenuation[lightIndex];
half4 directionAndRealtimeAttenuation = GetLightDirectionAndAttenuation(lightInput, positionWS);

light.attenuation = directionAndRealtimeAttenuation.w;
light.subtractiveModeAttenuation = lightInput.distanceAttenuation.w;
light.color = lightInput.color;
light.subtractiveModeAttenuation = lightInput.color.w;
light.color = lightInput.color.rgb;
return light;
}

正在加载...
取消
保存