浏览代码

Remove attenuation of box lights and massage the code a bit

/main
Evgenii Golubev 7 年前
当前提交
83cff96d
共有 5 个文件被更改,包括 64 次插入53 次删除
  1. 62
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  2. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  3. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  4. 38
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  5. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitReference.hlsl

62
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl


//-----------------------------------------------------------------------------
float3 EvaluateCookie_Directional(LightLoopContext lightLoopContext, DirectionalLightData lightData,
float3 positionWS)
float3 lightToSample)
float3 lightToSample = positionWS - lightData.positionWS;
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSample, transpose(lightToWorld));

float shadowMask = 1.0;
color = lightData.color;
attenuation = 1.0;
attenuation = 1.0; // Note: no volumetric attenuation along shadow rays for directional lights
[branch] if (lightData.cookieIndex >= 0)
{
float3 lightToSample = positionWS - lightData.positionWS;
float3 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSample);
color *= cookie;
}
#ifdef SHADOWS_SHADOWMASK
// shadowMaskSelector.x is -1 if there is no shadow mask

#endif
}
// Note: no volumetric attenuation along shadow rays for directional lights.
[branch] if (lightData.cookieIndex >= 0)
{
float3 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, positionWS);
color *= cookie;
}
}
//-----------------------------------------------------------------------------

float4 EvaluateCookie_Punctual(LightLoopContext lightLoopContext, LightData lightData,
float3 positionWS)
float3 lightToSample)
float3 lightToSample = positionWS - lightData.positionWS;
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSample, transpose(lightToWorld));
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSample, transpose(lightToWorld));
float4 cookie;

// None of the outputs are premultiplied.
void EvaluateLight_Punctual(LightLoopContext lightLoopContext, PositionInputs posInput,
LightData lightData, BakeLightingData bakeLightingData,
float3 N, float3 L, float dist, float distSq,
float3 N, float3 L, float3 lightToSample, float dist, float distSq,
out float3 color, out float attenuation)
{
float3 positionWS = posInput.positionWS;

color = lightData.color;
attenuation = GetPunctualShapeAttenuation(lightData, L, distSq);
#if (SHADEROPTIONS_VOLUMETRIC_LIGHTING_PRESET != 0)
float distProj = dot(lightToSample, lightData.forward);
float distVol = (lightData.lightType == GPULIGHTTYPE_PROJECTOR_BOX) ? distProj : dist;
attenuation *= TransmittanceHomogeneousMedium(_GlobalFog_Extinction, distVol);
#endif
// Projector lights always have cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, lightToSample);
color *= cookie.rgb;
attenuation *= cookie.a;
}
#ifdef SHADOWS_SHADOWMASK
// shadowMaskSelector.x is -1 if there is no shadow mask
// Note that we override shadow value (in case we don't have any dynamic shadow)

#endif
}
#if (SHADEROPTIONS_VOLUMETRIC_LIGHTING_PRESET != 0)
[flatten] if (lightData.lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
float3 lightToSample = positionWS - lightData.positionWS;
dist = dot(-lightToSample, L);
}
shadow *= TransmittanceHomogeneousMedium(_GlobalFog_Extinction, dist);
#endif
// Projector lights always have cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, positionWS);
color *= cookie.rgb;
attenuation *= cookie.a;
}
}

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


lightData.positionWS = light.light.transform.position;
// Setting 0 for invSqrAttenuationRadius mean we have no range attenuation, but still have inverse square attenuation.
lightData.invSqrAttenuationRadius = additionalLightData.applyRangeAttenuation ? 1.0f / (light.range * light.range) : 0.0f;
bool applyRangeAttenuation = additionalLightData.applyRangeAttenuation && (gpuLightType != GPULightType.ProjectorBox);
lightData.invSqrAttenuationRadius = applyRangeAttenuation ? 1.0f / (light.range * light.range) : 0.0f;
lightData.color = GetLightColor(light);
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/Resources/VolumetricLighting.compute


float3 L = -lightToSample * rsqrt(distSq);
float3 color; float attenuation;
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, dist, distSq,
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, lightToSample, dist, distSq,
color, attenuation);
float intensity = attenuation * rcpPdf;

float t = tEntr + tOffset;
posInput.positionWS = GetPointAtDistance(ray, t);
float3 L = -light.forward;
float3 L = -light.forward;
float3 lightToSample = posInput.positionWS - light.positionWS;
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, 1, 1,
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, lightToSample, 1, 1,
color, attenuation);
// Note: the 'weight' accounts for transmittance from 'tEntr' to 't'.

38
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------
// This function apply BSDF
void BSDF( float3 V, float3 L, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
// This function apply BSDF. Assumes that NdotL is positive.
void BSDF( float3 V, float3 L, float NdotL, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{

// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114).
float NdotL = saturate(dot(N, L)); // Must have the same value without the clamp
float LdotV = dot(L, V);
float invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)) - caution about the case where V and L are opposite, it can happen, use max to avoid this

// Note: We use NdotL here to early out, but in case of clear coat this is not correct. But we are ok with this
[branch] if (intensity > 0.0)
{
BSDF(V, L, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
lighting.diffuse *= intensity * lightData.diffuseScale;
lighting.specular *= intensity * lightData.specularScale;

float3 lightToSample = posInput.positionWS - lightData.positionWS;
int lightType = lightData.lightType;
float3 unL = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? -lightToSample : -lightData.forward;
float distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
float3 N = bsdfData.normalWS;
float3 L = unL * distRcp;
float NdotL = dot(N, L);
float3 L;
float dist, distSq, distProj;
if (lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
dist = distSq = 1; // No distance attenuation
L = -lightData.forward; // No angle attenuation
}
else
{
float3 unL = -lightToSample;
distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
dist = distSq * distRcp;
L = unL * distRcp;
}
float3 N = bsdfData.normalWS;
float NdotL = dot(N, L);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{

float3 color;
float attenuation;
EvaluateLight_Punctual(lightLoopContext, posInput, lightData, bakeLightingData, N, L, dist, distSq, color, attenuation);
EvaluateLight_Punctual(lightLoopContext, posInput, lightData, bakeLightingData, N, L,
lightToSample, dist, distSq, color, attenuation);
float intensity = saturate(attenuation * NdotL);

bsdfData.roughnessT = max(bsdfData.roughnessT, lightData.minRoughness);
bsdfData.roughnessB = max(bsdfData.roughnessB, lightData.minRoughness);
BSDF(V, L, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
lighting.diffuse *= intensity * lightData.diffuseScale;
lighting.specular *= intensity * lightData.specularScale;

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitReference.hlsl


{
float3 lightDiff, lightSpec;
BSDF(V, L, positionWS, preLightData, bsdfData, lightDiff, lightSpec);
BSDF(V, L, NdotL, positionWS, preLightData, bsdfData, lightDiff, lightSpec);
diffuseLighting += lightDiff * (sinLT / dist2 * NdotL);
specularLighting += lightSpec * (sinLT / dist2 * NdotL);

float cosLNs = saturate(dot(-L, Ns));
// We calculate area reference light with the area integral rather than the solid angle one.
float illuminance = cosLNs * saturate(dot(bsdfData.normalWS, L)) / (sqrDist * lightPdf);
float NdotL = saturate(dot(bsdfData.normalWS, L));
float illuminance = cosLNs * NdotL / (sqrDist * lightPdf);
float3 localDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 localSpecularLighting = float3(0.0, 0.0, 0.0);

BSDF(V, L, positionWS, preLightData, bsdfData, localDiffuseLighting, localSpecularLighting);
BSDF(V, L, NdotL, positionWS, preLightData, bsdfData, localDiffuseLighting, localSpecularLighting);
localDiffuseLighting *= lightData.color * illuminance * lightData.diffuseScale;
localSpecularLighting *= lightData.color * illuminance * lightData.specularScale;
}

正在加载...
取消
保存