浏览代码

Merge remote-tracking branch 'refs/remotes/origin/master' into Branch_Batching2

/Branch_batcher
Arnaud Carre 8 年前
当前提交
833d6910
共有 52 个文件被更改,包括 3282 次插入431 次删除
  1. 1
      Assets/ScriptableRenderPipeline/AdditionalLightData.cs
  2. 25
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  3. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
  4. 11
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset
  5. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  6. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  7. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  8. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  9. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  10. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  11. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  12. 149
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  13. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  14. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  15. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl
  16. 146
      Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl
  17. 18
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl
  18. 8
      Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl
  19. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl
  20. 14
      Assets/ScriptableRenderPipeline/ShaderLibrary/SampleUVMappingInternal.hlsl
  21. 16
      Assets/ScriptableRenderPipeline/common/TextureCache.cs
  22. 758
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity
  23. 96
      ProjectSettings/InputManager.asset
  24. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SSSProfile.meta
  25. 9
      Assets/ScriptableRenderPipeline/common/Debugging.meta
  26. 197
      Assets/TestScenes/HDTest/GraphicTest/Two Sided/Material/GroundLeaf_DoubleSidedFlipSSS.mat
  27. 8
      Assets/TestScenes/HDTest/GraphicTest/Two Sided/Material/GroundLeaf_DoubleSidedFlipSSS.mat.meta
  28. 37
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SSSProfile/FoliageSSSProfile.asset
  29. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SSSProfile/FoliageSSSProfile.asset.meta
  30. 288
      Assets/ScriptableRenderPipeline/common/Debugging/DebugActionManager.cs
  31. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugActionManager.cs.meta
  32. 235
      Assets/ScriptableRenderPipeline/common/Debugging/DebugItemDrawer.cs
  33. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugItemDrawer.cs.meta
  34. 267
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenu.cs
  35. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenu.cs.meta
  36. 453
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuItemUI.cs
  37. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuItemUI.cs.meta
  38. 194
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuManager.cs
  39. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuManager.cs.meta
  40. 178
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUI.cs
  41. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUI.cs.meta
  42. 57
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUpdater.cs
  43. 12
      Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUpdater.cs.meta
  44. 138
      Assets/ScriptableRenderPipeline/common/Debugging/Debugging.cs
  45. 9
      Assets/ScriptableRenderPipeline/common/Debugging/Editor.meta
  46. 12
      Assets/ScriptableRenderPipeline/common/Debugging/Editor/DebugMenuEditor.cs.meta
  47. 68
      Assets/ScriptableRenderPipeline/common/Debugging/Editor/DebugMenuEditor.cs
  48. 138
      Assets/ScriptableRenderPipeline/common/Debugging.cs
  49. 0
      /Assets/ScriptableRenderPipeline/common/Debugging/Debugging.cs.meta

1
Assets/ScriptableRenderPipeline/AdditionalLightData.cs


public bool affectSpecular = true;
public LightArchetype archetype = LightArchetype.Punctual;
public bool isDoubleSided = false; // Rectangular area lights only
[Range(0.0f, 20.0f)]
public float lightLength = 0.0f; // Area & projector lights

25
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


using System.Collections;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

return debugDisplayMode != DebugDisplayMode.None;
}
public void RegisterDebug()
{
DebugMenuManager.instance.AddDebugItem<float>("Display Stats", "Frame Rate", () => 1.0f / Time.deltaTime, null, true);
DebugMenuManager.instance.AddDebugItem<float>("Display Stats", "Frame Time", () => Time.deltaTime * 1000.0f, null, true);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, bool>("Enable Shadows", () => lightingDebugSettings.enableShadows, (value) => lightingDebugSettings.enableShadows = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, ShadowMapDebugMode>("Shadow Debug Mode", () => lightingDebugSettings.shadowDebugMode, (value) => lightingDebugSettings.shadowDebugMode = (ShadowMapDebugMode)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, uint>("Shadow Map Index", () => lightingDebugSettings.shadowMapIndex, (value) => lightingDebugSettings.shadowMapIndex = (uint)value);
//DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, LightingDebugMode>("Lighting Debug Mode", () => lightingDebugSettings.lightingDebugMode, (value) => lightingDebugSettings.lightingDebugMode = (LightingDebugMode)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, bool>("Override Smoothness", () => lightingDebugSettings.overrideSmoothness, (value) => lightingDebugSettings.overrideSmoothness = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, float>("Override Smoothness Value", () => lightingDebugSettings.overrideSmoothnessValue, (value) => lightingDebugSettings.overrideSmoothnessValue = (float)value, false, new DebugItemDrawFloatMinMax(0.0f, 1.0f));
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, Color>("Debug Lighting Albedo", () => lightingDebugSettings.debugLightingAlbedo, (value) => lightingDebugSettings.debugLightingAlbedo = (Color)value);
DebugMenuManager.instance.AddDebugItem<bool>("Lighting", "Display Sky Reflection", () => lightingDebugSettings.displaySkyReflection, (value) => lightingDebugSettings.displaySkyReflection = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, float>("Sky Reflection Mipmap", () => lightingDebugSettings.skyReflectionMipmap, (value) => lightingDebugSettings.skyReflectionMipmap = (float)value, false, new DebugItemDrawFloatMinMax(0.0f, 1.0f));
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Display Opaque",() => renderingDebugSettings.displayOpaqueObjects, (value) => renderingDebugSettings.displayOpaqueObjects = (bool)value);
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Display Transparency",() => renderingDebugSettings.displayTransparentObjects, (value) => renderingDebugSettings.displayTransparentObjects = (bool)value);
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Enable Distortion",() => renderingDebugSettings.enableDistortion, (value) => renderingDebugSettings.enableDistortion = (bool)value);
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Enable Subsurface Scattering",() => renderingDebugSettings.enableSSS, (value) => renderingDebugSettings.enableSSS = (bool)value);
}
public void OnValidate()
{

public bool enableShadows = true;
public ShadowMapDebugMode shadowDebugMode = ShadowMapDebugMode.None;
public uint shadowMapIndex = 0;
public bool overrideSmoothness = false;
public float overrideSmoothnessValue = 0.5f;
public Color debugLightingAlbedo = new Color(0.5f, 0.5f, 0.5f);

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader


UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
int2 pixelCoord = posInput.unPositionSS.xy;
int2 tileCoord = (float2)pixelCoord / TILE_SIZE;
int2 mouseTileCoord = _MousePixelCoord / TILE_SIZE;
int2 offsetInTile = pixelCoord - tileCoord * TILE_SIZE;
int2 tileCoord = (float2)pixelCoord / GetTileSize();
int2 mouseTileCoord = _MousePixelCoord / GetTileSize();
int2 offsetInTile = pixelCoord - tileCoord * GetTileSize();
int n = 0;
#ifdef SHOW_LIGHT_CATEGORIES

// Tile overlap counter
if (n >= 0)
{
result = OverlayHeatMap(int2(posInput.unPositionSS.xy) & (TILE_SIZE - 1), n);
result = OverlayHeatMap(int2(posInput.unPositionSS.xy) & (GetTileSize() - 1), n);
}
#ifdef SHOW_LIGHT_CATEGORIES

bool border = any(offsetInTile == 0 || offsetInTile == TILE_SIZE - 1);
bool border = any(offsetInTile == 0 || offsetInTile == GetTileSize() - 1);
float4 result2 = float4(1.0, 1.0, 1.0, border ? 1.0 : 0.5);
result = AlphaBlend(result, result2);
}

11
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset


useForwardRenderingOnly: 0
useDepthPrepass: 0
sssSettings:
numProfiles: 0
profiles: []
numProfiles: 7
profiles:
- {fileID: 11400000, guid: d6ee4403015766f4093158d69216c0bf, type: 2}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


debugDisplaySettings.OnValidate();
sssSettings.OnValidate();
}
void OnEnable()
{
debugDisplaySettings.RegisterDebug();
}
}
[Serializable]

private void CopyDepthBufferIfNeeded(ScriptableRenderContext renderContext)
{
var cmd = new CommandBuffer();
var cmd = new CommandBuffer() { name = NeedDepthBufferCopy() ? "Copy DepthBuffer" : "Set DepthBuffer"};
if (NeedDepthBufferCopy())
{
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", renderContext))

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


public int IESIndex;
public int cookieIndex;
public Vector2 size; // Used by area, projector and spot lights; x = cot(outerHalfAngle) for spot lights
public Vector2 size; // Used by area, projector and spot lights; x = cot(outerHalfAngle) for spot lights
public bool twoSided; // Used by rectangular area lights only
public float unused;
};
[GenerateHLSL]

16
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


int shadowIndex;
int IESIndex;
int cookieIndex;
int lightType;
bool twoSided;
int lightType;
float unused;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData

{
return value.cookieIndex;
}
int GetLightType(LightData value)
{
return value.lightType;
}
bool GetTwoSided(LightData value)
int GetLightType(LightData value)
return value.twoSided;
return value.lightType;
}
float GetUnused(LightData value)
{
return value.unused;
}
//

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


if (additionalData.archetype != LightArchetype.Punctual)
{
lightData.twoSided = additionalData.isDoubleSided;
lightData.size = new Vector2(additionalData.lightLength, additionalData.lightWidth);
}

Vector3 dimensions = new Vector3(lightData.size.x * 0.5f + radius, lightData.size.y * 0.5f + radius, radius);
if (!lightData.twoSided)
{
centerVS += zAxisVS * radius * 0.5f;
dimensions.z *= 0.5f;
}
dimensions.z *= 0.5f;
centerVS += zAxisVS * radius * 0.5f;
bound.center = centerVS;
bound.boxAxisX = dimensions.x * xAxisVS;

}
#endif
using (new Utilities.ProfilingSample(m_PassSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass", renderContext))
using (new Utilities.ProfilingSample((m_PassSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass") + (outputSplitLightingForSSS ? " MRT" : ""), renderContext))
{
var cmd = new CommandBuffer();
cmd.name = bUseClusteredForDeferred ? "Clustered pass" : "Tiled pass";

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


StructuredBuffer<uint> g_vLightListGlobal; // don't support Buffer yet in unity
#ifdef USE_FPTL_LIGHTLIST
#define TILE_SIZE TILE_SIZE_FPTL
#endif
// Don't do a "#else" so we can catch error if including call don't setup thing correctly
#ifdef USE_CLUSTERED_LIGHTLIST
#define TILE_SIZE TILE_SIZE_CLUSTERED
#endif
#define DWORD_PER_TILE 16 // See dwordsPerTile in TilePass.cs, we have roomm for 31 lights and a number of light value all store on 16 bit (ushort)
// these uniforms are only needed for when OPAQUES_ONLY is NOT defined

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


uint GetTileSize()
{
return TILE_SIZE_CLUSTERED;
if (_UseTileLightList)
return TILE_SIZE_FPTL;
else
return TILE_SIZE_CLUSTERED;
}
void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


public static GUIContent maskMapSText = new GUIContent("Mask Map - M(R), AO(G), S(A)", "Mask map");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (BC7/BC5/DXT5(nm))");
public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent horizonFadeText = new GUIContent("Horizon Fade (Spec occlusion)", "horizon fade is use to control specular occlusion");

149
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


#define LTC_GGX_MATRIX_INDEX 0 // RGBA
#define LTC_DISNEY_DIFFUSE_MATRIX_INDEX 1 // RGBA
#define LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX 2 // RGB, A unused
#define LTC_LUT_SIZE 64
#define LTC_LUT_SCALE ((LTC_LUT_SIZE - 1) * rcp(LTC_LUT_SIZE))
#define LTC_LUT_OFFSET (0.5 * rcp(LTC_LUT_SIZE))
#define SSS_N_PROFILES 8
#define SSS_N_PROFILES 8
#define SSS_LOW_THICKNESS 0.002 // 2 mm
uint _EnableSSS; // Globally toggles subsurface scattering on/off
uint _TransmissionFlags; // 1 bit/profile; 0 = inf. thick, 1 = supports transmission
uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter

bsdfData.diffuseColor = baseColor;
// TODO take from subsurfaceProfile
bsdfData.fresnel0 = 0.04; /* 0.028 ? */
bsdfData.subsurfaceProfile = (SSS_N_PROFILES - 1) * inGBuffer2.a;
bsdfData.subsurfaceProfile = (SSS_N_PROFILES - 0.9) * inGBuffer2.a; // Need to bias for integers to round trip through the G-buffer
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule).
bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * inGBuffer2.r + 0.0001;
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +

// Precomputed lighting data to send to the various lighting functions
struct PreLightData
{
// General
// GGX iso
// Aniso
// GGX Aniso
// IBL
float3 iblDirWS; // Dominant specular direction, used for IBL in EvaluateBSDF_Env()
float iblMipLevel;

{
PreLightData preLightData;
// We have handle the case of NdotV being negative in GetData() function with GetShiftedNdotV.
// So we don't need to saturate or take the abs here.
// In case a material use negative normal for double sided lighting like speedtree this will be handle in the GetData() code too.
preLightData.NdotV = dot(bsdfData.normalWS, V);
// General
float3 iblNormalWS = bsdfData.normalWS;
// GetShiftedNdotV return a positive NdotV
// In case a material use negative normal for double sided lighting like Speedtree they need to do a new calculation
preLightData.NdotV = GetShiftedNdotV(iblNormalWS, V); // Handle artificat for specular lighting
// GGX iso
float iblNdotV = preLightData.NdotV;
float3 iblNormalWS = bsdfData.normalWS;
// Check if we precompute anisotropy too
// GGX aniso
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{
preLightData.TdotV = dot(bsdfData.tangentWS, V);

iblNormalWS = GetAnisotropicModifiedNormal(bsdfData.bitangentWS, bsdfData.normalWS, V, bsdfData.anisotropy);
iblNormalWS = GetAnisotropicModifiedNormal(bsdfData.bitangentWS, iblNormalWS, V, bsdfData.anisotropy);
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NDotV) and use iblNormalWS
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV) and use iblNormalWS
GetPreIntegratedFGD(iblNdotV, bsdfData.perceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD);
// IBL
GetPreIntegratedFGD(preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD);
// Area light specific
// Area light
// Scale and bias for the current precomputed table - the constant use here are the one that have been use when the table in LtcData.DisneyDiffuse.cs and LtcData.GGX.cs was use
float2 uv = 0.0078125 + 0.984375 * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);
float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);
// Get the inverse LTC matrix for GGX
// Note we load the matrix transpose (avoid to have to transpose it in shader)

float NdotL = saturate(dot(bsdfData.normalWS, L));
float NdotV = preLightData.NdotV;
float LdotV = dot(L, V);
float invLenLV = rsqrt(abs(2 + 2 * LdotV)); // invLenLV = rcp(length(L + V))
// GCN Optimization: reference PBR Diffuse Lighting for GGX + Smith Microsurfaces
float invLenLV = rsqrt(abs(2.0 * LdotV + 2.0)); // invLenLV = rcp(length(L + V))
float LdotH = saturate(invLenLV + invLenLV * LdotV);
float LdotH = saturate(invLenLV * LdotV + invLenLV);
float3 F = F_Schlick(bsdfData.fresnel0, LdotH);

diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float4 cookie = float4(1.0, 1.0, 1.0, 1.0);
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.shadowIndex >= 0)
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.cookieIndex >= 0)
{
float3 lightToSurface = positionWS - lightData.positionWS;

[branch] if (bsdfData.enableTransmission)
{
// Reverse the normal.
illuminance = saturate(dot(-bsdfData.normalWS, L));
// Apply the cookie. Do not apply shadows.
illuminance *= cookie.a;
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
// The difference between the Disney Diffuse and the Lambertian BRDF for transmittance is negligible.
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.
float3 backLight = (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale * Lambert());
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
float3 transmittedLight = backLight * bsdfData.diffuseColor * bsdfData.transmittance;

diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float4 cookie = float4(1.0, 1.0, 1.0, 1.0);
float shadow = 1;
// TODO: measure impact of having all these dynamic branch here and the gain (or not) of testing illuminace > 0

// illuminance *= SampleIES(lightLoopContext, lightData.IESIndex, sphericalCoord, 0).r;
//}
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.shadowIndex >= 0)
float shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
float shadow = GetPunctualShadowAttenuation(lightLoopContext, lightData.lightType, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = GetPunctualShadowAttenuation(lightLoopContext, lightData.lightType, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
shadow = lerp(1.0, shadow, lightData.shadowDimmer);

[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.cookieIndex >= 0)
{
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);

[branch] if (bsdfData.enableTransmission)
{
// Reverse the normal.
illuminance = saturate(dot(-bsdfData.normalWS, L)) * attenuation;
// Apply the cookie. Do not apply shadows.
illuminance *= cookie.a;
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
illuminance *= attenuation;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmittance is negligible.
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.
float3 backLight = (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale * Lambert());
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
float3 transmittedLight = backLight * bsdfData.diffuseColor * bsdfData.transmittance;

diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float4 cookie = float4(1.0, 1.0, 1.0, 1.0);
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.shadowIndex >= 0)
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.cookieIndex >= 0)
{
// Compute the texture coordinates in [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;

[branch] if (bsdfData.enableTransmission)
{
// Reverse the normal.
illuminance = saturate(dot(-bsdfData.normalWS, L) * clipFactor);
// Apply the cookie. Do not apply shadows.
illuminance *= cookie.a;
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
illuminance *= clipFactor;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmittance is negligible.
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.
float3 backLight = (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale * Lambert());
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
float3 transmittedLight = backLight * bsdfData.diffuseColor * bsdfData.transmittance;

float3 L = normalize(unL);
// Cosine of the angle between the light direction and the normal of the light's surface.
float cosLNs = dot(-L, Ns);
cosLNs = lightData.twoSided ? abs(cosLNs) : saturate(cosLNs);
float cosLNs = saturate(dot(-L, Ns));
// We calculate area reference light with the area integral rather than the solid angle one.
float illuminance = cosLNs * saturate(dot(bsdfData.normalWS, L)) / (sqrDist * lightPdf);

diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
// TODO: This could be precomputed.
float halfWidth = lightData.size.x * 0.5;
float halfHeight = lightData.size.y * 0.5;
float3 unL = lightData.positionWS - positionWS;
float3 unL = lightData.positionWS - positionWS;
[branch]
if (dot(lightData.forward, unL) >= 0)
{
// The light is back-facing.
return;
}
// TODO: This could be precomputed.
float halfWidth = lightData.size.x * 0.5;
float halfHeight = lightData.size.y * 0.5;
// Define the dimensions of the attenuation volume.
// TODO: This could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);

// Evaluate the diffuse part.
{
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
ltcValue = LTCEvaluate(matL, V, bsdfData.normalWS, preLightData.NdotV, lightData.twoSided,
k_identity3x3);
ltcValue = LTCEvaluate(matL, V, bsdfData.normalWS, preLightData.NdotV, k_identity3x3);
ltcValue = LTCEvaluate(matL, V, bsdfData.normalWS, preLightData.NdotV, lightData.twoSided,
preLightData.ltcXformDisneyDiffuse);
ltcValue = LTCEvaluate(matL, V, bsdfData.normalWS, preLightData.NdotV, preLightData.ltcXformDisneyDiffuse);
#endif
if (ltcValue == 0.0)

float3 fresnelTerm = bsdfData.fresnel0 * preLightData.ltcGGXFresnelMagnitudeDiff
+ (float3)preLightData.ltcGGXFresnelMagnitude;
ltcValue = LTCEvaluate(matL, V, bsdfData.normalWS, preLightData.NdotV, lightData.twoSided,
preLightData.ltcXformGGX);
ltcValue = LTCEvaluate(matL, V, bsdfData.normalWS, preLightData.NdotV, preLightData.ltcXformGGX);
ltcValue *= lightData.specularScale;
specularLighting = fresnelTerm * lightData.color * ltcValue;
}

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


#endif
surfaceData.normalWS = float3(0.0, 0.0, 0.0); // Need to init this to keep quiet the compiler, but this is overriden later (0, 0, 0) so if we forget to override the compiler may comply.
// TODO: think about using BC5
normalTS = ADD_IDX(GetNormalTS)(input, layerTexCoord, detailNormalTS, detailMask, false, 0.0);
#if defined(_MASKMAP_IDX)

surfaceData.materialId = (_EnableSSS || _MaterialID != MATERIALID_LIT_SSS) ? _MaterialID : MATERIALID_LIT_STANDARD;
// TODO: think about using BC5
#ifdef _TANGENTMAP
#ifdef _NORMALMAP_TANGENT_SPACE_IDX // Normal and tangent use same space
float3 tangentTS = SAMPLE_UVMAPPING_NORMALMAP(_TangentMap, sampler_TangentMap, layerTexCoord.base, 1.0);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


public class SubsurfaceScatteringSettings : ISerializationCallbackReceiver
{
public const int maxNumProfiles = 8;
public const int neutralProfileID = 7;
public const int neutralProfileID = maxNumProfiles - 1;
public int numProfiles;
public SubsurfaceScatteringProfile[] profiles;

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl


}
// This function convert the tangent space normal/tangent to world space and orthonormalize it + apply a correction of the normal if it is not pointing towards the near plane
void GetNormalAndTangentWS(FragInputs input, float3 V, float3 normalTS, inout float3 normalWS, inout float3 tangentWS, bool wantNegativeNormal = false)
void GetNormalAndTangentWS(FragInputs input, float3 V, float3 normalTS, inout float3 normalWS, inout float3 tangentWS)
{
#ifdef SURFACE_GRADIENT
normalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], normalTS);

GetShiftedNdotV(normalWS, V, wantNegativeNormal);
// Orthonormalize the basis vectors using the Gram-Schmidt process.
// We assume that the length of the surface normal is sufficiently close to 1.

146
Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl


#ifndef UNITY_AREA_LIGHTING_INCLUDED
#define UNITY_AREA_LIGHTING_INCLUDED
float IntegrateEdge(float3 v1, float3 v2)
#define SPHERE_LIGHT_APPROXIMATION
// Not normalized by the factor of 1/TWO_PI.
float3 ComputeEdgeFactor(float3 V1, float3 V2)
float cosTheta = dot(v1, v2);
// Clamp to avoid artifacts. This particular constant gives the best results.
cosTheta = Clamp(cosTheta, -0.9999, 0.9999);
float theta = FastACos(cosTheta);
float res = cross(v1, v2).z * theta * rsqrt(1.0 - cosTheta * cosTheta); // optimization from * 1 / sin(theta)
float V1oV2 = dot(V1, V2);
float3 V1xV2 = cross(V1, V2);
#if 0
return V1xV2 * (rsqrt(1.0 - V1oV2 * V1oV2) * acos(V1oV2));
#else
// Approximate: { y = rsqrt(1.0 - V1oV2 * V1oV2) * acos(V1oV2) } on [0, 1].
// Fit: HornerForm[MiniMaxApproximation[ArcCos[x]/Sqrt[1 - x^2], {x, {0, 1 - $MachineEpsilon}, 6, 0}][[2, 1]]].
// Maximum relative error: 2.6855360216340534 * 10^-6. Intensities up to 1000 are artifact-free.
float x = abs(V1oV2);
float y = 1.5707921083647782 + x * (-0.9995697178013095 + x * (0.778026455830408 + x * (-0.6173111361273548 + x * (0.4202724111150622 + x * (-0.19452783598217288 + x * 0.04232040013661036)))));
if (V1oV2 < 0)
{
// Undo range reduction.
y = PI * rsqrt(saturate(1 - V1oV2 * V1oV2)) - y;
}
return res;
return V1xV2 * y;
#endif
}
// Not normalized by the factor of 1/TWO_PI.
// Ref: Improving radiosity solutions through the use of analytically determined form-factors.
float IntegrateEdge(float3 V1, float3 V2)
{
// 'V1' and 'V2' are represented in a coordinate system with N = (0, 0, 1).
return ComputeEdgeFactor(V1, V2).z;
// Baum's equation
// Expects non-normalized vertex positions
float PolygonRadiance(float4x3 L, bool twoSided)
// 'sinSqSigma' is the sine^2 of the half of the opening angle of the sphere as seen from the shaded point.
// 'cosOmega' is the cosine of the angle between the normal and the direction to the center of the light.
// N.b.: this function accounts for horizon clipping.
float DiffuseSphereLightIrradiance(float sinSqSigma, float cosOmega)
float irradiance;
#if 0 // Ref: Area Light Sources for Real-Time Graphics, page 4 (1996).
float sinSqOmega = saturate(1 - cosOmega * cosOmega);
float cosSqSigma = saturate(1 - sinSqSigma);
float sinSqGamma = saturate(cosSqSigma / sinSqOmega);
float cosSqGamma = saturate(1 - sinSqGamma);
float sinSigma = sqrt(sinSqSigma);
float sinGamma = sqrt(sinSqGamma);
float cosGamma = sqrt(cosSqGamma);
float sigma = asin(sinSigma);
float omega = acos(cosOmega);
float gamma = asin(sinGamma);
if (omega < 0 || omega >= HALF_PI + sigma)
{
// Full horizon occlusion (case #4).
return 0;
}
float e = sinSqSigma * cosOmega;
[branch]
if (omega < HALF_PI - sigma)
{
// No horizon occlusion (case #1).
irradiance = e;
}
else
{
float g = (-2 * sqrt(sinSqOmega * cosSqSigma) + sinGamma) * cosGamma + (HALF_PI - gamma);
float h = cosOmega * (cosGamma * sqrt(saturate(sinSqSigma - cosSqGamma)) + sinSqSigma * asin(saturate(cosGamma / sinSigma)));
if (omega < HALF_PI)
{
// Partial horizon occlusion (case #2).
irradiance = e + INV_PI * (g - h);
}
else
{
// Partial horizon occlusion (case #3).
irradiance = INV_PI * (g + h);
}
}
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015).
float cosSqOmega = cosOmega * cosOmega;
[branch]
if (cosSqOmega > sinSqSigma)
{
irradiance = sinSqSigma * saturate(cosOmega);
}
else
{
float cotanOmega = cosOmega * rsqrt(1 - cosSqOmega);
float x = rcp(sinSqSigma) - 1;
float y = -cotanOmega * sqrt(x);
float z = sqrt(1 - cosSqOmega * rcp(sinSqSigma));
irradiance = INV_PI * ((cosOmega * acos(y) - z * sqrt(x)) * sinSqSigma + atan(z * rsqrt(x)));
}
#endif
return max(irradiance, 0);
}
// Expects non-normalized vertex positions.
float PolygonIrradiance(float4x3 L)
{
#ifdef SPHERE_LIGHT_APPROXIMATION
for (int i = 0; i < 4; i++)
{
L[i] = normalize(L[i]);
}
float3 F = float3(0, 0, 0);
for (uint edge = 0; edge < 4; edge++)
{
float3 V1 = L[edge];
float3 V2 = L[(edge + 1) % 4];
F += INV_TWO_PI * ComputeEdgeFactor(V1, V2);
}
float f2 = saturate(dot(F, F));
float sinSqSigma = sqrt(f2);
float cosOmega = clamp(F.z * rsqrt(f2), -1, 1);
return DiffuseSphereLightIrradiance(sinSqSigma, cosOmega);
#else
// 1. ClipQuadToHorizon
// detect clipping config

sum *= INV_TWO_PI; // Normalization
sum = twoSided ? abs(sum) : max(sum, 0.0);
sum = max(sum, 0.0);
#endif
float LTCEvaluate(float4x3 L, float3 V, float3 N, float NdotV, bool twoSided, float3x3 invM)
float LTCEvaluate(float4x3 L, float3 V, float3 N, float NdotV, float3x3 invM)
{
// Construct a view-dependent orthonormal basis around N.
// TODO: it could be stored in PreLightData, since all LTC lights compute it more than once.

invM = mul(transpose(basis), invM);
L = mul(L, invM);
// Polygon radiance in transformed configuration - specular
return PolygonRadiance(L, twoSided);
// Polygon irradiance in the transformed configuration
return PolygonIrradiance(L);
}
float LineFpo(float tLDDL, float lrcpD, float rcpD)

18
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl


// Helper functions
//-----------------------------------------------------------------------------
// NdotV should not be negative for visible pixels, but it can happen due to the
// perspective projection and the normal mapping + decals. In that case, the normal
// should be modified to become valid (i.e facing the camera) to avoid weird artifacts.
// Note: certain applications (e.g. SpeedTree) require to still have negative normal to perform their own two sided lighting, they can use wantNegativeNormal
// This will potentially reduce the length of the normal at edges of geometry.
float GetShiftedNdotV(inout float3 N, float3 V, bool wantNegativeNormal)
// NdotV can be negative for visible pixels due to the perspective projection, the normal mapping and decals.
// This can produce visible artifacts with direct specular lighting (white point, black point) and indirect specular (artifact with cubemap fetch)
// A way to reduce artifact is to limit NdotV value to not be negative and calculate reflection vector for cubemap with a shifted normal (i.e what depends on the view)
// This is what provide this function
// Note: NdotV return by this function is always positive, no need for saturate
float GetShiftedNdotV(inout float3 N, float3 V)
float limit = rcp(256.0); // Determined mostly by the quality of the G-buffer normal encoding
const float limit = 0.0001; // Epsilon value that avoid divide by 0 (several BSDF divide by NdotV)
if (!wantNegativeNormal && NdotV < limit)
if (NdotV < limit)
// We do not renormalize the normal because { abs(length(N) - 1.0) < limit }.
// We do not renormalize the normal because { abs(length(N) - 1.0) < limit } + It is use for cubemap
N += (-NdotV + limit) * V;
NdotV = limit;
}

8
Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl


return deriv * scale;
}
// Unpack normal as DXT5nm (1, y, 0, x) or BC5 (x, y, 0, 1)
float2 UnpackDerivativeNormalRGorAG(float4 packedNormal, float scale = 1.0)
{
// This do the trick
packedNormal.w *= packedNormal.x;
return UnpackDerivativeNormalAG(packedNormal, scale);
}
float2 UnpackDerivativeNormalRGB(float4 packedNormal, float scale = 1.0)
{
const float fS = 1.0 / (128.0 * 128.0);

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl


float3 UnpackNormalmapRGorAG(float4 packedNormal, float scale = 1.0)
{
// This do the trick
packedNormal.x *= packedNormal.w;
float3 normal;
normal.xy = packedNormal.xy * 2.0 - 1.0;
normal.xy *= scale;
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
return normal;
packedNormal.w *= packedNormal.x;
return UnpackNormalAG(packedNormal, scale);
}
//-----------------------------------------------------------------------------

14
Assets/ScriptableRenderPipeline/ShaderLibrary/SampleUVMappingInternal.hlsl


// Nested multiple includes of the file to handle all variations of normal map (AG, RG or RGB)
// TODO: Handle BC5 format, currently this code is for DXT5nm - After the change, rename this function UnpackNormalmapRGorAG
// This version is use for the base normal map
// This version is use for the base normal map (BC5 or DXT5nm)
#define UNPACK_NORMAL_FUNC UnpackNormalAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalAG
#define UNPACK_NORMAL_FUNC UnpackNormalmapRGorAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGorAG
#endif
#include "SampleUVMappingNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX

// This version is for normalmap with AG encoding only. Mainly use with details map.
// This version is for normalmap with AG encoding only. Use with details map encoded with others properties (like smoothness).
#if defined(UNITY_NO_DXT5nm)
#define UNPACK_NORMAL_FUNC UnpackNormalRGB
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGB
#else
#endif
#include "SampleUVMappingNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC

16
Assets/ScriptableRenderPipeline/common/TextureCache.cs


private static uint g_MaxFrameCount = unchecked((uint)(-1));
private static uint g_InvalidTexID = (uint)0;
public int FetchSlice(Texture texture)
public int FetchSlice(Texture texture, bool forceReinject=false)
{
var sliceIndex = -1;

//assert(TexID!=g_InvalidTexID);
if (texId == g_InvalidTexID) return 0;
var bSwapSlice = false;
var bSwapSlice = forceReinject;
if (m_TextureCacheVersion != s_GlobalTextureCacheVersion)
sliceIndex = m_LocatorInSliceArray[texId];
bFoundAvailOrExistingSlice = true;
if(m_TextureCacheVersion!=s_GlobalTextureCacheVersion)
m_LocatorInSliceArray.Remove(texId);
}
else
{
sliceIndex = m_LocatorInSliceArray[texId];
bFoundAvailOrExistingSlice = true;
bSwapSlice = true; // force a reinject.
}
//assert(m_SliceArray[sliceIndex].TexID==TexID);
}

758
Assets/TestScenes/HDTest/HDRenderLoopTest.unity
文件差异内容过多而无法显示
查看文件

96
ProjectSettings/InputManager.asset


type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 2
axis: 5
joyNum: 0
- serializedVersion: 3
m_Name: Debug Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 2
axis: 6
joyNum: 0
- serializedVersion: 3
m_Name: Debug Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 6
joyNum: 0
- serializedVersion: 3
m_Name: Debug Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 6
joyNum: 0
- serializedVersion: 3
m_Name: Debug Validate
descriptiveName:
descriptiveNegativeName:
negativeButton: return
positiveButton:
altNegativeButton: joystick button 0
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 6
joyNum: 0
- serializedVersion: 3
m_Name: Debug Persistent
descriptiveName:
descriptiveNegativeName:
negativeButton: right shift
positiveButton:
altNegativeButton: joystick button 2
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 6
joyNum: 0

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/SSSProfile.meta


fileFormatVersion: 2
guid: a0ba759eadcfdcc44bc08adad4960ed0
folderAsset: yes
timeCreated: 1493162006
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/common/Debugging.meta


fileFormatVersion: 2
guid: 58a02e8711d94134393b2a8ac22b96ca
folderAsset: yes
timeCreated: 1491989728
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

197
Assets/TestScenes/HDTest/GraphicTest/Two Sided/Material/GroundLeaf_DoubleSidedFlipSSS.mat


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: GroundLeaf_DoubleSidedFlipSSS
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _ALPHATEST_ON _DOUBLESIDED_ON _MASKMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_CustomRenderQueue: 2450
stringTagMap:
RenderType: TransparentCutout
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AnisotropyMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 00447c5eeb984f54d92c80818840a36b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 2800000, guid: 0c3144d154991884c8aa53e7dc7893ff, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DiffuseLightingMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissiveColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 00447c5eeb984f54d92c80818840a36b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap:
m_Texture: {fileID: 2800000, guid: b24f69ff4ace9194fb0d9eee4f5cf1a4, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 2800000, guid: b24f69ff4ace9194fb0d9eee4f5cf1a4, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: 0c3144d154991884c8aa53e7dc7893ff, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecularOcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubSurfaceRadiusMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 1
- _Anisotropy: 0
- _BlendMode: 0
- _BumpScale: 1
- _CullMode: 0
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale: 1
- _DetailAlbedoScale: 1
- _DetailHeightScale: 1
- _DetailMapMode: 0
- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedEnable: 1
- _DoubleSidedMirrorEnable: 1
- _DoubleSidedMode: 2
- _Drag: 1
- _DstBlend: 0
- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 0
- _EnableWind: 0
- _GlossMapScale: 0.892
- _Glossiness: 0.507
- _GlossyReflections: 1
- _HeightAmplitude: 0.32
- _HeightBias: 0
- _HeightCenter: 0.68
- _HeightMapMode: 0
- _HeightScale: 1
- _HorizonFade: 1
- _InitialBend: 1
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 1
- _NormalMapSpace: 0
- _NormalScale: 1
- _OcclusionStrength: 1
- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _Parallax: 0.02
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _StencilRef: 1
- _Stiffness: 1
- _SubsurfaceProfile: 0
- _SubsurfaceRadius: 1
- _SurfaceType: 0
- _TessellationBackFaceCullEpsilon: -0.375
- _TessellationFactor: 4
- _TessellationFactorMaxDistance: 50
- _TessellationFactorMinDistance: 20
- _TessellationFactorTriangleSize: 100
- _TessellationMode: 1
- _TessellationObjectScale: 0
- _TessellationShapeFactor: 0.75
- _TexWorldScale: 1
- _Thickness: 0.5
- _UVBase: 0
- _UVDetail: 0
- _UVMappingPlanar: 0
- _UVSec: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 0.5882353, g: 0.5882353, b: 0.5882353, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}

8
Assets/TestScenes/HDTest/GraphicTest/Two Sided/Material/GroundLeaf_DoubleSidedFlipSSS.mat.meta


fileFormatVersion: 2
guid: 943c7c930eb495d4486788572dc49a12
timeCreated: 1460562588
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

37
Assets/ScriptableRenderPipeline/HDRenderPipeline/SSSProfile/FoliageSSSProfile.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: FoliageSSSProfile
m_EditorClassIdentifier:
stdDev1: {r: 0.27931032, g: 1, b: 0.050000012, a: 0}
stdDev2: {r: 0.3010142, g: 0.8235294, b: 0.05, a: 0}
lerpWeight: 0.5
texturingMode: 0
enableTransmission: 1
tintColor: {r: 1, g: 1, b: 1, a: 1}
thicknessRemap: {x: 0, y: 0.2873168}
settingsIndex: 0
m_FilterKernel:
- {x: 0.28517896, y: 0.09090909, z: 0.9996764, w: -0.00000009903661}
- {x: 0.22566724, y: 0.09090909, z: 0.00016186091, w: -0.209237}
- {x: 0.10604589, y: 0.09090909, z: 8.6876086e-17, w: -0.43068767}
- {x: 0.024215871, y: 0.09090909, z: 5.8571e-41, w: -0.6816498}
- {x: 0.0014802383, y: 0.09090909, z: 0, w: -1.0000685}
- {x: 0.0000013396462, y: 0.09090909, z: 0, w: -1.5417894}
- {x: 0.22566712, y: 0.09090909, z: 0.00016185877, w: 0.20923716}
- {x: 0.10604589, y: 0.09090909, z: 8.6876086e-17, w: 0.43068767}
- {x: 0.02421585, y: 0.09090909, z: 5.857e-41, w: 0.6816499}
- {x: 0.0014802383, y: 0.09090909, z: 0, w: 1.0000685}
- {x: 0.0000013396391, y: 0.09090909, z: 0, w: 1.5417898}
m_HalfRcpVariances:
- {x: 6.4090853, y: 0.5, z: 199.99991}
- {x: 5.518182, y: 0.7372449, z: 200}
m_HalfRcpWeightedVariances: {x: 5.9386554, y: 0.60145676, z: 199.99997, w: 0.60145676}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/SSSProfile/FoliageSSSProfile.asset.meta


fileFormatVersion: 2
guid: d6ee4403015766f4093158d69216c0bf
timeCreated: 1493161911
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

288
Assets/ScriptableRenderPipeline/common/Debugging/DebugActionManager.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
public class DebugActionManager
{
static private DebugActionManager s_Instance = null;
static public DebugActionManager instance
{
get
{
if (s_Instance == null)
s_Instance = new DebugActionManager();
return s_Instance;
}
}
private static string kEnableDebugBtn1 = "Enable Debug Button 1";
private static string kEnableDebugBtn2 = "Enable Debug Button 2";
private static string kDebugPreviousBtn = "Debug Previous";
private static string kDebugNextBtn = "Debug Next";
private static string kValidateBtn = "Debug Validate";
private static string kPersistentBtn = "Debug Persistent";
private static string kDPadVertical = "Debug Vertical";
private static string kDPadHorizontal = "Debug Horizontal";
private string[] m_RequiredInputButtons = { kEnableDebugBtn1, kEnableDebugBtn2, kDebugPreviousBtn, kDebugNextBtn, kValidateBtn, kPersistentBtn, kDPadVertical, kDPadHorizontal };
public enum DebugAction
{
EnableDebugMenu,
PreviousDebugMenu,
NextDebugMenu,
Validate,
Persistent,
MoveVertical,
MoveHorizontal,
DebugActionCount
}
enum DebugActionRepeatMode
{
Never,
Delay
}
class DebugActionDesc
{
public List<string[]> buttonTriggerList = new List<string[]>();
public string axisTrigger = "";
public List<KeyCode[]> keyTriggerList = new List<KeyCode[]>();
public DebugActionRepeatMode repeatMode = DebugActionRepeatMode.Never;
public float repeatDelay = 0.0f;
}
class DebugActionState
{
enum DebugActionKeyType
{
Button,
Axis,
Key
}
DebugActionKeyType m_Type;
string[] m_PressedButtons;
string m_PressedAxis = "";
KeyCode[] m_PressedKeys;
bool[] m_TriggerPressedUp = null;
float m_Timer;
bool m_RunningAction = false;
float m_ActionState = 0.0f;
public bool runningAction { get { return m_RunningAction; } }
public float actionState { get { return m_ActionState; } }
public float timer{ get { return m_Timer; } }
private void Trigger(int triggerCount, float state)
{
m_ActionState = state;
m_RunningAction = true;
m_Timer = 0.0f;
m_TriggerPressedUp = new bool[triggerCount];
for (int i = 0; i < m_TriggerPressedUp.Length; ++i)
m_TriggerPressedUp[i] = false;
}
public void TriggerWithButton(string[] buttons, float state)
{
m_Type = DebugActionKeyType.Button;
m_PressedButtons = buttons;
m_PressedAxis = "";
Trigger(buttons.Length, state);
}
public void TriggerWithAxis(string axis, float state)
{
m_Type = DebugActionKeyType.Axis;
m_PressedAxis = axis;
Trigger(1, state);
}
public void TriggerWithKey(KeyCode[] keys, float state)
{
m_Type = DebugActionKeyType.Key;
m_PressedKeys = keys;
m_PressedAxis = "";
Trigger(keys.Length, state);
}
private void Reset()
{
m_RunningAction = false;
m_Timer = 0.0f;
m_TriggerPressedUp = null;
}
public void Update(DebugActionDesc desc)
{
// Always reset this so that the action can only be caught once until repeat/reset
m_ActionState = 0.0f;
if (m_TriggerPressedUp != null)
{
m_Timer += Time.deltaTime;
for(int i = 0 ; i < m_TriggerPressedUp.Length ; ++i)
{
if (m_Type == DebugActionKeyType.Button)
m_TriggerPressedUp[i] |= Input.GetButtonUp(m_PressedButtons[i]);
else if(m_Type == DebugActionKeyType.Axis)
m_TriggerPressedUp[i] |= (Input.GetAxis(m_PressedAxis) == 0.0f);
else
m_TriggerPressedUp[i] |= Input.GetKeyUp(m_PressedKeys[i]);
}
bool allTriggerUp = true;
foreach (bool value in m_TriggerPressedUp)
allTriggerUp &= value;
if(allTriggerUp || (m_Timer > desc.repeatDelay && desc.repeatMode == DebugActionRepeatMode.Delay))
{
Reset();
}
}
}
}
bool m_Valid = false;
DebugActionDesc[] m_DebugActions = null;
DebugActionState[] m_DebugActionStates = null;
DebugActionManager()
{
m_Valid = Debugging.CheckRequiredInputButtonMapping(m_RequiredInputButtons);
m_DebugActions = new DebugActionDesc[(int)DebugAction.DebugActionCount];
m_DebugActionStates = new DebugActionState[(int)DebugAction.DebugActionCount];
DebugActionDesc enableDebugMenu = new DebugActionDesc();
enableDebugMenu.buttonTriggerList.Add(new[] { kEnableDebugBtn1, kEnableDebugBtn2 });
enableDebugMenu.keyTriggerList.Add(new[] { KeyCode.LeftControl, KeyCode.Backspace });
enableDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.EnableDebugMenu, enableDebugMenu);
DebugActionDesc nextDebugMenu = new DebugActionDesc();
nextDebugMenu.buttonTriggerList.Add(new[] { kDebugNextBtn });
nextDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.NextDebugMenu, nextDebugMenu);
DebugActionDesc previousDebugMenu = new DebugActionDesc();
previousDebugMenu.buttonTriggerList.Add(new[] { kDebugPreviousBtn });
previousDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.PreviousDebugMenu, previousDebugMenu);
DebugActionDesc validate = new DebugActionDesc();
validate.buttonTriggerList.Add(new[] { kValidateBtn });
validate.repeatMode = DebugActionRepeatMode.Delay;
validate.repeatDelay = 0.25f;
AddAction(DebugAction.Validate, validate);
DebugActionDesc persistent = new DebugActionDesc();
persistent.buttonTriggerList.Add(new[] { kPersistentBtn });
persistent.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.Persistent, persistent);
AddAction(DebugAction.MoveVertical, new DebugActionDesc { axisTrigger = kDPadVertical, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.2f } );
AddAction(DebugAction.MoveHorizontal, new DebugActionDesc { axisTrigger = kDPadHorizontal, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.2f } );
}
void AddAction(DebugAction action, DebugActionDesc desc)
{
int index = (int)action;
m_DebugActions[index] = desc;
m_DebugActionStates[index] = new DebugActionState();
}
void SampleAction(int actionIndex)
{
DebugActionDesc desc = m_DebugActions[actionIndex];
DebugActionState state = m_DebugActionStates[actionIndex];
//bool canSampleAction = (state.actionTriggered == false) || (desc.repeatMode == DebugActionRepeatMode.Delay && state.timer > desc.repeatDelay);
if(state.runningAction == false)
{
// Check button triggers
for (int buttonListIndex = 0; buttonListIndex < desc.buttonTriggerList.Count; ++buttonListIndex)
{
string[] buttons = desc.buttonTriggerList[buttonListIndex];
bool allButtonPressed = true;
foreach (string button in buttons)
{
allButtonPressed = allButtonPressed && Input.GetButton(button);
if (!allButtonPressed)
break;
}
if (allButtonPressed)
{
state.TriggerWithButton(buttons, 1.0f);
break;
}
}
// Check axis triggers
if(desc.axisTrigger != "")
{
float axisValue = Input.GetAxis(desc.axisTrigger);
if(axisValue != 0.0f)
{
state.TriggerWithAxis(desc.axisTrigger, axisValue);
}
}
// Check key triggers
for (int keyListIndex = 0; keyListIndex < desc.keyTriggerList.Count; ++keyListIndex)
{
KeyCode[] keys = desc.keyTriggerList[keyListIndex];
bool allKeyPressed = true;
foreach (KeyCode key in keys)
{
allKeyPressed = allKeyPressed && Input.GetKey(key);
if (!allKeyPressed)
break;
}
if (allKeyPressed)
{
state.TriggerWithKey(keys, 1.0f);
break;
}
}
}
}
void UpdateAction(int actionIndex)
{
DebugActionDesc desc = m_DebugActions[actionIndex];
DebugActionState state = m_DebugActionStates[actionIndex];
if(state.runningAction)
{
state.Update(desc);
}
}
public void Update()
{
if (!m_Valid)
return;
for(int actionIndex = 0 ; actionIndex < m_DebugActions.Length ; ++actionIndex)
{
UpdateAction(actionIndex);
SampleAction(actionIndex);
}
}
public float GetAction(DebugAction action)
{
return m_DebugActionStates[(int)action].actionState;
}
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugActionManager.cs.meta


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

235
Assets/ScriptableRenderPipeline/common/Debugging/DebugItemDrawer.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering
{
public class DebugItemDrawer
{
protected DebugMenuItem m_MenuItem = null;
// Label for simple GUI items
GUIContent m_Label;
List<GUIContent> m_EnumStrings = null;
List<int> m_EnumValues = null;
public DebugItemDrawer()
{
}
public void SetDebugItem(DebugMenuItem item)
{
m_MenuItem = item;
m_Label = new GUIContent(m_MenuItem.name);
Type itemType = m_MenuItem.GetItemType();
if(itemType.BaseType == typeof(System.Enum))
{
Array arr = Enum.GetValues(itemType);
m_EnumStrings = new List<GUIContent>(arr.Length);
m_EnumValues = new List<int>(arr.Length);
foreach(var value in arr)
{
m_EnumStrings.Add(new GUIContent(value.ToString()));
m_EnumValues.Add((int)value);
}
}
}
public virtual void ClampValues(Func<object> getter, Action<object> setter) {}
public virtual DebugMenuItemUI BuildGUI(GameObject parent, DebugMenuItem menuItem)
{
DebugMenuItemUI newItemUI = null;
if (menuItem.GetItemType() == typeof(bool))
{
newItemUI = new DebugMenuBoolItemUI(parent, menuItem, m_Label.text);
}
else if (menuItem.GetItemType() == typeof(int))
{
newItemUI = new DebugMenuIntItemUI(parent, menuItem, m_Label.text);
}
else if (menuItem.GetItemType() == typeof(uint))
{
newItemUI = new DebugMenuUIntItemUI(parent, menuItem, m_Label.text);
}
else if (menuItem.GetItemType() == typeof(float))
{
newItemUI = new DebugMenuFloatItemUI(parent, menuItem, m_Label.text);
}
else if (menuItem.GetItemType() == typeof(Color))
{
newItemUI = new DebugMenuColorItemUI(parent, menuItem, m_Label.text);
}
else if (m_MenuItem.GetItemType().BaseType == typeof(System.Enum))
{
newItemUI = new DebugMenuEnumItemUI(parent, menuItem, m_Label.text, m_EnumStrings, m_EnumValues);
}
return newItemUI;
}
#if UNITY_EDITOR
void DrawBoolItem()
{
bool value = (bool)m_MenuItem.GetValue();
if (m_MenuItem.readOnly)
{
EditorGUILayout.LabelField(m_Label, new GUIContent(value.ToString()));
}
else
{
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.Toggle(m_Label, value);
if (EditorGUI.EndChangeCheck())
{
m_MenuItem.SetValue(value);
}
}
}
void DrawIntItem()
{
int value = (int)m_MenuItem.GetValue();
if (m_MenuItem.readOnly)
{
EditorGUILayout.LabelField(m_Label, new GUIContent(value.ToString()));
}
else
{
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntField(m_Label, value);
if (EditorGUI.EndChangeCheck())
{
m_MenuItem.SetValue(value);
}
}
}
void DrawUIntItem()
{
int value = (int)(uint)m_MenuItem.GetValue();
if (m_MenuItem.readOnly)
{
EditorGUILayout.LabelField(m_Label, new GUIContent(value.ToString()));
}
else
{
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntField(m_Label, value);
if (EditorGUI.EndChangeCheck())
{
value = System.Math.Max(0, value);
m_MenuItem.SetValue((uint)value);
}
}
}
void DrawFloatItem()
{
float value = (float)m_MenuItem.GetValue();
if(m_MenuItem.readOnly)
{
EditorGUILayout.LabelField(m_Label, new GUIContent(value.ToString()));
}
else
{
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.FloatField(m_Label, value);
if (EditorGUI.EndChangeCheck())
{
m_MenuItem.SetValue(value);
}
}
}
void DrawColorItem()
{
EditorGUI.BeginChangeCheck();
Color value = EditorGUILayout.ColorField(m_Label, (Color)m_MenuItem.GetValue());
if (EditorGUI.EndChangeCheck())
{
m_MenuItem.SetValue(value);
}
}
void DrawEnumItem()
{
EditorGUI.BeginChangeCheck();
int value = EditorGUILayout.IntPopup(m_Label, (int)m_MenuItem.GetValue(), m_EnumStrings.ToArray(), m_EnumValues.ToArray());
if (EditorGUI.EndChangeCheck())
{
m_MenuItem.SetValue(value);
}
}
public virtual void OnEditorGUI()
{
if (m_MenuItem.GetItemType() == typeof(bool))
{
DrawBoolItem();
}
else if (m_MenuItem.GetItemType() == typeof(int))
{
DrawIntItem();
}
else if(m_MenuItem.GetItemType() == typeof(uint))
{
DrawUIntItem();
}
else if (m_MenuItem.GetItemType() == typeof(float))
{
DrawFloatItem();
}
else if (m_MenuItem.GetItemType() == typeof(Color))
{
DrawColorItem();
}
else if (m_MenuItem.GetItemType().BaseType == typeof(System.Enum))
{
DrawEnumItem();
}
}
#endif
}
public class DebugItemDrawFloatMinMax
: DebugItemDrawer
{
float m_Min = 0.0f;
float m_Max = 1.0f;
public DebugItemDrawFloatMinMax(float min, float max)
{
m_Min = min;
m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
{
if (m_MenuItem == null)
return;
if(m_MenuItem.GetItemType() == typeof(float))
{
setter(Mathf.Clamp((float)getter(), m_Min, m_Max));
}
}
#if UNITY_EDITOR
public override void OnEditorGUI()
{
EditorGUI.BeginChangeCheck();
float value = EditorGUILayout.Slider(m_MenuItem.name, (float)m_MenuItem.GetValue(), m_Min, m_Max);
if (EditorGUI.EndChangeCheck())
{
m_MenuItem.SetValue(value);
}
}
#endif
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugItemDrawer.cs.meta


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

267
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenu.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace UnityEngine.Experimental.Rendering
{
public class DebugMenuItem
{
public Type type { get { return m_Type; } }
public string name { get { return m_Name; } }
public DebugItemDrawer drawer { get { return m_Drawer; } }
public bool dynamicDisplay { get { return m_DynamicDisplay; } }
public bool readOnly { get { return m_Setter == null; } }
public DebugMenuItem(string name, Type type, Func<object> getter, Action<object> setter, bool dynamicDisplay = false, DebugItemDrawer drawer = null)
{
m_Type = type;
m_Setter = setter;
m_Getter = getter;
m_Name = name;
m_Drawer = drawer;
m_DynamicDisplay = dynamicDisplay;
}
public Type GetItemType()
{
return m_Type;
}
public void SetValue(object value)
{
// Setter can be null for readonly items
if(m_Setter != null)
{
m_Setter(value);
m_Drawer.ClampValues(m_Getter, m_Setter);
}
}
public object GetValue()
{
return m_Getter();
}
Func<object> m_Getter;
Action<object> m_Setter;
Type m_Type;
string m_Name;
DebugItemDrawer m_Drawer = null;
bool m_DynamicDisplay = false;
}
public class DebugMenu
{
public string name { get { return m_Name; } }
public int itemCount { get { return m_Items.Count; } }
protected string m_Name = "Unknown Debug Menu";
private GameObject m_Root = null;
private List<DebugMenuItem> m_Items = new List<DebugMenuItem>();
private List<DebugMenuItemUI> m_ItemsUI = new List<DebugMenuItemUI>();
private int m_SelectedItem = -1;
public DebugMenu(string name)
{
m_Name = name;
}
public DebugMenuItem GetDebugMenuItem(int index)
{
if (index >= m_Items.Count || index < 0)
return null;
return m_Items[index];
}
public DebugMenuItem GetSelectedDebugMenuItem()
{
if(m_SelectedItem != -1)
{
return m_Items[m_SelectedItem];
}
return null;
}
public bool HasItem(DebugMenuItem debugItem)
{
foreach(var item in m_Items)
{
if (debugItem == item)
return true;
}
return false;
}
public void RemoveDebugItem(DebugMenuItem debugItem)
{
m_Items.Remove(debugItem);
RebuildGUI();
}
public void AddDebugItem(DebugMenuItem debugItem)
{
m_Items.Add(debugItem);
RebuildGUI();
}
// TODO: Move this to UI classes
public GameObject BuildGUI(GameObject parent)
{
m_Root = new GameObject(string.Format("{0}", m_Name));
m_Root.transform.SetParent(parent.transform);
m_Root.transform.localPosition = Vector3.zero;
m_Root.transform.localScale = Vector3.one;
UI.VerticalLayoutGroup menuVL = m_Root.AddComponent<UI.VerticalLayoutGroup>();
menuVL.spacing = 5.0f;
menuVL.childControlWidth = true;
menuVL.childControlHeight = true;
menuVL.childForceExpandWidth = true;
menuVL.childForceExpandHeight = false;
RectTransform menuVLRectTransform = m_Root.GetComponent<RectTransform>();
menuVLRectTransform.pivot = new Vector2(0.0f, 0.0f);
menuVLRectTransform.localPosition = new Vector3(0.0f, 0.0f);
menuVLRectTransform.anchorMin = new Vector2(0.0f, 0.0f);
menuVLRectTransform.anchorMax = new Vector2(1.0f, 1.0f);
RebuildGUI();
m_Root.SetActive(false);
return m_Root;
}
private void RebuildGUI()
{
m_Root.transform.DetachChildren();
DebugMenuUI.CreateTextElement(string.Format("{0} Title", m_Name), m_Name, 14, TextAnchor.MiddleLeft, m_Root);
m_ItemsUI.Clear();
foreach (DebugMenuItem menuItem in m_Items)
{
DebugItemDrawer drawer = menuItem.drawer; // Should never be null, we have at least the default drawer
m_ItemsUI.Add(drawer.BuildGUI(m_Root, menuItem));
}
}
void SetSelectedItem(int index)
{
if(m_SelectedItem != -1)
{
m_ItemsUI[m_SelectedItem].SetSelected(false);
}
m_SelectedItem = index;
m_ItemsUI[m_SelectedItem].SetSelected(true);
}
public void SetSelected(bool value)
{
m_Root.SetActive(value);
if(value)
{
if (m_SelectedItem == -1)
{
NextItem();
}
else
SetSelectedItem(m_SelectedItem);
}
}
int NextItemIndex(int current)
{
return (current + 1) % m_Items.Count;
}
void NextItem()
{
if(m_Items.Count != 0)
{
int newSelected = (m_SelectedItem + 1) % m_Items.Count;
SetSelectedItem(newSelected);
}
}
int PreviousItemIndex(int current)
{
int newSelected = current - 1;
if (newSelected == -1)
newSelected = m_Items.Count - 1;
return newSelected;
}
void PreviousItem()
{
if(m_Items.Count != 0)
{
int newSelected = m_SelectedItem - 1;
if (newSelected == -1)
newSelected = m_Items.Count - 1;
SetSelectedItem(newSelected);
}
}
public void OnMoveHorizontal(float value)
{
if(m_SelectedItem != -1 && !m_Items[m_SelectedItem].readOnly)
{
if (value > 0.0f)
m_ItemsUI[m_SelectedItem].OnIncrement();
else
m_ItemsUI[m_SelectedItem].OnDecrement();
}
}
public void OnMoveVertical(float value)
{
if (value > 0.0f)
PreviousItem();
else
NextItem();
}
public void OnValidate()
{
if (m_SelectedItem != -1 && !m_Items[m_SelectedItem].readOnly)
m_ItemsUI[m_SelectedItem].OnValidate();
}
public void AddDebugMenuItem<ItemType>(string name, Func<object> getter, Action<object> setter, bool dynamicDisplay = false, DebugItemDrawer drawer = null)
{
if (drawer == null)
drawer = new DebugItemDrawer();
DebugMenuItem newItem = new DebugMenuItem(name, typeof(ItemType), getter, setter, dynamicDisplay, drawer);
drawer.SetDebugItem(newItem);
m_Items.Add(newItem);
}
public void Update()
{
// Can happen if the debug menu has been disabled (all UI is destroyed). We can't test DebugMenuManager directly though because of the persistant debug menu (which is always displayed no matter what)
if (m_Root == null)
return;
foreach(var itemUI in m_ItemsUI)
{
if(itemUI.dynamicDisplay)
itemUI.Update();
}
}
}
public class LightingDebugMenu
: DebugMenu
{
public LightingDebugMenu()
: base("Lighting")
{
}
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenu.cs.meta


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

453
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuItemUI.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
public abstract class DebugMenuItemUI
{
protected GameObject m_Root = null;
protected DebugMenuItem m_MenuItem = null;
public bool dynamicDisplay { get { return m_MenuItem.dynamicDisplay; } }
protected DebugMenuItemUI(DebugMenuItem menuItem)
{
m_MenuItem = menuItem;
}
public abstract void SetSelected(bool value);
public abstract void OnValidate();
public abstract void OnIncrement();
public abstract void OnDecrement();
public abstract void Update();
}
public class DebugMenuSimpleItemUI : DebugMenuItemUI
{
protected GameObject m_Name = null;
protected GameObject m_Value = null;
protected DebugMenuSimpleItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(menuItem)
{
m_Root = DebugMenuUI.CreateHorizontalLayoutGroup("", true, true, false, false, parent);
m_Name = DebugMenuUI.CreateTextElement(m_MenuItem.name, name, 10, TextAnchor.MiddleLeft, m_Root);
var layoutElem = m_Name.AddComponent<UI.LayoutElement>();
layoutElem.minWidth = DebugMenuUI.kDebugItemNameWidth;
m_Value = DebugMenuUI.CreateTextElement(string.Format("{0} value", name), "", 10, TextAnchor.MiddleLeft, m_Root);
}
public override void SetSelected(bool value)
{
m_Name.GetComponent<UI.Text>().color = value ? DebugMenuUI.kColorSelected : DebugMenuUI.kColorUnSelected;
m_Value.GetComponent<UI.Text>().color = value ? DebugMenuUI.kColorSelected : DebugMenuUI.kColorUnSelected;
}
public override void OnValidate()
{
throw new System.NotImplementedException();
}
public override void OnIncrement()
{
throw new System.NotImplementedException();
}
public override void OnDecrement()
{
throw new System.NotImplementedException();
}
public override void Update()
{
throw new System.NotImplementedException();
}
}
public class DebugMenuBoolItemUI : DebugMenuSimpleItemUI
{
public DebugMenuBoolItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(parent, menuItem, name)
{
Update();
}
public override void Update()
{
m_Value.GetComponent<UI.Text>().text = (bool)m_MenuItem.GetValue() ? "True" : "False";
}
public override void OnValidate()
{
m_MenuItem.SetValue(!(bool)m_MenuItem.GetValue());
Update();
}
public override void OnIncrement()
{
OnValidate();
}
public override void OnDecrement()
{
OnValidate();
}
}
public class DebugMenuFloatItemUI : DebugMenuSimpleItemUI
{
bool m_SelectIncrementMode = false;
int m_CurrentIncrementIndex = -1;
public DebugMenuFloatItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(parent, menuItem, name)
{
Update();
}
public override void Update()
{
float currentValue = (float)m_MenuItem.GetValue();
bool isNegative = currentValue < 0.0f;
// Easier to format the string without caring about the '-' sign. We add it back at the end
currentValue = Mathf.Abs(currentValue);
char separator = System.Convert.ToChar(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
// Start with the maximum amount of trailing zeros
string valueWithMaxDecimals = string.Format("{0:0.00000}", currentValue);
// Remove trailing zeros until we reach the separator or we reach the decimal we are currently editing.
int separatorIndex = valueWithMaxDecimals.LastIndexOf(separator);
int index = valueWithMaxDecimals.Length - 1;
while (
valueWithMaxDecimals[index] == '0' // Remove trailing zeros
&& index > (separatorIndex + 1) // until we reach the separator
&& index > (System.Math.Abs(m_CurrentIncrementIndex) + separatorIndex)) // Or it's the index of the current decimal being edited (so as to display the last trailing zero in this case)
{
index--;
}
string finalValue = new string(valueWithMaxDecimals.ToCharArray(), 0, index + 1);
// Add leading zeros until we reach where the current order is being edited.
if(m_CurrentIncrementIndex > 0)
{
float incrementValue = Mathf.Pow(10.0f, (float)m_CurrentIncrementIndex);
if(incrementValue > currentValue)
{
float compareValue = currentValue + 1.0f; // Start at 1.0f because we know that we are going to increment by 10 or more
while (incrementValue > compareValue)
{
finalValue = finalValue.Insert(0, "0");
compareValue *= 10.0f;
}
}
}
// When selecting which decimal/order you want to edit, we show brackets around the figure to show the user.
if(m_SelectIncrementMode)
{
separatorIndex = finalValue.LastIndexOf(separator); // separator may have changed place if we added leading zeros
int bracketIndex = separatorIndex - m_CurrentIncrementIndex;
if(m_CurrentIncrementIndex >= 0) // Skip separator
bracketIndex -= 1;
finalValue = finalValue.Insert(bracketIndex, "[");
finalValue = finalValue.Insert(bracketIndex + 2, "]");
}
if(isNegative)
finalValue = finalValue.Insert(0, "-");
m_Value.GetComponent<UI.Text>().text = finalValue;
}
public override void OnValidate()
{
m_SelectIncrementMode = !m_SelectIncrementMode;
Update();
}
public override void OnIncrement()
{
if(!m_SelectIncrementMode)
{
m_MenuItem.SetValue((float)m_MenuItem.GetValue() + Mathf.Pow(10.0f, (float)m_CurrentIncrementIndex));
}
else
{
m_CurrentIncrementIndex -= 1; // * 0.1 (10^m_CurrentIncrementIndex)
m_CurrentIncrementIndex = System.Math.Max(-5, m_CurrentIncrementIndex);
}
Update();
}
public override void OnDecrement()
{
if (!m_SelectIncrementMode)
{
m_MenuItem.SetValue((float)m_MenuItem.GetValue() - Mathf.Pow(10.0f, (float)m_CurrentIncrementIndex));
}
else
{
m_CurrentIncrementIndex += 1; // * 10 (10^m_CurrentIncrementIndex)
}
Update();
}
}
// Everything is done with int. We don't really care about values > 2b for debugging.
public class DebugMenuIntegerItemUI : DebugMenuSimpleItemUI
{
bool m_SelectIncrementMode = false;
int m_CurrentIncrementIndex = 0;
public DebugMenuIntegerItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(parent, menuItem, name)
{
}
protected void UpdateText(int value)
{
bool isNegative = value < 0f;
// Easier to format the string without caring about the '-' sign. We add it back at the end
value = System.Math.Abs(value);
string finalValue = string.Format("{0}", value);
// Add leading zeros until we reach where the current order is being edited.
if(m_CurrentIncrementIndex > 0)
{
int incrementValue = (int)System.Math.Pow(10, m_CurrentIncrementIndex);
if(incrementValue > value)
{
int compareValue = System.Math.Max(value, 1);
while (incrementValue > compareValue)
{
finalValue = finalValue.Insert(0, "0");
compareValue *= 10;
}
}
}
// When selecting which decimal/order you want to edit, we show brackets around the figure to show the user.
if(m_SelectIncrementMode)
{
int bracketIndex = finalValue.Length - 1 - m_CurrentIncrementIndex;
finalValue = finalValue.Insert(bracketIndex, "[");
finalValue = finalValue.Insert(bracketIndex + 2, "]");
}
if(isNegative)
finalValue = finalValue.Insert(0, "-");
m_Value.GetComponent<UI.Text>().text = finalValue;
}
protected virtual int GetIntegerValue()
{
throw new System.NotImplementedException();
}
protected virtual void SetIntegerValue(int value)
{
throw new System.NotImplementedException();
}
public override void Update()
{
UpdateText(GetIntegerValue());
}
public override void OnValidate()
{
m_SelectIncrementMode = !m_SelectIncrementMode;
Update();
}
public override void OnIncrement()
{
if (!m_SelectIncrementMode)
{
SetIntegerValue(GetIntegerValue() + (int)Mathf.Pow(10.0f, (float)m_CurrentIncrementIndex));
}
else
{
m_CurrentIncrementIndex -= 1; // *= 0.1 (10^m_CurrentIncrementIndex)
m_CurrentIncrementIndex = System.Math.Max(0, m_CurrentIncrementIndex);
}
Update();
}
public override void OnDecrement()
{
if (!m_SelectIncrementMode)
{
SetIntegerValue(GetIntegerValue() - (int)Mathf.Pow(10.0f, (float)m_CurrentIncrementIndex));
}
else
{
m_CurrentIncrementIndex += 1; // *= 10 (10^m_CurrentIncrementIndex)
m_CurrentIncrementIndex = System.Math.Max(0, m_CurrentIncrementIndex);
}
Update();
}
}
public class DebugMenuIntItemUI : DebugMenuIntegerItemUI
{
public DebugMenuIntItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(parent, menuItem, name)
{
UpdateText((int)m_MenuItem.GetValue());
}
protected override int GetIntegerValue()
{
return (int)m_MenuItem.GetValue();
}
protected override void SetIntegerValue(int value)
{
m_MenuItem.SetValue(value);
}
}
public class DebugMenuUIntItemUI : DebugMenuIntegerItemUI
{
public DebugMenuUIntItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(parent, menuItem, name)
{
UpdateText((int)(uint)m_MenuItem.GetValue());
}
protected override int GetIntegerValue()
{
return (int)(uint)m_MenuItem.GetValue();
}
protected override void SetIntegerValue(int value)
{
m_MenuItem.SetValue((uint)System.Math.Max(0, value));
}
}
public class DebugMenuEnumItemUI : DebugMenuSimpleItemUI
{
int m_CurrentValueIndex = 0;
List<GUIContent> m_ValueNames;
List<int> m_Values;
public DebugMenuEnumItemUI(GameObject parent, DebugMenuItem menuItem, string name, List<GUIContent> valueNames, List<int> values)
: base(parent, menuItem, name)
{
m_Values = values;
m_ValueNames = valueNames;
m_CurrentValueIndex = FindIndexForValue((int)m_MenuItem.GetValue());
Update();
}
private int FindIndexForValue(int value)
{
for(int i = 0 ; i < m_Values.Count ; ++i)
{
if (m_Values[i] == value)
return i;
}
return -1;
}
public override void Update()
{
if(m_CurrentValueIndex != -1)
{
m_Value.GetComponent<UI.Text>().text = m_ValueNames[m_CurrentValueIndex].text;
}
}
public override void OnValidate()
{
OnIncrement();
}
public override void OnIncrement()
{
m_CurrentValueIndex = (m_CurrentValueIndex + 1) % m_Values.Count;
m_MenuItem.SetValue(m_CurrentValueIndex);
Update();
}
public override void OnDecrement()
{
m_CurrentValueIndex -= 1;
if (m_CurrentValueIndex < 0)
m_CurrentValueIndex = m_Values.Count - 1;
m_MenuItem.SetValue(m_CurrentValueIndex);
Update();
}
}
public class DebugMenuColorItemUI : DebugMenuItemUI
{
protected GameObject m_Name = null;
protected GameObject m_ColorRect = null;
public DebugMenuColorItemUI(GameObject parent, DebugMenuItem menuItem, string name)
: base(menuItem)
{
m_MenuItem = menuItem;
m_Root = DebugMenuUI.CreateHorizontalLayoutGroup(name, true, true, false, false, parent);
m_Name = DebugMenuUI.CreateTextElement(m_MenuItem.name, name, 10, TextAnchor.MiddleLeft, m_Root);
var layoutElemName = m_Name.AddComponent<UI.LayoutElement>();
layoutElemName.minWidth = DebugMenuUI.kDebugItemNameWidth;
// Force layout because we need the right height for the color rect element afterward.
UI.LayoutRebuilder.ForceRebuildLayoutImmediate(m_Root.GetComponent<RectTransform>());
RectTransform nameRect = m_Name.GetComponent<RectTransform>();
m_ColorRect = new GameObject();
m_ColorRect.transform.SetParent(m_Root.transform, false);
m_ColorRect.AddComponent<UI.Image>();
UI.LayoutElement layoutElem = m_ColorRect.AddComponent<UI.LayoutElement>();
// We need to set min width/height because without an image, the size would be zero.
layoutElem.minHeight = nameRect.rect.height;
layoutElem.minWidth = 40.0f;
Update();
}
public override void Update()
{
Color currentValue = (Color)m_MenuItem.GetValue();
UI.Image image = m_ColorRect.GetComponent<UI.Image>();
image.color = currentValue;
}
public override void SetSelected(bool value)
{
m_Name.GetComponent<UI.Text>().color = value ? DebugMenuUI.kColorSelected : DebugMenuUI.kColorUnSelected;
}
// TODO: Edit mode!
public override void OnValidate()
{
}
public override void OnIncrement()
{
}
public override void OnDecrement()
{
}
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuItemUI.cs.meta


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

194
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuManager.cs


using System;
using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
public class DebugMenuManager
{
static private DebugMenuManager s_Instance = null;
static public DebugMenuManager instance
{
get
{
if (s_Instance == null)
{
s_Instance = new DebugMenuManager();
}
return s_Instance;
}
}
DebugMenuManager()
{
LookUpDebugMenuClasses();
m_PersistentDebugMenu = new DebugMenu("Persistent");
m_DebugMenuUI = new DebugMenuUI(this);
}
bool m_Enabled = false;
int m_ActiveMenuIndex = 0;
List<DebugMenu> m_DebugMenus = new List<DebugMenu>();
DebugMenu m_PersistentDebugMenu = null;
DebugMenuUI m_DebugMenuUI = null;
public bool isEnabled { get { return m_Enabled; } }
public int activeMenuIndex { get { return m_ActiveMenuIndex; } set { m_ActiveMenuIndex = value; } }
public int menuCount { get { return m_DebugMenus.Count; } }
public DebugMenu GetDebugMenu(int index)
{
if (index < m_DebugMenus.Count)
return m_DebugMenus[index];
else
return null;
}
public DebugMenu GetPersistentDebugMenu()
{
return m_PersistentDebugMenu;
}
void LookUpDebugMenuClasses()
{
// Prepare all debug menus
var types = Assembly.GetAssembly(typeof(DebugMenu)).GetTypes()
.Where(t => t.IsSubclassOf(typeof(DebugMenu)));
m_DebugMenus.Clear();
foreach (var type in types)
{
m_DebugMenus.Add((DebugMenu)Activator.CreateInstance(type));
}
}
public void PreviousDebugMenu()
{
m_DebugMenus[m_ActiveMenuIndex].SetSelected(false);
m_ActiveMenuIndex = m_ActiveMenuIndex - 1;
if (m_ActiveMenuIndex == -1)
m_ActiveMenuIndex = m_DebugMenus.Count - 1;
m_DebugMenus[m_ActiveMenuIndex].SetSelected(true);
}
public void NextDebugMenu()
{
m_DebugMenus[m_ActiveMenuIndex].SetSelected(false);
m_ActiveMenuIndex = (m_ActiveMenuIndex + 1) % m_DebugMenus.Count;
m_DebugMenus[m_ActiveMenuIndex].SetSelected(true);
}
public void ToggleMenu()
{
m_Enabled = !m_Enabled;
m_DebugMenuUI.BuildGUI();
m_DebugMenuUI.Toggle();
m_DebugMenus[m_ActiveMenuIndex].SetSelected(m_Enabled);
}
public void OnValidate()
{
m_DebugMenus[m_ActiveMenuIndex].OnValidate();
}
public void OnMakePersistent()
{
DebugMenuItem selectedItem = m_DebugMenus[m_ActiveMenuIndex].GetSelectedDebugMenuItem();
if(selectedItem != null && selectedItem.readOnly)
{
if(m_PersistentDebugMenu.HasItem(selectedItem))
{
m_PersistentDebugMenu.RemoveDebugItem(selectedItem);
}
else
{
m_PersistentDebugMenu.AddDebugItem(selectedItem);
}
}
if(m_PersistentDebugMenu.itemCount == 0)
{
m_PersistentDebugMenu.SetSelected(false);
m_DebugMenuUI.EnablePersistentView(false); // Temp, should just need the above. Wait for background UI to be moved to menu itself
}
else
{
m_PersistentDebugMenu.SetSelected(true);
m_DebugMenuUI.EnablePersistentView(true);
}
}
public void OnMoveHorizontal(float value)
{
m_DebugMenus[m_ActiveMenuIndex].OnMoveHorizontal(value);
}
public void OnMoveVertical(float value)
{
m_DebugMenus[m_ActiveMenuIndex].OnMoveVertical(value);
}
T GetDebugMenu<T>() where T:DebugMenu
{
foreach(DebugMenu menu in m_DebugMenus)
{
if (menu is T)
return menu as T;
}
return null;
}
DebugMenu GetDebugMenu(string name)
{
foreach(DebugMenu menu in m_DebugMenus)
{
if (menu.name == name)
return menu;
}
return null;
}
public void Update()
{
if (m_ActiveMenuIndex != -1)
m_DebugMenus[m_ActiveMenuIndex].Update();
m_PersistentDebugMenu.Update();
}
public void AddDebugItem<DebugMenuType, ItemType>(string name, Func<object> getter, Action<object> setter = null, bool dynamicDisplay = false, DebugItemDrawer drawer = null) where DebugMenuType : DebugMenu
{
DebugMenuType debugMenu = GetDebugMenu<DebugMenuType>();
if (debugMenu != null)
{
debugMenu.AddDebugMenuItem<ItemType>(name, getter, setter, dynamicDisplay, drawer);
}
}
public void AddDebugItem<ItemType>(string debugMenuName, string name, Func<object> getter, Action<object> setter = null, bool dynamicDisplay = false, DebugItemDrawer drawer = null)
{
DebugMenu debugMenu = GetDebugMenu(debugMenuName);
// If the menu does not exist, create a generic one. This way, users don't have to explicitely create a new DebugMenu class if they don't need any particular overriding of default behavior.
if(debugMenu == null)
{
debugMenu = new DebugMenu(debugMenuName);
m_DebugMenus.Add(debugMenu);
}
if (debugMenu != null)
{
debugMenu.AddDebugMenuItem<ItemType>(name, getter, setter, dynamicDisplay, drawer);
}
}
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuManager.cs.meta


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

178
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUI.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
public class DebugMenuUI
{
public static Color kColorSelected = new Color(1.0f, 1.0f, 1.0f, 1.0f);
public static Color kColorUnSelected = new Color(0.25f, 0.25f, 0.25f, 1.0f);
public static Color kBackgroundColor = new Color(0.5f, 0.5f, 0.5f, 0.4f);
public static float kDebugItemNameWidth = 150.0f;
GameObject m_Root = null;
GameObject[] m_MenuRoots = null;
GameObject m_MainMenuRoot = null;
GameObject m_PersistentMenuRoot = null;
bool m_Enabled = false;
DebugMenuManager m_DebugMenuManager = null;
public DebugMenuUI(DebugMenuManager manager)
{
m_DebugMenuManager = manager;
}
public void Toggle()
{
m_Enabled = !m_Enabled;
m_MainMenuRoot.SetActive(m_Enabled);
}
public void EnablePersistentView(bool value)
{
m_PersistentMenuRoot.SetActive(value);
}
void CleanUpGUI()
{
Object.Destroy(m_Root);
}
public void BuildGUI()
{
if (m_Root != null)
return;
float kBorderSize = 5.0f;
m_Root = new GameObject("DebugMenu Root");
Canvas canvas = m_Root.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
UI.CanvasScaler canvasScaler = m_Root.AddComponent<UI.CanvasScaler>();
canvasScaler.uiScaleMode = UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(800.0f, 600.0f);
// TODO: Move background an layout to the menu itself.
m_MainMenuRoot = new GameObject("Background");
m_MainMenuRoot.AddComponent<CanvasRenderer>();
var image = m_MainMenuRoot.AddComponent<UI.Image>();
m_MainMenuRoot.transform.SetParent(m_Root.transform, false);
image.rectTransform.pivot = new Vector2(0.0f, 0.0f);
image.rectTransform.localPosition = Vector3.zero;
image.rectTransform.localScale = Vector3.one;
image.rectTransform.anchorMin = new Vector2(0.0f, 0.0f);
image.rectTransform.anchorMax = new Vector2(0.5f, 1.0f);
image.rectTransform.anchoredPosition = new Vector2(kBorderSize, kBorderSize);
image.rectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
image.color = kBackgroundColor;
GameObject goVL = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_MainMenuRoot);
RectTransform menuVLRectTransform = goVL.GetComponent<RectTransform>();
menuVLRectTransform.pivot = new Vector2(0.0f, 0.0f);
menuVLRectTransform.localPosition = Vector3.zero;
menuVLRectTransform.localScale = Vector3.one;
menuVLRectTransform.anchorMin = new Vector2(0.0f, 0.0f);
menuVLRectTransform.anchorMax = new Vector2(1.0f, 1.0f);
menuVLRectTransform.anchoredPosition = new Vector2(kBorderSize, kBorderSize);
menuVLRectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
// TODO: Move background an layout to the menu itself.
m_PersistentMenuRoot = new GameObject("Background_Persistent");
m_PersistentMenuRoot.AddComponent<CanvasRenderer>();
image = m_PersistentMenuRoot.AddComponent<UI.Image>();
m_PersistentMenuRoot.transform.SetParent(m_Root.transform, false);
image.rectTransform.pivot = new Vector2(0.0f, 0.0f);
image.rectTransform.localPosition = Vector3.zero;
image.rectTransform.localScale = Vector3.one;
image.rectTransform.anchorMin = new Vector2(0.7f, 0.8f);
image.rectTransform.anchorMax = new Vector2(1.0f, 1.0f);
image.rectTransform.anchoredPosition = new Vector2(kBorderSize, kBorderSize);
image.rectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
image.color = kBackgroundColor;
GameObject goVL2 = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_PersistentMenuRoot);
menuVLRectTransform = goVL2.GetComponent<RectTransform>();
menuVLRectTransform.pivot = new Vector2(0.0f, 0.0f);
menuVLRectTransform.localPosition = Vector3.zero;
menuVLRectTransform.localScale = Vector3.one;
menuVLRectTransform.anchorMin = new Vector2(0.0f, 0.0f);
menuVLRectTransform.anchorMax = new Vector2(1.0f, 1.0f);
menuVLRectTransform.anchoredPosition = new Vector2(kBorderSize, kBorderSize);
menuVLRectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
m_PersistentMenuRoot.SetActive(false);
DebugMenuUI.CreateTextElement("DebugMenuTitle", "Debug Menu", 14, TextAnchor.MiddleCenter, goVL);
int menuCount = m_DebugMenuManager.menuCount;
m_MenuRoots = new GameObject[menuCount];
for (int i = 0; i < menuCount; ++i)
{
m_MenuRoots[i] = m_DebugMenuManager.GetDebugMenu(i).BuildGUI(goVL);
}
m_DebugMenuManager.GetPersistentDebugMenu().BuildGUI(goVL2);
}
public static GameObject CreateVerticalLayoutGroup(string name, bool controlWidth, bool controlHeight, bool forceExpandWidth, bool forceExpandHeight, GameObject parent = null )
{
return CreateVerticalLayoutGroup(name, controlWidth, controlHeight, forceExpandWidth, forceExpandHeight, 0.0f, parent);
}
public static GameObject CreateVerticalLayoutGroup(string name, bool controlWidth, bool controlHeight, bool forceExpandWidth, bool forceExpandHeight, float spacing, GameObject parent = null )
{
GameObject go = new GameObject(name);
go.transform.SetParent(parent.transform, false);
UI.VerticalLayoutGroup verticalLayout = go.AddComponent<UI.VerticalLayoutGroup>();
verticalLayout.childControlHeight = controlHeight;
verticalLayout.childControlWidth = controlWidth;
verticalLayout.childForceExpandHeight = forceExpandHeight;
verticalLayout.childForceExpandWidth = forceExpandWidth;
verticalLayout.spacing = spacing;
return go;
}
public static GameObject CreateHorizontalLayoutGroup(string name, bool controlWidth, bool controlHeight, bool forceExpandWidth, bool forceExpandHeight, GameObject parent = null)
{
return CreateHorizontalLayoutGroup(name, controlWidth, controlHeight, forceExpandWidth, forceExpandHeight, 0.0f, parent);
}
public static GameObject CreateHorizontalLayoutGroup(string name, bool controlWidth, bool controlHeight, bool forceExpandWidth, bool forceExpandHeight, float spacing = 1.0f, GameObject parent = null)
{
GameObject go = new GameObject(name);
go.transform.SetParent(parent.transform, false);
UI.HorizontalLayoutGroup horizontalLayout = go.AddComponent<UI.HorizontalLayoutGroup>();
horizontalLayout.childControlHeight = controlHeight;
horizontalLayout.childControlWidth = controlWidth;
horizontalLayout.childForceExpandHeight = forceExpandHeight;
horizontalLayout.childForceExpandWidth = forceExpandWidth;
horizontalLayout.spacing = spacing;
return go;
}
public static GameObject CreateTextElement(string elementName, string text, int size = 14, TextAnchor alignment = TextAnchor.MiddleLeft, GameObject parent = null)
{
GameObject goText = new GameObject(elementName);
goText.transform.SetParent(parent.transform, false);
goText.transform.transform.localPosition = Vector3.zero;
goText.transform.transform.localScale = Vector3.one;
UI.Text textComponent = goText.AddComponent<UI.Text>();
textComponent.font = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
textComponent.text = text;
textComponent.alignment = alignment;
textComponent.fontSize = size;
textComponent.verticalOverflow = VerticalWrapMode.Overflow;
textComponent.color = DebugMenuUI.kColorUnSelected;
RectTransform rectTransform = goText.GetComponent<RectTransform>();
rectTransform.pivot = new Vector2(0.0f, 0.0f);
rectTransform.localPosition = new Vector3(0.0f, 0.0f);
rectTransform.anchorMin = new Vector2(0.0f, 0.0f);
rectTransform.anchorMax = new Vector2(1.0f, 1.0f);
return goText;
}
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUI.cs.meta


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

57
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUpdater.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
[ExecuteInEditMode]
public class DebugMenuUpdater : MonoBehaviour
{
void Update()
{
DebugMenuManager.instance.Update();
DebugActionManager.instance.Update();
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.EnableDebugMenu) != 0.0f)
{
DebugMenuManager.instance.ToggleMenu();
}
if (DebugMenuManager.instance.isEnabled)
{
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.PreviousDebugMenu) != 0.0f)
{
DebugMenuManager.instance.PreviousDebugMenu();
}
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.NextDebugMenu) != 0.0f)
{
DebugMenuManager.instance.NextDebugMenu();
}
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.Validate) != 0.0f)
{
DebugMenuManager.instance.OnValidate();
}
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.Persistent) != 0.0f)
{
DebugMenuManager.instance.OnMakePersistent();
}
float moveHorizontal = DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.MoveHorizontal);
if (moveHorizontal != 0.0f)
{
DebugMenuManager.instance.OnMoveHorizontal(moveHorizontal);
}
float moveVertical = DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.MoveVertical);
if (moveVertical != 0.0f)
{
DebugMenuManager.instance.OnMoveVertical(moveVertical);
}
}
}
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging/DebugMenuUpdater.cs.meta


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

138
Assets/ScriptableRenderPipeline/common/Debugging/Debugging.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
public class Debugging : MonoBehaviour
{
private static bool m_DebugControlEnabled = false;
public static bool debugControlEnabled { get { return m_DebugControlEnabled; } }
private float m_DebugControlEnabledMsgTime = 3.0f;
private float m_DebugControlEnabledMsgTimer = 0.0f;
private bool m_DebugKeyUp1 = false;
private bool m_DebugKeyUp2 = false;
private bool m_CanReceiveInput = true;
private static List<string> m_DebugMessages = new List<string>();
private static string kEnableDebugBtn1 = "Enable Debug Button 1";
private static string kEnableDebugBtn2 = "Enable Debug Button 2";
private string[] m_RequiredInputButtons = { kEnableDebugBtn1, kEnableDebugBtn2 };
private bool m_Valid = true;
public static void PushDebugMessage(string message)
{
m_DebugMessages.Add(message);
}
static public bool CheckRequiredInputButtonMapping(string[] values)
{
bool inputsOk = true;
foreach (string value in values)
{
try
{
Input.GetButton(value);
}
catch
{
Debug.LogError(string.Format("Required input button mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
static public bool CheckRequiredInputAxisMapping(string[] values)
{
bool inputsOk = true;
foreach (string value in values)
{
try
{
Input.GetAxis(value);
}
catch
{
Debug.LogWarning(string.Format("Required input axis mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
void OnEnable()
{
m_Valid = CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
void Update()
{
//if (m_Valid)
//{
// m_DebugControlEnabledMsgTimer += Time.deltaTime;
// bool enableDebug = Input.GetButton(kEnableDebugBtn1) && Input.GetButton(kEnableDebugBtn2) || Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.Backspace);
// if (m_CanReceiveInput && enableDebug)
// {
// m_DebugControlEnabled = !m_DebugControlEnabled;
// m_DebugControlEnabledMsgTimer = 0.0f;
// m_CanReceiveInput = false;
// m_DebugKeyUp1 = false;
// m_DebugKeyUp2 = false;
// }
// if (Input.GetButtonUp(kEnableDebugBtn1))
// {
// m_DebugKeyUp1 = true;
// }
// if (Input.GetButtonUp(kEnableDebugBtn2))
// {
// m_DebugKeyUp2 = true;
// }
// // For keyboard you want to be able to keep ctrl pressed.
// if (Input.GetKeyUp(KeyCode.Backspace))
// {
// m_DebugKeyUp1 = m_DebugKeyUp2 = true;
// }
// m_CanReceiveInput = m_DebugKeyUp1 && m_DebugKeyUp2;
// if (m_DebugControlEnabledMsgTimer < m_DebugControlEnabledMsgTime)
// {
// if (m_DebugControlEnabled)
// PushDebugMessage("Debug Controls Enabled");
// else
// PushDebugMessage("Debug Controls Disabled");
// }
//}
}
void OnGUI()
{
using (new GUILayout.HorizontalScope())
{
GUILayout.Space(10.0f);
using (new GUILayout.VerticalScope())
{
GUILayout.Space(10.0f);
for (int i = 0; i < m_DebugMessages.Count; ++i)
{
GUILayout.Label(m_DebugMessages[i]);
}
}
}
// Make sure to clear only after all relevant events have occured.
if (Event.current.type == EventType.Repaint)
m_DebugMessages.Clear();
}
}
}

9
Assets/ScriptableRenderPipeline/common/Debugging/Editor.meta


fileFormatVersion: 2
guid: 81304ee5cfbb2ff4b90df73d308d903e
folderAsset: yes
timeCreated: 1492162286
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/common/Debugging/Editor/DebugMenuEditor.cs.meta


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

68
Assets/ScriptableRenderPipeline/common/Debugging/Editor/DebugMenuEditor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace UnityEngine.Experimental.Rendering
{
// This is the class that handles rendering the debug menu in the editor (as opposed to the runtime version in the player)
public class DebugMenuEditor : EditorWindow
{
[MenuItem("HDRenderPipeline/Debug Menu")]
static void DisplayDebugMenu()
{
var window = EditorWindow.GetWindow<DebugMenuEditor>("Debug Menu");
window.Show();
}
DebugMenuManager m_DebugMenu = null;
DebugMenuEditor()
{
}
void OnEnable()
{
m_DebugMenu = DebugMenuManager.instance;
}
void OnGUI()
{
if (m_DebugMenu == null)
return;
// Contrary to the menu in the player, here we always render the menu wether it's enabled or not. This is a separate window so user can manage it however they want.
EditorGUI.BeginChangeCheck();
int debugMenuCount = m_DebugMenu.menuCount;
int activeMenuIndex = m_DebugMenu.activeMenuIndex;
using (new EditorGUILayout.HorizontalScope())
{
for(int i = 0 ; i < debugMenuCount ; ++i)
{
GUIStyle style = EditorStyles.miniButtonMid;
if (i == 0)
style = EditorStyles.miniButtonLeft;
if (i == debugMenuCount - 1)
style = EditorStyles.miniButtonRight;
if (GUILayout.Toggle(i == activeMenuIndex, new GUIContent(m_DebugMenu.GetDebugMenu(i).name), style))
activeMenuIndex = i;
}
}
if(EditorGUI.EndChangeCheck())
{
m_DebugMenu.activeMenuIndex = activeMenuIndex;
}
using(new EditorGUILayout.VerticalScope())
{
DebugMenu activeMenu = m_DebugMenu.GetDebugMenu(m_DebugMenu.activeMenuIndex);
for (int i = 0; i < activeMenu.itemCount; ++i)
{
activeMenu.GetDebugMenuItem(i).drawer.OnEditorGUI();
}
}
}
}
}

138
Assets/ScriptableRenderPipeline/common/Debugging.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{
public class Debugging : MonoBehaviour
{
private static bool m_DebugControlEnabled = false;
public static bool debugControlEnabled { get { return m_DebugControlEnabled; } }
private float m_DebugControlEnabledMsgTime = 3.0f;
private float m_DebugControlEnabledMsgTimer = 0.0f;
private bool m_DebugKeyUp1 = false;
private bool m_DebugKeyUp2 = false;
private bool m_CanReceiveInput = true;
private static List<string> m_DebugMessages = new List<string>();
private static string kEnableDebugBtn1 = "Enable Debug Button 1";
private static string kEnableDebugBtn2 = "Enable Debug Button 2";
private string[] m_RequiredInputButtons = { kEnableDebugBtn1, kEnableDebugBtn2 };
private bool m_Valid = true;
public static void PushDebugMessage(string message)
{
m_DebugMessages.Add(message);
}
static public bool CheckRequiredInputButtonMapping(string[] values)
{
bool inputsOk = true;
foreach (string value in values)
{
try
{
Input.GetButton(value);
}
catch
{
Debug.LogWarning(string.Format("Required input button mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
static public bool CheckRequiredInputAxisMapping(string[] values)
{
bool inputsOk = true;
foreach (string value in values)
{
try
{
Input.GetAxis(value);
}
catch
{
Debug.LogWarning(string.Format("Required input axis mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
void OnEnable()
{
m_Valid = CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
void Update()
{
if (m_Valid)
{
m_DebugControlEnabledMsgTimer += Time.deltaTime;
bool enableDebug = Input.GetButton(kEnableDebugBtn1) && Input.GetButton(kEnableDebugBtn2) || Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.Backspace);
if (m_CanReceiveInput && enableDebug)
{
m_DebugControlEnabled = !m_DebugControlEnabled;
m_DebugControlEnabledMsgTimer = 0.0f;
m_CanReceiveInput = false;
m_DebugKeyUp1 = false;
m_DebugKeyUp2 = false;
}
if (Input.GetButtonUp(kEnableDebugBtn1))
{
m_DebugKeyUp1 = true;
}
if (Input.GetButtonUp(kEnableDebugBtn2))
{
m_DebugKeyUp2 = true;
}
// For keyboard you want to be able to keep ctrl pressed.
if (Input.GetKeyUp(KeyCode.Backspace))
{
m_DebugKeyUp1 = m_DebugKeyUp2 = true;
}
m_CanReceiveInput = m_DebugKeyUp1 && m_DebugKeyUp2;
if (m_DebugControlEnabledMsgTimer < m_DebugControlEnabledMsgTime)
{
if (m_DebugControlEnabled)
PushDebugMessage("Debug Controls Enabled");
else
PushDebugMessage("Debug Controls Disabled");
}
}
}
void OnGUI()
{
using (new GUILayout.HorizontalScope())
{
GUILayout.Space(10.0f);
using (new GUILayout.VerticalScope())
{
GUILayout.Space(10.0f);
for (int i = 0; i < m_DebugMessages.Count; ++i)
{
GUILayout.Label(m_DebugMessages[i]);
}
}
}
// Make sure to clear only after all relevant events have occured.
if (Event.current.type == EventType.Repaint)
m_DebugMessages.Clear();
}
}
}

/Assets/ScriptableRenderPipeline/common/Debugging.cs.meta → /Assets/ScriptableRenderPipeline/common/Debugging/Debugging.cs.meta

正在加载...
取消
保存