浏览代码

HDRenderPipeline: Add support for light specular color tint

/Add-support-for-light-specular-color-tint
Sebastien Lagarde 7 年前
当前提交
c368db5a
共有 10 个文件被更改,包括 143 次插入111 次删除
  1. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs
  2. 11
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs
  3. 5
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs
  4. 23
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  5. 76
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  6. 46
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  7. 4
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  8. 69
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  9. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl
  10. 10
      SampleScenes/HDTest/TransparencyTest.meta

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs


public readonly GUIContent shapeLengthBox = new GUIContent("Size X", "");
public readonly GUIContent shapeWidthBox = new GUIContent("Size Y", "");
public readonly GUIContent applyRangeAttenuation = new GUIContent("Apply Range Attenuation", "Allows disabling range attenuation. This is useful indoor (like a room) to avoid having to setup a large range for a light to get correct inverse square attenuation that may leak out of the indoor");
public readonly GUIContent overrideColorForSpecular = new GUIContent("Override color for specular", "This option allow to override the color use for specular lighting. CAUTION: This option break all physical lighting rules. Must be use with care.");
public readonly GUIContent specularColor = new GUIContent("Color", "The color to use for specular lighting");
public readonly GUIContent shape = new GUIContent("Type", "Specifies the current type of light. Possible types are Directional, Spot, Point, Rectangle and Line lights.");
public readonly GUIContent[] shapeNames;

11
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs


public SerializedProperty shapeRadius;
public SerializedProperty maxSmoothness;
public SerializedProperty applyRangeAttenuation;
public SerializedProperty overrideColorForSpecular;
public SerializedProperty specularColor;
// Editor stuff
public SerializedProperty useOldInspector;

shapeRadius = o.Find(x => x.shapeRadius),
maxSmoothness = o.Find(x => x.maxSmoothness),
applyRangeAttenuation = o.Find(x => x.applyRangeAttenuation),
overrideColorForSpecular = o.Find(x => x.overrideColorForSpecular),
specularColor = o.Find(x => x.specularColor),
// Editor stuff
useOldInspector = o.Find(x => x.useOldInspector),

EditorGUILayout.PropertyField(m_AdditionalLightData.fadeDistance, s_Styles.fadeDistance);
EditorGUILayout.PropertyField(m_AdditionalLightData.lightDimmer, s_Styles.lightDimmer);
EditorGUILayout.PropertyField(m_AdditionalLightData.applyRangeAttenuation, s_Styles.applyRangeAttenuation);
EditorGUILayout.PropertyField(m_AdditionalLightData.overrideColorForSpecular, s_Styles.overrideColorForSpecular);
EditorGUI.indentLevel++;
using (new UnityEditor.EditorGUI.DisabledGroupScope(!m_AdditionalLightData.overrideColorForSpecular.boolValue))
{
EditorGUILayout.PropertyField(m_AdditionalLightData.specularColor, s_Styles.specularColor);
}
EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
}
}

5
ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs


// Only for Rectangle/Line/box projector lights
[Range(0.0f, 20.0f)]
[FormerlySerializedAs("lightLength")]
[FormerlySerializedAs("lightWidth")]
public float shapeWidth = 0.5f;
// Only for pyramid projector

// If true, we apply the smooth attenuation factor on the range attenuation to get 0 value, else the attenuation is just inverse square and never reach 0
public bool applyRangeAttenuation = true;
public bool overrideColorForSpecular = false;
public Color specularColor = Color.white;
// This is specific for the LightEditor GUI and not use at runtime
public bool useOldInspector = false;

23
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


public Vector3 positionWS;
public bool tileCookie;
public Vector3 color;
public Vector3 diffuseColor;
public Vector3 specularColor;
public float unused0;
public float specularScale;
public float unused1;
public float diffuseScale;
public float unused2;
};
[GenerateHLSL]

public float invSqrAttenuationRadius;
public Vector3 color;
public Vector3 diffuseColor;
public Vector3 specularColor;
public GPULightType lightType;
public float specularScale;
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.
public float diffuseScale;
public float shadowDimmer;
public float shadowDimmer;
public int unused0;
public GPULightType lightType;
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.
};

76
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


{
float3 positionWS;
bool tileCookie;
float3 color;
float3 diffuseColor;
float3 specularColor;
float unused0;
float specularScale;
float unused1;
float diffuseScale;
float unused2;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.LightData

float3 positionWS;
float invSqrAttenuationRadius;
float3 color;
float3 diffuseColor;
float3 specularColor;
int lightType;
float specularScale;
float minRoughness;
float diffuseScale;
float shadowDimmer;
float shadowDimmer;
int unused0;
int lightType;
float minRoughness;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData

{
return value.tileCookie;
}
float3 GetColor(DirectionalLightData value)
float3 GetDiffuseColor(DirectionalLightData value)
return value.color;
return value.diffuseColor;
float3 GetSpecularColor(DirectionalLightData value)
{
return value.specularColor;
}
float GetUnused0(DirectionalLightData value)
{
return value.unused0;
}
float3 GetForward(DirectionalLightData value)
{
return value.forward;

{
return value.right;
}
float GetSpecularScale(DirectionalLightData value)
float GetUnused1(DirectionalLightData value)
return value.specularScale;
return value.unused1;
float GetDiffuseScale(DirectionalLightData value)
float GetUnused2(DirectionalLightData value)
return value.diffuseScale;
return value.unused2;
}
//

{
return value.invSqrAttenuationRadius;
}
float3 GetColor(LightData value)
float3 GetDiffuseColor(LightData value)
return value.color;
return value.diffuseColor;
float3 GetSpecularColor(LightData value)
{
return value.specularColor;
}
int GetLightType(LightData value)
{
return value.lightType;
}
float3 GetForward(LightData value)
{
return value.forward;

{
return value.right;
}
float GetSpecularScale(LightData value)
float GetMinRoughness(LightData value)
return value.specularScale;
return value.minRoughness;
float GetDiffuseScale(LightData value)
float GetShadowDimmer(LightData value)
return value.diffuseScale;
return value.shadowDimmer;
}
float GetAngleScale(LightData value)
{

{
return value.angleOffset;
}
float GetShadowDimmer(LightData value)
{
return value.shadowDimmer;
}
int GetUnused0(LightData value)
{
return value.unused0;
}
}
int GetLightType(LightData value)
{
return value.lightType;
}
float GetMinRoughness(LightData value)
{
return value.minRoughness;
}
//

46
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


return new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
}
public Vector3 GetLightSpecularColor(HDAdditionalLightData data)
{
return new Vector3(data.specularColor.r, data.specularColor.g, data.specularColor.b);
}
public bool GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, HDAdditionalLightData additionalData, AdditionalShadowData additionalShadowData, int lightIndex)
{
var directionalLightData = new DirectionalLightData();

directionalLightData.up = light.light.transform.up * 2 / additionalData.shapeWidth;
directionalLightData.right = light.light.transform.right * 2 / additionalData.shapeLength;
directionalLightData.positionWS = light.light.transform.position;
directionalLightData.color = GetLightColor(light);
directionalLightData.diffuseScale = additionalData.affectDiffuse ? diffuseDimmer : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? specularDimmer : 0.0f;
Vector3 color = GetLightColor(light);
float diffuseScale = additionalData.affectDiffuse ? diffuseDimmer : 0.0f;
float specularScale = additionalData.affectSpecular ? specularDimmer : 0.0f;
directionalLightData.diffuseColor = color * diffuseScale;
Vector3 specularColorTint = GetLightSpecularColor(additionalData);
specularColorTint.Scale(color);
directionalLightData.specularColor = specularColorTint * specularScale;
directionalLightData.shadowIndex = directionalLightData.cookieIndex = -1;
if (light.light.cookie != null)

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;
lightData.color = GetLightColor(light);
// Calculate light fading
float distanceToCamera = (lightData.positionWS - camera.transform.position).magnitude;
float distanceFade = ComputeLinearDistanceFade(distanceToCamera, additionalLightData.fadeDistance);
float lightScale = additionalLightData.lightDimmer * distanceFade;
float diffuseScale = additionalLightData.affectDiffuse ? lightScale * m_TileSettings.diffuseGlobalDimmer : 0.0f;
float specularScale = additionalLightData.affectSpecular ? lightScale * m_TileSettings.specularGlobalDimmer : 0.0f;
if (diffuseScale <= 0.0f && specularScale <= 0.0f)
return false;
Vector3 color = GetLightColor(light);
lightData.diffuseColor = color * diffuseScale;
Vector3 specularColorTint = GetLightSpecularColor(additionalLightData);
specularColorTint.Scale(color);
lightData.specularColor = specularColorTint * specularScale;
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)
lightData.up = light.light.transform.up;

lightData.angleScale = 0.0f;
lightData.angleOffset = 1.0f;
}
float distanceToCamera = (lightData.positionWS - camera.transform.position).magnitude;
float distanceFade = ComputeLinearDistanceFade(distanceToCamera, additionalLightData.fadeDistance);
float lightScale = additionalLightData.lightDimmer * distanceFade;
lightData.diffuseScale = additionalLightData.affectDiffuse ? lightScale * m_TileSettings.diffuseGlobalDimmer : 0.0f;
lightData.specularScale = additionalLightData.affectSpecular ? lightScale * m_TileSettings.specularGlobalDimmer : 0.0f;
if (lightData.diffuseScale <= 0.0f && lightData.specularScale <= 0.0f)
return false;
lightData.cookieIndex = -1;
lightData.shadowIndex = -1;

4
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute


float3 L = -lightData.forward; // Lights point backwards in Unity
float intensity = 1;
float3 color = lightData.color;
float3 color = lightData.diffuseColor;
#ifdef USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
// Note: we apply the scattering coefficient and the constant part of the phase function later.

float dist = sqrt(distSq);
float3 L = lightToSample * -rsqrt(distSq);
float intensity = GetPunctualShapeAttenuation(lightData, L, distSq);
float3 color = lightData.color;
float3 color = lightData.diffuseColor;
#ifdef USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
// Note: we apply the scattering coefficient and the constant part of the phase function later.

69
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


float4 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSurface);
// Premultiply.
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;
lightData.diffuseColor *= cookie.rgb * cookie.a;
lightData.specularColor *= cookie.rgb * cookie.a;
}
[branch] if (illuminance > 0.0)

diffuseLighting *= illuminance * lightData.diffuseScale;
specularLighting *= illuminance * lightData.specularScale;
diffuseLighting *= illuminance;
specularLighting *= illuminance;
}
[branch] if (bsdfData.enableTransmission)

float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
diffuseLighting += EvaluateTransmission(bsdfData, illuminance, shadow);
// Save ALU by applying 'lightData.color' only once.
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
// Save ALU by applying 'color' only once.
diffuseLighting *= lightData.diffuseColor;
specularLighting *= lightData.specularColor;
lighting.directDiffuse += diffuseLighting;
lighting.directSpecular += specularLighting;

float attenuation = GetPunctualShapeAttenuation(lightData, L, distSq);
// Premultiply.
lightData.diffuseScale *= attenuation;
lightData.specularScale *= attenuation;
float colorScale = attenuation;
float3 diffuseLighting = float3(0.0, 0.0, 0.0);
float3 specularLighting = float3(0.0, 0.0, 0.0);

float volumetricShadow = Transmittance(OpticalDepthHomogeneous(preLightData.globalFogExtinction, dist));
// Premultiply.
lightData.diffuseScale *= volumetricShadow;
lightData.specularScale *= volumetricShadow;
colorScale *= volumetricShadow;
#endif
// Projector lights always have a cookies, so we can perform clipping inside the if().

// Premultiply.
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;
lightData.diffuseColor *= cookie.rgb;
lightData.specularColor *= cookie.rgb;
colorScale *= cookie.a;
}
[branch] if (illuminance > 0.0)

diffuseLighting *= illuminance * lightData.diffuseScale;
specularLighting *= illuminance * lightData.specularScale;
diffuseLighting *= illuminance;
specularLighting *= illuminance;
}
[branch] if (bsdfData.enableTransmission)

float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
diffuseLighting += EvaluateTransmission(bsdfData, illuminance, shadow);
// Save ALU by applying 'lightData.color' only once.
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
// Save ALU by applying 'color' only once.
diffuseLighting *= lightData.diffuseColor * colorScale;
specularLighting *= lightData.specularColor * colorScale;
lighting.directDiffuse += diffuseLighting;
lighting.directSpecular += specularLighting;

// Terminate if the shaded point is too far away.
if (intensity == 0.0) return;
lightData.diffuseScale *= intensity;
lightData.specularScale *= intensity;
lightData.diffuseColor *= intensity;
lightData.specularColor *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
lightData.positionWS -= positionWS;

// Evaluate the diffuse part
{
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
ltcValue *= lightData.diffuseScale;
diffuseLighting = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
}

// Use the Lambertian approximation for performance reasons.
// The matrix multiplication should not generate any extra ALU on GCN.
ltcValue = LTCEvaluate(P1, P2, B, mul(flipMatrix, k_identity3x3));
ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, ltcValue, 1);

{
// TODO
// ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcXformClearCoat);
// ltcValue *= lightData.specularScale;
// specularLighting = preLightData.ltcClearCoatFresnelTerm * (ltcValue * bsdfData.coatCoverage);
}

ltcValue *= lightData.specularScale;
// Save ALU by applying 'lightData.color' only once.
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
// Save ALU by applying 'color' only once.
diffuseLighting *= lightData.diffuseColor;
specularLighting *= lightData.specularColor;
#endif // LIT_DISPLAY_REFERENCE_AREA
lighting.directDiffuse += diffuseLighting;

// Terminate if the shaded point is too far away.
if (intensity == 0.0) return;
lightData.diffuseScale *= intensity;
lightData.specularScale *= intensity;
lightData.diffuseColor *= intensity;
lightData.specularColor *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
lightData.positionWS -= positionWS;

{
// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformDiffuse));
ltcValue *= lightData.diffuseScale;
diffuseLighting = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
}

// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, ltcTransform));
ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, ltcValue, 1);

{
// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformSpecular));
ltcValue *= lightData.specularScale;
// Save ALU by applying 'lightData.color' only once.
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
// Save ALU by applying 'color' only once.
diffuseLighting *= lightData.diffuseColor;
specularLighting *= lightData.specularColor;
#endif // LIT_DISPLAY_REFERENCE_AREA
lighting.directDiffuse += diffuseLighting;

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl


// The factor of 2 is due to the fact: Integral{0, 2 PI}{max(0, cos(x))dx} = 2.
float normFactor = 2.0 * invPdf * rcp(sampleCount);
diffuseLighting *= normFactor * lightData.diffuseScale * lightData.color;
specularLighting *= normFactor * lightData.specularScale * lightData.color;
diffuseLighting *= normFactor * lightData.diffuseColor;
specularLighting *= normFactor * lightData.specularColor;
}
//-----------------------------------------------------------------------------

if (illuminance > 0.0)
{
BSDF(V, L, positionWS, preLightData, bsdfData, localDiffuseLighting, localSpecularLighting);
localDiffuseLighting *= lightData.color * illuminance * lightData.diffuseScale;
localSpecularLighting *= lightData.color * illuminance * lightData.specularScale;
localDiffuseLighting *= lightData.diffuseColor * illuminance;
localSpecularLighting *= lightData.specularColor * illuminance;
}
diffuseLighting += localDiffuseLighting;

10
SampleScenes/HDTest/TransparencyTest.meta


fileFormatVersion: 2
guid: 901744c84a8bdd3498f92ff846e7aeb0
folderAsset: yes
timeCreated: 1508989318
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存