浏览代码

Merge remote-tracking branch 'refs/remotes/origin/Add-Per-Pixel-scale' into Add-Per-Pixel-Scale-Seb

/stochastic_alpha_test
sebastienlagarde 7 年前
当前提交
b466af28
共有 11 个文件被更改,包括 92 次插入64 次删除
  1. 4
      SampleScenes/OnTileDeferredTest/Common/MobileTestSceneManager.cs
  2. 8
      ScriptableRenderPipeline/Core/Debugging/DebugItemHandler.cs
  3. 2
      ScriptableRenderPipeline/Core/Debugging/DebugItemUI.cs
  4. 16
      ScriptableRenderPipeline/Core/Debugging/DebugMenuState.cs
  5. 2
      ScriptableRenderPipeline/Core/Debugging/DebugPanel.cs
  6. 41
      ScriptableRenderPipeline/Core/Debugging/DebugPanelUI.cs
  7. 9
      ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  8. 4
      ScriptableRenderPipeline/HDRenderPipeline/Debug/LightingDebugPanel.cs
  9. 41
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  10. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  11. 27
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs

4
SampleScenes/OnTileDeferredTest/Common/MobileTestSceneManager.cs


int detectSwipe() {
if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Ended) {
Vector2 endPosition = Input.GetTouch (0).position;
Vector2 delta = endPosition - startPosition;
//Vector2 delta = endPosition - startPosition;
if (startPosition.x < endPosition.x)
return 1;

detectTouchBegan();
#endif
}
}
}

8
ScriptableRenderPipeline/Core/Debugging/DebugItemHandler.cs


m_DebugItem = item;
}
// Method user needs to override for specific value clamping.
public virtual void ClampValues(Func<object> getter, Action<object> setter) {}
// Method user needs to override for specific value validation.
public virtual void ValidateValues(Func<object> getter, Action<object> setter) {}
// Method that will create UI items for runtime debug menu.
public abstract DebugItemUI BuildGUI(GameObject parent);

m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
setter(Mathf.Clamp((float)getter(), m_Min, m_Max));
}

m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
setter(Math.Min(m_Max, Math.Max(m_Min, (uint)getter())));
}

2
ScriptableRenderPipeline/Core/Debugging/DebugItemUI.cs


public bool dynamicDisplay { get { return (m_DebugItem.flags & DebugItemFlag.DynamicDisplay) != 0; } }
public DebugItem debugItem { get { return m_DebugItem; } }
protected DebugItemUI(DebugItem debugItem)
{
m_DebugItem = debugItem;

16
ScriptableRenderPipeline/Core/Debugging/DebugMenuState.cs


namespace UnityEngine.Experimental.Rendering
{
[Serializable]
public abstract class DebugItemState
: ScriptableObject
{

if (debugItemState == null)
{
debugItemState = item.handler.CreateDebugItemState();
debugItemState.hideFlags = HideFlags.DontSave;
debugItemState.Initialize(item);
debugItemState.SetValue(item.GetValue());
AddDebugItemState(debugItemState);
if(debugItemState != null)
{
debugItemState.hideFlags = HideFlags.DontSave;
debugItemState.Initialize(item);
debugItemState.SetValue(item.GetValue());
AddDebugItemState(debugItemState);
}
else
{
Debug.LogWarning(String.Format("DebugItemState for item {0} of type {1} is not provided.\nDid you implement CreateDebugItemState in your custom Handler?", item.name, item.type));
}
}
}
}

2
ScriptableRenderPipeline/Core/Debugging/DebugPanel.cs


if(m_Setter != null)
{
m_Setter(value);
m_Handler.ClampValues(m_Getter, m_Setter);
m_Handler.ValidateValues(m_Getter, m_Setter);
}
if (record && OnItemDirty != null)

41
ScriptableRenderPipeline/Core/Debugging/DebugPanelUI.cs


GameObject.Destroy(child.gameObject);
}
m_ItemsUI.Clear();
protected void AddDebugItemUI(DebugItem item, GameObject parent)
{
#if UNITY_EDITOR
// We don't want runtime only items even in the "player" debug menu if we are in the editor.
if (item.runtimeOnly)
return;
#endif
if(item.editorOnly)
return;
DebugItemUI itemUI = item.handler.BuildGUI(parent);
if(itemUI == null)
{
Debug.LogWarning(String.Format("DebugItemUI not provided for item {0} of type {1}.\n Did you implement BuildGUI for your custom Handler?", item.name, item.type));
}
else
{
m_ItemsUI.Add(itemUI);
}
}
m_ItemsUI.Clear();
#if UNITY_EDITOR
// We don't want runtime only items even in the "player" debug menu if we are in the editor.
if (item.runtimeOnly)
continue;
#endif
if(!item.editorOnly)
{
DebugItemHandler handler = item.handler; // Should never be null, we have at least the default handler
m_ItemsUI.Add(handler.BuildGUI(parent));
}
AddDebugItemUI(item, parent);
}
}

{
if (m_SelectedItem != -1)
{
return m_DebugPanel.GetDebugItem(m_SelectedItem);
return m_ItemsUI[m_SelectedItem].debugItem;
}
return null;

public void OnMoveHorizontal(float value)
{
if (m_SelectedItem != -1 && !m_DebugPanel.GetDebugItem(m_SelectedItem).readOnly)
if (m_SelectedItem != -1 && !m_ItemsUI[m_SelectedItem].debugItem.readOnly)
{
if (value > 0.0f)
m_ItemsUI[m_SelectedItem].OnIncrement();

public void OnValidate()
{
if (m_SelectedItem != -1 && !m_DebugPanel.GetDebugItem(m_SelectedItem).readOnly)
if (m_SelectedItem != -1 && !m_ItemsUI[m_SelectedItem].debugItem.readOnly)
m_ItemsUI[m_SelectedItem].OnValidate();
}

9
ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution.
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness)
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness, uint mipMapCount)
return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
return perceptualRoughness * mipMapCount;
}
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness)
{
return PerceptualRoughnessToMipmapLevel(perceptualRoughness, UNITY_SPECCUBE_LOD_STEPS);
}
// The *accurate* version of the non-linear remapping. It works by

4
ScriptableRenderPipeline/HDRenderPipeline/Debug/LightingDebugPanel.cs


}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
m_Max = (uint)hdPipeline.GetShadowAtlasCount() - 1;

}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
m_Max = (uint)hdPipeline.GetCurrentShadowCount() - 1;

41
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// Color pyramid (width, height, lodcount, Unused)
float4 _GaussianPyramidColorMipSize;
TEXTURE2D(_GaussianPyramidColorTexture);
SAMPLER2D(sampler_GaussianPyramidColorTexture);
SAMPLER2D(sampler_PyramidDepthTexture);
SamplerState ltc_trilinear_clamp_sampler;
// TODO: This one should be set into a constant Buffer at pass frequency (with _Screensize)
TEXTURE2D(_PreIntegratedFGD);
TEXTURE2D_ARRAY(_LtcData); // We pack the 3 Ltc data inside a texture array

// Encode normal on 20bit with oct compression + 2bit of sign
float2 octNormalWS = PackNormalOctEncode((surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT) ? surfaceData.coatNormalWS : surfaceData.normalWS);
// To have more precision encode the sign of xy in a separate uint
uint octNormalSign = (octNormalWS.x > 0.0 ? 1 : 0) + (octNormalWS.y > 0.0 ? 2 : 0);
uint octNormalSign = (octNormalWS.x < 0.0 ? 1 : 0) | (octNormalWS.y < 0.0 ? 2 : 0);
// Store octNormalSign on two bits with perceptualRoughness
outGBuffer1 = float4(abs(octNormalWS), PackFloatInt10bit(PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness), octNormalSign, 4.0), PackMaterialId(surfaceData.materialId));

{
// Encode tangent on 16bit with oct compression
float2 octTangentWS = PackNormalOctEncode(surfaceData.tangentWS);
outGBuffer2 = float4(octTangentWS * 0.5 + 0.5, surfaceData.anisotropy, PackFloatInt8bit(surfaceData.metallic, 0.0, 4.0));
// To have more precision encode the sign of xy in a separate uint
uint octTangentSign = (octTangentWS.x < 0.0 ? 1 : 0) | (octTangentWS.y < 0.0 ? 2 : 0);
outGBuffer2 = float4(abs(octTangentWS), surfaceData.anisotropy, PackFloatInt8bit(surfaceData.metallic, octTangentSign, 4.0));
}
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT)
{

int octNormalSign;
UnpackFloatInt10bit(inGBuffer1.b, 4.0, bsdfData.perceptualRoughness, octNormalSign);
inGBuffer1.r *= (octNormalSign & 1) ? 1.0 : -1.0;
inGBuffer1.g *= (octNormalSign & 2) ? 1.0 : -1.0;
inGBuffer1.r = (octNormalSign & 1) ? -inGBuffer1.r : inGBuffer1.r;
inGBuffer1.g = (octNormalSign & 2) ? -inGBuffer1.g : inGBuffer1.g;
bsdfData.normalWS = UnpackNormalOctEncode(float2(inGBuffer1.r, inGBuffer1.g));
bsdfData.roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);

else if (bsdfData.materialId == MATERIALID_LIT_ANISO && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_ANISO))
{
float metallic;
int unused;
UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, unused);
int octTangentSign;
UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, octTangentSign);
float3 tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0));
inGBuffer2.r = (octTangentSign & 1) ? -inGBuffer2.r : inGBuffer2.r;
inGBuffer2.g = (octTangentSign & 2) ? -inGBuffer2.g : inGBuffer2.g;
float3 tangentWS = UnpackNormalOctEncode(inGBuffer2.rg);
float anisotropy = inGBuffer2.b;
FillMaterialIdAnisoData(bsdfData.roughness, bsdfData.normalWS, tangentWS, anisotropy, bsdfData);
}

float3 refractedBackPointWS = float3(0.0, 0.0, 0.0);
float opticalDepth = 0.0;
uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
// For all refraction approximation, to calculate the refracted point in world space,
// we approximate the scene as a plane (back plane) with normal -V at the depth hit point.
// (We avoid to raymarch the depth texture to get the refracted point.)

float3 R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Get the depth of the approximated back plane
float pyramidDepth = SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, posInput.positionSS, 2.0).r;
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane

// So the light is refracted twice: in and out of the tangent sphere
// Get the depth of the approximated back plane
float pyramidDepth = SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, posInput.positionSS, 2.0).r;
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane

float3 R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Get the depth of the approximated back plane
float pyramidDepth = SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, posInput.positionSS, 2.0).r;
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane

// Calculate screen space coordinates of refracted point in back plane
float4 refractedBackPointCS = mul(_ViewProjMatrix, float4(refractedBackPointWS, 1.0));
float2 refractedBackPointSS = ComputeScreenSpacePosition(refractedBackPointCS);
float refractedBackPointDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, refractedBackPointSS, 0.0).r, _ZBufferParams);
float refractedBackPointDepth = LinearEyeDepth(LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, refractedBackPointSS * depthSize, 0).r, _ZBufferParams);
// Exit if texel is out of color buffer
// Or if the texel is from an object in front of the object

{
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, sampler_GaussianPyramidColorTexture, posInput.positionSS, 0.0).rgb;
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
float mipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, sampler_GaussianPyramidColorTexture, refractedBackPointSS.xy, mipLevel).rgb;
float mipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness, uint(_GaussianPyramidColorMipSize.z));
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, refractedBackPointSS, mipLevel).rgb;
// Beer-Lamber law for absorption
float3 transmittance = exp(-bsdfData.absorptionCoefficient * opticalDepth);

// Use perfect flat transparency when we cannot fetch the correct pixel color for the refracted point
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, sampler_GaussianPyramidColorTexture, posInput.positionSS, 0.0).rgb;
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
#endif
}

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
float3 interpolatedVertexNormal = input.worldToTangent[2].xyz;
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;

27
ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


private Camera m_CurrCamera = null;
private int m_LightIndicesCount = 0;
private ComputeBuffer m_LightIndexListBuffer;
private static readonly int kMaxCascades = 4;

private RenderTargetIdentifier m_CameraColorRT;
private RenderTargetIdentifier m_CameraDepthRT;
private bool m_RenderToIntermediateTarget = false;
private bool m_IntermediateTextureArray = false;
private const int kShadowDepthBufferBits = 16;

{
m_LightIndexListBuffer.Dispose();
m_LightIndexListBuffer = null;
m_LightIndicesCount = 0;
}
}

private void ShadowPass(VisibleLight[] visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
{
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
{
VisibleLight mainLight = visibleLights[lightData.mainLightIndex];
if (mainLight.light.shadows != LightShadows.None)

// Setup camera matrices
context.SetupCameraProperties(m_CurrCamera, stereoEnabled);
RendererConfiguration rendererSettings = GetRendererSettings(ref lightData);
BeginForwardRendering(ref context, renderingConfig);

// shadow lights types.
// Lightweight pipeline only supports 1 single directional shadow light.
// Any additional pixel lights don't cast shadows.
//
//
// 2) If shadows are disabled or no shadow light is present then main light is the main brighest directional
// 3) If neither a shadow light or main light is first visible light.
private int GetMainLightIndex(VisibleLight[] lights)

int mainShadowLight = -1;
for (int i = 0; i < lights.Length; ++i)
for (int i = 0; i < lights.Length; ++i)
if (shadowsEnabled && LightweightUtils.IsSupportedShadowType (lights[i].lightType) && lights[i].light.shadows != LightShadows.None)
if (shadowsEnabled && LightweightUtils.IsSupportedShadowType (lights[i].lightType) && lights[i].light.shadows != LightShadows.None)
{
// Shadow Type priority: Soft > Hard > None
if (mainShadowLight < 0 || lights[i].light.shadows > lights[mainShadowLight].light.shadows)

if (lights[i].lightType == LightType.Directional)
if (lights[i].lightType == LightType.Directional)
{
if (mainDirectional < 0 || lights[i].light.intensity > lights[mainDirectional].light.intensity)
mainDirectional = i;

if (mainShadowLight >= 0)
if (mainShadowLight >= 0)
}
}
return 0;
}

{
// Main light has an optimized shader path for main light. This will benefit games that only care about a single light.
// Lightweight pipeline also supports only a single shadow light, if available it will be the main light.
if (lightData.mainLightIndex != -1)
if (lightData.mainLightIndex != -1)
{
SetupMainLightConstants (cmd, lights, lightData.mainLightIndex, ref context);
if (lightData.shadowsRendered)

int[] lightIndexMap = m_CullResults.GetLightIndexMap();
int lightIter = 0;
for (int i = 0; i < totalLightCount; ++i)
for (int i = 0; i < totalLightCount; ++i)
if (i == lightData.mainLightIndex || lightIter >= maxLights)
if (i == lightData.mainLightIndex || lightIter >= maxLights)
{
lightIndexMap[i] = -1;
continue;

正在加载...
取消
保存