diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png index 6d3dc0d0d70..ba84aea3eb6 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28ab15af71725fac497906d56db558c021070de09198f0a21d390f447449012b -size 227381 +oid sha256:9782b8e1c0c09dcae4ffccbdc2d13c4e24b294d642969918a770a9227fb9aaa1 +size 230013 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png.meta b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png.meta index a6abf3cb112..b16598cc364 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png.meta +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1705_Decals-stress-test.png.meta @@ -1,9 +1,9 @@ fileFormatVersion: 2 -guid: b6b56924b0cb8334684daab8c5427608 +guid: ec153bdfef165ae4ca60c7c02e1d0b3f TextureImporter: internalIDToNameTable: [] externalObjects: {} - serializedVersion: 10 + serializedVersion: 11 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -57,6 +57,7 @@ TextureImporter: maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + applyGammaDecoding: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl index 3f179827f91..2c5139393d7 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl @@ -686,36 +686,37 @@ TEMPLATE_3_FLT(RangeRemap, min, max, t, return saturate((t - min) / (max - min)) // Texture utilities // ---------------------------------------------------------------------------- -float ComputeTextureLOD(float2 uvdx, float2 uvdy, float2 scale) +float ComputeTextureLOD(float2 uvdx, float2 uvdy, float2 scale, float bias = 0.0) { float2 ddx_ = scale * uvdx; float2 ddy_ = scale * uvdy; - float d = max(dot(ddx_, ddx_), dot(ddy_, ddy_)); + float d = max(dot(ddx_, ddx_), dot(ddy_, ddy_)); - return max(0.5 * log2(d), 0.0); + return max(0.5 * log2(d) - bias, 0.0); } -float ComputeTextureLOD(float2 uv) +float ComputeTextureLOD(float2 uv, float bias = 0.0) { float2 ddx_ = ddx(uv); float2 ddy_ = ddy(uv); - return ComputeTextureLOD(ddx_, ddy_, 1.0); + return ComputeTextureLOD(ddx_, ddy_, 1.0, bias); } // x contains width, w contains height -float ComputeTextureLOD(float2 uv, float2 texelSize) +float ComputeTextureLOD(float2 uv, float2 texelSize, float bias = 0.0) { uv *= texelSize; - return ComputeTextureLOD(uv); + return ComputeTextureLOD(uv, bias); } // LOD clamp is optional and happens outside the function. -float ComputeTextureLOD(float3 duvw_dx, float3 duvw_dy, float3 duvw_dz, float scale) +float ComputeTextureLOD(float3 duvw_dx, float3 duvw_dy, float3 duvw_dz, float scale, float bias = 0.0) { float d = Max3(dot(duvw_dx, duvw_dx), dot(duvw_dy, duvw_dy), dot(duvw_dz, duvw_dz)); - return 0.5 * log2(d * (scale * scale)); + + return max(0.5f * log2(d * (scale * scale)) - bias, 0.0); } diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index b306b24fd44..7f493cbbd3d 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -552,6 +552,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Diffusion Profile and Material references in HDRP materials are now correctly exported to unity packages. Note that the diffusion profile or the material references need to be edited once before this can work properly. ### Changed +- Improve MIP selection for decals on Transparents - Color buffer pyramid is not allocated anymore if neither refraction nor distortion are enabled - Rename Emission Radius to Radius in UI in Point, Spot - Angular Diameter parameter for directional light is no longuer an advanced property diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl index be2bdb5cbeb..6a251a7606e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl @@ -11,10 +11,10 @@ DECLARE_DBUFFER_TEXTURE(_DBufferTexture); void ApplyBlendNormal(inout float4 dst, inout uint matMask, float2 texCoords, uint mapMask, float3x3 decalToWorld, float blend, float lod) { float4 src; - src.xyz = mul(decalToWorld, UnpackNormalmapRGorAG(SAMPLE_TEXTURE2D_LOD(_DecalAtlas2D, _trilinear_clamp_sampler_DecalAtlas2D, texCoords, lod))) * 0.5f + 0.5f; + src.xyz = mul(decalToWorld, UnpackNormalmapRGorAG(SAMPLE_TEXTURE2D_LOD(_DecalAtlas2D, _trilinear_clamp_sampler_DecalAtlas2D, texCoords, lod))) * 0.5 + 0.5; src.w = blend; - dst.xyz = src.xyz * src.w + dst.xyz * (1.0f - src.w); - dst.w = dst.w * (1.0f - src.w); + dst.xyz = src.xyz * src.w + dst.xyz * (1.0 - src.w); + dst.w = dst.w * (1.0 - src.w); matMask |= mapMask; } @@ -26,8 +26,8 @@ void ApplyBlendDiffuse(inout float4 dst, inout uint matMask, float2 texCoords, f } src.w *= blend; blend = src.w; // diffuse texture alpha affects all other channels - dst.xyz = src.xyz * src.w + dst.xyz * (1.0f - src.w); - dst.w = dst.w * (1.0f - src.w); + dst.xyz = src.xyz * src.w + dst.xyz * (1.0 - src.w); + dst.w = dst.w * (1.0 - src.w); matMask |= mapMask; } @@ -45,12 +45,12 @@ void ApplyBlendMask(inout float4 dbuffer2, inout float2 dbuffer3, inout uint mat src.z = scalingMAB.z * src.z; src.w = lerp(remappingAOS.z, remappingAOS.w, src.w); float maskBlend; - if (blendParams.x == 1.0f) // normal blend source is mask blue channel + if (blendParams.x == 1.0) // normal blend source is mask blue channel normalBlend = src.z * decalBlend; else - normalBlend = albedoBlend; // normal blend source is albedo alpha + normalBlend = albedoBlend; // normal blend source is albedo alpha - if (blendParams.y == 1.0f) // mask blend source is mask blue channel + if (blendParams.y == 1.0) // mask blend source is mask blue channel maskBlend = src.z * decalBlend; else maskBlend = albedoBlend; // mask blend siurce is albedo alpha @@ -102,23 +102,24 @@ void ApplyBlendMask(inout float4 dbuffer2, inout float2 dbuffer3, inout uint mat dbuffer3Mask = float2(1, 1); // M alpha, AO alpha } - dbuffer2.xyz = (dbuffer2Mask.xyz == 1) ? src.xyz * src.w + dbuffer2.xyz * (1.0f - src.w) : dbuffer2.xyz; - dbuffer2.w = (dbuffer2Mask.w == 1) ? dbuffer2.w * (1.0f - src.w) : dbuffer2.w; + dbuffer2.xyz = (dbuffer2Mask.xyz == 1) ? src.xyz * src.w + dbuffer2.xyz * (1.0 - src.w) : dbuffer2.xyz; + dbuffer2.w = (dbuffer2Mask.w == 1) ? dbuffer2.w * (1.0 - src.w) : dbuffer2.w; - dbuffer3.xy = (dbuffer3Mask.xy == 1) ? dbuffer3.xy * (1.0f - src.w) : dbuffer3.xy; + dbuffer3.xy = (dbuffer3Mask.xy == 1) ? dbuffer3.xy * (1.0 - src.w) : dbuffer3.xy; matMask |= mapMask; } - +// In order that the lod for with transpartent decal better match the lod for opaque decal +// We use ComputeTextureLOD with bias == 0.5 void EvalDecalMask(PositionInputs posInput, float3 positionRWSDdx, float3 positionRWSDdy, DecalData decalData, inout float4 DBuffer0, inout float4 DBuffer1, inout float4 DBuffer2, inout float2 DBuffer3, inout uint mask, inout float alpha) { // Get the relative world camera to decal matrix float4x4 worldToDecal = ApplyCameraTranslationToInverseMatrix(decalData.worldToDecal); float3 positionDS = mul(worldToDecal, float4(posInput.positionWS, 1.0)).xyz; - positionDS = positionDS * float3(1.0, -1.0, 1.0) + float3(0.5, 0.5f, 0.5); // decal clip space - if ((all(positionDS.xyz > 0.0f) && all(1.0f - positionDS.xyz > 0.0f))) + positionDS = positionDS * float3(1.0, -1.0, 1.0) + float3(0.5, 0.5, 0.5); // decal clip space + if ((all(positionDS.xyz > 0.0) && all(1.0 - positionDS.xyz > 0.0))) { float2 uvScale = float2(decalData.normalToWorld[3][0], decalData.normalToWorld[3][1]); float2 uvBias = float2(decalData.normalToWorld[3][2], decalData.normalToWorld[3][3]); @@ -126,7 +127,7 @@ void EvalDecalMask(PositionInputs posInput, float3 positionRWSDdx, float3 positi positionDS.xz = frac(positionDS.xz); // clamp by half a texel to avoid sampling neighboring textures in the atlas - float2 clampAmount = float2(0.5f / _DecalAtlasResolution.x, 0.5f / _DecalAtlasResolution.y); + float2 clampAmount = float2(0.5 / _DecalAtlasResolution.x, 0.5 / _DecalAtlasResolution.y); float2 diffuseMin = decalData.diffuseScaleBias.zw + clampAmount; // offset into atlas is in .zw float2 diffuseMax = decalData.diffuseScaleBias.zw + decalData.diffuseScaleBias.xy - clampAmount; // scale relative to full atlas size is in .xy so total texture extent in atlas is (1,1) * scale @@ -147,15 +148,15 @@ void EvalDecalMask(PositionInputs posInput, float3 positionRWSDdx, float3 positi float2 sampleDiffuseDdx = positionDSDdx.xz * decalData.diffuseScaleBias.xy; // factor in the atlas scale float2 sampleDiffuseDdy = positionDSDdy.xz * decalData.diffuseScaleBias.xy; - float lodDiffuse = ComputeTextureLOD(sampleDiffuseDdx, sampleDiffuseDdy, _DecalAtlasResolution); + float lodDiffuse = ComputeTextureLOD(sampleDiffuseDdx, sampleDiffuseDdy, _DecalAtlasResolution, 0.5); - float2 sampleNormalDdx = positionDSDdx.xz * decalData.normalScaleBias.xy; - float2 sampleNormalDdy = positionDSDdy.xz * decalData.normalScaleBias.xy; - float lodNormal = ComputeTextureLOD(sampleNormalDdx, sampleNormalDdy, _DecalAtlasResolution); + float2 sampleNormalDdx = positionDSDdx.xz * decalData.normalScaleBias.xy; + float2 sampleNormalDdy = positionDSDdy.xz * decalData.normalScaleBias.xy; + float lodNormal = ComputeTextureLOD(sampleNormalDdx, sampleNormalDdy, _DecalAtlasResolution, 0.5); - float2 sampleMaskDdx = positionDSDdx.xz * decalData.maskScaleBias.xy; - float2 sampleMaskDdy = positionDSDdy.xz * decalData.maskScaleBias.xy; - float lodMask = ComputeTextureLOD(sampleMaskDdx, sampleMaskDdy, _DecalAtlasResolution); + float2 sampleMaskDdx = positionDSDdx.xz * decalData.maskScaleBias.xy; + float2 sampleMaskDdy = positionDSDdy.xz * decalData.maskScaleBias.xy; + float lodMask = ComputeTextureLOD(sampleMaskDdx, sampleMaskDdy, _DecalAtlasResolution, 0.5); float albedoBlend = decalData.normalToWorld[0][3]; float4 src = decalData.baseColor; @@ -165,9 +166,9 @@ void EvalDecalMask(PositionInputs posInput, float3 positionRWSDdx, float3 positi alpha = alpha < albedoBlend ? albedoBlend : alpha; // use decal alpha if it is higher than transparent alpha float albedoContribution = decalData.normalToWorld[1][3]; - if (albedoContribution == 0.0f) + if (albedoContribution == 0.0) { - mask = 0; // diffuse will not get modified + mask = 0; // diffuse will not get modified } float normalBlend = albedoBlend; @@ -208,13 +209,13 @@ DecalSurfaceData GetDecalSurfaceData(PositionInputs posInput, inout float alpha) #if defined(_SURFACE_TYPE_TRANSPARENT) && defined(HAS_LIGHTLOOP) // forward transparent using clustered decals uint decalCount, decalStart; - DBuffer0 = float4(0.0f, 0.0f, 0.0f, 1.0f); - DBuffer1 = float4(0.5f, 0.5f, 0.5f, 1.0f); - DBuffer2 = float4(0.0f, 0.0f, 0.0f, 1.0f); + DBuffer0 = float4(0.0, 0.0, 0.0, 1.0); + DBuffer1 = float4(0.5, 0.5, 0.5, 1.0); + DBuffer2 = float4(0.0, 0.0, 0.0, 1.0); #ifdef DECALS_4RT - DBuffer3 = float2(1.0f, 1.0f); + DBuffer3 = float2(1.0, 1.0); #else - float2 DBuffer3 = float2(1.0f, 1.0f); + float2 DBuffer3 = float2(1.0, 1.0); #endif #ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER