Terrain detail material blending (#5714)
* Added buffer for material properties of detail mateirals, storing them in a multi-indexed data vector. Updated shader with relevant struct and buffer, but the buffer will need to be moved out of the mateiral SRG to work. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Added buffer for material properties of detail mateirals, storing them in a multi-indexed data vector. Updated shader with relevant struct and buffer, but the buffer will need to be moved out of the mateiral SRG to work. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Added buffer for material properties of detail mateirals, storing them in a multi-indexed data vector. Updated shader with relevant struct and buffer, but the buffer will need to be moved out of the mateiral SRG to work. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * - Moved settings related to the detail material to a partial view srg owned by the terrain gem. - Added support for base color in detail materials. - Hooked up basic base color rendering of detail materials. - Corrected the way the material data was stored. - Added ref counting for detail materials so they can be released when no longer used. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Added buffer for material properties of detail mateirals, storing them in a multi-indexed data vector. Updated shader with relevant struct and buffer, but the buffer will need to be moved out of the mateiral SRG to work. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * - Moved settings related to the detail material to a partial view srg owned by the terrain gem. - Added support for base color in detail materials. - Hooked up basic base color rendering of detail materials. - Corrected the way the material data was stored. - Added ref counting for detail materials so they can be released when no longer used. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Detail materials now put textures into bindless array that's accessed in the shader. Shader now pulls all the detail materal information for a single mateiral but does no blending. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Correcting rebase merge problem. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Fix detail roughness fade out with distance. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Adding tests for new MultiIndexedDataVector functions Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Updates to move bindless array to separate SRG - Exposed BindSrg() in renderpass so it's possible to add additional SRGs to a pass - Created a TerrainSrg for use by the terrain forward shader - Moved the bindless array out of the partial view SRG to the TerrainSrg Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Moved more properties out of the view srg to the terrain srg. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Spelling fixes Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Fixing bug where the roughness min/max value were inverted. Also fixed bug where bad data would show for areas where there was no macro material. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Detail material blending WIP. Mostly working, but small seams between each materila id pixel. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Switching to using Load() for the detail material IDs and calculating the positions manually since Gather()'s precsion leaves seams along the edges. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Updates from PR review Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Fixing case issues and updating function name due to a recent fix. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Switching to using SampleGrad() instead of Sample() for detail textures to fix a bug where the incorrect mip level was chosen around the seams of the detail material id texture. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Remove unneeded sampler and some debug settings in the shader. Condensing some duplicate code Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Updates from PR review and some minor improvements Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Updated with PR feedback. Fixed a fairly significant bug with blending. Also contains a few minor fixes, simplifications, and comments for clarity. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Update weight adjustment equation to trust the compiler less Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * fix bug Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Fixing bug in terrain normal factor. Adjusting normal calculation to avoid the need for an identity transform. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Removing unused fields from the material SRG. Adding basecolor back in in the material type. Updating the default terrain material to not use fields that no longer exist. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com>
This commit is contained in:
@@ -2,5 +2,10 @@
|
||||
"description": "",
|
||||
"materialType": "PbrTerrain.materialtype",
|
||||
"parentMaterial": "",
|
||||
"propertyLayoutVersion": 1
|
||||
"propertyLayoutVersion": 1,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [ 0.18, 0.18, 0.18 ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,19 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"baseColor": [
|
||||
{
|
||||
"name": "color",
|
||||
"displayName": "Color",
|
||||
"description": "Color is displayed as sRGB but the values are stored as linear color.",
|
||||
"type": "Color",
|
||||
"defaultValue": [ 1.0, 1.0, 1.0 ],
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"name": "m_baseColor"
|
||||
}
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"id": "detailTextureMultiplier",
|
||||
|
||||
@@ -93,10 +93,6 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject
|
||||
|
||||
ShaderResourceGroup TerrainMaterialSrg : SRG_PerMaterial
|
||||
{
|
||||
float m_detailTextureMultiplier;
|
||||
float m_detailFadeDistance;
|
||||
float m_detailFadeLength;
|
||||
|
||||
Sampler m_sampler
|
||||
{
|
||||
AddressU = Wrap;
|
||||
@@ -109,22 +105,11 @@ ShaderResourceGroup TerrainMaterialSrg : SRG_PerMaterial
|
||||
|
||||
// Base Color
|
||||
float3 m_baseColor;
|
||||
float m_baseColorFactor;
|
||||
Texture2D m_baseColorMap;
|
||||
|
||||
// Normal
|
||||
Texture2D m_normalMap;
|
||||
bool m_flipNormalX;
|
||||
bool m_flipNormalY;
|
||||
float m_normalFactor;
|
||||
|
||||
// Roughness
|
||||
Texture2D m_roughnessMap;
|
||||
float m_roughnessFactor;
|
||||
|
||||
// Specular
|
||||
Texture2D m_specularF0Map;
|
||||
float m_specularF0Factor;
|
||||
// Detail Material Properties
|
||||
float m_detailTextureMultiplier;
|
||||
float m_detailFadeDistance;
|
||||
float m_detailFadeLength;
|
||||
}
|
||||
|
||||
option bool o_useTerrainSmoothing = false;
|
||||
|
||||
@@ -57,7 +57,30 @@ DetailSurface GetDefaultDetailSurface()
|
||||
return surface;
|
||||
}
|
||||
|
||||
void WeightDetailSurface(inout DetailSurface surface, in float weight)
|
||||
{
|
||||
surface.m_color *= weight;
|
||||
surface.m_normal *= weight;
|
||||
surface.m_roughness *= weight;
|
||||
surface.m_specularF0 *= weight;
|
||||
surface.m_metalness *= weight;
|
||||
surface.m_occlusion *= weight;
|
||||
surface.m_height *= weight;
|
||||
}
|
||||
|
||||
void AddDetailSurface(inout DetailSurface surface, in DetailSurface surfaceToAdd)
|
||||
{
|
||||
surface.m_color += surfaceToAdd.m_color;
|
||||
surface.m_normal += surfaceToAdd.m_normal;
|
||||
surface.m_roughness += surfaceToAdd.m_roughness;
|
||||
surface.m_specularF0 += surfaceToAdd.m_specularF0;
|
||||
surface.m_metalness += surfaceToAdd.m_metalness;
|
||||
surface.m_occlusion += surfaceToAdd.m_occlusion;
|
||||
surface.m_height += surfaceToAdd.m_height;
|
||||
}
|
||||
|
||||
// Detail material index getters
|
||||
|
||||
uint GetDetailColorIndex(TerrainSrg::DetailMaterialData materialData)
|
||||
{
|
||||
return materialData.m_colorNormalImageIndices & 0x0000FFFF;
|
||||
@@ -95,22 +118,22 @@ uint GetDetailHeightIndex(TerrainSrg::DetailMaterialData materialData)
|
||||
|
||||
// Detail material value getters
|
||||
|
||||
float3 GetDetailColor(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float3 GetDetailColor(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float3 color = materialData.m_baseColor;
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureBaseColor) > 0)
|
||||
{
|
||||
color = TerrainSrg::m_detailTextures[GetDetailColorIndex(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).rgb;
|
||||
color = TerrainSrg::m_detailTextures[GetDetailColorIndex(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).rgb;
|
||||
}
|
||||
return color * materialData.m_baseColorFactor;
|
||||
}
|
||||
|
||||
float3 GetDetailNormal(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float3 GetDetailNormal(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float2 normal = float2(0.0, 0.0);
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureNormal) > 0)
|
||||
{
|
||||
normal = TerrainSrg::m_detailTextures[GetDetailNormalIndex(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).rg;
|
||||
normal = TerrainSrg::m_detailTextures[GetDetailNormalIndex(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).rg;
|
||||
}
|
||||
|
||||
// X and Y are inverted here to be consistent with SampleNormalXY in NormalInput.azsli.
|
||||
@@ -125,53 +148,53 @@ float3 GetDetailNormal(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
return GetTangentSpaceNormal(normal, materialData.m_normalFactor);
|
||||
}
|
||||
|
||||
float GetDetailRoughness(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float GetDetailRoughness(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float roughness = materialData.m_roughnessScale;
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureRoughness) > 0)
|
||||
{
|
||||
roughness = TerrainSrg::m_detailTextures[GetDetailRoughnessIndex(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).r;
|
||||
roughness = TerrainSrg::m_detailTextures[GetDetailRoughnessIndex(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).r;
|
||||
roughness = materialData.m_roughnessBias + roughness * materialData.m_roughnessScale;
|
||||
}
|
||||
return roughness;
|
||||
}
|
||||
|
||||
float GetDetailMetalness(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float GetDetailMetalness(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float metalness = 1.0;
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureMetallic) > 0)
|
||||
{
|
||||
metalness = TerrainSrg::m_detailTextures[GetDetailMetalnessIndex(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).r;
|
||||
metalness = TerrainSrg::m_detailTextures[GetDetailMetalnessIndex(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).r;
|
||||
}
|
||||
return metalness * materialData.m_metalFactor;
|
||||
}
|
||||
|
||||
float GetDetailSpecularF0(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float GetDetailSpecularF0(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float specularF0 = 1.0;
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureSpecularF0) > 0)
|
||||
{
|
||||
specularF0 = TerrainSrg::m_detailTextures[GetDetailSpecularF0Index(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).r;
|
||||
specularF0 = TerrainSrg::m_detailTextures[GetDetailSpecularF0Index(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).r;
|
||||
}
|
||||
return specularF0 * materialData.m_specularF0Factor;
|
||||
}
|
||||
|
||||
float GetDetailOcclusion(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float GetDetailOcclusion(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float occlusion = 1.0;
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureOcclusion) > 0)
|
||||
{
|
||||
occlusion = TerrainSrg::m_detailTextures[GetDetailOcclusionIndex(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).r;
|
||||
occlusion = TerrainSrg::m_detailTextures[GetDetailOcclusionIndex(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).r;
|
||||
}
|
||||
return occlusion * materialData.m_occlusionFactor;
|
||||
}
|
||||
|
||||
float GetDetailHeight(TerrainSrg::DetailMaterialData materialData, float2 uv)
|
||||
float GetDetailHeight(TerrainSrg::DetailMaterialData materialData, float2 uv, float2 ddx, float2 ddy)
|
||||
{
|
||||
float height = materialData.m_heightFactor;
|
||||
if ((materialData.m_flags & DetailTextureFlags::UseTextureHeight) > 0)
|
||||
{
|
||||
height = TerrainSrg::m_detailTextures[GetDetailHeightIndex(materialData)].Sample(TerrainMaterialSrg::m_sampler, uv).r;
|
||||
height = TerrainSrg::m_detailTextures[GetDetailHeightIndex(materialData)].SampleGrad(TerrainMaterialSrg::m_sampler, uv, ddx, ddy).r;
|
||||
height = materialData.m_heightOffset + height * materialData.m_heightFactor;
|
||||
}
|
||||
return height;
|
||||
@@ -181,15 +204,19 @@ void GetDetailSurfaceForMaterial(inout DetailSurface surface, uint materialId, f
|
||||
{
|
||||
TerrainSrg::DetailMaterialData detailMaterialData = TerrainSrg::m_detailMaterialData[materialId];
|
||||
|
||||
surface.m_color = GetDetailColor(detailMaterialData, uv);
|
||||
surface.m_normal = GetDetailNormal(detailMaterialData, uv);
|
||||
surface.m_roughness = GetDetailRoughness(detailMaterialData, uv);
|
||||
surface.m_specularF0 = GetDetailSpecularF0(detailMaterialData, uv);
|
||||
surface.m_metalness = GetDetailMetalness(detailMaterialData, uv);
|
||||
surface.m_occlusion = GetDetailOcclusion(detailMaterialData, uv);
|
||||
surface.m_height = GetDetailHeight(detailMaterialData, uv);
|
||||
float2 uvDdx = ddx(uv);
|
||||
float2 uvDdy = ddy(uv);
|
||||
|
||||
surface.m_color = GetDetailColor(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
surface.m_normal = GetDetailNormal(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
surface.m_roughness = GetDetailRoughness(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
surface.m_specularF0 = GetDetailSpecularF0(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
surface.m_metalness = GetDetailMetalness(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
surface.m_occlusion = GetDetailOcclusion(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
surface.m_height = GetDetailHeight(detailMaterialData, uv, uvDdx, uvDdy);
|
||||
}
|
||||
|
||||
// Debugs the detail material by choosing a random color per material ID and rendering it without blending.
|
||||
void GetDebugDetailSurface(inout DetailSurface surface, uint material1, uint material2, float blend, float2 idUv)
|
||||
{
|
||||
float3 material1Color = float3(0.1, 0.1, 0.1);
|
||||
@@ -210,7 +237,7 @@ void GetDebugDetailSurface(inout DetailSurface surface, uint material1, uint mat
|
||||
surface.m_color = lerp(material1Color, material2Color, blend);
|
||||
float seamBlend = 0.0;
|
||||
const float halfLineWidth = 1.0 / 2048.0;
|
||||
if (any(abs(idUv) % 1.0 < halfLineWidth) || any(abs(idUv) % 1.0 > 1.0 - halfLineWidth))
|
||||
if (any(frac(abs(idUv)) < halfLineWidth) || any(frac(abs(idUv)) > 1.0 - halfLineWidth))
|
||||
{
|
||||
seamBlend = 1.0;
|
||||
}
|
||||
@@ -225,26 +252,114 @@ void GetDebugDetailSurface(inout DetailSurface surface, uint material1, uint mat
|
||||
surface.m_height = 0.5;
|
||||
}
|
||||
|
||||
bool GetDetailSurface(inout DetailSurface surface, float2 idUv, float2 uv)
|
||||
//Blend a single detail material sample (with two possible material ids) onto a DetailSurface.
|
||||
void BlendDetailMaterial(inout DetailSurface surface, uint material1, uint material2, float blend, float2 detailUv, float weight)
|
||||
{
|
||||
uint4 material1 = TerrainSrg::m_detailMaterialIdImage.GatherRed(TerrainSrg::DetailSampler, idUv, 0).xyzw;
|
||||
uint4 material2 = TerrainSrg::m_detailMaterialIdImage.GatherGreen(TerrainSrg::DetailSampler, idUv, 0).xyzw;
|
||||
DetailSurface tempSurface;
|
||||
GetDetailSurfaceForMaterial(tempSurface, material1, detailUv);
|
||||
WeightDetailSurface(tempSurface, weight * (1.0 - blend));
|
||||
AddDetailSurface(surface, tempSurface);
|
||||
if (material2 != 0xFF)
|
||||
{
|
||||
GetDetailSurfaceForMaterial(tempSurface, material2, detailUv);
|
||||
WeightDetailSurface(tempSurface, weight * blend);
|
||||
AddDetailSurface(surface, tempSurface);
|
||||
}
|
||||
}
|
||||
|
||||
const float maxBlendAmount = 0xFF;
|
||||
/*
|
||||
Populates a DetailSurface with material data gathered form the 4 nearest samples to detailMaterialIdUv. The weight
|
||||
of each detail material's contribution is calculated based on the distance to the center point for that sample (for
|
||||
instance, if detailMaterialIdUv falls perfectly in-between all 4 samples, then each sample will be weighed at 25%).
|
||||
Each sample can have two different detail materials defined with a blend value to determine their relative contribution.
|
||||
The detailUv is used for sampling the textures of each detail material.
|
||||
*/
|
||||
bool GetDetailSurface(inout DetailSurface surface, float2 detailMaterialIdUv, float2 detailUv)
|
||||
{
|
||||
float2 textureSize;
|
||||
TerrainSrg::m_detailMaterialIdImage.GetDimensions(textureSize.x, textureSize.y);
|
||||
|
||||
float2 detailMaterialIdCoord = detailMaterialIdUv * textureSize; // uv -> pixel coordinate
|
||||
|
||||
// detailMaterialIdCoord could be negative, so add textureSize to ensure it is positive
|
||||
detailMaterialIdCoord += textureSize;
|
||||
|
||||
// The detail material id texture wraps since the "center" point can be anywhere in the texture, so mod by texturesize
|
||||
int2 detailMaterailIdTopLeft = int2(detailMaterialIdCoord) % textureSize;
|
||||
int2 detailMaterailIdBottomRight = (int2(detailMaterialIdCoord) + 1) % textureSize;
|
||||
|
||||
// Using Load() to gather the nearest 4 samples (Gather4() isn't used because of precision issues with uvs).
|
||||
uint4 s1 = TerrainSrg::m_detailMaterialIdImage.Load(int3(detailMaterailIdTopLeft.x, detailMaterailIdBottomRight.y, 0));
|
||||
uint4 s2 = TerrainSrg::m_detailMaterialIdImage.Load(int3(detailMaterailIdBottomRight, 0));
|
||||
uint4 s3 = TerrainSrg::m_detailMaterialIdImage.Load(int3(detailMaterailIdBottomRight.x, detailMaterailIdTopLeft.y, 0));
|
||||
uint4 s4 = TerrainSrg::m_detailMaterialIdImage.Load(int3(detailMaterailIdTopLeft, 0));
|
||||
|
||||
uint4 material1 = uint4(s1.x, s2.x, s3.x, s4.x);
|
||||
uint4 material2 = uint4(s1.y, s2.y, s3.y, s4.y);
|
||||
|
||||
// convert integer of 0-255 to float of 0-1.
|
||||
float4 blends = float4(TerrainSrg::m_detailMaterialIdImage.GatherBlue(TerrainSrg::DetailSampler, idUv, 0).xyzw) / maxBlendAmount;
|
||||
const float maxBlendAmount = 0xFF;
|
||||
float4 blends = float4(s1.z, s2.z, s3.z, s4.z) / maxBlendAmount;
|
||||
|
||||
// Calculate weight based on proximity to detail material samples
|
||||
float2 gatherWeight = frac(detailMaterialIdCoord);
|
||||
// Adjust the gather weight for better interpolation by (3x^2 - 2x^3). This helps avoid diamond-shaped artifacts in binlinear filtering.
|
||||
gatherWeight = gatherWeight * gatherWeight * (3.0 - 2.0 * gatherWeight);
|
||||
|
||||
if (o_debugDetailMaterialIds)
|
||||
{
|
||||
float2 idUv = (detailMaterialIdCoord + gatherWeight - 0.5) / textureSize;
|
||||
GetDebugDetailSurface(surface, material1.x, material2.x, blends.x, idUv);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (material1.x == 0xFF)
|
||||
// If any sample has no materials, give up.
|
||||
if (any(material1 == 0xFF))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GetDetailSurfaceForMaterial(surface, material1.x, uv);
|
||||
if (all(material1.x == material1.yzw) && all(material2.x == material2.yzw))
|
||||
{
|
||||
// Fast path for same material ids
|
||||
GetDetailSurfaceForMaterial(surface, material1.x, detailUv);
|
||||
if (material2.x != 0xFF)
|
||||
{
|
||||
float4 material2Blends = 1.0 - blends;
|
||||
DetailSurface tempSurface;
|
||||
float weight =
|
||||
((1.0 - gatherWeight.x) * gatherWeight.y * material2Blends.x) +
|
||||
(gatherWeight.x * gatherWeight.y * material2Blends.y) +
|
||||
(gatherWeight.x * (1.0 - gatherWeight.y) * material2Blends.z) +
|
||||
((1.0 - gatherWeight.x) * (1.0 - gatherWeight.y) * material2Blends.w);
|
||||
WeightDetailSurface(surface, weight);
|
||||
GetDetailSurfaceForMaterial(tempSurface, material2.x, detailUv);
|
||||
WeightDetailSurface(tempSurface, 1.0 - weight);
|
||||
AddDetailSurface(surface, tempSurface);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = (DetailSurface)0;
|
||||
|
||||
// X
|
||||
float weight = (1.0 - gatherWeight.x) * gatherWeight.y;
|
||||
BlendDetailMaterial(surface, material1.x, material2.x, blends.x, detailUv, weight);
|
||||
|
||||
// Y
|
||||
weight = gatherWeight.x * gatherWeight.y;
|
||||
BlendDetailMaterial(surface, material1.y, material2.y, blends.y, detailUv, weight);
|
||||
|
||||
// Z
|
||||
weight = gatherWeight.x * (1.0 - gatherWeight.y);
|
||||
BlendDetailMaterial(surface, material1.z, material2.z, blends.z, detailUv, weight);
|
||||
|
||||
// W
|
||||
weight = (1.0 - gatherWeight.x) * (1.0 - gatherWeight.y);
|
||||
BlendDetailMaterial(surface, material1.w, material2.w, blends.w, detailUv, weight);
|
||||
}
|
||||
|
||||
surface.m_normal = normalize(surface.m_normal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -109,9 +109,10 @@ ForwardPassOutput TerrainPBR_MainPassPS(VSOutput IN)
|
||||
{
|
||||
bool flipX = ObjectSrg::m_macroMaterialData[i].m_flipNormalX;
|
||||
bool flipY = ObjectSrg::m_macroMaterialData[i].m_flipNormalY;
|
||||
bool factor = ObjectSrg::m_macroMaterialData[i].m_normalFactor;
|
||||
macroNormal = GetNormalInputTS(ObjectSrg::m_macroNormalMap[i], TerrainMaterialSrg::m_sampler,
|
||||
macroUv, flipX, flipY, CreateIdentity3x3(), true, factor);
|
||||
float factor = ObjectSrg::m_macroMaterialData[i].m_normalFactor;
|
||||
|
||||
float2 sampledValue = SampleNormalXY(ObjectSrg::m_macroNormalMap[i], TerrainMaterialSrg::m_sampler, macroUv, flipX, flipY);
|
||||
macroNormal = normalize(GetTangentSpaceNormal_Unnormalized(sampledValue.xy, factor));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -129,7 +130,7 @@ ForwardPassOutput TerrainPBR_MainPassPS(VSOutput IN)
|
||||
// Check to make sure we're inside the detail texture's bounds and within where detail textures should be drawn.
|
||||
if (detailFactor < 1.0 && all(detailRegionUv > TerrainSrg::m_detailHalfPixelUv) && all(detailRegionUv < 1.0 - TerrainSrg::m_detailHalfPixelUv))
|
||||
{
|
||||
detailRegionUv += TerrainSrg::m_detailMaterialIdImageCenter - (0.5);
|
||||
detailRegionUv += TerrainSrg::m_detailMaterialIdImageCenter - 0.5;
|
||||
hasDetailSurface = GetDetailSurface(detailSurface, detailRegionUv, detailUv);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
{
|
||||
"Source" : "./TerrainPBR_ForwardPass.azsl",
|
||||
|
||||
"CompilerHints" :
|
||||
{
|
||||
"DisableOptimizations" : false,
|
||||
"GenerateDebugInfo" : false
|
||||
},
|
||||
|
||||
"DepthStencilState" :
|
||||
{
|
||||
"Depth" :
|
||||
|
||||
@@ -17,16 +17,6 @@ ShaderResourceGroupSemantic SRG_Terrain
|
||||
|
||||
ShaderResourceGroup TerrainSrg : SRG_Terrain
|
||||
{
|
||||
|
||||
Sampler DetailSampler
|
||||
{
|
||||
AddressU = Wrap;
|
||||
AddressV = Wrap;
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = Point;
|
||||
};
|
||||
|
||||
struct DetailMaterialData
|
||||
{
|
||||
// Uv
|
||||
|
||||
Reference in New Issue
Block a user