浏览代码

Merge remote-tracking branch 'refs/remotes/origin/master' into Add-physical-Light-unit-2

/main
Sebastien Lagarde 6 年前
当前提交
0d688467
共有 45 个文件被更改,包括 1249 次插入247 次删除
  1. 9
      ScriptableRenderPipeline/Core/CoreRP/Editor/MaterialUpgrader.cs
  2. 2
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileFactory.cs
  3. 4
      ScriptableRenderPipeline/Core/CoreRP/Inputs/InputRegistering.cs
  4. 10
      ScriptableRenderPipeline/Core/CoreRP/Shadow/AdditionalShadowData.cs
  5. 87
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  6. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.Styles.cs
  7. 23
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs
  8. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/ProceduralSky/ProceduralSkyEditor.cs
  9. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/SkySettingsEditor.cs
  10. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/UpgradeStandardShaderMaterials.cs
  11. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  12. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  13. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs
  14. 225
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  15. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-clustered.compute
  16. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild.compute
  17. 24
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/scrbound.compute
  18. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl
  19. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesMatrixDefsHDCamera.hlsl
  20. 46
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Shadows/HDShadowSettings.cs
  21. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/HDRISky/HDRISkyRenderer.cs
  22. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  23. 11
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  24. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs
  25. 21
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-DefaultParticle.mat
  26. 8
      ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner.meta
  27. 208
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardsToHDLitMaterialUpgrader.cs
  28. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardsToHDLitMaterialUpgrader.cs.meta
  29. 44
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Unlit/UnlitsToHDUnlitUpgrader.cs
  30. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Unlit/UnlitsToHDUnlitUpgrader.cs.meta
  31. 57
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/ContactShadowsEditor.cs
  32. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/ContactShadowsEditor.cs.meta
  33. 66
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/HDShadowSettingsEditor.cs
  34. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/HDShadowSettingsEditor.cs.meta
  35. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Shadows/ContactShadows.cs
  36. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Shadows/ContactShadows.cs.meta
  37. 11
      ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.cs.meta
  38. 9
      ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.shader.meta
  39. 282
      ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.cs
  40. 98
      ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.shader
  41. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardSpecularToHDLitMaterialUpgrader.cs.meta
  42. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardToHDLitMaterialUpgrader.cs.meta
  43. 45
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardToHDLitMaterialUpgrader.cs
  44. 43
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardSpecularToHDLitMaterialUpgrader.cs

9
ScriptableRenderPipeline/Core/CoreRP/Editor/MaterialUpgrader.cs


Dictionary<string, float> m_FloatPropertiesToSet = new Dictionary<string, float>();
Dictionary<string, Color> m_ColorPropertiesToSet = new Dictionary<string, Color>();
List<string> m_TexturesToRemove = new List<string>();
Dictionary<string, Texture> m_TexturesToSet = new Dictionary<string, Texture>();
class KeywordFloatRename

foreach (var prop in m_TexturesToRemove)
dstMaterial.SetTexture(prop, null);
foreach (var prop in m_TexturesToSet)
dstMaterial.SetTexture(prop.Key, prop.Value);
foreach (var prop in m_FloatPropertiesToSet)
dstMaterial.SetFloat(prop.Key, prop.Value);

public void SetColor(string propertyName, Color value)
{
m_ColorPropertiesToSet[propertyName] = value;
}
public void SetTexture(string propertyName, Texture value)
{
m_TexturesToSet[propertyName] = value;
}
public void RenameKeywordToFloat(string oldName, string newName, float setVal, float unsetVal)

2
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileFactory.cs


else
{
var scenePath = Path.GetDirectoryName(scene.path);
var extPath = scene.name + "_Profiles";
var extPath = scene.name;
var profilePath = scenePath + "/" + extPath;
if (!AssetDatabase.IsValidFolder(profilePath))

4
ScriptableRenderPipeline/Core/CoreRP/Inputs/InputRegistering.cs


static public void RegisterInputs(List<InputManagerEntry> entries)
{
/*
// Grab reference to input manager
var currentSelection = UnityEditor.Selection.activeObject;
UnityEditor.EditorApplication.ExecuteMenuItem("Edit/Project Settings/Input");

soInputManager.ApplyModifiedProperties();
UnityEditor.Selection.activeObject = currentSelection;
*/
}
}

10
ScriptableRenderPipeline/Core/CoreRP/Shadow/AdditionalShadowData.cs


[Range(0.0f, 1.0f)]
public float shadowDimmer = 1.0f;
public float shadowFadeDistance = 10000.0f;
// Contact shadows
public bool enableContactShadows = false;
[Range(0.0f, 1.0f)]
public float contactShadowLength = 0.0f;
[Range(0.0f, 1.0f)]
public float contactShadowDistanceScaleFactor = 0.5f;
public float contactShadowMaxDistance = 50.0f;
public float contactShadowFadeDistance = 5.0f;
[Range(4, 64)]
public uint contactShadowSampleCount = 8;
// bias control
public float viewBiasMin = 0.5f;
public float viewBiasMax = 10.0f;

87
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


public Matrix4x4[] viewMatrixStereo;
public Matrix4x4[] projMatrixStereo;
public Vector4 centerEyeTranslationOffset;
// Non oblique projection matrix (RHS)
public Matrix4x4 nonObliqueProjMatrix

var gpuView = camera.worldToCameraMatrix;
var gpuNonJitteredProj = GL.GetGPUProjectionMatrix(nonJitteredCameraProj, true);
// In stereo, this corresponds to the center eye position
var relPos = pos; // World-origin-relative
relPos = Vector3.zero; // Camera-relative
}
var gpuVP = gpuNonJitteredProj * gpuView;

screenSize = new Vector4(screenWidth, screenHeight, 1.0f / screenWidth, 1.0f / screenHeight);
}
// Stopgap method used to extract stereo combined matrix state.
public void UpdateStereoDependentState(FrameSettings frameSettings, ref ScriptableCullingParameters cullingParams)
{
if (!frameSettings.enableStereo)
return;
// What constants in UnityPerPass need updating for stereo considerations?
// _ViewProjMatrix - It is used directly for generating tesselation factors. This should be the same
// across both eyes for consistency, and to keep shadow-generation eye-independent
// _ViewParam - Used for isFrontFace determination, should be the same for both eyes. There is the scenario
// where there might be multi-eye sets that are divergent enough where this assumption is not valid,
// but that's a future problem
// _InvProjParam - Intention was for generating linear depths, but not currently used. Will need to be stereo-ized if
// actually needed.
// _FrustumPlanes - Also used for generating tesselation factors. Should be fine to use the combined stereo VP
// to calculate frustum planes.
// TODO: Would it be worth calculating my own combined view/proj matrix in Update?
// In engine, we modify the view and proj matrices accordingly in order to generate the single cull
// * Get the center eye view matrix, and pull it back to cover both eyes
// * Generated an expanded projection matrix (one method - max bound of left/right proj matrices)
// and move near/far planes to match near/far locations of proj matrices located at eyes.
// I think using the cull matrices is valid, as long as I only use them for tess factors in shader.
// Using them for other calculations (like light list generation) could be problematic.
var stereoCombinedViewMatrix = cullingParams.cullStereoView;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// This is pulled back from the center eye, so set the offset
var translation = stereoCombinedViewMatrix.GetColumn(3);
translation += centerEyeTranslationOffset;
stereoCombinedViewMatrix.SetColumn(3, translation);
}
viewMatrix = stereoCombinedViewMatrix;
var stereoCombinedProjMatrix = cullingParams.cullStereoProj;
projMatrix = GL.GetGPUProjectionMatrix(stereoCombinedProjMatrix, true);
viewParam = new Vector4(viewMatrix.determinant, 0.0f, 0.0f, 0.0f);
frustum = Frustum.Create(viewProjMatrix, true, true);
// Left, right, top, bottom, near, far.
for (int i = 0; i < 6; i++)
{
frustumPlaneEquations[i] = new Vector4(frustum.planes[i].normal.x, frustum.planes[i].normal.y, frustum.planes[i].normal.z, frustum.planes[i].distance);
}
}
void ConfigureStereoMatrices()
{
for (uint eyeIndex = 0; eyeIndex < 2; eyeIndex++)

projMatrixStereo[eyeIndex] = camera.GetStereoProjectionMatrix((Camera.StereoscopicEye)eyeIndex);
projMatrixStereo[eyeIndex] = GL.GetGPUProjectionMatrix(projMatrixStereo[eyeIndex], true);
}
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
var leftTranslation = viewMatrixStereo[0].GetColumn(3);
var rightTranslation = viewMatrixStereo[1].GetColumn(3);
var centerTranslation = (leftTranslation + rightTranslation) / 2;
var centerOffset = -centerTranslation;
centerOffset.w = 0;
// TODO: Grabbing the CenterEye transform would be preferable, but XRNode.CenterEye
// doesn't always seem to be valid.
for (uint eyeIndex = 0; eyeIndex < 2; eyeIndex++)
{
var translation = viewMatrixStereo[eyeIndex].GetColumn(3);
translation += centerOffset;
viewMatrixStereo[eyeIndex].SetColumn(3, translation);
}
centerEyeTranslationOffset = centerOffset;
}
// TODO: Fetch the single cull matrix stuff

public void SetupGlobalStereoParams(CommandBuffer cmd)
{
var viewProjStereo = new Matrix4x4[2];
var invViewStereo = new Matrix4x4[2];
var invProjStereo = new Matrix4x4[2];
var invViewProjStereo = new Matrix4x4[2];

invProjStereo[eyeIndex] = proj.inverse;
var vp = proj * viewMatrixStereo[eyeIndex];
invViewProjStereo[eyeIndex] = vp.inverse;
var view = viewMatrixStereo[eyeIndex];
invViewStereo[eyeIndex] = view.inverse;
viewProjStereo[eyeIndex] = proj * view;
invViewProjStereo[eyeIndex] = viewProjStereo[eyeIndex].inverse;
cmd.SetGlobalMatrixArray(HDShaderIDs._ViewMatrixStereo, viewMatrixStereo);
cmd.SetGlobalMatrixArray(HDShaderIDs._ViewProjMatrixStereo, viewProjStereo);
cmd.SetGlobalMatrixArray(HDShaderIDs._InvViewMatrixStereo, invViewStereo);
cmd.SetGlobalMatrixArray(HDShaderIDs._InvProjMatrixStereo, invProjStereo);
cmd.SetGlobalMatrixArray(HDShaderIDs._InvViewProjMatrixStereo, invViewProjStereo);
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.Styles.cs


public readonly GUIContent[] shapeNames;
// Additional shadow data
public readonly GUIContent shadowCascades = new GUIContent("Cascades", "");
public readonly GUIContent shadowCascadeCount = new GUIContent("Cascade Count", "");
public readonly GUIContent[] shadowCascadeRatios = { new GUIContent("Cascade 1"), new GUIContent("Cascade 2"), new GUIContent("Cascade 3") };
public readonly GUIContent contactShadow = new GUIContent("Contact Shadows");
public readonly GUIContent contactShadowLength = new GUIContent("Length", "Length of rays used to gather contact shadows in world units.\nZero will disable the feature.");
public readonly GUIContent contactShadowDistanceScaleFactor = new GUIContent("Distance Scale Factor", "Contact Shadows are scaled up with distance. Use this parameter to dampen this effect.");
public readonly GUIContent contactShadowMaxDistance = new GUIContent("Max Distance", "Distance from the camera in world units at which contact shadows are faded out to zero.");
public readonly GUIContent contactShadowFadeDistance = new GUIContent("Fade Distance", "Distance in world units over which the contact shadows are faded out (see Max Distance).");
public readonly GUIContent contactShadowSampleCount = new GUIContent("Sample Count", "Number of samples when ray casting.");
// Bias control
public readonly GUIContent viewBiasMin = new GUIContent("View Bias");

23
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs


{
public SerializedProperty dimmer;
public SerializedProperty fadeDistance;
public SerializedProperty cascadeCount;
public SerializedProperty cascadeRatios;
public SerializedProperty cascadeBorders;
public SerializedProperty enableContactShadows;
public SerializedProperty contactShadowLength;
public SerializedProperty contactShadowDistanceScaleFactor;
public SerializedProperty contactShadowMaxDistance;
public SerializedProperty contactShadowFadeDistance;
public SerializedProperty contactShadowSampleCount;
// Bias control
public SerializedProperty viewBiasMin;

{
dimmer = o.Find(x => x.shadowDimmer),
fadeDistance = o.Find(x => x.shadowFadeDistance),
cascadeCount = o.Find("shadowCascadeCount"),
cascadeRatios = o.Find("shadowCascadeRatios"),
cascadeBorders = o.Find("shadowCascadeBorders"),
enableContactShadows = o.Find(x => x.enableContactShadows),
contactShadowLength = o.Find(x => x.contactShadowLength),
contactShadowDistanceScaleFactor = o.Find(x => x.contactShadowDistanceScaleFactor),
contactShadowMaxDistance = o.Find(x => x.contactShadowMaxDistance),
contactShadowFadeDistance = o.Find(x => x.contactShadowFadeDistance),
contactShadowSampleCount = o.Find(x => x.contactShadowSampleCount),
viewBiasMin = o.Find(x => x.viewBiasMin),
viewBiasMax = o.Find(x => x.viewBiasMax),

{
bool shadowsEnabled = EditorGUILayout.Toggle(CoreEditorUtils.GetContent("Enable Shadows"), settings.shadowsType.enumValueIndex != 0);
settings.shadowsType.enumValueIndex = shadowsEnabled ? (int)LightShadows.Hard : (int)LightShadows.None;
if (settings.lightType.enumValueIndex == (int)LightType.Directional)
{
EditorGUILayout.PropertyField(m_AdditionalShadowData.enableContactShadows, CoreEditorUtils.GetContent("Enable Contact Shadows"));
}
}
EditorGUILayout.PropertyField(m_AdditionalLightData.showAdditionalSettings);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/ProceduralSky/ProceduralSkyEditor.cs


EditorGUILayout.Space();
base.CommonSkySettingsGUI();
base.CommonSkySettingsGUI(false);
}
}
}

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/SkySettingsEditor.cs


SerializedDataParameter m_EnvUpdateMode;
SerializedDataParameter m_EnvUpdatePeriod;
SerializedProperty m_UseForBaking;
public override void OnEnable()
{
var o = new PropertyFetcher<SkySettings>(serializedObject);

m_EnvUpdatePeriod = Unpack(o.Find(x => x.updatePeriod));
}
protected void CommonSkySettingsGUI()
protected void CommonSkySettingsGUI(bool enableRotation = true)
PropertyField(m_SkyRotation);
if(enableRotation)
PropertyField(m_SkyRotation);
PropertyField(m_EnvUpdateMode);
if (!m_EnvUpdateMode.value.hasMultipleDifferentValues && m_EnvUpdateMode.value.intValue == (int)EnvironementUpdateMode.Realtime)

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/UpgradeStandardShaderMaterials.cs


static List<MaterialUpgrader> GetHDUpgraders()
{
var upgraders = new List<MaterialUpgrader>();
upgraders.Add(new StandardToHDLitMaterialUpgrader("Standard", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass));
upgraders.Add(new StandardSpecularToHDLitMaterialUpgrader("Standard (Specular setup)", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass));
upgraders.Add(new StandardsToHDLitMaterialUpgrader("Standard", "HDRenderPipeline/Lit"));
upgraders.Add(new StandardsToHDLitMaterialUpgrader("Standard (Specular setup)", "HDRenderPipeline/Lit"));
upgraders.Add(new StandardsToHDLitMaterialUpgrader("Standard (Roughness setup)", "HDRenderPipeline/Lit"));
upgraders.Add(new UnlitsToHDUnlitUpgrader("Unlit/Color", "HDRenderPipeline/Unlit"));
upgraders.Add(new UnlitsToHDUnlitUpgrader("Unlit/Texture", "HDRenderPipeline/Unlit"));
upgraders.Add(new UnlitsToHDUnlitUpgrader("Unlit/Transparent", "HDRenderPipeline/Unlit"));
upgraders.Add(new UnlitsToHDUnlitUpgrader("Unlit/Transparent Cutout", "HDRenderPipeline/Unlit"));
return upgraders;
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


if (m_CurrentWidth > 0 && m_CurrentHeight > 0)
m_LightLoop.ReleaseResolutionDependentBuffers();
m_LightLoop.AllocResolutionDependentBuffers(hdCamera.actualWidth, hdCamera.actualHeight);
m_LightLoop.AllocResolutionDependentBuffers((int)hdCamera.screenSize.x, (int)hdCamera.screenSize.y, m_FrameSettings.enableStereo);
}
// Warning: (resolutionChanged == false) if you open a new Editor tab of the same size!

UpdateShadowSettings();
m_SkyManager.UpdateCurrentSkySettings(hdCamera);
// TODO: Float HDCamera setup higher in order to pass stereo into GetCullingParameters
ScriptableCullingParameters cullingParams;
if (!CullResults.GetCullingParameters(camera, m_FrameSettings.enableStereo, out cullingParams))
{

m_LightLoop.UpdateCullingParameters(ref cullingParams);
hdCamera.UpdateStereoDependentState(m_FrameSettings, ref cullingParams);
#if UNITY_EDITOR
// emit scene view UI

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int g_vBoundsBuffer = Shader.PropertyToID("g_vBoundsBuffer");
public static readonly int _LightVolumeData = Shader.PropertyToID("_LightVolumeData");
public static readonly int g_data = Shader.PropertyToID("g_data");
public static readonly int g_mProjection = Shader.PropertyToID("g_mProjection");
public static readonly int g_mInvProjection = Shader.PropertyToID("g_mInvProjection");
public static readonly int g_mProjectionArr = Shader.PropertyToID("g_mProjectionArr");
public static readonly int g_mInvProjectionArr = Shader.PropertyToID("g_mInvProjectionArr");
public static readonly int g_viDimensions = Shader.PropertyToID("g_viDimensions");
public static readonly int g_vLightList = Shader.PropertyToID("g_vLightList");

public static readonly int _TaaFrameIndex = Shader.PropertyToID("_TaaFrameIndex");
public static readonly int _TaaFrameRotation = Shader.PropertyToID("_TaaFrameRotation");
public static readonly int _ViewMatrixStereo = Shader.PropertyToID("_ViewMatrixStereo");
public static readonly int _ViewProjMatrixStereo = Shader.PropertyToID("_ViewProjMatrixStereo");
public static readonly int _InvViewMatrixStereo = Shader.PropertyToID("_InvViewMatrixStereo");
public static readonly int _InvProjMatrixStereo = Shader.PropertyToID("_InvProjMatrixStereo");
public static readonly int _InvViewProjMatrixStereo = Shader.PropertyToID("_InvViewProjMatrixStereo");

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs


cmd.Blit(source, destination, new Vector2(camera.scaleBias.x, camera.scaleBias.y), Vector2.zero);
}
// This particular case is for blitting a camera-scaled texture into a non scaling texture. So we setup the full viewport (implicit in cmd.Blit) but have to scale the input UVs.
// This particular case is for blitting a non-scaled texture into a scaled texture. So we setup the partial viewport but don't scale the input UVs.
public static void BlitCameraTexture(CommandBuffer cmd, HDCamera camera, RenderTargetIdentifier source, RTHandle destination)
{
// Will set the correct camera viewport as well.

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


public const int k_MaxEnvLightsOnScreen = 64;
public const int k_MaxShadowOnScreen = 16;
public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;
public const int k_MaxStereoEyes = 2;
public static readonly Vector3 k_BoxCullingExtentThreshold = Vector3.one * 0.01f;
// Static keyword is required here else we get a "DestroyBuffer can only be called from the main thread"

public List<SFiniteLightBound> bounds;
public List<LightVolumeData> lightVolumes;
public List<SFiniteLightBound> rightEyeBounds;
public List<LightVolumeData> rightEyeLightVolumes;
public void Clear()
{

bounds.Clear();
lightVolumes.Clear();
rightEyeBounds.Clear();
rightEyeLightVolumes.Clear();
}
public void Allocate()

bounds = new List<SFiniteLightBound>();
lightVolumes = new List<LightVolumeData>();
rightEyeBounds = new List<SFiniteLightBound>();
rightEyeLightVolumes = new List<LightVolumeData>();
}
}

int GetNumTileFtplX(HDCamera hdCamera)
{
return (hdCamera.actualWidth + (LightDefinitions.s_TileSizeFptl - 1)) / LightDefinitions.s_TileSizeFptl;
return ((int)hdCamera.screenSize.x + (LightDefinitions.s_TileSizeFptl - 1)) / LightDefinitions.s_TileSizeFptl;
return (hdCamera.actualHeight + (LightDefinitions.s_TileSizeFptl - 1)) / LightDefinitions.s_TileSizeFptl;
return ((int)hdCamera.screenSize.y + (LightDefinitions.s_TileSizeFptl - 1)) / LightDefinitions.s_TileSizeFptl;
return (hdCamera.actualWidth + (LightDefinitions.s_TileSizeClustered - 1)) / LightDefinitions.s_TileSizeClustered;
return ((int)hdCamera.screenSize.x + (LightDefinitions.s_TileSizeClustered - 1)) / LightDefinitions.s_TileSizeClustered;
return (hdCamera.actualHeight + (LightDefinitions.s_TileSizeClustered - 1)) / LightDefinitions.s_TileSizeClustered;
return ((int)hdCamera.screenSize.y + (LightDefinitions.s_TileSizeClustered - 1)) / LightDefinitions.s_TileSizeClustered;
}
public bool GetFeatureVariantsEnabled()

s_GenAABBKernel = buildScreenAABBShader.FindKernel("ScreenBoundsAABB");
s_AABBBoundsBuffer = new ComputeBuffer(2 * k_MaxLightsOnScreen, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
s_LightVolumeDataBuffer = new ComputeBuffer(k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightVolumeData)));
// The bounds and light volumes are view-dependent, and AABB is additionally projection dependent.
// The view and proj matrices are per eye in stereo. This means we have to double the size of these buffers.
// TODO: Maybe in stereo, we will only support half as many lights total, in order to minimize buffer size waste.
// Alternatively, we could re-size these buffers if any stereo camera is active, instead of unilaterally increasing buffer size.
// TODO: I don't think k_MaxLightsOnScreen corresponds to the actual correct light count for cullable light types (punctual, area, env, decal)
s_AABBBoundsBuffer = new ComputeBuffer(k_MaxStereoEyes * 2 * k_MaxLightsOnScreen, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(k_MaxStereoEyes* k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
s_LightVolumeDataBuffer = new ComputeBuffer(k_MaxStereoEyes* k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightVolumeData)));
s_DispatchIndirectBuffer = new ComputeBuffer(LightDefinitions.s_NumFeatureVariants * 3, sizeof(uint), ComputeBufferType.IndirectArguments);
// Cluster

return 8 * (1 << k_Log2NumClusters); // total footprint for all layers of the tile (measured in light index entries)
}
// TODO: Add proper stereo support
public void AllocResolutionDependentBuffers(int width, int height)
public void AllocResolutionDependentBuffers(int width, int height, bool stereoEnabled)
var nrStereoLayers = stereoEnabled ? 2 : 1;
var nrTiles = nrTilesX * nrTilesY;
var nrTiles = nrTilesX * nrTilesY * nrStereoLayers;
s_TileFeatureFlags = new ComputeBuffer(nrTilesX * nrTilesY, sizeof(uint));
s_TileFeatureFlags = new ComputeBuffer(nrTiles, sizeof(uint));
var nrClusterTiles = nrClustersX * nrClustersY;
var nrClusterTiles = nrClustersX * nrClustersY * nrStereoLayers;
s_PerVoxelOffset = new ComputeBuffer((int)LightCategory.Count * (1 << k_Log2NumClusters) * nrClusterTiles, sizeof(uint));
s_PerVoxelLightLists = new ComputeBuffer(NumLightIndicesPerClusteredTile() * nrClusterTiles, sizeof(uint));

{
var nrBigTilesX = (width + 63) / 64;
var nrBigTilesY = (height + 63) / 64;
var nrBigTiles = nrBigTilesX * nrBigTilesY;
var nrBigTiles = nrBigTilesX * nrBigTilesY * nrStereoLayers;
s_BigTileLightList = new ComputeBuffer(LightDefinitions.s_MaxNrBigTileLightsPlusOne * nrBigTiles, sizeof(uint));
}
}

return Matrix4x4.Scale(new Vector3(1, 1, -1)) * camera.worldToCameraMatrix;
}
static Matrix4x4 WorldToViewStereo(Camera camera, Camera.StereoscopicEye eyeIndex)
{
return Matrix4x4.Scale(new Vector3(1, 1, -1)) * camera.GetStereoViewMatrix(eyeIndex);
}
// For light culling system, we need non oblique projection matrices
static Matrix4x4 CameraProjectionNonObliqueLHS(HDCamera camera)
{

}
static Matrix4x4 CameraProjectionStereoLHS(Camera camera, Camera.StereoscopicEye eyeIndex)
{
return camera.GetStereoProjectionMatrix(eyeIndex) * Matrix4x4.Scale(new Vector3(1, 1, -1));
}
public Vector3 GetLightColor(VisibleLight light)
{
return new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);

directionalLightData.dynamicShadowCasterOnly = 0;
}
// Fallback to the first non shadow casting directional light.
m_CurrentSunLight = m_CurrentSunLight == null ? light.light : m_CurrentSunLight;
m_lightList.directionalLights.Add(directionalLightData);

// TODO: we should be able to do this calculation only with LightData without VisibleLight light, but for now pass both
public void GetLightVolumeDataAndBound(LightCategory lightCategory, GPULightType gpuLightType, LightVolumeType lightVolumeType,
VisibleLight light, LightData lightData, Vector3 lightDimensions, Matrix4x4 worldToView)
VisibleLight light, LightData lightData, Vector3 lightDimensions, Matrix4x4 worldToView,
Camera.StereoscopicEye eyeIndex = Camera.StereoscopicEye.Left)
{
// Then Culling side
var range = lightDimensions.z;

Debug.Assert(false, "TODO: encountered an unknown GPULightType.");
}
m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
if (eyeIndex == Camera.StereoscopicEye.Left)
{
m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
}
else
{
m_lightList.rightEyeBounds.Add(bound);
m_lightList.rightEyeLightVolumes.Add(lightVolumeData);
}
}

m_lightList.envLights.Add(envLightData);
return true;
}
public void GetEnvLightVolumeDataAndBound(ProbeWrapper probe, LightVolumeType lightVolumeType, Matrix4x4 worldToView)
public void GetEnvLightVolumeDataAndBound(ProbeWrapper probe, LightVolumeType lightVolumeType, Matrix4x4 worldToView, Camera.StereoscopicEye eyeIndex = Camera.StereoscopicEye.Left)
{
var bound = new SFiniteLightBound();
var lightVolumeData = new LightVolumeData();

}
}
m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
if (eyeIndex == Camera.StereoscopicEye.Left)
{
m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
}
else
{
m_lightList.rightEyeBounds.Add(bound);
m_lightList.rightEyeLightVolumes.Add(lightVolumeData);
}
}
public int GetCurrentShadowCount()

m_lightList.Clear();
Vector3 camPosWS = camera.transform.position;
var stereoEnabled = m_FrameSettings.enableStereo;
// Note: Light with null intensity/Color are culled by the C++, no need to test it here
if (cullResults.visibleLights.Count != 0 || cullResults.visibleReflectionProbes.Count != 0)

AdditionalShadowData asd = vl.light.GetComponent<AdditionalShadowData>();
if (asd != null && asd.shadowDimmer > 0.0f)
{
// Discover sun light and update cascade info from Volumes
// TODO: This should be moved to GetDirectionalLightData when we merge the two loops here.
// Careful it must still be done BEFORE the call to ProcessShadowRequests
if (vl.lightType == LightType.Directional && m_CurrentSunLight == null)
{
var hdShadowSettings = VolumeManager.instance.stack.GetComponent<HDShadowSettings>();
asd.SetShadowCascades(hdShadowSettings.cascadeShadowSplitCount, hdShadowSettings.cascadeShadowSplits, hdShadowSettings.cascadeShadowBorders );
}
}
uint shadowRequestCount = (uint)m_ShadowRequests.Count;
uint shadowRequestCount = (uint)m_ShadowRequests.Count;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, ShaderConfig.s_CameraRelativeRendering != 0, cullResults.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);

// For now we will still apply the maximum of shadow here but we don't apply the sorting by priority + slot allocation yet
// 2. Go through all lights, convert them to GPU format.
// Create simultaneously data for culling (LigthVolumeData and rendering)
// Simultaneously create data for culling (LightVolumeData and SFiniteLightBound)
Vector3 camPosWS = camera.transform.position;
var rightEyeWorldToView = Matrix4x4.identity;
if (stereoEnabled)
{
worldToView = WorldToViewStereo(camera, Camera.StereoscopicEye.Left);
rightEyeWorldToView = WorldToViewStereo(camera, Camera.StereoscopicEye.Right);
}
for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex)
{

// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], lightDimensions, worldToView);
if (stereoEnabled)
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], lightDimensions, rightEyeWorldToView, Camera.StereoscopicEye.Right);
// We make the light position camera-relative as late as possible in order
// to allow the preceding code to work with the absolute world space coordinates.

if (GetEnvLightData(cmd, camera, probeWrapper))
{
GetEnvLightVolumeDataAndBound(probeWrapper, lightVolumeType, worldToView);
if (stereoEnabled)
GetEnvLightVolumeDataAndBound(probeWrapper, lightVolumeType, rightEyeWorldToView, Camera.StereoscopicEye.Right);
// We make the light position camera-relative as late as possible in order
// to allow the preceding code to work with the absolute world space coordinates.

Debug.Assert(m_lightList.bounds.Count == m_lightCount);
Debug.Assert(m_lightList.lightVolumes.Count == m_lightCount);
m_lightList.bounds.AddRange(DecalSystem.m_Bounds);
m_lightList.lightVolumes.AddRange(DecalSystem.m_LightVolumes);
m_lightCount += DecalSystem.m_DecalDatasCount;
if (DecalSystem.m_DecalDatasCount > 0)
{
// TODO: This adds the entire array to the buffer, likely introducing
// empty entries into the buffer. Currently, stereo assumes this buffer to
// be tightly packed. Decals are currently disabled for stereo anyway, so we
// will coordinate on a proper solution for this.
m_lightList.bounds.AddRange(DecalSystem.m_Bounds);
m_lightList.lightVolumes.AddRange(DecalSystem.m_LightVolumes);
m_lightCount += DecalSystem.m_DecalDatasCount;
}
if (stereoEnabled)
{
// TODO: Proper decal + stereo cull management
Debug.Assert(m_lightList.rightEyeBounds.Count == m_lightCount);
Debug.Assert(m_lightList.rightEyeLightVolumes.Count == m_lightCount);
// TODO: GC considerations?
m_lightList.bounds.AddRange(m_lightList.rightEyeBounds);
m_lightList.lightVolumes.AddRange(m_lightList.rightEyeLightVolumes);
}
UpdateDataBuffers();
m_maxShadowDistance = shadowSettings.maxShadowDistance;

var camera = hdCamera.camera;
cmd.BeginSample("Build Light List");
var w = camera.pixelWidth;
var h = camera.pixelHeight;
var w = (int)hdCamera.screenSize.x;
var h = (int)hdCamera.screenSize.y;
// camera to screen matrix (and it's inverse)
var proj = CameraProjectionNonObliqueLHS(hdCamera);
var projscr = temp * proj;
var invProjscr = projscr.inverse;
// camera to screen matrix (and it's inverse)
var projArr = new Matrix4x4[2];
var projscrArr = new Matrix4x4[2];
var invProjscrArr = new Matrix4x4[2];
if (m_FrameSettings.enableStereo)
{
for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
{
projArr[eyeIndex] = CameraProjectionStereoLHS(hdCamera.camera, (Camera.StereoscopicEye)eyeIndex);
projscrArr[eyeIndex] = temp * projArr[eyeIndex];
invProjscrArr[eyeIndex] = projscrArr[eyeIndex].inverse;
}
}
else
{
projArr[0] = CameraProjectionNonObliqueLHS(hdCamera);
projscrArr[0] = temp * projArr[0];
invProjscrArr[0] = projscrArr[0].inverse;
}
// generate screen-space AABBs (used for both fptl and clustered).
if (m_lightCount != 0)
{

temp.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
var projh = temp * proj;
var invProjh = projh.inverse;
var projhArr = new Matrix4x4[2];
var invProjhArr = new Matrix4x4[2];
if (m_FrameSettings.enableStereo)
{
for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
{
projhArr[eyeIndex] = temp * projArr[eyeIndex];
invProjhArr[eyeIndex] = projhArr[eyeIndex].inverse;
}
}
else
{
projhArr[0] = temp * projArr[0];
invProjhArr[0] = projhArr[0].inverse;
}
// In the stereo case, we have two sets of light bounds to iterate over (bounds are in per-eye view space)
cmd.SetComputeMatrixParam(buildScreenAABBShader, HDShaderIDs.g_mProjection, projh);
cmd.SetComputeMatrixParam(buildScreenAABBShader, HDShaderIDs.g_mInvProjection, invProjh);
cmd.SetComputeMatrixArrayParam(buildScreenAABBShader, HDShaderIDs.g_mProjectionArr, projhArr);
cmd.SetComputeMatrixArrayParam(buildScreenAABBShader, HDShaderIDs.g_mInvProjectionArr, invProjhArr);
// In stereo, we output two sets of AABB bounds
cmd.DispatchCompute(buildScreenAABBShader, s_GenAABBKernel, (m_lightCount + 7) / 8, 1, 1);
int tgY = m_FrameSettings.enableStereo ? 2 : 1;
cmd.DispatchCompute(buildScreenAABBShader, s_GenAABBKernel, (m_lightCount + 7) / 8, tgY, 1);
}
// enable coarse 2D pass on 64x64 tiles (used for both fptl and clustered).

cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs._EnvLightIndexShift, m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs._DecalIndexShift, m_lightList.lights.Count + m_lightList.envLights.Count);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);
cmd.SetComputeMatrixParam(buildPerBigTileLightListShader, HDShaderIDs.g_mScrProjection, projscr);
cmd.SetComputeMatrixParam(buildPerBigTileLightListShader, HDShaderIDs.g_mInvScrProjection, invProjscr);
cmd.SetComputeMatrixParam(buildPerBigTileLightListShader, HDShaderIDs.g_mScrProjection, projscrArr[0]);
cmd.SetComputeMatrixParam(buildPerBigTileLightListShader, HDShaderIDs.g_mInvScrProjection, invProjscrArr[0]);
cmd.SetComputeFloatParam(buildPerBigTileLightListShader, HDShaderIDs.g_fNearPlane, camera.nearClipPlane);
cmd.SetComputeFloatParam(buildPerBigTileLightListShader, HDShaderIDs.g_fFarPlane, camera.farClipPlane);
cmd.SetComputeBufferParam(buildPerBigTileLightListShader, s_GenListPerBigTileKernel, HDShaderIDs.g_vLightList, s_BigTileLightList);

cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, HDShaderIDs._LightVolumeData, s_LightVolumeDataBuffer);
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, HDShaderIDs.g_data, s_ConvexBoundsBuffer);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mScrProjection, projscr);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mInvScrProjection, invProjscr);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mScrProjection, projscrArr[0]);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mInvScrProjection, invProjscrArr[0]);
cmd.SetComputeTextureParam(buildPerTileLightListShader, s_GenListPerTileKernel, HDShaderIDs.g_depth_tex, cameraDepthBufferRT);
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, HDShaderIDs.g_vLightList, s_LightList);
if (m_FrameSettings.lightLoopSettings.enableBigTilePrepass)

}
// Cluster
VoxelLightListGeneration(cmd, hdCamera, projscr, invProjscr, cameraDepthBufferRT);
VoxelLightListGeneration(cmd, hdCamera, projscrArr[0], invProjscrArr[0], cameraDepthBufferRT);
if (enableFeatureVariants)
{

using (new ProfilingSample(cmd, "Deferred Directional Shadow", CustomSamplerId.TPDeferredDirectionalShadow.GetSampler()))
{
AdditionalShadowData asd = m_CurrentSunLight.GetComponent<AdditionalShadowData>();
ContactShadows contactShadows = VolumeManager.instance.stack.GetComponent<ContactShadows>();
bool enableContactShadows = m_FrameSettings.enableContactShadows && asd.enableContactShadows && asd.contactShadowLength > 0.0f;
bool enableContactShadows = m_FrameSettings.enableContactShadows && contactShadows.enable && contactShadows.length > 0.0f;
int kernel;
if (enableContactShadows)
kernel = m_FrameSettings.enableForwardRenderingOnly ? s_deferredDirectionalShadow_Contact_Kernel : s_deferredDirectionalShadow_Contact_Normals_Kernel;

if (enableContactShadows)
{
float contactShadowRange = Mathf.Clamp(asd.contactShadowFadeDistance, 0.0f, asd.contactShadowMaxDistance);
float contactShadowFadeEnd = asd.contactShadowMaxDistance;
float contactShadowRange = Mathf.Clamp(contactShadows.fadeDistance, 0.0f, contactShadows.maxDistance);
float contactShadowFadeEnd = contactShadows.maxDistance;
Vector4 contactShadowParams = new Vector4(asd.contactShadowLength, asd.contactShadowDistanceScaleFactor, contactShadowFadeEnd, contactShadowOneOverFadeRange);
Vector4 contactShadowParams = new Vector4(contactShadows.length, contactShadows.distanceScaleFactor, contactShadowFadeEnd, contactShadowOneOverFadeRange);
cmd.SetComputeIntParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalContactShadowSampleCount, (int)asd.contactShadowSampleCount);
cmd.SetComputeIntParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalContactShadowSampleCount, contactShadows.sampleCount);
}
cmd.SetComputeIntParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalShadowIndex, m_CurrentSunLightShadowIndex);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-clustered.compute


InterlockedAdd(g_LayeredSingleIdxBuffer[0], (uint) iSpaceAvail, start); // alloc list memory
}
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// All our cull data are in the same list, but at render time envLights are separated so we need to shift the index
// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT];
ZERO_INITIALIZE_ARRAY(int, shiftIndex, LIGHTCATEGORY_COUNT);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild.compute


int localOffs=0;
int offs = tileIDX.y*nrTilesX + tileIDX.x;
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// All our cull data are in the same list, but at render time envLights are separated so we need to shift the index
// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT];
ZERO_INITIALIZE_ARRAY(int, shiftIndex, LIGHTCATEGORY_COUNT);

24
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/scrbound.compute


uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvProjection;
uniform float4x4 g_mProjection;
uniform float4x4 g_mInvProjectionArr[2];
uniform float4x4 g_mProjectionArr[2];
StructuredBuffer<SFiniteLightBound> g_data : register( t0 );

void ScreenBoundsAABB(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
uint groupID = u3GroupID.x;
uint eyeIndex = u3GroupID.y; // currently, can only be 0 or 1
// The g_ is preserved in order to make cross-pipeline (FPTL) updates easier
float4x4 g_mInvProjection = g_mInvProjectionArr[eyeIndex];
float4x4 g_mProjection = g_mProjectionArr[eyeIndex];
//uint vindex = groupID * NR_THREADS + threadID;
unsigned int g = groupID;

const int lgtIndex = subLigt+(int) g*8;
const int sideIndex = (int) (t%8);
SFiniteLightBound lgtDat = g_data[lgtIndex];
const int eyeAdjustedLgtIndex = lgtIndex + (eyeIndex * g_iNrVisibLights);
SFiniteLightBound lgtDat = g_data[eyeAdjustedLgtIndex];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;

//g_vBoundsBuffer[lgtIndex+g_iNrVisibLights] = float3(0.5*vMax.x+0.5, -0.5*vMin.y+0.5, vMax.z*VIEWPORT_SCALE_Z);
// changed for unity
g_vBoundsBuffer[lgtIndex+0] = float3(0.5*vMin.x+0.5, 0.5*vMin.y+0.5, vMin.z*VIEWPORT_SCALE_Z);
g_vBoundsBuffer[lgtIndex+(int) g_iNrVisibLights] = float3(0.5*vMax.x+0.5, 0.5*vMax.y+0.5, vMax.z*VIEWPORT_SCALE_Z);
// Each light's AABB is represented by two float3s, the min and max of the box.
// And for stereo, we have two sets of lights. Therefore, each eye has a set of mins, followed by
// a set of maxs, and each set is equal to g_iNrVisibLights.
const int eyeBaseIndex = eyeIndex * g_iNrVisibLights * 2;
const int minIndex = eyeBaseIndex + lgtIndex + 0;
const int maxIndex = eyeBaseIndex + lgtIndex + (int)g_iNrVisibLights;
g_vBoundsBuffer[minIndex] = float3(0.5*vMin.x + 0.5, 0.5*vMin.y + 0.5, vMin.z*VIEWPORT_SCALE_Z);
g_vBoundsBuffer[maxIndex] = float3(0.5*vMax.x + 0.5, 0.5*vMax.y + 0.5, vMax.z*VIEWPORT_SCALE_Z);
}
}
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


#if defined(USING_STEREO_MATRICES)
CBUFFER_START(UnityPerPassStereo)
float4x4 _ViewMatrixStereo[2];
// Proj not needed...yet?
float4x4 _ViewProjMatrixStereo[2];
float4x4 _InvViewMatrixStereo[2];
float4x4 _InvProjMatrixStereo[2];
float4x4 _InvViewProjMatrixStereo[2];
CBUFFER_END

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesMatrixDefsHDCamera.hlsl


#define UNITY_MATRIX_M unity_ObjectToWorld
#define UNITY_MATRIX_I_M unity_WorldToObject
#define UNITY_MATRIX_V unity_StereoMatrixV[unity_StereoEyeIndex]
#define UNITY_MATRIX_I_V unity_StereoMatrixInvV[unity_StereoEyeIndex]
#define UNITY_MATRIX_V _ViewMatrixStereo[unity_StereoEyeIndex]
#define UNITY_MATRIX_I_V _InvViewMatrixStereo[unity_StereoEyeIndex]
#define UNITY_MATRIX_VP unity_StereoMatrixVP[unity_StereoEyeIndex]
#define UNITY_MATRIX_VP _ViewProjMatrixStereo[unity_StereoEyeIndex]
#define UNITY_MATRIX_I_VP _InvViewProjMatrixStereo[unity_StereoEyeIndex]
#else

46
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Shadows/HDShadowSettings.cs


[Serializable]
public class HDShadowSettings : VolumeComponent
{
public NoInterpMinFloatParameter maxShadowDistance = new NoInterpMinFloatParameter(500.0f, 0.0f);
float[] m_CascadeShadowSplits = new float[3];
float[] m_CascadeShadowBorders = new float[4];
public float[] cascadeShadowSplits
{
get
{
m_CascadeShadowSplits[0] = cascadeShadowSplit0;
m_CascadeShadowSplits[1] = cascadeShadowSplit1;
m_CascadeShadowSplits[2] = cascadeShadowSplit2;
return m_CascadeShadowSplits;
}
}
public float[] cascadeShadowBorders
{
get
{
m_CascadeShadowBorders[0] = cascadeShadowBorder0;
m_CascadeShadowBorders[1] = cascadeShadowBorder1;
m_CascadeShadowBorders[2] = cascadeShadowBorder2;
m_CascadeShadowBorders[3] = cascadeShadowBorder3;
return m_CascadeShadowBorders;
}
}
[Tooltip("Maximum shadow distance for all light types.")]
public NoInterpMinFloatParameter maxShadowDistance = new NoInterpMinFloatParameter(500.0f, 0.0f);
[Tooltip("Number of splits for cascaded shadow maps.")]
public NoInterpClampedIntParameter cascadeShadowSplitCount = new NoInterpClampedIntParameter(4, 1, 4);
[Tooltip("Ratio of the first split against max shadow distance.")]
public NoInterpClampedFloatParameter cascadeShadowSplit0 = new NoInterpClampedFloatParameter(0.05f, 0.0f, 1.0f);
[Tooltip("Ratio of the second split against max shadow distance.")]
public NoInterpClampedFloatParameter cascadeShadowSplit1 = new NoInterpClampedFloatParameter(0.15f, 0.0f, 1.0f);
[Tooltip("Ratio of the third split against max shadow distance.")]
public NoInterpClampedFloatParameter cascadeShadowSplit2 = new NoInterpClampedFloatParameter(0.3f, 0.0f, 1.0f);
[Tooltip("Border size between first and second split.")]
public NoInterpMinFloatParameter cascadeShadowBorder0 = new NoInterpMinFloatParameter(0.0f, 0.0f);
[Tooltip("Border size between second and third split.")]
public NoInterpMinFloatParameter cascadeShadowBorder1 = new NoInterpMinFloatParameter(0.0f, 0.0f);
[Tooltip("Border size between third and last split.")]
public NoInterpMinFloatParameter cascadeShadowBorder2 = new NoInterpMinFloatParameter(0.0f, 0.0f);
[Tooltip("Border size at the end of last split.")]
public NoInterpMinFloatParameter cascadeShadowBorder3 = new NoInterpMinFloatParameter(0.0f, 0.0f);
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/HDRISky/HDRISkyRenderer.cs


public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderForCubemap)
{
m_SkyHDRIMaterial.SetTexture(HDShaderIDs._Cubemap, m_HdriSkyParams.skyHDRI);
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_HdriSkyParams.exposure, m_HdriSkyParams.multiplier, m_HdriSkyParams.rotation, 0.0f));
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_HdriSkyParams.exposure, m_HdriSkyParams.multiplier, -m_HdriSkyParams.rotation, 0.0f)); // -rotation to match Legacy...
// This matrix needs to be updated at the draw call frequency.
m_PropertyBlock.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/ProceduralSky/ProceduralSkyRenderer.cs


sunDirection = -builtinParams.sunLight.transform.forward;
}
m_SkyProceduralMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_ProceduralSkyParams.exposure, m_ProceduralSkyParams.multiplier, m_ProceduralSkyParams.rotation, 0.0f));
m_SkyProceduralMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_ProceduralSkyParams.exposure, m_ProceduralSkyParams.multiplier, 0.0f, 0.0f));
m_SkyProceduralMaterial.SetFloat(_SunSizeParam, m_ProceduralSkyParams.sunSize);
m_SkyProceduralMaterial.SetFloat(_SunSizeConvergenceParam, m_ProceduralSkyParams.sunSizeConvergence);
m_SkyProceduralMaterial.SetFloat(_AtmoshpereThicknessParam, m_ProceduralSkyParams.atmosphereThickness);

11
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


// SdotL * invAngleRange + (-cosOuterAngle * invAngleRange)
// If we precompute the terms in a MAD instruction
float cosOuterAngle = Mathf.Cos(Mathf.Deg2Rad * lightData.spotAngle * 0.5f);
float cosInneAngle = Mathf.Cos(LightmapperUtils.ExtractInnerCone(lightData.light) * 0.5f);
float smoothAngleRange = Mathf.Max(0.001f, cosInneAngle - cosOuterAngle);
// We neeed to do a null check for particle lights
// This should be changed in the future
// Particle lights will use an inline function
float cosInnerAngle;
if (lightData.light != null)
cosInnerAngle = Mathf.Cos(LightmapperUtils.ExtractInnerCone(lightData.light) * 0.5f);
else
cosInnerAngle = Mathf.Cos((2.0f * Mathf.Atan(Mathf.Tan(lightData.spotAngle * 0.5f * Mathf.Deg2Rad) * (64.0f - 18.0f) / 64.0f)) * 0.5f);
float smoothAngleRange = Mathf.Max(0.001f, cosInnerAngle - cosOuterAngle);
float invAngleRange = 1.0f / smoothAngleRange;
float add = -cosOuterAngle * invAngleRange;
lightSpotAttenuation = new Vector4(invAngleRange, add, 0.0f);

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs


{
public bool Equals(VisibleLight x, VisibleLight y)
{
if (x.light == null && y.light == null)
return true;
if (x.light == null || y.light == null)
return false;
if (obj.light == null) // Particle light weirdness
return obj.GetHashCode();
return obj.light.GetInstanceID();
}
}

21
ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-DefaultParticle.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Lightweight-DefaultParticle
m_Shader: {fileID: 4800000, guid: b7839dad95683814aa64166edc107ae2, type: 3}
m_ShaderKeywords:
m_Shader: {fileID: 4800000, guid: 0406db5a14f94604a8c57ccfbc9f3b46, type: 3}
m_ShaderKeywords: _ALPHABLEND_ON
m_CustomRenderQueue: -1
stringTagMap: {}
m_CustomRenderQueue: 3000
stringTagMap:
RenderType: Transparent
disabledShaderPasses:
- ALWAYS
m_SavedProperties:

- _CameraFadingEnabled: 0
- _CameraFarFadeDistance: 2
- _CameraNearFadeDistance: 1
- _ColorMode: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailNormalMapScale: 1

- _DistortionStrengthScaled: 0
- _DstBlend: 0
- _DstBlend: 10
- _EmissionEnabled: 0
- _FlipbookMode: 0
- _GlossMapScale: 1

- _LightingEnabled: 1
- _LightingEnabled: 0
- _Mode: 0
- _Mode: 2
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0

- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlend: 5
- _ZWrite: 1
- _ZWrite: 0
- _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}

8
ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner.meta


fileFormatVersion: 2
guid: 87845c683f4fa7546a3910e641768da8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

208
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardsToHDLitMaterialUpgrader.cs


using UnityEngine;
using System.Collections.Generic;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class StandardsToHDLitMaterialUpgrader : MaterialUpgrader
{
static readonly string Standard = "Standard";
static readonly string Standard_Spec = "Standard (Specular setup)";
static readonly string Standard_Rough = "Standard (Roughness setup)";
public StandardsToHDLitMaterialUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer = null)
{
RenameShader(sourceShaderName, destShaderName, finalizer);
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameFloat("_BumpScale", "_NormalScale");
RenameTexture("_ParallaxMap", "_HeightMap");
RenameTexture("_EmissionMap", "_EmissiveColorMap");
RenameTexture("_DetailAlbedoMap", "_DetailMap");
RenameFloat("_UVSec", "_UVDetail");
SetFloat("_LinkDetailsWithBase", 0);
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameFloat("_Cutoff", "_AlphaCutoff");
RenameKeywordToFloat("_ALPHATEST_ON", "_AlphaCutoffEnable", 1f, 0f);
if (sourceShaderName == Standard)
{
SetFloat("_MaterialID", 1f);
}
if (sourceShaderName == Standard_Spec)
{
SetFloat("_MaterialID", 4f);
RenameColor("_SpecColor", "_SpecularColor");
RenameTexture("_SpecGlossMap", "_SpecularColorMap");
}
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset;
base.Convert(srcMaterial, dstMaterial);
// ---------- Mask Map ----------
// Metallic
bool hasMetallic = false;
Texture metallicMap;
if ( (srcMaterial.shader.name == Standard) || (srcMaterial.shader.name == Standard_Rough) )
{
hasMetallic = srcMaterial.GetTexture("_MetallicGlossMap") != null;
if (hasMetallic) metallicMap = TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white);
}
else
metallicMap = Texture2D.blackTexture;
// Occlusion
bool hasOcclusion = srcMaterial.GetTexture("_OcclusionMap") != null;
Texture occlusionMap;
if (hasOcclusion) occlusionMap = TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white);
// Detail Mask
bool hasDetailMask = srcMaterial.GetTexture("_DetailMask") != null;
Texture detailMaskMap;
if (hasDetailMask) detailMaskMap = TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white);
// Smoothness
bool hasSmoothness = false;
Texture2D smoothnessMap = TextureCombiner.TextureFromColor(Color.grey);
if (srcMaterial.shader.name == Standard_Rough)
hasSmoothness = srcMaterial.GetTexture("_SpecGlossMap")!=null;
else
{
string smoothnessTextureChannel = "_MainTex";
if (srcMaterial.shader.name == Standard_Rough)
smoothnessMap = (Texture2D) TextureCombiner.GetTextureSafe(srcMaterial, "_SpecGlossMap", Color.grey);
else
{
if ( srcMaterial.GetFloat("_SmoothnessTextureChannel") == 0 )
{
if (srcMaterial.shader.name == Standard) smoothnessTextureChannel = "_MetallicGlossMap";
if (srcMaterial.shader.name == Standard_Spec) smoothnessTextureChannel = "_SpecGlossMap";
}
smoothnessMap = (Texture2D) srcMaterial.GetTexture( smoothnessTextureChannel );
if (smoothnessMap == null || !TextureCombiner.TextureHasAlpha(smoothnessMap))
{
hasSmoothness = true;
smoothnessMap = TextureCombiner.TextureFromColor(Color.white * srcMaterial.GetFloat("_Glossiness"));
}
}
}
// Build the mask map
if ( hasMetallic || hasOcclusion || hasDetailMask || hasSmoothness )
{
Texture2D maskMap;
TextureCombiner maskMapCombiner = new TextureCombiner(
TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white), 4, // Metallic
TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white), 4, // Occlusion
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white), 4, // Detail Mask
smoothnessMap, (srcMaterial.shader.name == Standard_Rough)?-4:3 // Smoothness Texture
);
string maskMapPath = AssetDatabase.GetAssetPath(srcMaterial);
maskMapPath = maskMapPath.Remove(maskMapPath.Length-4) + "_MaskMap.png";
maskMap = maskMapCombiner.Combine( maskMapPath );
dstMaterial.SetTexture("_MaskMap", maskMap);
}
dstMaterial.SetFloat("_AORemapMin", 1f - srcMaterial.GetFloat("_OcclusionStrength"));
// Specular Setup Specific
if (srcMaterial.shader.name == Standard_Spec)
{
// if there is a specular map, change the specular color to white
if (srcMaterial.GetTexture("_SpecGlossMap") != null ) dstMaterial.SetColor("_SpecularColor", Color.white);
}
// ---------- Height Map ----------
bool hasHeightMap = srcMaterial.GetTexture("_ParallaxMap") != null;
if (hasHeightMap) // Enable Parallax Occlusion Mapping
{
dstMaterial.SetFloat("_DisplacementMode", 2);
dstMaterial.SetFloat("_HeightPoMAmplitude", srcMaterial.GetFloat("_Parallax") * 2f);
}
// ---------- Detail Map ----------
bool hasDetailAlbedo = srcMaterial.GetTexture("_DetailAlbedoMap") != null;
bool hasDetailNormal = srcMaterial.GetTexture("_DetailNormalMap") != null;
if ( hasDetailAlbedo || hasDetailNormal )
{
Texture2D detailMap;
TextureCombiner detailCombiner = new TextureCombiner(
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailAlbedoMap", Color.grey), 4, // Albedo (overlay)
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 1, // Normal Y
TextureCombiner.midGrey, 1, // Smoothness
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 0 // Normal X
);
string detailMapPath = AssetDatabase.GetAssetPath(srcMaterial);
detailMapPath = detailMapPath.Remove(detailMapPath.Length-4) + "_DetailMap.png";
detailMap = detailCombiner.Combine( detailMapPath );
dstMaterial.SetTexture("_DetailMap", detailMap);
}
// Blend Mode
int previousBlendMode = srcMaterial.GetInt("_Mode");
switch (previousBlendMode)
{
case 0: // Opaque
dstMaterial.SetFloat("_SurfaceType", 0);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
break;
case 1: // Cutout
dstMaterial.SetFloat("_SurfaceType", 0);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 1);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
break;
case 2: // Fade -> Alpha + Disable preserve specular
dstMaterial.SetFloat("_SurfaceType", 1);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 0);
break;
case 3: // Transparent -> Alpha
dstMaterial.SetFloat("_SurfaceType", 1);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
break;
}
// Emission: Convert the HDR emissive color to ldr color + intensity
Color hdrEmission = srcMaterial.GetColor("_EmissionColor");
float intensity = Mathf.Max(hdrEmission.r, Mathf.Max(hdrEmission.g, hdrEmission.b));
if (intensity > 1f)
{
hdrEmission.r /= intensity;
hdrEmission.g /= intensity;
hdrEmission.b /= intensity;
}
else
intensity = 1f;
intensity = Mathf.Pow(intensity, 2.2f); // Gamma to Linear conversion
dstMaterial.SetColor("_EmissiveColor", hdrEmission);
dstMaterial.SetFloat("_EmissiveIntensity", intensity);
HDEditorUtils.ResetMaterialKeywords(dstMaterial);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardsToHDLitMaterialUpgrader.cs.meta


fileFormatVersion: 2
guid: 3892a7f1ec73e554fb1bd8be6a6d3400
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

44
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Unlit/UnlitsToHDUnlitUpgrader.cs


using UnityEngine;
using System.Collections.Generic;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class UnlitsToHDUnlitUpgrader : MaterialUpgrader
{
string Unlit_Color = "Unlit/Color";
string Unlit_Texture = "Unlit/Texture";
string Unlit_Transparent = "Unlit/Transparent";
string Unlit_Cutout = "Unlit/Transparent Cutout";
public UnlitsToHDUnlitUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer = null)
{
RenameShader(sourceShaderName, destShaderName, finalizer);
if (sourceShaderName == Unlit_Color)
RenameColor("_Color", "_UnlitColor");
else // all other unlit have a texture
RenameTexture("_MainTex", "_UnlitColorMap");
if (sourceShaderName == Unlit_Cutout)
{
RenameFloat("_Cutoff", "_AlphaCutoff");
SetFloat("_AlphaCutoffEnable", 1f);
}
else
SetFloat("_AlphaCutoffEnable", 0f);
SetFloat("_SurfaceType", (sourceShaderName == Unlit_Transparent)? 1f : 0f );
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
//dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset;
base.Convert(srcMaterial, dstMaterial);
HDEditorUtils.ResetMaterialKeywords(dstMaterial);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Unlit/UnlitsToHDUnlitUpgrader.cs.meta


fileFormatVersion: 2
guid: b6a8dfccb93f0a946a7bc1521ab32f43
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

57
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/ContactShadowsEditor.cs


using System.Collections;
using UnityEngine;
using UnityEditor;
using UnityEditor.Experimental.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CanEditMultipleObjects]
[VolumeComponentEditor(typeof(ContactShadows))]
public class ContactShadowsEditor : VolumeComponentEditor
{
public readonly GUIContent contactShadow = new GUIContent("Contact Shadows");
public readonly GUIContent contactShadowLength = new GUIContent("Length", "Length of rays used to gather contact shadows in world units.\nZero will disable the feature.");
public readonly GUIContent contactShadowDistanceScaleFactor = new GUIContent("Distance Scale Factor", "Contact Shadows are scaled up with distance. Use this parameter to dampen this effect.");
public readonly GUIContent contactShadowMaxDistance = new GUIContent("Max Distance", "Distance from the camera in world units at which contact shadows are faded out to zero.");
public readonly GUIContent contactShadowFadeDistance = new GUIContent("Fade Distance", "Distance in world units over which the contact shadows are faded out (see Max Distance).");
public readonly GUIContent contactShadowSampleCount = new GUIContent("Sample Count", "Number of samples when ray casting.");
SerializedDataParameter m_Enable;
SerializedDataParameter m_Length;
SerializedDataParameter m_DistanceScaleFactor;
SerializedDataParameter m_MaxDistance;
SerializedDataParameter m_FadeDistance;
SerializedDataParameter m_SampleCount;
public override void OnEnable()
{
var o = new PropertyFetcher<ContactShadows>(serializedObject);
m_Enable = Unpack(o.Find(x => x.enable));
m_Length = Unpack(o.Find(x => x.length));
m_DistanceScaleFactor = Unpack(o.Find(x => x.distanceScaleFactor));
m_MaxDistance = Unpack(o.Find(x => x.maxDistance));
m_FadeDistance = Unpack(o.Find(x => x.fadeDistance));
m_SampleCount = Unpack(o.Find(x => x.sampleCount));
}
public override void OnInspectorGUI()
{
PropertyField(m_Enable, CoreEditorUtils.GetContent("Enable"));
if (!m_Enable.value.hasMultipleDifferentValues)
{
using (new EditorGUI.DisabledGroupScope(!m_Enable.value.boolValue))
{
PropertyField(m_Length, CoreEditorUtils.GetContent("Length|Length of rays used to gather contact shadows in world units."));
PropertyField(m_DistanceScaleFactor, CoreEditorUtils.GetContent("Distance Scale Factor|Contact Shadows are scaled up with distance. Use this parameter to dampen this effect."));
PropertyField(m_MaxDistance, CoreEditorUtils.GetContent("Max Distance|Distance from the camera in world units at which contact shadows are faded out to zero."));
PropertyField(m_FadeDistance, CoreEditorUtils.GetContent("Fade Distance|Distance in world units over which the contact shadows fade out (see Max Distance)."));
PropertyField(m_SampleCount, CoreEditorUtils.GetContent("Sample Count|Number of samples when ray casting."));
}
}
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/ContactShadowsEditor.cs.meta


fileFormatVersion: 2
guid: f5a268c81ffd7634db3a9a0cb30af239
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

66
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/HDShadowSettingsEditor.cs


using System.Collections;
using UnityEngine;
using UnityEditor;
using UnityEditor.Experimental.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CanEditMultipleObjects]
[VolumeComponentEditor(typeof(HDShadowSettings))]
public class HDShadowSettingsEditor : VolumeComponentEditor
{
SerializedDataParameter m_MaxShadowDistance;
SerializedDataParameter m_CascadeShadowSplitCount;
SerializedDataParameter[] m_CascadeShadowSplits = new SerializedDataParameter[3];
SerializedDataParameter[] m_CascadeShadowBorders = new SerializedDataParameter[4];
// For now we don't use borders so we hide the UI.
bool m_bShowBorders = false;
public override void OnEnable()
{
var o = new PropertyFetcher<HDShadowSettings>(serializedObject);
m_MaxShadowDistance = Unpack(o.Find(x => x.maxShadowDistance));
m_CascadeShadowSplitCount = Unpack(o.Find(x => x.cascadeShadowSplitCount));
m_CascadeShadowSplits[0] = Unpack(o.Find(x => x.cascadeShadowSplit0));
m_CascadeShadowSplits[1] = Unpack(o.Find(x => x.cascadeShadowSplit1));
m_CascadeShadowSplits[2] = Unpack(o.Find(x => x.cascadeShadowSplit2));
m_CascadeShadowBorders[0] = Unpack(o.Find(x => x.cascadeShadowBorder0));
m_CascadeShadowBorders[1] = Unpack(o.Find(x => x.cascadeShadowBorder1));
m_CascadeShadowBorders[2] = Unpack(o.Find(x => x.cascadeShadowBorder2));
m_CascadeShadowBorders[3] = Unpack(o.Find(x => x.cascadeShadowBorder3));
}
public override void OnInspectorGUI()
{
PropertyField(m_MaxShadowDistance, CoreEditorUtils.GetContent("Max Distance"));
EditorGUILayout.Space();
PropertyField(m_CascadeShadowSplitCount, CoreEditorUtils.GetContent("Cascade Count"));
if (!m_CascadeShadowSplitCount.value.hasMultipleDifferentValues)
{
EditorGUI.indentLevel++;
int splitCount = m_CascadeShadowSplitCount.value.intValue;
for (int i = 0; i < splitCount - 1; i++)
{
PropertyField(m_CascadeShadowSplits[i], CoreEditorUtils.GetContent(string.Format("Split {0}", i + 1)));
}
if(m_bShowBorders)
{
EditorGUILayout.Space();
for (int i = 0; i < splitCount; i++)
{
PropertyField(m_CascadeShadowBorders[i], CoreEditorUtils.GetContent(string.Format("Border {0}", i + 1)));
}
}
EditorGUI.indentLevel--;
}
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/HDShadowSettingsEditor.cs.meta


fileFormatVersion: 2
guid: d8efece7d7ee34048a4b794bf3234ca3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Shadows/ContactShadows.cs


using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public class ContactShadows : VolumeComponent
{
// Contact shadows
public BoolParameter enable = new BoolParameter(false);
public ClampedFloatParameter length = new ClampedFloatParameter(0.15f, 0.0f, 1.0f);
public ClampedFloatParameter distanceScaleFactor = new ClampedFloatParameter(0.5f, 0.0f, 1.0f);
public MinFloatParameter maxDistance = new MinFloatParameter(50.0f, 0.0f);
public MinFloatParameter fadeDistance = new MinFloatParameter(5.0f, 0.0f);
public NoInterpClampedIntParameter sampleCount = new NoInterpClampedIntParameter(8, 4, 64);
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Shadows/ContactShadows.cs.meta


fileFormatVersion: 2
guid: 56b145d2b9ee1ac4f846968484e7485a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

11
ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.cs.meta


fileFormatVersion: 2
guid: 1a9d1eab24683cb42a7c52b9d850d154
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.shader.meta


fileFormatVersion: 2
guid: 8486e1ca5cc45c34c94df540d5676ec3
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

282
ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class TextureCombiner
{
public static Texture2D _midGrey;
public static Texture2D midGrey
{
get
{
if (_midGrey == null)
_midGrey = TextureFromColor(Color.grey);
return _midGrey;
}
}
private static Dictionary<Color, Texture2D> singleColorTextures = new Dictionary<Color, Texture2D>();
public static Texture2D TextureFromColor(Color color)
{
if (color == Color.white) return Texture2D.whiteTexture;
if (color == Color.black) return Texture2D.blackTexture;
bool makeTexture = !singleColorTextures.ContainsKey(color);
if (!makeTexture)
makeTexture = (singleColorTextures[color] == null);
if (makeTexture)
{
Texture2D tex = new Texture2D(1,1, TextureFormat.ARGB32, false, true);
tex.SetPixel(0,0,color);
tex.Apply();
singleColorTextures[color] = tex;
}
return singleColorTextures[color];
}
public static Texture GetTextureSafe( Material srcMaterial, string propertyName, Color fallback)
{
return GetTextureSafe( srcMaterial, propertyName, TextureFromColor(fallback) );
}
public static Texture GetTextureSafe( Material srcMaterial, string propertyName, Texture fallback)
{
if (!srcMaterial.HasProperty(propertyName))
return fallback;
Texture tex = srcMaterial.GetTexture(propertyName);
if (tex == null)
return fallback;
else
return tex;
}
public static TextureFormat[] TextureFormatsWithouthAlpha = new TextureFormat[]{
TextureFormat.ASTC_RGB_10x10 ,
TextureFormat.ASTC_RGB_12x12 ,
TextureFormat.ASTC_RGB_4x4 ,
TextureFormat.ASTC_RGB_5x5 ,
TextureFormat.ASTC_RGB_6x6 ,
TextureFormat.ASTC_RGB_8x8 ,
TextureFormat.BC4 ,
TextureFormat.BC5 ,
TextureFormat.DXT1 ,
TextureFormat.DXT1Crunched ,
TextureFormat.EAC_R ,
TextureFormat.EAC_R_SIGNED ,
TextureFormat.EAC_RG ,
TextureFormat.EAC_RG_SIGNED ,
TextureFormat.ETC2_RGB ,
TextureFormat.ETC_RGB4 ,
TextureFormat.ETC_RGB4_3DS ,
TextureFormat.ETC_RGB4Crunched ,
TextureFormat.PVRTC_RGB2 ,
TextureFormat.PVRTC_RGB4 ,
TextureFormat.R16 ,
TextureFormat.R8 ,
TextureFormat.RFloat ,
TextureFormat.RG16 ,
TextureFormat.RGB24 ,
TextureFormat.RGB565 ,
TextureFormat.RGB9e5Float ,
TextureFormat.RGFloat ,
TextureFormat.RGHalf ,
TextureFormat.RHalf ,
TextureFormat.YUY2
};
public static bool TextureHasAlpha ( Texture2D tex )
{
if (tex == null) return false;
bool o = true;
int i=0;
while ( i < TextureFormatsWithouthAlpha.Length && o)
{
o = tex.format != TextureFormatsWithouthAlpha[i];
++i;
}
return o;
}
private Texture m_rSource;
private Texture m_gSource;
private Texture m_bSource;
private Texture m_aSource;
// Chanels are : r=0, g=1, b=2, a=3, greyscale from rgb = 4
// If negative, the chanel is inverted
private int m_rChanel;
private int m_gChanel;
private int m_bChanel;
private int m_aChanel;
// Chanels remaping
private Vector4[] m_remapings = new Vector4[]{
new Vector4(0f, 1f, 0f, 0f),
new Vector4(0f, 1f, 0f, 0f),
new Vector4(0f, 1f, 0f, 0f),
new Vector4(0f, 1f, 0f, 0f)
};
private bool m_bilinearFilter;
private Dictionary<Texture, Texture> m_RawTextures;
public TextureCombiner( Texture rSource, int rChanel, Texture gSource, int gChanel, Texture bSource, int bChanel, Texture aSource, int aChanel, bool bilinearFilter = true )
{
m_rSource = rSource;
m_gSource = gSource;
m_bSource = bSource;
m_aSource = aSource;
m_rChanel = rChanel;
m_gChanel = gChanel;
m_bChanel = bChanel;
m_aChanel = aChanel;
m_bilinearFilter = bilinearFilter;
}
public void SetRemapping( int channel, float min, float max)
{
if (channel > 3 || channel < 0) return;
m_remapings[channel].x = min;
m_remapings[channel].y = max;
}
public Texture2D Combine( string savePath )
{
int xMin = int.MaxValue;
int yMin = int.MaxValue;
if (m_rSource.width > 4 && m_rSource.width < xMin) xMin = m_rSource.width;
if (m_gSource.width > 4 && m_gSource.width < xMin) xMin = m_gSource.width;
if (m_bSource.width > 4 && m_bSource.width < xMin) xMin = m_bSource.width;
if (m_aSource.width > 4 && m_aSource.width < xMin) xMin = m_aSource.width;
if (xMin == int.MaxValue) xMin = 4;
if (m_rSource.height > 4 && m_rSource.height < yMin) yMin = m_rSource.height;
if (m_gSource.height > 4 && m_gSource.height < yMin) yMin = m_gSource.height;
if (m_bSource.height > 4 && m_bSource.height < yMin) yMin = m_bSource.height;
if (m_aSource.height > 4 && m_aSource.height < yMin) yMin = m_aSource.height;
if (yMin == int.MaxValue) yMin = 4;
Texture2D combined = new Texture2D(xMin, yMin, TextureFormat.RGBAFloat, true, true);
combined.hideFlags = HideFlags.DontUnloadUnusedAsset;
Material combinerMaterial = new Material(Shader.Find("Hidden/SRP_Core/TextureCombiner"));
combinerMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset;
combinerMaterial.SetTexture("_RSource", GetRawTexture(m_rSource));
combinerMaterial.SetTexture("_GSource", GetRawTexture(m_gSource));
combinerMaterial.SetTexture("_BSource", GetRawTexture(m_bSource));
combinerMaterial.SetTexture("_ASource", GetRawTexture(m_aSource));
combinerMaterial.SetFloat("_RChannel", m_rChanel);
combinerMaterial.SetFloat("_GChannel", m_gChanel);
combinerMaterial.SetFloat("_BChannel", m_bChanel);
combinerMaterial.SetFloat("_AChannel", m_aChanel);
combinerMaterial.SetVector("_RRemap", m_remapings[0]);
combinerMaterial.SetVector("_GRemap", m_remapings[1]);
combinerMaterial.SetVector("_BRemap", m_remapings[2]);
combinerMaterial.SetVector("_ARemap", m_remapings[3]);
RenderTexture combinedRT = new RenderTexture(xMin, yMin, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.sRGB);
Graphics.Blit(Texture2D.whiteTexture, combinedRT, combinerMaterial);
// Readback the render texture
RenderTexture previousActive = RenderTexture.active;
RenderTexture.active = combinedRT;
combined.ReadPixels(new Rect(0, 0, xMin, yMin), 0, 0, false);
combined.Apply();
RenderTexture.active = previousActive;
byte[] bytes = new byte[0];
if (savePath.EndsWith("png"))
bytes = ImageConversion.EncodeToPNG(combined);
if (savePath.EndsWith("exr"))
bytes = ImageConversion.EncodeToEXR(combined);
if (savePath.EndsWith("jpg"))
bytes = ImageConversion.EncodeToJPG(combined);
string systemPath = Path.Combine(Application.dataPath.Remove(Application.dataPath.Length-6), savePath);
File.WriteAllBytes(systemPath, bytes);
Object.DestroyImmediate(combined);
AssetDatabase.ImportAsset(savePath);
TextureImporter combinedImporter = (TextureImporter) AssetImporter.GetAtPath(savePath);
combinedImporter.sRGBTexture = false;
combinedImporter.SaveAndReimport();
if (savePath.EndsWith("exr"))
{
// The options for the platform string are: "Standalone", "iPhone", "Android", "WebGL", "Windows Store Apps", "PSP2", "PS4", "XboxOne", "Nintendo 3DS", "WiiU", "tvOS".
combinedImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings(){name = "Standalone", format = TextureImporterFormat.DXT5, overridden = true });
}
combined = AssetDatabase.LoadAssetAtPath<Texture2D>(savePath);
//cleanup "raw" textures
foreach( KeyValuePair<Texture, Texture> prop in m_RawTextures )
{
if (AssetDatabase.Contains(prop.Value))
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(prop.Value));
}
Object.DestroyImmediate(combinerMaterial);
m_RawTextures.Clear();
return combined;
}
private Texture GetRawTexture (Texture original, bool sRGB = false)
{
if (m_RawTextures == null) m_RawTextures = new Dictionary<Texture, Texture>();
if (!m_RawTextures.ContainsKey(original))
{
if ( AssetDatabase.Contains(original))
{
string path = AssetDatabase.GetAssetPath(original);
string rawPath = "Assets/raw_"+Path.GetFileName(path);
AssetDatabase.CopyAsset(path, rawPath);
AssetDatabase.ImportAsset(rawPath);
TextureImporter rawImporter = (TextureImporter) TextureImporter.GetAtPath(rawPath);
rawImporter.textureType = TextureImporterType.Default;
rawImporter.mipmapEnabled = false;
rawImporter.isReadable = true;
rawImporter.filterMode = m_bilinearFilter? FilterMode.Bilinear : FilterMode.Point;
rawImporter.npotScale = TextureImporterNPOTScale.None;
rawImporter.wrapMode = TextureWrapMode.Clamp;
rawImporter.sRGBTexture = sRGB;
rawImporter.maxTextureSize = 8192;
rawImporter.textureCompression = TextureImporterCompression.Uncompressed;
rawImporter.SaveAndReimport();
m_RawTextures.Add(original, AssetDatabase.LoadAssetAtPath<Texture>(rawPath));
}
else
m_RawTextures.Add(original, original);
}
return m_RawTextures[original];
}
}

98
ScriptableRenderPipeline/Core/CoreRP/Editor/TextureCombiner/TextureCombiner.shader


Shader "Hidden/SRP_Core/TextureCombiner"
{
Properties
{
// Chanels are : r=0, g=1, b=2, a=3, greyscale from rgb = 4
// If the chanel value is negative, we invert the value
[Linear][NoScaleOffset] _RSource ("R Source", 2D) = "white" {}
_RChannel ("R Channel", float) = 0
_RRemap ("R Remap", Vector) = (0, 1, 0, 0)
[Linear][NoScaleOffset] _GSource ("G Source", 2D) = "white" {}
_GChannel ("G Channel", float) = 1
_GRemap ("G Remap", Vector) = (0, 1, 0, 0)
[Linear][NoScaleOffset] _BSource ("B Source", 2D) = "white" {}
_BChannel ("B Channel", float) = 2
_BRemap ("B Remap", Vector) = (0, 1, 0, 0)
[Linear][NoScaleOffset] _ASource ("A Source", 2D) = "white" {}
_AChannel ("A Channel", float) = 3
_ARemap ("A Remap", Vector) = (0, 1, 0, 0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _RSource, _GSource, _BSource, _ASource;
float _RChannel, _GChannel, _BChannel, _AChannel;
float4 _RRemap, _GRemap, _BRemap, _ARemap;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
float PlotSourcetoChanel(float4 source, float param, float2 remap)
{
if (param < 0 )
{
param = -param;
source = float4(1,1,1,1) - source;
}
float o;
if (param >= 4)
o = source.r * 0.3 + source.g * 0.59 + source.b * 0.11; // Photoshop desaturation : G*.59+R*.3+B*.11
else
o = source[param];
return o * ( remap.y - remap.x) + remap.x ;
}
float PlotSourcetoChanel(float4 source, float param)
{
return PlotSourcetoChanel(source, param, float2(0,1) );
}
float4 frag (v2f i) : SV_Target
{
float4 col = float4(0,0,0,0);
col.r = PlotSourcetoChanel( tex2D(_RSource, i.uv), _RChannel, _RRemap );
col.g = PlotSourcetoChanel( tex2D(_GSource, i.uv), _GChannel, _GRemap );
col.b = PlotSourcetoChanel( tex2D(_BSource, i.uv), _BChannel, _BRemap );
col.a = PlotSourcetoChanel( tex2D(_ASource, i.uv), _AChannel, _ARemap );
return col;
}
ENDCG
}
}
}

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardSpecularToHDLitMaterialUpgrader.cs.meta


fileFormatVersion: 2
guid: 775bef174b1e2ed47972a143845e1191
timeCreated: 1479911618
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardToHDLitMaterialUpgrader.cs.meta


fileFormatVersion: 2
guid: fedbd6bc5d95f4d768cb8077e8454b4e
timeCreated: 1479851295
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

45
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardToHDLitMaterialUpgrader.cs


using UnityEngine;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class StandardToHDLitMaterialUpgrader : MaterialUpgrader
{
public StandardToHDLitMaterialUpgrader() : this("Standard", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass) {}
public StandardToHDLitMaterialUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer)
{
RenameShader(sourceShaderName, destShaderName, finalizer);
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameFloat("_BumpScale", "_NormalScale");
RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameFloat("_Cutoff", "_AlphaCutoff");
RenameKeywordToFloat("_ALPHATEST_ON", "_AlphaCutoffEnable", 1f, 0f);
// the HD renderloop packs detail albedo and detail normals into a single texture.
// mapping the detail normal map, if any, to the detail map, should do the right thing if
// there is no detail albedo.
RenameTexture("_DetailNormalMap", "_DetailMap");
// Metallic uses [Gamma] attribute in standard shader but not in Lit.
// @Seb: Should we convert?
RenameFloat("_Metallic", "_Metallic");
//@TODO: Seb. Why do we multiply color by intensity
// in shader when we can just store a color?
// builtinData.emissiveColor * builtinData.emissiveIntensity
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
base.Convert(srcMaterial, dstMaterial);
//@TODO: Find a good way of setting up keywords etc from properties.
// Code should be shared with material UI code.
}
}
}

43
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/StandardSpecularToHDLitMaterialUpgrader.cs


using UnityEngine;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class StandardSpecularToHDLitMaterialUpgrader : MaterialUpgrader
{
public StandardSpecularToHDLitMaterialUpgrader() : this("Standard (Specular setup)", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass) {}
public StandardSpecularToHDLitMaterialUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer)
{
RenameShader(sourceShaderName, destShaderName, finalizer);
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameFloat("_BumpScale", "_NormalScale");
RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameFloat("_Cutoff", "_AlphaCutoff");
RenameKeywordToFloat("_ALPHATEST_ON", "_AlphaCutoffEnable", 1f, 0f);
// the HD renderloop packs detail albedo and detail normals into a single texture.
// mapping the detail normal map, if any, to the detail map, should do the right thing if
// there is no detail albedo.
RenameTexture("_DetailNormalMap", "_DetailMap");
// Anything reasonable that can be done here?
//RenameFloat("_SpecColor", ...);
//@TODO: Seb. Why do we multiply color by intensity
// in shader when we can just store a color?
// builtinData.emissiveColor * builtinData.emissiveIntensity
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
base.Convert(srcMaterial, dstMaterial);
//@TODO: Find a good way of setting up keywords etc from properties.
// Code should be shared with material UI code.
}
}
}
正在加载...
取消
保存