浏览代码

Revert last wrongly merge in Unity2017.3, should not have been done...

/Yibing-Project-2
Sebastien Lagarde 7 年前
当前提交
48c698bd
共有 36 个文件被更改,包括 173 次插入2571 次删除
  1. 40
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs.meta
  3. 114
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SSS Settings.asset
  4. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl
  5. 25
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
  6. 5
      ScriptableRenderPipeline/LightweightPipeline.meta
  7. 4
      Tests.meta
  8. 36
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/037_Shader_StandardParticleShaders/Standard Particle Shader/Scripts/LookAt.cs
  9. 10
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Materials/ComplexMaterial/Textures.meta
  10. 43
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/035_Shader_TerrainShaders/Free_SpeedTrees/Broadleaves.obj
  11. 78
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/035_Shader_TerrainShaders/Free_SpeedTrees/Broadleaves.obj.meta
  12. 10
      SampleScenes/HDTest/TransparencyTest.meta
  13. 519
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/Vegetation.shader
  14. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/Vegetation.shader.meta
  15. 269
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationData.hlsl
  16. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationData.hlsl.meta
  17. 176
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationDataMeshModification.hlsl
  18. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationDataMeshModification.hlsl.meta
  19. 21
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationProperties.hlsl
  20. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationProperties.hlsl.meta
  21. 56
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationWind.hlsl
  22. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationWind.hlsl.meta
  23. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Character.meta
  24. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Eye.meta
  25. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Fabric.meta
  26. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Hair.meta
  27. 327
      ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare1.hlsl
  28. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare1.hlsl.meta
  29. 881
      ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare2.hlsl
  30. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare2.hlsl.meta
  31. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation.meta

40
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


// We compute subsurface scattering here. Therefore, no objects rendered afterwards will exhibit SSS.
// Currently, there is no efficient way to switch between SRT and MRT for the forward pass;
// therefore, forward-rendered objects do not output split lighting required for the SSS pass.
// YIBING END
//SubsurfaceScatteringPass(hdCamera, cmd, m_Asset.sssSettings);
// YIBING END
SubsurfaceScatteringPass(hdCamera, cmd, sssSettings);
// YIBING BEGIN
RenderForwardOnlyOpaqueSplitLighting(m_CullResults, camera, renderContext, cmd);
// TEMP: We need to perform a second render of the stencil it to be take into account for SSS with Disney
// When we implement forward SSS i HD,be sure we do it correctly and don't duplicate copy
PrepareAndBindStencilTexture(cmd);
SubsurfaceScatteringPass(hdCamera, cmd, m_Asset.sssSettings);
// YIBING END
RenderLightingDebug(hdCamera, cmd, m_CameraColorBufferRT, m_CurrentDebugDisplaySettings);

}
}
}
// YIBING BEGIN
void RenderForwardOnlyOpaqueSplitLighting(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
string passName = "ForwardOnlyOpaqueSplitLighting";
using (new ProfilingSample(cmd, passName))
{
RenderTargetIdentifier[] colorMRTs = new RenderTargetIdentifier[4];
colorMRTs[0] = m_CameraColorBufferRT;
colorMRTs[1] = m_CameraSssDiffuseLightingBufferRT;
colorMRTs[2] = m_GbufferManager.GetGBuffers()[0];
colorMRTs[3] = m_GbufferManager.GetGBuffers()[2];
CoreUtils.SetRenderTarget(cmd, colorMRTs, m_CameraDepthStencilBufferRT);
m_LightLoop.RenderForward(camera, cmd, true);
// Forward opaque material always have a prepass (whether or not we use deferred, whether or not there is option like alpha test only) so we pass the right depth state here.
// YIBING PROJECT Note: The shader don't use DoAlphaTest, let's don't care about performance and just redo the clip test here.
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, new ShaderPassName(passName), HDUtils.k_RendererConfigurationBakedLighting);
// We need to unset the multi render target before going further, because compute shader SSS pass will not be able to bind the Gbuffer set in write mode.
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
}
}
// YIBING END
void RenderTransparentDepthPrepass(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{

2
ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs.meta


fileFormatVersion: 2
guid: 6cca8ebc3f1f3ec40bdeeebd8df71a62
guid: a586982c0c38ee64095f06495d043462
timeCreated: 1501072635
licenseType: Pro
MonoImporter:

114
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SSS Settings.asset


m_Script: {fileID: 11500000, guid: 3418a08abd15e9a49af3ccbc9e15b5ea, type: 3}
m_Name: SSS Settings
m_EditorClassIdentifier:
useDisneySSS: 0
useDisneySSS: 1
- name: girl skin SSS
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 0.30882353, g: 0.12904185, b: -0.009083053, a: 1}
- name: Skin
scatteringDistance: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1}
transmissionTint: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1}
thicknessRemap: {x: 0, y: 31.125778}
worldScale: 1
scatterDistance1: {r: 1, g: 0.75902635, b: 0.60294116, a: 0}
scatterDistance2: {r: 0.88235295, g: 0.08474346, b: 0.05, a: 0}
lerpWeight: 0.388
- name: eye test
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 14.300124}
worldScale: 1
scatterDistance1: {r: 0.9338235, g: 0.83239096, b: 0.50124353, a: 0}
scatterDistance2: {r: 1, g: 0.72636914, b: 0.47794116, a: 0}
lerpWeight: 0.586
- name: hoodie fabric
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 3.1851997}
worldScale: 1
scatterDistance1: {r: 0.83823526, g: 1, b: 0.78676474, a: 0}
scatterDistance2: {r: 0.7780933, g: 0.8235294, b: 0.05, a: 0}
lerpWeight: 0.712
- name: Foliage SSS
scatteringDistance: {r: 0.75735295, g: 0.7008203, b: 0.24502596, a: 1}
transmissionTint: {r: 0.62860185, g: 0.71323526, b: 0.24124135, a: 1}
texturingMode: 0
transmissionMode: 1
thicknessRemap: {x: 0, y: 10.9375}
worldScale: 1
scatterDistance1: {r: 0.05, g: 0.7967537, b: 0.8308824, a: 0}
scatterDistance2: {r: 0.20000005, g: 1, b: 0.05, a: 0}
lerpWeight: 0.5
- name: SkinSSSProfile
scatteringDistance: {r: 0.6691177, g: 0.4336563, b: 0.3689987, a: 1}
transmissionTint: {r: 1, g: 0.6321458, b: 0.5294118, a: 1}
texturingMode: 1
transmissionMode: 2
thicknessRemap: {x: 0, y: 7.96165}
worldScale: 1
scatterDistance1: {r: 0.86764705, g: 0.395545, b: 0.395545, a: 0}
scatterDistance2: {r: 0.13235295, g: 0.05, b: 0.05, a: 0}
lerpWeight: 0.5
- name: Leaves LowSSSProfile
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 0.24773444, g: 0.28676468, b: 0.15814228, a: 1}
texturingMode: 0
transmissionMode: 1
thicknessRemap: {x: 0.01, y: 0.1}
thicknessRemap: {x: 0, y: 8.152544}
scatterDistance1: {r: 0.05, g: 1, b: 0.7103448, a: 0}
scatterDistance2: {r: 0.862069, g: 1, b: 0.05, a: 0}
scatterDistance1: {r: 0.3019608, g: 0.20000002, b: 0.20000002, a: 0}
scatterDistance2: {r: 0.6, g: 0.20000002, b: 0.20000002, a: 0}
- name: leaves close up
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 0.99868155, g: 1, b: 0.9044118, a: 1}
- name: Foliage
scatteringDistance: {r: 0.7568628, g: 0.7019608, b: 0.24313727, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
thicknessRemap: {x: 0.30539423, y: 17.054262}
worldScale: 1
scatterDistance1: {r: 0.7867041, g: 1.0220588, b: 0.7439987, a: 0}
scatterDistance2: {r: 0.95818, g: 1.0367647, b: 0.49551255, a: 0}
lerpWeight: 0.5
- name: skin SSS
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 0.43199998, b: 0, a: 1}
texturingMode: 0
transmissionMode: 2
thicknessRemap: {x: 1.5147563, y: 25}
worldScale: 1
scatterDistance1: {r: 0.9411765, g: 0.7540866, b: 0.5536332, a: 0}
scatterDistance2: {r: 0.66176474, g: 0.34001017, b: 0.16544119, a: 0}
lerpWeight: 0.51
- name: Profile 81
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
thicknessRemap: {x: 0, y: 0.2873168}
lerpWeight: 1
- name: Profile 91
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 101
lerpWeight: 0.5
- name: Profile 2
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0

scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 111
- name: Profile 3
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0

scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 121
- name: Profile 4
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0

scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 131
- name: Profile 5
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0

scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 141
- name: Profile 6
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl


#include "Unlit/Unlit.hlsl"
#elif defined(UNITY_MATERIAL_IRIDESCENCE)
//#include "Iridescence/Iridescence.hlsl"
// YIBING BEGIN
#elif defined(UNITY_MATERIAL_HAIR)
#include "Hair/Hair.hlsl"
#elif defined(UNITY_MATERIAL_EYE)
#include "Eye/Eye.hlsl"
#elif defined(UNITY_MATERIAL_FABRIC)
#include "Fabric/Fabric.hlsl"
// YIBING END
#endif
//-----------------------------------------------------------------------------

25
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


#endif // TESSELLATION_ON
void Frag(PackedVaryingsToPS packedInput,
// YIBING BEGIN
#ifdef FORWARD_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // this is outSpecular
out float4 outDiffuse : SV_Target1,
out float4 outGbuffer0 : SV_Target2,
out float4 outGbuffer2 : SV_Target3
#else
out float4 outColor : SV_Target0
#endif
//out float4 outColor : SV_Target0
// YIBING END
out float4 outColor : SV_Target0
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif

bakeLightingData.bakeShadowMask = float4(builtinData.shadowMask0, builtinData.shadowMask1, builtinData.shadowMask2, builtinData.shadowMask3);
#endif
LightLoop(V, posInput, preLightData, bsdfData, bakeLightingData, featureFlags, diffuseLighting, specularLighting);
// YIBING BEGIN
// If we have split lighting it mean we are opaque (no SSS on transparent)
#ifdef FORWARD_SPLIT_LIGHTING
outColor = float4(specularLighting, 1.0);
outDiffuse = float4(diffuseLighting, 1.0);
outGbuffer0 = EncodeSplitLightingGBuffer0(surfaceData);
outGbuffer2 = EncodeSplitLightingGBuffer1(surfaceData);
#else
#endif
// outColor = float4(diffuseLighting + specularLighting, builtinData.opacity);
// YIBING END
}
#ifdef _DEPTHOFFSET_ON

5
ScriptableRenderPipeline/LightweightPipeline.meta


fileFormatVersion: 2
guid: f9ca3ff6d08b48b42ae424159889f367
guid: 4923a4700d4d643a9a862a74e04870b3
timeCreated: 1509065726
timeCreated: 1481548458
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

4
Tests.meta


fileFormatVersion: 2
guid: f81d4d56cb6097e4d9f9bf7ef575ef55
guid: eb8e04b048ac2104e8e83f973e2f7829
timeCreated: 1509065725
timeCreated: 1503385907
licenseType: Pro
DefaultImporter:
externalObjects: {}

36
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/037_Shader_StandardParticleShaders/Standard Particle Shader/Scripts/LookAt.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// </summary>
public class LookAt : MonoBehaviour {
private Transform cam;
// Use this for initialization
/// </summary>
public class LookAt : MonoBehaviour {
private Transform cam;
// Use this for initialization
cam = Camera.main.transform;
}
// Update is called once per frame
cam = Camera.main.transform;
}
// Update is called once per frame
transform.LookAt(cam);
}
}
transform.LookAt(cam);
}
}

10
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Materials/ComplexMaterial/Textures.meta


fileFormatVersion: 2
guid: ce883dc5ae95f394b8a00d0badafa35c
folderAsset: yes
timeCreated: 1509027998
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

43
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/035_Shader_TerrainShaders/Free_SpeedTrees/Broadleaves.obj


# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 14.05.2014 09:45:05
#
# object diamond
#
v 0.8296 -1.2260 0.0993
v 0.0687 -0.9154 0.4403
v -0.0157 -1.8703 0.1686
v -0.8101 -1.2001 0.0993
v 0.0000 0.0000 0.0000
# 5 vertices
vn -0.4082 0.0023 0.9129
vn -0.0470 -0.1441 0.9884
vn 0.0136 0.2725 0.9620
vn 0.0136 0.2725 0.9620
vn -0.0470 -0.1441 0.9884
vn 0.5624 -0.1491 0.8133
vn -0.4082 0.0023 0.9129
vn 0.0064 -0.4331 0.9013
vn -0.0470 -0.1441 0.9884
vn -0.0470 -0.1441 0.9884
vn 0.0064 -0.4331 0.9013
vn 0.5624 -0.1491 0.8133
# 12 vertex normals
vt 0.0005 0.6554 0.2258
vt 0.4641 0.4895 0.9995
vt 0.5155 0.9995 0.3830
vt 0.9995 0.6415 0.2258
vt 0.5059 0.0005 0.0005
# 5 texture coords
g diamond
s 1
f 1/1/1 2/2/2 3/3/3
f 3/3/4 2/2/5 4/4/6
f 1/1/7 5/5/8 2/2/9
f 2/2/10 5/5/11 4/4/12
# 4 faces

78
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/035_Shader_TerrainShaders/Free_SpeedTrees/Broadleaves.obj.meta


fileFormatVersion: 2
guid: cf3c778055c27074b849beaac044a88b
timeCreated: 1452616724
licenseType: Store
ModelImporter:
serializedVersion: 19
fileIDToRecycleName:
100000: //RootNode
100002: diamond
400000: //RootNode
400002: diamond
2300000: diamond
3300000: diamond
4300000: diamond
materials:
importMaterials: 1
materialName: 0
materialSearch: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleRotations: 1
optimizeGameObjects: 0
motionNodeName:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
clipAnimations: []
isReadable: 1
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
importBlendShapes: 1
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
optimizeMeshForGPU: 1
keepQuads: 0
weldVertices: 1
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
importAnimation: 1
copyAvatar: 0
humanDescription:
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
rootMotionBoneName:
hasTranslationDoF: 0
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 0
humanoidOversampling: 1
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

10
SampleScenes/HDTest/TransparencyTest.meta


fileFormatVersion: 2
guid: 7a6daa9d8dbc4904dae6deaa667846ef
folderAsset: yes
timeCreated: 1509455772
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

519
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/Vegetation.shader


Shader "HDRenderPipeline/Vegetation"
{
Properties
{
// Following set of parameters represent the parameters node inside the MaterialGraph.
// They are use to fill a SurfaceData. With a MaterialGraph this should not exist.
// Reminder. Color here are in linear but the UI (color picker) do the conversion sRGB to linear
_BaseColor("BaseColor", Color) = (1,1,1,1)
_BaseColorMap("BaseColorMap", 2D) = "white" {}
_Metallic("_Metallic", Range(0.0, 1.0)) = 0
_Smoothness("Smoothness", Range(0.0, 1.0)) = 1.0
_MaskMap("MaskMap", 2D) = "white" {}
_SmoothnessRemapMin("SmoothnessRemapMin", Float) = 0.0
_SmoothnessRemapMax("SmoothnessRemapMax", Float) = 1.0
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map
_NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value
_NormalScale("_NormalScale", Range(0.0, 2.0)) = 1
_BentNormalMap("_BentNormalMap", 2D) = "bump" {}
_BentNormalMapOS("_BentNormalMapOS", 2D) = "white" {}
_HeightMap("HeightMap", 2D) = "black" {}
// Caution: Default value of _HeightAmplitude must be (_HeightMax - _HeightMin) * 0.01
[HideInInspector] _HeightAmplitude("Height Amplitude", Float) = 0.02 // In world units. This will be computed in the UI.
_HeightMin("Heightmap Min", Float) = -1
_HeightMax("Heightmap Max", Float) = 1
_HeightCenter("Height Center", Range(0.0, 1.0)) = 0.5 // In texture space
_DetailMap("DetailMap", 2D) = "black" {}
_DetailAlbedoScale("_DetailAlbedoScale", Range(0.0, 2.0)) = 1
_DetailNormalScale("_DetailNormalScale", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(0.0, 2.0)) = 1
_TangentMap("TangentMap", 2D) = "bump" {}
_TangentMapOS("TangentMapOS", 2D) = "white" {}
_Anisotropy("Anisotropy", Range(-1.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}
_SubsurfaceProfile("Subsurface Profile", Int) = 0
_SubsurfaceRadius("Subsurface Radius", Range(0.0, 1.0)) = 1.0
_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.0, 1.0)) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_CoatCoverage("Coat Coverage", Range(0.0, 1.0)) = 1.0
_CoatIOR("Coat IOR", Range(0.0, 1.0)) = 0.5
_SpecularColor("SpecularColor", Color) = (1, 1, 1, 1)
_SpecularColorMap("SpecularColorMap", 2D) = "white" {}
// Following options are for the GUI inspector and different from the input parameters above
// These option below will cause different compilation flag.
[ToggleOff] _EnableSpecularOcclusion("Enable specular occlusion", Float) = 0.0
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}
_EmissiveIntensity("EmissiveIntensity", Float) = 0
[ToggleOff] _AlbedoAffectEmissive("Albedo Affect Emissive", Float) = 0.0
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 1.0
[Enum(Add, 0, Multiply, 1)] _DistortionBlendMode("Distortion Blend Mode", Int) = 0
[HideInInspector] _DistortionSrcBlend("Distortion Blend Src", Int) = 0
[HideInInspector] _DistortionDstBlend("Distortion Blend Dst", Int) = 0
[HideInInspector] _DistortionBlurSrcBlend("Distortion Blur Blend Src", Int) = 0
[HideInInspector] _DistortionBlurDstBlend("Distortion Blur Blend Dst", Int) = 0
[HideInInspector] _DistortionBlurBlendMode("Distortion Blur Blend Mode", Int) = 0
_DistortionScale("Distortion Scale", Float) = 1
_DistortionBlurScale("Distortion Blur Scale", Float) = 1
_DistortionBlurRemapMin("DistortionBlurRemapMin", Float) = 0.0
_DistortionBlurRemapMax("DistortionBlurRemapMax", Float) = 1.0
[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionMode("Refraction Mode", Int) = 0
_IOR("Indice Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_ATDistance("Transmittance Absorption Distance", Float) = 1.0
[ToggleOff] _PreRefractionPass("PreRefractionPass", Float) = 0.0
// Stencil state
[HideInInspector] _StencilRef("_StencilRef", Int) = 2 // StencilLightingUsage.RegularLighting (fixed at compile time)
// Blending state
[HideInInspector] _SurfaceType("__surfacetype", Float) = 0.0
[HideInInspector] _BlendMode("__blendmode", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[ToggleOff] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleOff] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0
[ToggleOff] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[Enum(UV0, 0, Planar, 4, TriPlanar, 5)] _UVBase("UV Set for base", Float) = 0
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _InvTilingScale("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Subsurface Scattering, 0, Standard, 1, Anisotropy, 2, ClearCoat, 3, Specular Color, 4)] _MaterialID("MaterialId", Int) = 1 // MaterialId.RegularLighting
[Enum(None, 0, Vertex displacement, 1, Pixel displacement, 2)] _DisplacementMode("DisplacementMode", Int) = 0
[ToggleOff] _DisplacementLockObjectScale("displacement lock object scale", Float) = 1.0
[ToggleOff] _DisplacementLockTilingScale("displacement lock tiling scale", Float) = 1.0
[ToggleOff] _DepthOffsetEnable("Depth Offset View space", Float) = 0.0
_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5
_PPDMaxSamples("Max sample for POM", Range(1.0, 64.0)) = 15
_PPDLodThreshold("Start lod to fade out the POM effect", Range(0.0, 16.0)) = 5
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[HideInInspector] _InvPrimScale("Inverse primitive scale for non-planar POM", Vector) = (1, 1, 0, 0)
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)
[ToggleOff] _LinkDetailsWithBase("LinkDetailsWithBase", Float) = 1.0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
// Wind
[ToggleOff] _EnableWind("Enable Wind", Float) = 0.0
_InitialBend("Initial Bend", float) = 1.0
_Stiffness("Stiffness", float) = 1.0
_Drag("Drag", float) = 1.0
_ShiverDrag("Shiver Drag", float) = 0.2
_ShiverDirectionality("Shiver Directionality", Range(0.0, 1.0)) = 0.5
//-------------------------------------------------------
//Windup Vegetation Wind
_VegNoise("Noise", 2D) = "white" {}
_VegWindMask("Wind Mask", 2D) = "white" {}
_VegPivot("Pivot", Vector) = (0, 0, 0, 0)
_VegStiffness("Stiffness", Range(0.1, 3.0)) = 1.0
_VegAssistantDirectional("Assistant Directional", Vector) = (0, 0, 0, 0)
_VegWindDirection("Wind Direction", Vector) = (0, 0, 0, 0)
_VegWindIntensity("Wind Intensity", Range(0.0, 1.0)) = 1.0
_VegWindSpeed("Wind Speed", Range(0.0, 2.0)) = 1.0
_VegDetailVariation("Detail Variation", Range(0.0, 100.0)) = 1.0
_VegLeafShakeScale("Leaf Shake Scale", Range(0.01, 8.0)) = 1.0
_VegLeafShakeSpeed("Leaf Shake Speed", Range(0.0, 1.0)) = 1.0
_VegLeafShakePower("Leaf Shake Power", Range(0.0, 3.0)) = 1.0
_VegPerLeafBendScale("Per-Leaf Bend Scale", Range(0.01, 3.0)) = 1.0
_VegPerLeafBendSpeed("Per-Leaf Bend Speed", Range(0.0, 1.0)) = 1.0
_VegPerLeafBendPower("Per-Leaf Bend Power", Range(0.0, 5.0)) = 1.0
//-------------------------------------------------------
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
_EmissionColor("Color", Color) = (1, 1, 1)
// HACK: GI Baking system relies on some properties existing in the shader ("_MainTex", "_Cutoff" and "_Color") for opacity handling, so we need to store our version of those parameters in the hard-coded name the GI baking system recognizes.
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go futher in dev
//#pragma enable_d3d11_debug_symbols
//-------------------------------------------------------------------------------------
// Variant
//-------------------------------------------------------------------------------------
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _ _REFRACTION_PLANE _REFRACTION_SPHERE
#pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _ _REQUIRE_UV2 _REQUIRE_UV3
#pragma shader_feature _NORMALMAP
#pragma shader_feature _MASKMAP
#pragma shader_feature _BENTNORMALMAP
#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _ENABLESPECULAROCCLUSION
#pragma shader_feature _HEIGHTMAP
#pragma shader_feature _TANGENTMAP
#pragma shader_feature _ANISOTROPYMAP
#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _SUBSURFACE_RADIUS_MAP
#pragma shader_feature _THICKNESSMAP
#pragma shader_feature _SPECULARCOLORMAP
// Keyword for transparent
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature _ _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_MULTIPLY _BLENDMODE_PRE_MULTIPLY
#pragma shader_feature _BLENDMODE_PRESERVE_SPECULAR_LIGHTING
#pragma shader_feature _ENABLE_FOG_ON_TRANSPARENT
// MaterialId are used as shader feature to allow compiler to optimize properly
// Note _MATID_STANDARD is not define as there is always the default case "_". We assign default as _MATID_STANDARD, so we never test _MATID_STANDARD
#pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR _MATID_CLEARCOAT
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
// enable dithering LOD crossfade
#pragma multi_compile _ LOD_FADE_CROSSFADE
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON
//-------------------------------------------------------------------------------------
// Define
//-------------------------------------------------------------------------------------
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
// Use surface gradient normal mapping as it handle correctly triplanar normal mapping and multiple UVSet
#define SURFACE_GRADIENT
// This shader support vertex modification
#define HAVE_VERTEX_MODIFICATION
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../Core/ShaderLibrary/Common.hlsl"
#include "../../../Core/ShaderLibrary/Wind.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
#include "../../Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
SubShader
{
Pass
{
Name "GBuffer" // Name is not used
Tags { "LightMode" = "GBuffer" } // This will be only for opaque object based on the RenderQueue index
Cull [_CullMode]
Stencil
{
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
#define ATTRIBUTES_NEED_TEXCOORD0
#define ATTRIBUTES_NEED_COLOR
#define SHADERPASS SHADERPASS_GBUFFER
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL
}
// This pass is the same as GBuffer only it does not do alpha test (the clip instruction is removed)
// This is due to the fact that on GCN, any shader with a clip instruction cannot benefit from HiZ so when we do a prepass, in order to get the most performance, we need to make a special case in the subsequent GBuffer pass.
Pass
{
Name "GBufferWithPrepass" // Name is not used
Tags { "LightMode" = "GBufferWithPrepass" } // This will be only for opaque object based on the RenderQueue index
Cull [_CullMode]
Stencil
{
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
#define SHADERPASS SHADERPASS_GBUFFER
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL
}
Pass
{
Name "GBufferDebugDisplay" // Name is not used
Tags{ "LightMode" = "GBufferDebugDisplay" } // This will be only for opaque object based on the RenderQueue index
Cull [_CullMode]
Stencil
{
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
#define DEBUG_DISPLAY
#define SHADERPASS SHADERPASS_GBUFFER
#include "../../ShaderVariables.hlsl"
#include "../../Debug/DebugDisplay.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL
}
// Extracts information for lightmapping, GI (emission, albedo, ...)
// This pass it not used during regular rendering.
Pass
{
Name "META"
Tags{ "LightMode" = "Meta" }
Cull Off
HLSLPROGRAM
// Lightmap memo
// DYNAMICLIGHTMAP_ON is used when we have an "enlighten lightmap" ie a lightmap updated at runtime by enlighten.This lightmap contain indirect lighting from realtime lights and realtime emissive material.Offline baked lighting(from baked material / light,
// both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON.
#define SHADERPASS SHADERPASS_LIGHT_TRANSPORT
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassLightTransport.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{ "LightMode" = "ShadowCaster" }
Cull[_CullMode]
ZClip Off
ZWrite On
ZTest LEqual
HLSLPROGRAM
//Need to force reading of uv + color for vertex animated shadows.
#define ATTRIBUTES_NEED_TEXCOORD0
#define ATTRIBUTES_NEED_COLOR
#define SHADERPASS SHADERPASS_SHADOWS
#define USE_LEGACY_UNITY_MATRIX_VARIABLES
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{ "LightMode" = "DepthOnly" }
Cull[_CullMode]
ZWrite On
HLSLPROGRAM
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
ENDHLSL
}
Pass
{
Name "Motion Vectors"
Tags{ "LightMode" = "MotionVectors" } // Caution, this need to be call like this to setup the correct parameters by C++ (legacy Unity)
Cull[_CullMode]
ZWrite Off // TODO: Test Z equal here.
HLSLPROGRAM
#define SHADERPASS SHADERPASS_VELOCITY
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitVelocityPass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"
ENDHLSL
}
Pass
{
Name "Distortion" // Name is not used
Tags { "LightMode" = "DistortionVectors" } // This will be only for transparent object based on the RenderQueue index
Blend [_DistortionSrcBlend] [_DistortionDstBlend], [_DistortionBlurSrcBlend] [_DistortionBlurDstBlend]
BlendOp Add, [_DistortionBlurBlendOp]
ZTest [_ZTestMode]
ZWrite off
Cull [_CullMode]
HLSLPROGRAM
#define SHADERPASS SHADERPASS_DISTORTION
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDistortionPass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassDistortion.hlsl"
ENDHLSL
}
Pass
{
Name "Forward" // Name is not used
Tags { "LightMode" = "Forward" } // This will be only for transparent object based on the RenderQueue index
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
Cull [_CullMode]
HLSLPROGRAM
#define SHADERPASS SHADERPASS_FORWARD
#include "../../ShaderVariables.hlsl"
#include "../../Lighting/Forward.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS
#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"
ENDHLSL
}
Pass
{
Name "ForwardDebugDisplay" // Name is not used
Tags{ "LightMode" = "ForwardDebugDisplay" } // This will be only for transparent object based on the RenderQueue index
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_CullMode]
HLSLPROGRAM
#define DEBUG_DISPLAY
#define SHADERPASS SHADERPASS_FORWARD
#include "../../ShaderVariables.hlsl"
#include "../../Debug/DebugDisplay.hlsl"
#include "../../Lighting/Forward.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS
#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "VegetationData.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"
ENDHLSL
}
}
CustomEditor "Experimental.Rendering.HDPipeline.VegetationGUI"
}

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/Vegetation.shader.meta


fileFormatVersion: 2
guid: ff1b756ebf5550048bed17a617e8f5b0
timeCreated: 1509479425
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

269
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationData.hlsl


#include "../../../Core/ShaderLibrary/SampleUVMapping.hlsl"
#include "../MaterialUtilities.hlsl"
//-------------------------------------------------------------------------------------
// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------
// TODO: move this function to commonLighting.hlsl once validated it work correctly
float GetSpecularOcclusionFromBentAO(float3 V, float3 bentNormalWS, SurfaceData surfaceData)
{
// Retrieve cone angle
// Ambient occlusion is cosine weighted, thus use following equation. See slide 129
float cosAv = sqrt(1.0 - surfaceData.ambientOcclusion);
float roughness = max(PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness), 0.01); // Clamp to 0.01 to avoid edge cases
float cosAs = exp2(-3.32193 * Sqr(roughness));
float cosB = dot(bentNormalWS, reflect(-V, surfaceData.normalWS));
return SphericalCapIntersectionSolidArea(cosAv, cosAs, cosB) / (TWO_PI * (1.0 - cosAs));
}
void GetBuiltinData(FragInputs input, SurfaceData surfaceData, float alpha, float3 bentNormalWS, float depthOffset, out BuiltinData builtinData)
{
// Builtin Data
builtinData.opacity = alpha;
// TODO: Sample lightmap/lightprobe/volume proxy
// This should also handle projective lightmap
builtinData.bakeDiffuseLighting = SampleBakedGI(input.positionWS, bentNormalWS, input.texCoord1, input.texCoord2);
// It is safe to call this function here as surfaceData have been filled
// We want to know if we must enable transmission on GI for SSS material, if the material have no SSS, this code will be remove by the compiler.
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
if (bsdfData.enableTransmission)
{
// For now simply recall the function with inverted normal, the compiler should be able to optimize the lightmap case to not resample the directional lightmap
// however it will not optimize the lightprobe case due to the proxy volume relying on dynamic if (we rely must get right of this dynamic if), not a problem for SH9, but a problem for proxy volume.
// TODO: optimize more this code.
// Add GI transmission contribution by resampling the GI for inverted vertex normal
builtinData.bakeDiffuseLighting += SampleBakedGI(input.positionWS, -input.worldToTangent[2], input.texCoord1, input.texCoord2) * bsdfData.transmittance;
}
// Emissive Intensity is only use here, but is part of BuiltinData to enforce UI parameters as we want the users to fill one color and one intensity
builtinData.emissiveIntensity = _EmissiveIntensity; // We still store intensity here so we can reuse it with debug code
builtinData.emissiveColor = _EmissiveColor * builtinData.emissiveIntensity * lerp(float3(1.0, 1.0, 1.0), surfaceData.baseColor.rgb, _AlbedoAffectEmissive);
#ifdef _EMISSIVE_COLOR_MAP
builtinData.emissiveColor *= SAMPLE_TEXTURE2D(_EmissiveColorMap, sampler_EmissiveColorMap, input.texCoord0).rgb;
#endif
builtinData.velocity = float2(0.0, 0.0);
#if (SHADERPASS == SHADERPASS_DISTORTION) || defined(DEBUG_DISPLAY)
float3 distortion = SAMPLE_TEXTURE2D(_DistortionVectorMap, sampler_DistortionVectorMap, input.texCoord0).rgb;
builtinData.distortion = distortion.rg * _DistortionScale;
builtinData.distortionBlur = clamp(distortion.b * _DistortionBlurScale, 0.0, 1.0) * (_DistortionBlurRemapMax - _DistortionBlurRemapMin) + _DistortionBlurRemapMin;
#else
builtinData.distortion = float2(0.0, 0.0);
builtinData.distortionBlur = 0.0;
#endif
builtinData.depthOffset = depthOffset;
}
// Struct that gather UVMapping info of all layers + common calculation
// This is use to abstract the mapping that can differ on layers
struct LayerTexCoord
{
#ifndef LAYERED_LIT_SHADER
UVMapping base;
UVMapping details;
#else
// Regular texcoord
UVMapping base0;
UVMapping base1;
UVMapping base2;
UVMapping base3;
UVMapping details0;
UVMapping details1;
UVMapping details2;
UVMapping details3;
// Dedicated for blend mask
UVMapping blendMask;
#endif
// Store information that will be share by all UVMapping
float3 vertexNormalWS; // TODO: store also object normal map for object triplanar
float3 triplanarWeights;
#ifdef SURFACE_GRADIENT
// tangent basis for each UVSet - up to 4 for now
float3 vertexTangentWS0, vertexBitangentWS0;
float3 vertexTangentWS1, vertexBitangentWS1;
float3 vertexTangentWS2, vertexBitangentWS2;
float3 vertexTangentWS3, vertexBitangentWS3;
#endif
};
#ifdef SURFACE_GRADIENT
void GenerateLayerTexCoordBasisTB(FragInputs input, inout LayerTexCoord layerTexCoord)
{
float3 vertexNormalWS = input.worldToTangent[2];
layerTexCoord.vertexTangentWS0 = input.worldToTangent[0];
layerTexCoord.vertexBitangentWS0 = input.worldToTangent[1];
// TODO: We should use relative camera position here - This will be automatic when we will move to camera relative space.
float3 dPdx = ddx_fine(input.positionWS);
float3 dPdy = ddy_fine(input.positionWS);
float3 sigmaX = dPdx - dot(dPdx, vertexNormalWS) * vertexNormalWS;
float3 sigmaY = dPdy - dot(dPdy, vertexNormalWS) * vertexNormalWS;
//float flipSign = dot(sigmaY, cross(vertexNormalWS, sigmaX) ) ? -1.0 : 1.0;
float flipSign = dot(dPdy, cross(vertexNormalWS, dPdx)) < 0.0 ? -1.0 : 1.0; // gives same as the commented out line above
// TODO: Optimize! The compiler will not be able to remove the tangent space that are not use because it can't know due to our UVMapping constant we use for both base and details
// To solve this we should track which UVSet is use for normal mapping... Maybe not as simple as it sounds
SurfaceGradientGenBasisTB(vertexNormalWS, sigmaX, sigmaY, flipSign, input.texCoord1, layerTexCoord.vertexTangentWS1, layerTexCoord.vertexBitangentWS1);
#if defined(_REQUIRE_UV2) || defined(_REQUIRE_UV3)
SurfaceGradientGenBasisTB(vertexNormalWS, sigmaX, sigmaY, flipSign, input.texCoord2, layerTexCoord.vertexTangentWS2, layerTexCoord.vertexBitangentWS2);
#endif
#if defined(_REQUIRE_UV3)
SurfaceGradientGenBasisTB(vertexNormalWS, sigmaX, sigmaY, flipSign, input.texCoord3, layerTexCoord.vertexTangentWS3, layerTexCoord.vertexBitangentWS3);
#endif
}
#endif
#ifndef LAYERED_LIT_SHADER
// Want to use only one sampler for normalmap/bentnormalmap either we use OS or TS. And either we have normal map or bent normal or both.
#ifdef _NORMALMAP_TANGENT_SPACE
#if defined(_NORMALMAP)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap
#elif defined(_BENTNORMALMAP)
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMap
#endif
#else
#if defined(_NORMALMAP)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS
#elif defined(_BENTNORMALMAP)
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMapOS
#endif
#endif
#define SAMPLER_DETAILMAP_IDX sampler_DetailMap
#define SAMPLER_MASKMAP_IDX sampler_MaskMap
#define SAMPLER_HEIGHTMAP_IDX sampler_HeightMap
#define SAMPLER_SUBSURFACE_RADIUSMAP_IDX sampler_SubsurfaceRadiusMap
#define SAMPLER_THICKNESSMAP_IDX sampler_ThicknessMap
// include LitDataIndividualLayer to define GetSurfaceData
#define LAYER_INDEX 0
#define ADD_IDX(Name) Name
#define ADD_ZERO_IDX(Name) Name
#ifdef _NORMALMAP
#define _NORMALMAP_IDX
#endif
#ifdef _NORMALMAP_TANGENT_SPACE
#define _NORMALMAP_TANGENT_SPACE_IDX
#endif
#ifdef _DETAIL_MAP
#define _DETAIL_MAP_IDX
#endif
#ifdef _SUBSURFACE_RADIUS_MAP
#define _SUBSURFACE_RADIUS_MAP_IDX
#endif
#ifdef _THICKNESSMAP
#define _THICKNESSMAP_IDX
#endif
#ifdef _MASKMAP
#define _MASKMAP_IDX
#endif
#ifdef _BENTNORMALMAP
#define _BENTNORMALMAP_IDX
#endif
#include "../Lit/LitDataIndividualLayer.hlsl"
// This maybe call directly by tessellation (domain) shader, thus all part regarding surface gradient must be done
// in function with FragInputs input as parameters
// layerTexCoord must have been initialize to 0 outside of this function
void GetLayerTexCoord(float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3,
float3 positionWS, float3 vertexNormalWS, inout LayerTexCoord layerTexCoord)
{
layerTexCoord.vertexNormalWS = vertexNormalWS;
layerTexCoord.triplanarWeights = ComputeTriplanarWeights(vertexNormalWS);
int mappingType = UV_MAPPING_UVSET;
#if defined(_MAPPING_PLANAR)
mappingType = UV_MAPPING_PLANAR;
#elif defined(_MAPPING_TRIPLANAR)
mappingType = UV_MAPPING_TRIPLANAR;
#endif
// Be sure that the compiler is aware that we don't use UV1 to UV3 for main layer so it can optimize code
ComputeLayerTexCoord( texCoord0, texCoord1, texCoord2, texCoord3, float4(1.0, 0.0, 0.0, 0.0), _UVDetailsMappingMask,
_BaseColorMap_ST.xy, _BaseColorMap_ST.zw, _DetailMap_ST.xy, _DetailMap_ST.zw, 1.0, _LinkDetailsWithBase,
positionWS, _TexWorldScale,
mappingType, layerTexCoord);
}
// This is call only in this file
// layerTexCoord must have been initialize to 0 outside of this function
void GetLayerTexCoord(FragInputs input, inout LayerTexCoord layerTexCoord)
{
#ifdef SURFACE_GRADIENT
GenerateLayerTexCoordBasisTB(input, layerTexCoord);
#endif
GetLayerTexCoord( input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
}
#include "../Lit/LitDataDisplacement.hlsl"
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.x);
#endif
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(input, layerTexCoord);
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
// 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;
float3 bentNormalTS;
float3 bentNormalWS;
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData, normalTS, bentNormalTS);
GetNormalWS(input, V, normalTS, surfaceData.normalWS);
// Use bent normal to sample GI if available
#ifdef _BENTNORMALMAP
GetNormalWS(input, V, bentNormalTS, bentNormalWS);
#else
bentNormalWS = surfaceData.normalWS;
#endif
// By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.
// If user provide bent normal then we process a better term
#if defined(_BENTNORMALMAP) && defined(_ENABLESPECULAROCCLUSION)
// If we have bent normal and ambient occlusion, process a specular occlusion
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData);
#elif defined(_MASKMAP)
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(dot(surfaceData.normalWS, V), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
#else
surfaceData.specularOcclusion = 1.0;
#endif
// This is use with anisotropic material
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
// Caution: surfaceData must be fully initialize before calling GetBuiltinData
GetBuiltinData(input, surfaceData, alpha, bentNormalWS, depthOffset, builtinData);
}
#include "VegetationDataMeshModification.hlsl"
#endif // #ifndef LAYERED_LIT_SHADER

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationData.hlsl.meta


fileFormatVersion: 2
guid: 5b0a17e7a97f28a4db53bcf95737633f
timeCreated: 1509483930
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

176
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationDataMeshModification.hlsl


float3 GetVertexDisplacement(float3 positionWS, float3 normalWS, float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 vertexColor)
{
// This call will work for both LayeredLit and Lit shader
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(texCoord0, texCoord1, texCoord2, texCoord3, positionWS, normalWS, layerTexCoord);
// TODO: do this algorithm for lod fetching as lod not available in vertex/domain shader
// http://www.sebastiansylvan.com/post/the-problem-with-tessellation-in-directx-11/
float lod = 0.0;
return ComputePerVertexDisplacement(layerTexCoord, vertexColor, lod) * normalWS;
}
#include "VegetationWind.hlsl"
void ApplyVertexModification(AttributesMesh input, float3 normalWS, inout float3 positionWS)
{
#if defined(_VERTEX_DISPLACEMENT)
positionWS += GetVertexDisplacement(positionWS, normalWS,
#ifdef ATTRIBUTES_NEED_TEXCOORD0
input.uv0,
#else
float2(0.0, 0.0),
#endif
#ifdef ATTRIBUTES_NEED_TEXCOORD1
input.uv1,
#else
float2(0.0, 0.0),
#endif
#ifdef ATTRIBUTES_NEED_TEXCOORD2
input.uv2,
#else
float2(0.0, 0.0),
#endif
#ifdef ATTRIBUTES_NEED_TEXCOORD3
input.uv3,
#else
float2(0.0, 0.0),
#endif
#ifdef ATTRIBUTES_NEED_COLOR
input.color
#else
float4(0.0, 0.0, 0.0, 0.0)
#endif
);
#endif
#ifdef _VERTEX_WIND
float3 rootWP = mul(GetObjectToWorldMatrix(), float4(0, 0, 0, 1)).xyz;
ApplyWindDisplacement(positionWS, normalWS, rootWP, _Stiffness, _Drag, _ShiverDrag, _ShiverDirectionality, _InitialBend, input.color.a, _Time);
#endif
//Main entry point to custom Windup vegetation wind
//-------------------------------------------------
#if defined(ATTRIBUTES_NEED_TEXCOORD0) && defined(ATTRIBUTES_NEED_COLOR)
ApplyVegetationWind(positionWS, input.positionOS, normalWS, input.uv0, input.color, _Time);
#endif
//-------------------------------------------------
}
#ifdef TESSELLATION_ON
float4 GetTessellationFactors(float3 p0, float3 p1, float3 p2, float3 n0, float3 n1, float3 n2)
{
float maxDisplacement = GetMaxDisplacement();
// For tessellation we want to process tessellation factor always from the point of view of the camera (to be consistent and avoid Z-fight).
// For the culling part however we want to use the current view (shadow view).
// Thus the following code play with both.
#if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS)
bool frustumCulledCurrentView = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])_FrustumPlanes); // _FrustumPlanes are primary camera planes
bool frustumCulledMainView = false;
#else
bool frustumCulledCurrentView = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])unity_CameraWorldClipPlanes); // unity_CameraWorldClipPlanes is set by legacy Unity in case of shadow and contain shadow view plan
// In the case of shadow, we don't want to tessellate anything that is not seen by the main view frustum. It can result in minor popping of tessellation into a shadow but we can't afford it anyway.
bool frustumCulledMainView = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])_FrustumPlanes);
#endif
bool faceCull = false;
#ifndef _DOUBLESIDED_ON
if (_TessellationBackFaceCullEpsilon > -0.99) // Is backface culling enabled ?
{
// Handle transform mirroring (like negative scaling)
// Caution: don't change p1/p2 directly as it is use later
float3 backfaceP1 = unity_WorldTransformParams.w < 0.0 ? p2 : p1;
float3 backfaceP2 = unity_WorldTransformParams.w < 0.0 ? p1 : p2;
faceCull = BackFaceCullTriangle(p0, backfaceP1, backfaceP2, _TessellationBackFaceCullEpsilon, GetCurrentViewPosition()); // Use shadow view
}
#endif
if (frustumCulledCurrentView || faceCull)
{
// Settings factor to 0 will kill the triangle
return float4(0.0, 0.0, 0.0, 0.0);
}
// See comment above:
// During shadow passes, we decide that anything outside the main view frustum should not be tessellated.
if (frustumCulledMainView)
{
return float4(1.0, 1.0, 1.0, 1.0);
}
// We use the parameters of the primary (scene view) camera in order
// to have identical tessellation levels for both the scene view and
// shadow views. Otherwise, depth comparisons become meaningless!
float3 tessFactor = float3(1.0, 1.0, 1.0);
// Adaptive screen space tessellation
if (_TessellationFactorTriangleSize > 0.0)
{
// return a value between 0 and 1
tessFactor *= GetScreenSpaceTessFactor( p0, p1, p2, _ViewProjMatrix, _ScreenSize, _TessellationFactorTriangleSize); // Use primary camera view
}
// Distance based tessellation
if (_TessellationFactorMaxDistance > 0.0)
{
float3 distFactor = GetDistanceBasedTessFactor(p0, p1, p2, GetPrimaryCameraPosition(), _TessellationFactorMinDistance, _TessellationFactorMaxDistance); // Use primary camera view
// We square the disance factor as it allow a better percptual descrease of vertex density.
tessFactor *= distFactor * distFactor;
}
tessFactor *= _TessellationFactor;
// TessFactor below 1.0 have no effect. At 0 it kill the triangle, so clamp it to 1.0
tessFactor.xyz = float3(max(1.0, tessFactor.x), max(1.0, tessFactor.y), max(1.0, tessFactor.z));
return CalcTriEdgeTessFactors(tessFactor);
}
// tessellationFactors
// x - 1->2 edge
// y - 2->0 edge
// z - 0->1 edge
// w - inside tessellation factor
void ApplyTessellationModification(VaryingsMeshToDS input, float3 normalWS, inout float3 positionWS)
{
#if defined(_TESSELLATION_DISPLACEMENT)
positionWS += GetVertexDisplacement(positionWS, normalWS,
#ifdef VARYINGS_DS_NEED_TEXCOORD0
input.texCoord0,
#else
float2(0.0, 0.0),
#endif
#ifdef VARYINGS_DS_NEED_TEXCOORD1
input.texCoord1,
#else
float2(0.0, 0.0),
#endif
#ifdef VARYINGS_DS_NEED_TEXCOORD2
input.texCoord2,
#else
float2(0.0, 0.0),
#endif
#ifdef VARYINGS_DS_NEED_TEXCOORD3
input.texCoord3,
#else
float2(0.0, 0.0),
#endif
#ifdef VARYINGS_DS_NEED_COLOR
input.color
#else
float4(0.0, 0.0, 0.0, 0.0)
#endif
);
#endif // _TESSELLATION_DISPLACEMENT
}
#endif // #ifdef TESSELLATION_ON

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationDataMeshModification.hlsl.meta


fileFormatVersion: 2
guid: d90d65d4c99d26c4e92f6677ac35cbba
timeCreated: 1509484407
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

21
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationProperties.hlsl


TEXTURE2D(_VegNoise);
SAMPLER2D(sampler_VegNoise);
TEXTURE2D(_VegWindMask);
SAMPLER2D(sampler_VegWindMask);
CBUFFER_START(_PerMaterial)
float4 _VegPivot;
float _VegStiffness;
float4 _VegAssistantDirectional;
float4 _VegWindDirection;
float _VegWindIntensity;
float _VegWindSpeed;
float _VegDetailVariation;
float _VegLeafShakeScale;
float _VegLeafShakeSpeed;
float _VegLeafShakePower;
float _VegPerLeafBendScale;
float _VegPerLeafBendSpeed;
float _VegPerLeafBendPower;
CBUFFER_END

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationProperties.hlsl.meta


fileFormatVersion: 2
guid: b9abd5b973633b846b6119a4ec8e8a54
timeCreated: 1509484592
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

56
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationWind.hlsl


#include "VegetationProperties.hlsl"
void ApplyVegetationWind( inout float3 positionWS,
float3 positionOS,
float3 normalW,
float2 texcoord,
float4 weights,
float4 time)
{
float3 normalWS = TransformObjectToWorldNormal(normalW);
float3 windDir = normalize(_VegWindDirection.xyz);
float windSpeedWS = _VegWindSpeed * time.y * 3.0;
float vertexToPivotDist = distance(positionOS, float3(0.0, 0.0, 0.0));
float distOffset = vertexToPivotDist / 128.0;
float3 posToPivot = positionWS.xyz - _VegPivot.xyz;
float3 shiftPivot = _VegPivot.xyz + normalize(posToPivot) * vertexToPivotDist * (1.0 + weights.x);
float3 posToShiftPivot = positionWS.xyz - shiftPivot.xyz;
float3 shiftPivotDistOffset = distance(positionOS, shiftPivot) / 64.0;
float3 axis = cross(posToShiftPivot, windDir);
float4 noiseUV = time.yyyy * 0.05f;
//float4 noise = tex2Dlod(sampler_VegNoise, float4(noiseUV.x, 0.5, 0.0, 0.0));
//#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
float4 noise = SAMPLE_TEXTURE2D_LOD(_VegNoise, sampler_VegNoise, float2(noiseUV.x, 0.5), 0.0);
half rad = radians(sin(windSpeedWS + (distOffset + shiftPivotDistOffset) / _VegStiffness) * distOffset * _VegWindIntensity * noise.x);
half radAssist = radians(sin(windSpeedWS) * distOffset * _VegWindIntensity * noise.x);
float3x3 rP = float3x3(axis.x * axis.x * (1.0f - cos(rad)) + cos(rad), axis.x * axis.y * (1.0f - cos(rad)) + axis.z * sin(rad), axis.x * axis.z * (1.0f - cos(rad)) - axis.y * sin(rad),
axis.x * axis.y * (1.0f - cos(rad)) - axis.z * sin(rad), axis.y * axis.y * (1.0f - cos(rad)) + cos(rad), axis.y * axis.z * (1.0f - cos(rad)) + axis.x * sin(rad),
axis.x * axis.z * (1.0f - cos(rad)) + axis.y * sin(rad), axis.y * axis.z * (1.0f - cos(rad)) - axis.x * sin(rad), axis.z * axis.z * (1.0f - cos(rad)) + cos(rad));
float3x3 rPAssist = float3x3(_VegAssistantDirectional.x * _VegAssistantDirectional.x * (1.0f - cos(radAssist)) + cos(radAssist), _VegAssistantDirectional.x * _VegAssistantDirectional.y * (1.0f - cos(radAssist)) + _VegAssistantDirectional.z * sin(radAssist), _VegAssistantDirectional.x * _VegAssistantDirectional.z * (1.0f - cos(radAssist)) - _VegAssistantDirectional.y * sin(radAssist),
_VegAssistantDirectional.x * _VegAssistantDirectional.y * (1.0f - cos(radAssist)) - _VegAssistantDirectional.z * sin(radAssist), _VegAssistantDirectional.y * _VegAssistantDirectional.y * (1.0f - cos(radAssist)) + cos(radAssist), _VegAssistantDirectional.y * _VegAssistantDirectional.z * (1.0f - cos(radAssist)) + _VegAssistantDirectional.x * sin(radAssist),
_VegAssistantDirectional.x * _VegAssistantDirectional.z * (1.0f - cos(radAssist)) + _VegAssistantDirectional.y * sin(radAssist), _VegAssistantDirectional.y * _VegAssistantDirectional.z * (1.0f - cos(radAssist)) - _VegAssistantDirectional.x * sin(radAssist), _VegAssistantDirectional.z * _VegAssistantDirectional.z * (1.0f - cos(radAssist)) + cos(radAssist));
float detailVariation = weights.g * _VegDetailVariation;
float3 leafShakeDeform = sin((positionWS / _VegLeafShakeScale + windSpeedWS * 5.0 * _VegLeafShakeSpeed) + detailVariation);
leafShakeDeform = clamp(leafShakeDeform, -1.0, 1.0);
leafShakeDeform *= _VegWindIntensity * noise * (1.0 + weights.g);
float4 perLeafMask = SAMPLE_TEXTURE2D_LOD(_VegWindMask, sampler_VegWindMask, float2(texcoord.x, texcoord.y), 0.0);
leafShakeDeform *= (normalWS * perLeafMask.r + (-normalWS) * perLeafMask.g) * _VegLeafShakePower;
float3 perLeafBending = sin((positionWS / _VegPerLeafBendScale + windSpeedWS * 3.0 * _VegPerLeafBendSpeed) * (windDir+_VegAssistantDirectional) + detailVariation + shiftPivotDistOffset / 0.5);
perLeafBending *= _VegWindIntensity * noise;
perLeafBending = float3(0.0, perLeafBending.y, 0.0f);
perLeafBending *= weights.b * perLeafMask.b * (1.0 + weights.g) * _VegPerLeafBendPower;
float3 rPAssistpos = mul(rPAssist, positionOS);
float3 pos = mul(rP, rPAssistpos) + perLeafBending + leafShakeDeform;
positionWS = mul(UNITY_MATRIX_M, float4(pos, 1.0)).xyz;
}

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation/VegetationWind.hlsl.meta


fileFormatVersion: 2
guid: fa32c39574d2ed444880dfb634c62aba
timeCreated: 1509485943
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Character.meta


fileFormatVersion: 2
guid: e358ae90302a03e409bc067e832525c5
folderAsset: yes
timeCreated: 1509071155
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Eye.meta


fileFormatVersion: 2
guid: 99b28ae1899c34841bb5edf61823d22d
folderAsset: yes
timeCreated: 1504677840
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Fabric.meta


fileFormatVersion: 2
guid: 6bee56a72daba3d479259196d046864c
folderAsset: yes
timeCreated: 1504677840
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Hair.meta


fileFormatVersion: 2
guid: dfab746be3b7dc34ebec9f9c63bc9a74
folderAsset: yes
timeCreated: 1504677840
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

327
ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare1.hlsl


// Sampler use by area light, gaussian pyramid, ambient occlusion etc...
SamplerState s_linear_clamp_sampler;
SamplerState s_trilinear_clamp_sampler;
// Rough refraction texture
// Color pyramid (width, height, lodcount, Unused)
TEXTURE2D(_GaussianPyramidColorTexture);
// Depth pyramid (width, height, lodcount, Unused)
TEXTURE2D(_PyramidDepthTexture);
CBUFFER_START(UnityGaussianPyramidParameters)
float4 _GaussianPyramidColorMipSize;
float4 _PyramidDepthMipSize;
CBUFFER_END
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
CBUFFER_START(UnityAmbientOcclusionParameters)
float4 _AmbientOcclusionParam; // xyz occlusion color, w directLightStrenght
CBUFFER_END
// 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
#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 MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV'
#ifdef WANT_SSS_CODE
// Subsurface scattering specific constant
#define SSS_WRAP_ANGLE (PI/12) // Used for wrap lighting
#define SSS_WRAP_LIGHT cos(PI/2 - SSS_WRAP_ANGLE)
CBUFFER_START(UnitySSSParameters)
uint _EnableSSSAndTransmission; // Globally toggles subsurface and transmission scattering on/off
uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
uint _TransmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
// Old SSS Model >>>
uint _UseDisneySSS;
float4 _HalfRcpVariancesAndWeights[SSS_N_PROFILES][2]; // 2x Gaussians in RGB, A is interpolation weights
// <<< Old SSS Model
// Use float4 to avoid any packing issue between compute and pixel shaders
float4 _ThicknessRemaps[SSS_N_PROFILES]; // R: start, G = end - start, BA unused
float4 _ShapeParams[SSS_N_PROFILES]; // RGB = S = 1 / D, A = filter radius
float4 _TransmissionTints[SSS_N_PROFILES]; // RGB = 1/4 * color, A = unused
CBUFFER_END
#endif
void ApplyDebugToSurfaceData(inout SurfaceData surfaceData)
{
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_SPECULAR_LIGHTING)
{
bool overrideSmoothness = _DebugLightingSmoothness.x != 0.0;
float overrideSmoothnessValue = _DebugLightingSmoothness.y;
if (overrideSmoothness)
{
surfaceData.perceptualSmoothness = overrideSmoothnessValue;
}
}
if (_DebugLightingMode == DEBUGLIGHTINGMODE_DIFFUSE_LIGHTING)
{
surfaceData.baseColor = _DebugLightingAlbedo.xyz;
}
#endif
}
//-----------------------------------------------------------------------------
// Debug method (use to display values)
//-----------------------------------------------------------------------------
void GetSurfaceDataDebug(uint paramId, SurfaceData surfaceData, inout float3 result, inout bool needLinearToSRGB)
{
GetGeneratedSurfaceDataDebug(paramId, surfaceData, result, needLinearToSRGB);
}
void GetBSDFDataDebug(uint paramId, BSDFData bsdfData, inout float3 result, inout bool needLinearToSRGB)
{
GetGeneratedBSDFDataDebug(paramId, bsdfData, result, needLinearToSRGB);
}
#ifdef WANT_SSS_CODE
void FillMaterialIdSSSData(float3 baseColor, int subsurfaceProfile, float subsurfaceRadius, float thickness, inout BSDFData bsdfData)
{
bsdfData.diffuseColor = baseColor;
bsdfData.fresnel0 = 0.028; // TODO take from subsurfaceProfile instead
bsdfData.subsurfaceProfile = subsurfaceProfile;
bsdfData.subsurfaceRadius = subsurfaceRadius;
bsdfData.thickness = _ThicknessRemaps[subsurfaceProfile].x + _ThicknessRemaps[subsurfaceProfile].y * thickness;
uint transmissionMode = BitFieldExtract(_TransmissionFlags, 2u, 2u * subsurfaceProfile);
bsdfData.enableTransmission = transmissionMode != SSS_TRSM_MODE_NONE && (_EnableSSSAndTransmission > 0);
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, subsurfaceProfile);
#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT) // In case of GI pass don't modify the diffuseColor
bool enableSssAndTransmission = false;
#elif defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SUBSURFACE_SCATTERING)
bool enableSssAndTransmission = true;
#else
bool enableSssAndTransmission = _EnableSSSAndTransmission != 0;
#endif
if (enableSssAndTransmission) // If we globally disable SSS effect, don't modify diffuseColor
{
// We modify the albedo here as this code is used by all lighting (including light maps and GI).
if (performPostScatterTexturing)
{
#if !defined(SHADERPASS) || (SHADERPASS != SHADERPASS_SUBSURFACE_SCATTERING)
bsdfData.diffuseColor = float3(1.0, 1.0, 1.0);
#endif
}
else
{
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
}
}
if (bsdfData.enableTransmission)
{
if (_UseDisneySSS)
{
bsdfData.transmittance = ComputeTransmittance(_ShapeParams[subsurfaceProfile].rgb,
_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
else
{
bsdfData.transmittance = ComputeTransmittanceJimenez(_HalfRcpVariancesAndWeights[subsurfaceProfile][0].rgb,
_HalfRcpVariancesAndWeights[subsurfaceProfile][0].a,
_HalfRcpVariancesAndWeights[subsurfaceProfile][1].rgb,
_HalfRcpVariancesAndWeights[subsurfaceProfile][1].a,
_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
bsdfData.transmittance *= bsdfData.diffuseColor; // Premultiply
}
}
#endif
// For image based lighting, a part of the BSDF is pre-integrated.
// This is done both for specular and diffuse (in case of DisneyDiffuse)
void GetPreIntegratedFGD(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity)
{
// Pre-integrate GGX FGD
// Integral{BSDF * <N,L> dw} =
// Integral{(F0 + (1 - F0) * (1 - <V,H>)^5) * (BSDF / F) * <N,L> dw} =
// F0 * Integral{(BSDF / F) * <N,L> dw} +
// (1 - F0) * Integral{(1 - <V,H>)^5 * (BSDF / F) * <N,L> dw} =
// (1 - F0) * x + F0 * y = lerp(x, y, F0)
// Pre integrate DisneyDiffuse FGD:
// z = DisneyDiffuse
float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD, s_linear_clamp_sampler, float2(NdotV, perceptualRoughness), 0).xyz;
specularFGD = lerp(preFGD.xxx, preFGD.yyy, fresnel0);
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
diffuseFGD = 1.0;
#else
// Remap from the [0, 1] to the [0.5, 1.5] range.
diffuseFGD = preFGD.z + 0.5;
#endif
reflectivity = preFGD.y;
}
// Precomputed lighting data to send to the various lighting functions
struct PreLightData
{
// General
float NdotV; // Geometric version (could be negative)
// GGX
float partLambdaV;
float energyCompensation;
float TdotV;
float BdotV;
// IBL
float3 iblDirWS; // Dominant specular direction, used for IBL in EvaluateBSDF_Env()
float iblMipLevel;
float3 specularFGD; // Store preconvoled BRDF for both specular and diffuse
float diffuseFGD;
// Area lights (17 VGPRs)
float3x3 orthoBasisViewNormal; // Right-handed view-dependent orthogonal basis around the normal (6x VGPRs)
float3x3 ltcTransformDiffuse; // Inverse transformation for Lambertian or Disney Diffuse (4x VGPRs)
float3x3 ltcTransformSpecular; // Inverse transformation for GGX (4x VGPRs)
float ltcMagnitudeDiffuse;
float3 ltcMagnitudeFresnel;
};
PreLightData GetPreLightData(float3 V, PositionInputs posInput, BSDFData bsdfData)
{
PreLightData preLightData;
preLightData.NdotV = dot(bsdfData.normalWS, V); // Store the unaltered (geometric) version
float NdotV = preLightData.NdotV;
// In the case of IBL we want shift a bit the normal that are not toward the viewver to reduce artifact
float3 iblNormalWS = GetViewShiftedNormal(bsdfData.normalWS, V, NdotV, MIN_N_DOT_V); // Use non clamped NdotV
float3 iblR = reflect(-V, iblNormalWS);
NdotV = max(NdotV, MIN_N_DOT_V); // Use the modified (clamped) version
// GGX aniso
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{
preLightData.TdotV = dot(bsdfData.tangentWS, V);
preLightData.BdotV = dot(bsdfData.bitangentWS, V);
preLightData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For GGX aniso and IBL we have done an empirical (eye balled) approximation compare to the reference.
// We use a single fetch, and we stretch the normal to use based on various criteria.
// result are far away from the reference but better than nothing
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS = (bsdfData.anisotropy >= 0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
// Reduce stretching for (perceptualRoughness < 0.2).
float stretch = abs(bsdfData.anisotropy) * saturate(5 * bsdfData.perceptualRoughness);
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV) and use iblNormalWS
// into function like GetSpecularDominantDir(). However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here.
// With this in mind and for performance reasons we chose to only use modified normal to calculate R.
float3 anisoIblNormalWS = GetAnisotropicModifiedNormal(grainDirWS, iblNormalWS, V, stretch);
iblR = reflect(-V, anisoIblNormalWS);
}
else // GGX iso
{
preLightData.TdotV = 0;
preLightData.BdotV = 0;
preLightData.partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, bsdfData.roughness);
iblR = reflect(-V, iblNormalWS);
}
float reflectivity;
// IBL
GetPreIntegratedFGD(NdotV, bsdfData.perceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD, reflectivity);
// Note: this is a ad-hoc tweak.
float iblRoughness, iblPerceptualRoughness;
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{
// Use the min roughness, and bias it for higher values of anisotropy and roughness.
float roughnessBias = 0.075 * bsdfData.anisotropy * bsdfData.roughness;
iblRoughness = saturate(min(bsdfData.roughnessT, bsdfData.roughnessB) + roughnessBias);
iblPerceptualRoughness = RoughnessToPerceptualRoughness(iblRoughness);
}
else
{
iblRoughness = bsdfData.roughness;
iblPerceptualRoughness = bsdfData.perceptualRoughness;
}
preLightData.iblDirWS = GetSpecularDominantDir(iblNormalWS, iblR, iblRoughness, NdotV);
preLightData.iblMipLevel = PerceptualRoughnessToMipmapLevel(iblPerceptualRoughness);
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// Ref: Practical multiple scattering compensation for microfacet models.
// We only apply the formulation for metals.
// For dielectrics, the change of reflectance is negligible.
// We deem the intensity difference of a couple of percent for high values of roughness
// to not be worth the cost of another precomputed table.
// Note: this formulation bakes the BSDF non-symmetric!
preLightData.energyCompensation = 1.0 / reflectivity - 1.0;
#else
preLightData.energyCompensation = 0.0;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
// Area light
// UVs for sampling the LUTs
float theta = FastACos(NdotV); // For Area light - UVs for sampling the LUTs
float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);
// Note we load the matrix transpose (avoid to have to transpose it in shader)
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
preLightData.ltcTransformDiffuse = k_identity3x3;
#else
// Get the inverse LTC matrix for Disney Diffuse
preLightData.ltcTransformDiffuse = 0.0;
preLightData.ltcTransformDiffuse._m22 = 1.0;
preLightData.ltcTransformDiffuse._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_DISNEY_DIFFUSE_MATRIX_INDEX, 0);
#endif
// Get the inverse LTC matrix for GGX
// Note we load the matrix transpose (avoid to have to transpose it in shader)
preLightData.ltcTransformSpecular = 0.0;
preLightData.ltcTransformSpecular._m22 = 1.0;
preLightData.ltcTransformSpecular._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_GGX_MATRIX_INDEX, 0);
// Construct a right-handed view-dependent orthogonal basis around the normal
preLightData.orthoBasisViewNormal[0] = normalize(V - bsdfData.normalWS * preLightData.NdotV);
preLightData.orthoBasisViewNormal[2] = bsdfData.normalWS;
preLightData.orthoBasisViewNormal[1] = normalize(cross(preLightData.orthoBasisViewNormal[2], preLightData.orthoBasisViewNormal[0]));
float3 ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
float ltcGGXFresnelMagnitudeDiff = ltcMagnitude.r; // The difference of magnitudes of GGX and Fresnel
float ltcGGXFresnelMagnitude = ltcMagnitude.g;
float ltcDisneyDiffuseMagnitude = ltcMagnitude.b;
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
preLightData.ltcMagnitudeDiffuse = 1;
#else
preLightData.ltcMagnitudeDiffuse = ltcDisneyDiffuseMagnitude;
#endif
// TODO: the fit seems rather poor. The scaling factor of 0.5 allows us
// to match the reference for rough metals, but further darkens dielectrics.
preLightData.ltcMagnitudeFresnel = bsdfData.fresnel0 * ltcGGXFresnelMagnitudeDiff + (float3)ltcGGXFresnelMagnitude;
return preLightData;
}

10
ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare1.hlsl.meta


fileFormatVersion: 2
guid: 0f24f4070ad17d14196c6ed72276a144
timeCreated: 1504900828
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

881
ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare2.hlsl


#ifdef HAS_LIGHTLOOP
//-----------------------------------------------------------------------------
// Lighting structure for light accumulation
//-----------------------------------------------------------------------------
// These structure allow to accumulate lighting accross the Lit material
// AggregateLighting is init to zero and transfer to EvaluateBSDF, but the LightLoop can't access its content.
struct DirectLighting
{
float3 diffuse;
float3 specular;
};
struct IndirectLighting
{
float3 specularReflected;
float3 specularTransmitted;
};
struct AggregateLighting
{
DirectLighting direct;
IndirectLighting indirect;
};
void AccumulateDirectLighting(DirectLighting src, inout AggregateLighting dst)
{
dst.direct.diffuse += src.diffuse;
dst.direct.specular += src.specular;
}
void AccumulateIndirectLighting(IndirectLighting src, inout AggregateLighting dst)
{
dst.indirect.specularReflected += src.specularReflected;
dst.indirect.specularTransmitted += src.specularTransmitted;
}
#ifdef WANT_SSS_CODE
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
// We assume that the back side of the object is a uniformly illuminated infinite plane
// with the reversed normal (and the view vector) of the current sample.
float3 EvaluateTransmission(BSDFData bsdfData, float intensity, float shadow)
{
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
float backLight = intensity * shadow;
return backLight * bsdfData.transmittance; // Premultiplied with the diffuse color
}
#endif
//-----------------------------------------------------------------------------
// EvaluateBSDF_Directional (supports directional and box projector lights)
//-----------------------------------------------------------------------------
float4 EvaluateCookie_Directional(LightLoopContext lightLoopContext, DirectionalLightData lightData,
float3 lighToSample)
{
// Compute the NDC position (in [-1, 1]^2) by projecting 'positionWS' onto the near plane.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lighToSample, transpose(lightToWorld));
float2 positionNDC = positionLS.xy;
bool isInBounds;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;
if (lightData.tileCookie)
{
// Tile the texture if the 'repeat' wrap mode is enabled.
coord = frac(coord);
isInBounds = true;
}
else
{
isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1.0 - positionLS.z) <= 1.0;
}
// We let the sampler handle tiling or clamping to border.
// Note: tiling (the repeat mode) is not currently supported.
float4 cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
cookie.a = isInBounds ? cookie.a : 0.0;
return cookie;
}
DirectLighting EvaluateBSDF_Directional( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput, PreLightData preLightData,
DirectionalLightData lightData, BSDFData bsdfData)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 positionWS = posInput.positionWS;
float3 L = -lightData.forward; // Lights are pointing backward in Unity
float NdotL = dot(bsdfData.normalWS, L);
float illuminance = saturate(NdotL);
float shadow = 1.0;
[branch] if (lightData.shadowIndex >= 0)
{
#ifdef _SURFACE_TYPE_TRANSPARENT
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
#else
shadow = LOAD_TEXTURE2D(_DeferredShadowTexture, posInput.unPositionSS).x;
#endif
illuminance *= shadow;
}
[branch] if (lightData.cookieIndex >= 0)
{
float3 lightToSurface = positionWS - lightData.positionWS;
float4 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSurface);
// Premultiply.
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;
}
[branch] if (illuminance > 0.0)
{
BSDF(V, L, positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
lighting.diffuse *= illuminance * lightData.diffuseScale;
lighting.specular *= illuminance * lightData.specularScale;
}
#ifdef WANT_SSS_CODE
[branch] if (bsdfData.enableTransmission)
{
// We apply wrapped lighting instead of the regular Lambertian diffuse
// to compensate for approximations within EvaluateTransmission().
float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
}
#endif
// Save ALU by applying 'lightData.color' only once.
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
return lighting;
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Punctual (supports spot, point and projector lights)
//-----------------------------------------------------------------------------
float4 EvaluateCookie_Punctual(LightLoopContext lightLoopContext, LightData lightData,
float3 lighToSample)
{
int lightType = lightData.lightType;
// Translate and rotate 'positionWS' into the light space.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lighToSample, transpose(lightToWorld));
float4 cookie;
[branch] if (lightType == GPULIGHTTYPE_POINT)
{
cookie = SampleCookieCube(lightLoopContext, positionLS, lightData.cookieIndex);
}
else
{
// Compute the NDC position (in [-1, 1]^2) by projecting 'positionWS' onto the plane at 1m distance.
// Box projector lights require no perspective division.
float perspectiveZ = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? positionLS.z : 1;
float2 positionNDC = positionLS.xy / perspectiveZ;
bool isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;
// We let the sampler handle clamping to border.
cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
cookie.a = isInBounds ? cookie.a : 0;
}
return cookie;
}
float GetPunctualShapeAttenuation(LightData lightData, float3 L, float distSq)
{
// Note: lightData.invSqrAttenuationRadius is 0 when applyRangeAttenuation is false
float attenuation = GetDistanceAttenuation(distSq, lightData.invSqrAttenuationRadius);
// Reminder: lights are oriented backward (-Z)
return attenuation * GetAngleAttenuation(L, -lightData.forward, lightData.angleScale, lightData.angleOffset);
}
DirectLighting EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 positionWS = posInput.positionWS;
int lightType = GPULightType;
// All punctual light type in the same formula, attenuation is neutral depends on light type.
// light.positionWS is the normalize light direction in case of directional light and invSqrAttenuationRadius is 0
// mean dot(unL, unL) = 1 and mean GetDistanceAttenuation() will return 1
// For point light and directional GetAngleAttenuation() return 1
float3 lightToSurface = positionWS - lightData.positionWS;
float3 unL = -lightToSurface;
float distSq = dot(unL, unL);
float dist = sqrt(distSq);
float3 L = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? unL * rsqrt(distSq) : -lightData.forward;
float NdotL = dot(bsdfData.normalWS, L);
float illuminance = saturate(NdotL);
float attenuation = GetPunctualShapeAttenuation(lightData, L, distSq);
// Premultiply.
lightData.diffuseScale *= attenuation;
lightData.specularScale *= attenuation;
float shadow = 1.0;
[branch] if (lightData.shadowIndex >= 0)
{
// TODO: make projector lights cast shadows.
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float4 L_dist = { L, dist };
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, bsdfData.normalWS, lightData.shadowIndex, L_dist, posInput.unPositionSS);
shadow = lerp(1.0, shadow, lightData.shadowDimmer);
illuminance *= shadow;
}
#ifdef VOLUMETRIC_SHADOWING_ENABLED
float volumetricShadow = Transmittance(OpticalDepthHomogeneous(preLightData.globalFogExtinction, dist));
// Premultiply.
lightData.diffuseScale *= volumetricShadow;
lightData.specularScale *= volumetricShadow;
#endif
// Projector lights always have a cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, lightToSurface);
// Premultiply.
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;
}
[branch] if (illuminance > 0.0)
{
bsdfData.roughness = max(bsdfData.roughness, lightData.minRoughness); // Simulate that a punctual light have a radius with this hack
BSDF(V, L, positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
lighting.diffuse *= illuminance * lightData.diffuseScale;
lighting.specular *= illuminance * lightData.specularScale;
}
#ifdef WANT_SSS_CODE
[branch] if (bsdfData.enableTransmission)
{
// We apply wrapped lighting instead of the regular Lambertian diffuse
// to compensate for approximations within EvaluateTransmission().
float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
}
#endif
// Save ALU by applying 'lightData.color' only once.
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
return lighting;
}
#include "Lit\LitReference.hlsl"
//-----------------------------------------------------------------------------
// EvaluateBSDF_Line - Approximation with Linearly Transformed Cosines
//-----------------------------------------------------------------------------
DirectLighting EvaluateBSDF_Line( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 positionWS = posInput.positionWS;
#ifdef LIT_DISPLAY_REFERENCE_AREA
IntegrateBSDF_LineRef(V, positionWS, preLightData, lightData, bsdfData,
lighting.diffuse, lighting.specular);
#else
float len = lightData.size.x;
float3 T = lightData.right;
float3 unL = lightData.positionWS - positionWS;
// Pick the major axis of the ellipsoid.
float3 axis = lightData.right;
// We define the ellipsoid s.t. r1 = (r + len / 2), r2 = r3 = r.
// TODO: This could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);
float invAspectRatio = radius / (radius + (0.5 * len));
// Compute the light attenuation.
float intensity = GetEllipsoidalDistanceAttenuation(unL, lightData.invSqrAttenuationRadius,
axis, invAspectRatio);
// Terminate if the shaded point is too far away.
if (intensity == 0.0)
return lighting;
lightData.diffuseScale *= intensity;
lightData.specularScale *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
lightData.positionWS -= positionWS;
// TODO: some of this could be precomputed.
float3 P1 = lightData.positionWS - T * (0.5 * len);
float3 P2 = lightData.positionWS + T * (0.5 * len);
// Rotate the endpoints into the local coordinate system.
P1 = mul(P1, transpose(preLightData.orthoBasisViewNormal));
P2 = mul(P2, transpose(preLightData.orthoBasisViewNormal));
// Compute the binormal in the local coordinate system.
float3 B = normalize(cross(P1, P2));
float ltcValue;
// Evaluate the diffuse part
{
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
ltcValue *= lightData.diffuseScale;
lighting.diffuse = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
}
#ifdef WANT_SSS_CODE
[branch] if (bsdfData.enableTransmission)
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,
0, 1, 0,
0, 0, -1);
// Use the Lambertian approximation for performance reasons.
// The matrix multiplication should not generate any extra ALU on GCN.
ltcValue = LTCEvaluate(P1, P2, B, mul(flipMatrix, k_identity3x3));
ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, ltcValue, 1);
}
#endif
// Evaluate the specular part
{
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
ltcValue *= lightData.specularScale;
lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
}
// Save ALU by applying 'lightData.color' only once.
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
#endif // LIT_DISPLAY_REFERENCE_AREA
return lighting;
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Area - Approximation with Linearly Transformed Cosines
//-----------------------------------------------------------------------------
// #define ELLIPSOIDAL_ATTENUATION
DirectLighting EvaluateBSDF_Rect( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 positionWS = posInput.positionWS;
#ifdef LIT_DISPLAY_REFERENCE_AREA
IntegrateBSDF_AreaRef(V, positionWS, preLightData, lightData, bsdfData,
lighting.diffuse, lighting.specular);
#else
float3 unL = lightData.positionWS - positionWS;
[branch]
if (dot(lightData.forward, unL) >= 0.0001)
{
// The light is back-facing.
return lighting;
}
// Rotate the light direction into the light space.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, -lightData.forward);
unL = mul(unL, transpose(lightToWorld));
// 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);
float3 invHalfDim = rcp(float3(radius + halfWidth,
radius + halfHeight,
radius));
// Compute the light attenuation.
#ifdef ELLIPSOIDAL_ATTENUATION
// The attenuation volume is an axis-aligned ellipsoid s.t.
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
float intensity = GetEllipsoidalDistanceAttenuation(unL, invHalfDim);
#else
// The attenuation volume is an axis-aligned box s.t.
// hX = (r + w / 2), hY = (r + h / 2), hZ = r.
float intensity = GetBoxDistanceAttenuation(unL, invHalfDim);
#endif
// Terminate if the shaded point is too far away.
if (intensity == 0.0)
return lighting;
lightData.diffuseScale *= intensity;
lightData.specularScale *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
lightData.positionWS -= positionWS;
float4x3 lightVerts;
// TODO: some of this could be precomputed.
lightVerts[0] = lightData.positionWS + lightData.right * halfWidth + lightData.up * halfHeight;
lightVerts[1] = lightData.positionWS + lightData.right * halfWidth + lightData.up * -halfHeight;
lightVerts[2] = lightData.positionWS + lightData.right * -halfWidth + lightData.up * -halfHeight;
lightVerts[3] = lightData.positionWS + lightData.right * -halfWidth + lightData.up * halfHeight;
// Rotate the endpoints into the local coordinate system.
lightVerts = mul(lightVerts, transpose(preLightData.orthoBasisViewNormal));
float ltcValue;
// Evaluate the diffuse part
{
// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformDiffuse));
ltcValue *= lightData.diffuseScale;
lighting.diffuse = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
}
#ifdef WANT_SSS_CODE
[branch] if (bsdfData.enableTransmission)
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,
0, 1, 0,
0, 0, -1);
// Use the Lambertian approximation for performance reasons.
// The matrix multiplication should not generate any extra ALU on GCN.
float3x3 ltcTransform = mul(flipMatrix, k_identity3x3);
// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, ltcTransform));
ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, ltcValue, 1);
}
#endif
// Evaluate the specular part
{
// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformSpecular));
ltcValue *= lightData.specularScale;
lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
}
// Save ALU by applying 'lightData.color' only once.
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
#endif // LIT_DISPLAY_REFERENCE_AREA
return lighting;
}
DirectLighting EvaluateBSDF_Area( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType)
{
if (GPULightType == GPULIGHTTYPE_LINE)
{
return EvaluateBSDF_Line(lightLoopContext, V, posInput, preLightData, lightData, bsdfData);
}
else
{
return EvaluateBSDF_Rect(lightLoopContext, V, posInput, preLightData, lightData, bsdfData);
}
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_SSLighting for screen space lighting
// ----------------------------------------------------------------------------
IndirectLighting EvaluateBSDF_SSReflection(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
inout float hierarchyWeight)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
// TODO
return lighting;
}
IndirectLighting EvaluateBSDF_SSRefraction(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
inout float hierarchyWeight)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
#if HAS_REFRACTION
// Refraction process:
// 1. Depending on the shape model, we calculate the refracted point in world space and the optical depth
// 2. We calculate the screen space position of the refracted point
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
// a. Get the corresponding color depending on the roughness from the gaussian pyramid of the color buffer
// b. Multiply by the transmittance for absorption (depends on the optical depth)
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.)
#if defined(_REFRACTION_PLANE)
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {bsdfData.normalWS} at {bsdfData.positionWS}
// with a thickness {bsdfData.thickness}
// Refracted ray
float3 R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Get the depth of the approximated back plane
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane
float distFromP = depth - posInput.depthVS;
// Optical depth within the thin plane
opticalDepth = bsdfData.thickness / dot(R, -bsdfData.normalWS);
// The refracted ray exiting the thin plane is the same as the incident ray (parallel interfaces and same ior)
float VoR = dot(-V, R);
float VoN = dot(V, bsdfData.normalWS);
refractedBackPointWS = posInput.positionWS + R * opticalDepth - V * (distFromP - VoR * opticalDepth);
#elif defined(_REFRACTION_SPHERE)
// Sphere shape model:
// We approximate locally the shape of the object as sphere, that is tangent to the shape.
// The sphere has a diameter of {bsdfData.thickness}
// The center of the sphere is at {bsdfData.positionWS} - {bsdfData.normalWS} * {bsdfData.thickness}
//
// So the light is refracted twice: in and out of the tangent sphere
// Get the depth of the approximated back plane
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane
float depthFromPosition = depth - posInput.depthVS;
// First refraction (tangent sphere in)
// Refracted ray
float3 R1 = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Center of the tangent sphere
float3 C = posInput.positionWS - bsdfData.normalWS * bsdfData.thickness * 0.5;
// Second refraction (tangent sphere out)
float NoR1 = dot(bsdfData.normalWS, R1);
// Optical depth within the sphere
opticalDepth = -NoR1 * bsdfData.thickness;
// Out hit point in the tangent sphere
float3 P1 = posInput.positionWS + R1 * opticalDepth;
// Out normal
float3 N1 = normalize(C - P1);
// Out refracted ray
float3 R2 = refract(R1, N1, bsdfData.ior);
float N1oR2 = dot(N1, R2);
float VoR1 = dot(V, R1);
// Refracted source point
refractedBackPointWS = P1 - R2 * (depthFromPosition - NoR1 * VoR1 * bsdfData.thickness) / N1oR2;
#endif
// 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(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
if (refractedBackPointDepth < posInput.depthVS
|| any(refractedBackPointSS < 0.0)
|| any(refractedBackPointSS > 1.0))
{
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
}
// Map the roughness to the correct mip map level of the color pyramid
float mipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness, uint(_GaussianPyramidColorMipSize.z));
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointSS, mipLevel).rgb;
// Beer-Lamber law for absorption
float3 transmittance = exp(-bsdfData.absorptionCoefficient * opticalDepth);
lighting.specularTransmitted *= transmittance;
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hiearchy priority
lighting.specularTransmitted *= weight;
#else
// No refraction, no need to go further
hierarchyWeight = 1.0;
#endif
return lighting;
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Env
// ----------------------------------------------------------------------------
// _preIntegratedFGD and _CubemapLD are unique for each BRDF
IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int envShapeType, int GPUImageBasedLightingType,
inout float hierarchyWeight)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
#if !HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
return lighting;
#endif
float3 envLighting = float3(0.0, 0.0, 0.0);
float3 positionWS = posInput.positionWS;
float weight = 1.0;
#ifdef LIT_DISPLAY_REFERENCE_IBL
envLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
// TODO: Do refraction reference (is it even possible ?)
// #ifdef LIT_DIFFUSE_LAMBERT_BRDF
// envLighting += IntegrateLambertIBLRef(lightData, V, bsdfData);
// #else
// envLighting += IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
// #endif
weight = 1.0;
#else
// TODO: factor this code in common, so other material authoring don't require to rewrite everything,
// TODO: test the strech from Tomasz
// float shrinkedRoughness = AnisotropicStrechAtGrazingAngle(bsdfData.roughness, bsdfData.perceptualRoughness, NdotV);
// Guideline for reflection volume: In HDRenderPipeline we separate the projection volume (the proxy of the scene) from the influence volume (what pixel on the screen is affected)
// However we add the constrain that the shape of the projection and influence volume is the same (i.e if we have a sphere shape projection volume, we have a shape influence).
// It allow to have more coherence for the dynamic if in shader code.
// Users can also chose to not have any projection, in this case we use the property minProjectionDistance to minimize code change. minProjectionDistance is set to huge number
// that simulate effect of no shape projection
float3 R = preLightData.iblDirWS;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
// This is the same code than what is use in screen space refraction
// TODO: put this code into a function
#if defined(_REFRACTION_PLANE)
R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
#elif defined(_REFRACTION_SPHERE)
float3 R1 = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Center of the tangent sphere
float3 C = posInput.positionWS - bsdfData.normalWS * bsdfData.thickness * 0.5;
// Second refraction (tangent sphere out)
float NoR1 = dot(bsdfData.normalWS, R1);
// Optical depth within the sphere
float opticalDepth = -NoR1 * bsdfData.thickness;
// Out hit point in the tangent sphere
float3 P1 = posInput.positionWS + R1 * opticalDepth;
// Out normal
float3 N1 = normalize(C - P1);
// Out refracted ray
R = refract(R1, N1, bsdfData.ior);
#endif
}
// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.
// CAUTION: localToWorld is the transform use to convert the cubemap capture point to world space (mean it include the offset)
// the center of the bounding box is thus in locals space: positionLS - offsetLS
// We use this formulation as it is the one of legacy unity that was using only AABB box.
float3x3 worldToLocal = transpose(float3x3(lightData.right, lightData.up, lightData.forward)); // worldToLocal assume no scaling
float3 positionLS = positionWS - lightData.positionWS;
positionLS = mul(positionLS, worldToLocal).xyz - lightData.offsetLS; // We want to calculate the intersection from the center of the bounding box.
// Note: using envShapeType instead of lightData.envShapeType allow to make compiler optimization in case the type is know (like for sky)
if (envShapeType == ENVSHAPETYPE_SPHERE)
{
// 1. First process the projection
float3 dirLS = mul(R, worldToLocal);
float sphereOuterDistance = lightData.innerDistance.x + lightData.blendDistance;
float dist = SphereRayIntersectSimple(positionLS, dirLS, sphereOuterDistance);
dist = max(dist, lightData.minProjectionDistance); // Setup projection to infinite if requested (mean no projection shape)
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.positionWS
R = (positionWS + dist * R) - lightData.positionWS;
// 2. Process the influence
float distFade = max(length(positionLS) - lightData.innerDistance.x, 0.0);
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
}
else if (envShapeType == ENVSHAPETYPE_BOX)
{
float3 dirLS = mul(R, worldToLocal);
float3 boxOuterDistance = lightData.innerDistance + float3(lightData.blendDistance, lightData.blendDistance, lightData.blendDistance);
float dist = BoxRayIntersectSimple(positionLS, dirLS, -boxOuterDistance, boxOuterDistance);
dist = max(dist, lightData.minProjectionDistance); // Setup projection to infinite if requested (mean no projection shape)
// No need to normalize for fetching cubemap
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.positionWS
R = (positionWS + dist * R) - lightData.positionWS;
// TODO: add distance based roughness
// Influence volume
// Calculate falloff value, so reflections on the edges of the volume would gradually blend to previous reflection.
float distFade = DistancePointBox(positionLS, -lightData.innerDistance, lightData.innerDistance);
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
}
// Smooth weighting
weight = Smoothstep01(weight);
float3 F = 1.0;
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, preLightData.iblMipLevel);
envLighting += F * preLD.rgb * preLightData.specularFGD;
#endif
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = envLighting * weight;
else
lighting.specularTransmitted = envLighting * weight;
return lighting;
}
//-----------------------------------------------------------------------------
// PostEvaluateBSDF
// ----------------------------------------------------------------------------
void PostEvaluateBSDF( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData, float3 bakeDiffuseLighting, AggregateLighting lighting,
out float3 diffuseLighting, out float3 specularLighting)
{
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the baseColor)
#define GTAO_MULTIBOUNCE_APPROX 1
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.unPositionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
// Add indirect diffuse + emissive (if any) - Ambient occlusion is multiply by emissive which is wrong but not a big deal
#if GTAO_MULTIBOUNCE_APPROX
bakeDiffuseLighting *= GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
#else
bakeDiffuseLighting *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), indirectAmbientOcclusion);
#endif
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(preLightData.NdotV, indirectAmbientOcclusion, bsdfData.roughness);
// Try to mimic multibounce with specular color. Not the point of the original formula but ok result.
// Take the min of screenspace specular occlusion and visibility cone specular occlusion
#if GTAO_MULTIBOUNCE_APPROX
lighting.indirect.specularReflected *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
#else
lighting.indirect.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
#endif
// TODO: we could call a function like PostBSDF that will apply albedo and divide by PI once for the loop
lighting.direct.diffuse *=
#if GTAO_MULTIBOUNCE_APPROX
GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
#else
lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
#endif
diffuseLighting = lighting.direct.diffuse + bakeDiffuseLighting;
// If refraction is enable we use the transmittanceMask to lerp between current diffuse lighting and refraction value
// Physically speaking, it should be transmittanceMask should be 1, but for artistic reasons, we let the value vary
#if HAS_REFRACTION
diffuseLighting = lerp(diffuseLighting, lighting.indirect.specularTransmitted, bsdfData.transmittanceMask);
#endif
specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering.
specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)
{
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO)
{
diffuseLighting = GetSpecularOcclusionFromAmbientOcclusion(preLightData.NdotV, indirectAmbientOcclusion, bsdfData.roughness);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#if GTAO_MULTIBOUNCE_APPROX
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#endif
#endif
}
#endif // #ifdef HAS_LIGHTLOOP

10
ScriptableRenderPipeline/HDRenderPipeline/Material/LightEvaluationShare2.hlsl.meta


fileFormatVersion: 2
guid: a5ae278c101d602428cf78a26d2444e9
timeCreated: 1504900828
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Vegetation.meta


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