namespace UnityEngine.Rendering.HighDefinition { //----------------------------------------------------------------------------- // structure definition //----------------------------------------------------------------------------- // Caution: Order is important and is use for optimization in light loop [GenerateHLSL] enum GPULightType { Directional, Point, Spot, ProjectorPyramid, ProjectorBox, // AreaLight Tube, // Keep Line lights before Rectangle. This is needed because of a compiler bug (see LightLoop.hlsl) Rectangle, // Currently not supported in real time (just use for reference) Disc, // Sphere, }; static class GPULightTypeExtension { public static bool IsAreaLight(this GPULightType lightType) { return lightType == GPULightType.Rectangle || lightType == GPULightType.Tube; } public static bool IsSpot(this GPULightType lightType) { return lightType == GPULightType.Spot || lightType == GPULightType.ProjectorBox || lightType == GPULightType.ProjectorPyramid; } } // This is use to distinguish between reflection and refraction probe in LightLoop [GenerateHLSL] enum GPUImageBasedLightingType { Reflection, Refraction }; /// /// Cookie Mode /// [GenerateHLSL] public enum CookieMode { /// No cookie at all. None, /// Cookie texture with clamped sampling mode. Clamp, /// Cookie texture with repeat sampling mode. Repeat, } // These structures share between C# and hlsl need to be align on float4, so we pad them. [GenerateHLSL(PackingRules.Exact, false)] struct DirectionalLightData { // Packing order depends on chronological access to avoid cache misses // Make sure to respect the 16-byte alignment public Vector3 positionRWS; public uint lightLayers; public Vector3 forward; public CookieMode cookieMode; public Vector4 cookieScaleOffset; public Vector3 right; // Rescaled by (2 / shapeWidth) public int shadowIndex; // -1 if unused (TODO: 16 bit) public Vector3 up; // Rescaled by (2 / shapeHeight) public int contactShadowIndex; // -1 if unused (TODO: 16 bit) public Vector3 color; public int contactShadowMask; // 0 if unused (TODO: 16 bit) public Vector3 shadowTint; // Use to tint shadow color public float shadowDimmer; public float volumetricShadowDimmer; // Replaces 'shadowDimmer' public int nonLightMappedOnly; // Used with ShadowMask (TODO: use a bitfield) [SurfaceDataAttributes(precision = FieldPrecision.Real)] public float minRoughness; // Hack public int screenSpaceShadowIndex; // -1 if unused (TODO: 16 bit) [SurfaceDataAttributes(precision = FieldPrecision.Real)] public Vector4 shadowMaskSelector; // Used with ShadowMask feature public float diffuseDimmer; public float specularDimmer; public float lightDimmer; public float volumetricLightDimmer; // Replaces 'lightDimer' public float penumbraTint; public float isRayTracedContactShadow; public float angularDiameter; // Units: radians public float distanceFromCamera; // -1 -> no sky interaction }; // These structures share between C# and hlsl need to be align on float4, so we pad them. [GenerateHLSL(PackingRules.Exact, false)] struct CelestialBodyData { public Vector3 color; public float radius; public Vector3 forward; public float distanceFromCamera; // -1 -> no sky interaction public Vector3 right; public float angularRadius; // Units: radians public Vector3 up; public int type; // 0: star, 1: moon public Vector3 surfaceColor; public float earthshine; public Vector4 surfaceTextureScaleOffset; // -1 if unused (TODO: 16 bit) public Vector3 sunDirection; public float flareCosInner; public Vector2 phaseAngleSinCos; public float flareCosOuter; public float flareSize; // Units: radians public Vector3 flareColor; public float flareFalloff; }; [GenerateHLSL(PackingRules.Exact, false)] struct LightData { // Packing order depends on chronological access to avoid cache misses // Make sure to respect the 16-byte alignment public Vector3 positionRWS; public uint lightLayers; public float lightDimmer; public float volumetricLightDimmer; // Replaces 'lightDimer' [SurfaceDataAttributes(precision = FieldPrecision.Real)] public float angleScale; // Spot light [SurfaceDataAttributes(precision = FieldPrecision.Real)] public float angleOffset; // Spot light public Vector3 forward; public float iesCut; // Spot light public GPULightType lightType; // TODO: move this up? public Vector3 right; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / shapeWidth) public float penumbraTint; [SurfaceDataAttributes(precision = FieldPrecision.Real)] public float range; public CookieMode cookieMode; public int shadowIndex; // -1 if unused (TODO: 16 bit) public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / shapeHeight) public float rangeAttenuationScale; public Vector3 color; public float rangeAttenuationBias; public Vector4 cookieScaleOffset; // coordinates of the cookie texture in the atlas public Vector3 shadowTint; // Use to tint shadow color public float shadowDimmer; public float volumetricShadowDimmer; // Replaces 'shadowDimmer' public int nonLightMappedOnly; // Used with ShadowMask feature (TODO: use a bitfield) [SurfaceDataAttributes(precision = FieldPrecision.Real)] public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius. // TODO: Instead of doing this, we should pack the ray traced shadow index into the tile cookie for instance public int screenSpaceShadowIndex; // -1 if unused (TODO: 16 bit) [SurfaceDataAttributes(precision = FieldPrecision.Real)] public Vector4 shadowMaskSelector; // Used with ShadowMask feature [SurfaceDataAttributes(precision = FieldPrecision.Real)] public Vector4 size; // Used by area (X = length or width, Y = height, Z = CosBarnDoorAngle, W = BarnDoorLength) and punctual lights (X = radius) public int contactShadowMask; // negative if unused (TODO: 16 bit) public float diffuseDimmer; public float specularDimmer; public float __unused__; public Vector2 padding; public float isRayTracedContactShadow; public float boxLightSafeExtent; }; [GenerateHLSL] enum EnvShapeType { None, Box, Sphere, Sky }; [GenerateHLSL] enum EnvConstants { ConvolutionMipCount = 7, } // 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 [GenerateHLSL(PackingRules.Exact, false)] struct EnvLightData { // Packing order depends on chronological access to avoid cache misses public uint lightLayers; // Proxy properties public Vector3 capturePositionRWS; public EnvShapeType influenceShapeType; // Box: extents = box extents // Sphere: extents.x = sphere radius public Vector3 proxyExtents; // User can chose if they use This is use in case we want to force infinite projection distance (i.e no projection); [SurfaceDataAttributes(precision = FieldPrecision.Real)] public float minProjectionDistance; public Vector3 proxyPositionRWS; public Vector3 proxyForward; public Vector3 proxyUp; public Vector3 proxyRight; // Influence properties public Vector3 influencePositionRWS; public Vector3 influenceForward; public Vector3 influenceUp; public Vector3 influenceRight; public Vector3 influenceExtents; public Vector3 blendDistancePositive; public Vector3 blendDistanceNegative; public Vector3 blendNormalDistancePositive; public Vector3 blendNormalDistanceNegative; [SurfaceDataAttributes(precision = FieldPrecision.Real)] public Vector3 boxSideFadePositive; [SurfaceDataAttributes(precision = FieldPrecision.Real)] public Vector3 boxSideFadeNegative; public float weight; public float multiplier; public float rangeCompressionFactorCompensation; // Only used for planar reflections to drop all mips below mip0 public float roughReflections; // Only used for reflection probes to avoid using the proxy for distance based roughness. public float distanceBasedRoughness; // Sampling properties public int envIndex; // The luma SH for irradiance at probe location. public Vector4 L0L1; public Vector4 L2_1; // First 4 coeffs of L2 {-2, -1, 0, 1} public float L2_2; // Last L2 coeff {2} // Whether the probe is normalized by probe volume content. public int normalizeWithAPV; public Vector2 padding; }; [GenerateHLSL(needAccessors = false, generateCBuffer = true)] unsafe struct EnvLightReflectionData { public const int s_MaxPlanarReflections = HDRenderPipeline.k_MaxPlanarReflectionsOnScreen; public const int s_MaxCubeReflections = HDRenderPipeline.k_MaxCubeReflectionsOnScreen; [HLSLArray(s_MaxPlanarReflections, typeof(Matrix4x4))] public fixed float _PlanarCaptureVP[s_MaxPlanarReflections * 4 * 4]; [HLSLArray(s_MaxPlanarReflections, typeof(Vector4))] public fixed float _PlanarScaleOffset[s_MaxPlanarReflections * 4]; [HLSLArray(s_MaxCubeReflections, typeof(Vector4))] public fixed float _CubeScaleOffset[s_MaxCubeReflections * 4]; }; [GenerateHLSL(needAccessors = false, generateCBuffer = true, constantRegister = (int)ConstantRegister.WorldEnvLightReflectionData)] unsafe struct WorldEnvLightReflectionData { public const int s_MaxPlanarReflections = HDRenderPipeline.k_MaxPlanarReflectionsOnScreen; public const int s_MaxCubeReflections = HDRenderPipeline.k_MaxCubeReflectionsOnScreen; [HLSLArray(s_MaxPlanarReflections, typeof(Matrix4x4))] public fixed float _PlanarCaptureVPWL[s_MaxPlanarReflections * 4 * 4]; [HLSLArray(s_MaxPlanarReflections, typeof(Vector4))] public fixed float _PlanarScaleOffsetWL[s_MaxPlanarReflections * 4]; [HLSLArray(s_MaxCubeReflections, typeof(Vector4))] public fixed float _CubeScaleOffsetWL[s_MaxCubeReflections * 4]; }; [GenerateHLSL] enum EnvCacheType { Texture2D, Cubemap } }