// TODO: This is the wrong way to handle resize/allocation. We can have several different camera here, mean that the loop on camera will allocate and deallocate
// the below buffer which is bad. Best is to have a set of buffer for each camera that is persistent and reallocate resource if need
// For now consider we have only one camera that go to this code, the main one.
m_SkyManager.Resize();// TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
m_SkyManager.Resize(camera.nearClipPlane,camera.farClipPlane);// TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
// TODO: Workflow problem here, I would like to only generate variant for the LIGHTLOOP_TILE_PASS case, not the LIGHTLOOP_SINGLE_PASS case. This must be on lightloop side and include here.... (Can we codition
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR)
for(int l=0; l<iNrCoarseLights; l++)
{
const uint idxCoarse = lightsListLDS[l];
[branch]if (idxCoarse<(uint)g_iNrVisibLights && _LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
bool canEnter = idxCoarse<(uint)g_iNrVisibLights;
if(canEnter) canEnter = _LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE; // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
publicreadonlyGUIContentlayerMapMaskText=newGUIContent("Layer Mask","Layer mask (multiplied by vertex color if enabled)");
publicreadonlyGUIContentlayerMapVertexColorText=newGUIContent("Use Vertex Color","If no layer mask is set, vertex color values between 0 and 1.0 are used as final mask.\nIf a layer mask is set, vertex color values are remapped between -1 and 1 and added to the mask (neutral at 0.5 vertex color).");
publicreadonlyGUIContentvertexColorHeightMultiplierText=newGUIContent("Vertex Height Scale","Scale applied to the vertex color height.");
publicreadonlyGUIContentvertexColorModeText=newGUIContent("Vertex Color Mode","Mode multiply: vertex color is multiply with the mask. Mode additive: vertex color values are remapped between -1 and 1 and added to the mask (neutral at 0.5 vertex color).");
publicreadonlyGUIContentlayerTilingText=newGUIContent("Tiling","Tiling factor applied to UVSet");
// 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.
publicstaticGUIContenttessellationFactorFixedText=newGUIContent("Fixed tessellation factor","If non negative, this value is a fixed tessellation factor use for tessellation");
publicstaticGUIContenttessellationFactorMaxDistanceText=newGUIContent("Max Distance","Maximun distance to the camera where triangle are tesselated");
publicstaticGUIContenttessellationFactorTriangleSizeText=newGUIContent("Triangle size","Desired screen space sized of triangle. Smaller value mean smaller triangle.");
publicstaticGUIContenttessellationFactorText=newGUIContent("Tessellation factor","This value is the tessellation factor use for tessellation, higher mean more tessellated");
publicstaticGUIContenttessellationFactorMinDistanceText=newGUIContent("Start fade distance","Distance (in unity unit) at which the tessellation start to fade out. Must be inferior at Max distance");
publicstaticGUIContenttessellationFactorMaxDistanceText=newGUIContent("End fade distance","Maximum distance (in unity unit) to the camera where triangle are tessellated");
publicstaticGUIContenttessellationFactorTriangleSizeText=newGUIContent("Triangle size","Desired screen space sized of triangle (in pixel). Smaller value mean smaller triangle.");
publicstaticGUIContenttessellationBackFaceCullEpsilonText=newGUIContent("Triangle culling Epsilon","If non zero, backface culling is enabled for tessellation, smaller number mean more aggressive culling and better performance");
publicstaticGUIContenttessellationObjectScaleText=newGUIContent("Enable object scale","Scale displacement taking into account the object scale");
publicstaticGUIContenttessellationBackFaceCullEpsilonText=newGUIContent("Triangle culling Epsilon","If -1.0 back face culling is enabled for tessellation, higher number mean more aggressive culling and better performance");
publicstaticGUIContenttessellationObjectScaleText=newGUIContent("Enable object scale","Tesselation displacement will take into account the object scale - Only work with uniform positive scale");
// In case we pack data uint16 buffer we need to change the output render target format to uint16
// TODO: Is there a way to automate these output type based on the format declare in lit.cs ?
// TODO: Check if anisotropy with a dynamic if on anisotropy > 0 is performant. Because it may mean we always calculate both isotropy and anisotropy case.
// Maybe we should always calculate anisotropy in case of standard ? Don't think the compile can optimize correctly.
// TODO: I haven't configure this sampler in the code, we should be able to do it (but Unity don't allow it for now...)
// By default Unity provide MIG_MAG_LINEAR_POINT sampler, so it fit with our need.
// TODO: to avoid the message Fragment program 'Frag' : sampler 'sampler_PreIntegratedFGD' has no matching texture and will be undefined.
// We need to test this define LIGHTLOOP_TILE_DIRECT, this is a bad workaround but no alternative until we can setup sampler correctly...
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
outGBuffer2 = float4(surfaceData.subSurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subSurfaceProfile / 8.0f); // Number of profile not define yet
outGBuffer2 = float4(surfaceData.subSurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subSurfaceProfile / 8.0); // Number of profile not define yet
}
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT)
{
bsdfData.fresnel0 = 0.028; // TODO take from subSurfaceProfile
bsdfData.subSurfaceRadius = inGBuffer2.r;
bsdfData.thickness = inGBuffer2.g;
bsdfData.subSurfaceProfile = inGBuffer2.a * 8.0f;
bsdfData.subSurfaceProfile = inGBuffer2.a * 8.0;
}
else if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT)
// We will add smoothly the contribution of the normal map by using lower mips with help of bias sampling. InfluenceFactor must be [0..numMips] // Caution it cause banding...
// Note: that we don't take details map into account here.
float maxMipBias = log2(max(_NormalMap0_TexelSize.z, _NormalMap0_TexelSize.w)); // don't do + 1 as it is for bias, not lod
// The idea here is to lerp toward vertex normal. This way when we don't want to inherit, we will combine layer 1/2/3 normal with a vertex normal which is neutral.
// Blend layer 1/2/3 normals before combining to the base layer. Again we need to have a neutral value for base layer (vertex normal) in case all weights are zero.
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalTS = reflect(normalTS, float3(0.0, 0.0, 1.0)); // Reflect around vertex normal (in tangent space this is z)
#endif
// TODO : Test if GetOddNegativeScale() is necessary here in case of normal map, as GetOddNegativeScale is take into account in CreateTangentToWorld();
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalTS = reflect(normalTS, float3(0.0, 0.0, 1.0)); // Reflect around vertex normal (in tangent space this is z)
#endif
// TODO : Test if GetOddNegativeScale() is necessary here in case of normal map, as GetOddNegativeScale is take into account in CreateTangentToWorld();
#define NEED_TANGENT_TO_WORLD 1 // NEED_TEXCOORD0 && (defined(_HEIGHTMAP) && defined(_PER_PIXEL_DISPLACEMENT)) TEMP!!!: until we fix tessellation so it can access normalOS
// When modifying this structure, update the tessellation code below
struct Attributes
{
float3 positionOS : POSITION;
#if NEED_TEXCOORD0
float2 uv0 : TEXCOORD0;
#endif
#if NEED_TANGENT_TO_WORLD
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
#endif
};
#ifdef TESSELLATION_ON
// Copy paste of above struct with POSITION rename to INTERNALTESSPOS (internal of unity shader compiler)
// If we have a lit shader, only the UV0 is available for opacity or heightmap
// If we have a layered shader, any UV can be use for this. To reduce the number of variant we groupt UV0/UV1 and UV2/UV3 instead of having variant for UV0/UV1/UV2/UV3
// When UVX is present, we assume that UVX - 1 ... UV0 is present
// If we have a lit shader, only the UV0 is available for opacity or heightmap
// If we have a layered shader, any UV can be use for this. To reduce the number of variant we groupt UV0/UV1 and UV2/UV3 instead of having variant for UV0/UV1/UV2/UV3
// When UVX is present, we assume that UVX - 1 ... UV0 is present
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow steps transform to clip space + instancing matrix)
// TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16)
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow steps transform to clip space + instancing matrix)
// #define ATTRIBUTES_NEED_NORMAL - When reenable, think to also enable code in VertMesh.hlsl
#if NEED_TANGENT_TO_WORLD
// output.normalOS = input.normalOS;
output.tangentOS = input.tangentOS;
#if REQUIRE_TANGENT_TO_WORLD
#define ATTRIBUTES_NEED_TANGENT
return output;
}
// About UV
// If we have a lit shader, only the UV0 is available for opacity or heightmap
// If we have a layered shader, any UV can be use for this. To reduce the number of variant we groupt UV0/UV1 and UV2/UV3 instead of having variant for UV0/UV1/UV2/UV3
// When UVX is present, we assume that UVX - 1 ... UV0 is present
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow steps transform to clip space + instancing matrix)
// This function convert the tangent space normal/tangent to world space and orthonormalize it + apply a correction of the normal if it is not pointing towards the near plane
float3 previousPositionOS : NORMAL; // Contain previous transform position (in case of skinning for example)
// TODO: Caution - For now the tesselation doesn't displace along the normal with Velocity shader as the previous previous position
// conflict with the normal in the semantic. This need to be fix!
};
struct VaryingsPassToPS
{
// Note: Z component is not use currently
// This is the clip space position. Warning, do not confuse with the value of positionCS in PackedVarying which is SV_POSITION and store in unPositionSS
// renderForCubemap: When rendering into a cube map, no depth buffer is available so user has to make sure not to use depth testing or the depth texture.
#pragma kernel ShadeDeferred_Clustered SHADE_DEFERRED_ENTRY=ShadeDeferred_Clustered USE_CLUSTERED_LIGHTLIST=1 ENABLE_DEBUG=0 //TODO: disabled clustered permutations so far as it leads to the error "All kernels must use same constant buffer layouts"
#pragma kernel ShadeDeferred_Clustered SHADE_DEFERRED_ENTRY=ShadeDeferred_Clustered USE_CLUSTERED_LIGHTLIST=1 ENABLE_DEBUG=0 //TODO: disabled clustered permutations so far as it leads to the error "All kernels must use same constant buffer layouts"
[branch]if(idxCoarse<(uint) g_iNrVisibLights && g_vLightData[idxCoarse].lightType!=SPHERE_LIGHT) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
if(canEnter) canEnter = g_vLightData[idxCoarse].lightType!=SPHERE_LIGHT; // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
// CAUTION: Only use with velocity currently, null else
// Note: Z component is not use currently
// This is the clip space position. Warning, do not confuse with the value of positionCS in PackedVarying which is SV_POSITION and store in unPositionSS