ATOM-15518 Change Multilayer PBR To Use Lerp Base Blending

Changed to lerp-based blending, with an implicit base layer.
Renamed some variables to be more clear (blendWeight instead of blendMask, since the weights could come from vertex colors instead of a texture).
Updated DefaultBlendMask_layers.png to better suit the new layering model. It has a black background and overlapping R, G, and B areas.
Updated some of the test materials UV transforms to better fit the new DefaultBlendMask_layers image.
Added a new test object, which is a plane that has painted vertices.
Note that I updated test criteria in AtomSampleViewer to account for these changes as well.
This commit is contained in:
Chris Santora
2021-05-10 23:04:56 -07:00
parent 4c453bf4b6
commit 89bb0edb30
10 changed files with 87 additions and 61 deletions
@@ -204,7 +204,7 @@
"displayName": "Debug Draw Mode",
"description": "Enables various debug view features.",
"type": "Enum",
"enumValues": [ "None", "BlendMaskValues", "DepthMaps" ],
"enumValues": [ "None", "BlendSource", "DepthMaps" ],
"defaultValue": "None",
"connection": {
"type": "ShaderOption",
@@ -42,7 +42,7 @@ COMMON_SRG_INPUTS_PARALLAX(prefix)
ShaderResourceGroup MaterialSrg : SRG_PerMaterial
{
Texture2D m_blendMaskTexture;
Texture2D m_blendMaskTexture;
uint m_blendMaskUvIndex;
// Auto-generate material SRG fields for common inputs for each layer
@@ -113,7 +113,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
// ------ Shader Options ----------------------------------------
enum class DebugDrawMode { None, BlendMaskValues, DepthMaps };
enum class DebugDrawMode { None, BlendSource, DepthMaps };
option DebugDrawMode o_debugDrawMode;
enum class BlendMaskSource { TextureMap, VertexColors, Fallback };
@@ -127,6 +127,10 @@ option bool o_blendMask_isBound;
// ------ Blend Utilities ----------------------------------------
// This is mainly used to pass extra data to the GetDepth callback function during the parallax depth search.
// But since we have it, we use it in some other functions as well rather than passing it around.
static float3 s_blendMaskFromVertexStream;
//! Returns the BlendMaskSource that will actually be used when rendering (not necessarily the same BlendMaskSource specified by the user)
BlendMaskSource GetFinalBlendMaskSource()
{
@@ -151,40 +155,63 @@ BlendMaskSource GetFinalBlendMaskSource()
}
}
//! Return the final blend mask values to be used for rendering, based on the available data and configuration.
float3 GetBlendMaskValues(float2 uv, float3 vertexBlendMask)
//! Return the raw blend source values directly from the blend mask or vertex colors, depending on the available data and configuration.
//! layer1 is an implicit base layer
//! layer2 is weighted by r
//! layer3 is weighted by g
//! b is reserved for perhaps a dedicated puddle layer
float3 GetBlendSourceValues(float2 uv)
{
float3 blendMaskValues;
float3 blendSourceValues = float3(0,0,0);
switch(GetFinalBlendMaskSource())
{
case BlendMaskSource::TextureMap:
blendMaskValues = MaterialSrg::m_blendMaskTexture.Sample(MaterialSrg::m_sampler, uv).rgb;
blendSourceValues = MaterialSrg::m_blendMaskTexture.Sample(MaterialSrg::m_sampler, uv).rgb;
break;
case BlendMaskSource::VertexColors:
blendMaskValues = vertexBlendMask;
break;
case BlendMaskSource::Fallback:
blendMaskValues = float3(1,1,1);
blendSourceValues = s_blendMaskFromVertexStream;
break;
}
blendMaskValues = blendMaskValues / (blendMaskValues.r + blendMaskValues.g + blendMaskValues.b);
return blendMaskValues;
return blendSourceValues;
}
float BlendLayers(float layer1, float layer2, float layer3, float3 blendMaskValues)
//! Return the final blend mask values to be used for rendering, based on the available data and configuration.
//! @return The blend weights for each layer.
//! Even though layer1 not explicitly specified in the blend source data, it is explicitly included with the returned values.
//! layer1 = r
//! layer2 = g
//! layer3 = b
float3 GetBlendWeights(float2 uv)
{
return dot(float3(layer1, layer2, layer3), blendMaskValues);
float3 blendSourceValues = GetBlendSourceValues(uv);
// Calculate blend weights such that multiplying and adding them with layer data is equivalent
// to lerping between each layer.
// final = lerp(final, layer1, blendWeights.r)
// final = lerp(final, layer2, blendWeights.g)
// final = lerp(final, layer3, blendWeights.b)
float3 blendWeights;
blendWeights.b = blendSourceValues.g;
blendWeights.g = (1.0 - blendSourceValues.g) * blendSourceValues.r;
blendWeights.r = (1.0 - blendSourceValues.g) * (1.0 - blendSourceValues.r);
return blendWeights;
}
float2 BlendLayers(float2 layer1, float2 layer2, float2 layer3, float3 blendMaskValues)
float BlendLayers(float layer1, float layer2, float layer3, float3 blendWeights)
{
return layer1 * blendMaskValues.r + layer2 * blendMaskValues.g + layer3 * blendMaskValues.b;
return dot(float3(layer1, layer2, layer3), blendWeights);
}
float3 BlendLayers(float3 layer1, float3 layer2, float3 layer3, float3 blendMaskValues)
float2 BlendLayers(float2 layer1, float2 layer2, float2 layer3, float3 blendWeights)
{
return layer1 * blendMaskValues.r + layer2 * blendMaskValues.g + layer3 * blendMaskValues.b;
return layer1 * blendWeights.r + layer2 * blendWeights.g + layer3 * blendWeights.b;
}
float3 BlendLayers(float3 layer1, float3 layer2, float3 layer3, float3 blendWeights)
{
return layer1 * blendWeights.r + layer2 * blendWeights.g + layer3 * blendWeights.b;
}
// ------ Parallax Utilities ----------------------------------------
@@ -203,16 +230,6 @@ bool ShouldHandleParallaxInDepthShaders()
return ShouldHandleParallax() && o_parallax_enablePixelDepthOffset;
}
// These static values are used to pass extra data to the GetDepth callback function during the parallax depth search.
static float3 s_blendMaskFromVertexStream;
//! Setup static variables that are needed by the GetDepth callback function
//! @param vertexBlendMask the blend mask values from the vertex input stream.
void GetDepth_Setup(float3 vertexBlendMask)
{
s_blendMaskFromVertexStream = vertexBlendMask;
}
// Callback function for ParallaxMapping.azsli
DepthResult GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy)
{
@@ -260,8 +277,8 @@ DepthResult GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy)
// Note, when the blend source is BlendMaskSource::VertexColors, parallax will not be able to blend correctly between layers. It will end up using the same blend mask values
// for every UV position when searching for the intersection. This leads to smearing artifacts at the transition point, but these won't be so noticeable as long as
// you have a small depth factor relative to the size of the blend transition.
float3 blendMaskValues = GetBlendMaskValues(uv, s_blendMaskFromVertexStream);
float3 blendWeights = GetBlendWeights(uv);
float depth = BlendLayers(layerDepthValues.r, layerDepthValues.g, layerDepthValues.b, blendMaskValues);
float depth = BlendLayers(layerDepthValues.r, layerDepthValues.g, layerDepthValues.b, blendWeights);
return DepthResultAbsolute(depth);
}
@@ -108,7 +108,7 @@ PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace)
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, float3(0, 0, 0) };
PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents, 1);
GetDepth_Setup(IN.m_blendMask);
s_blendMaskFromVertexStream = IN.m_blendMask;
float depth;
@@ -134,6 +134,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
{
depth = IN.m_position.z;
s_blendMaskFromVertexStream = IN.m_blendMask;
// ------- Tangents & Bitangets -------
// We support two UV streams, but only a single stream of tangent/bitangent. So for UV[1+] we generated the tangent/bitangent in screen-space.
@@ -156,15 +158,14 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// ------- Debug Modes -------
if(o_debugDrawMode == DebugDrawMode::BlendMaskValues)
if(o_debugDrawMode == DebugDrawMode::BlendSource)
{
float3 blendMaskValues = GetBlendMaskValues(IN.m_uv[MaterialSrg::m_blendMaskUvIndex], IN.m_blendMask);
return DebugOutput(blendMaskValues);
float3 blendSource = GetBlendSourceValues(IN.m_uv[MaterialSrg::m_blendMaskUvIndex]);
return DebugOutput(blendSource);
}
if(o_debugDrawMode == DebugDrawMode::DepthMaps)
{
GetDepth_Setup(IN.m_blendMask);
float depth = GetNormalizedDepth(-MaterialSrg::m_displacementMax, -MaterialSrg::m_displacementMin, IN.m_uv[MaterialSrg::m_parallaxUvIndex], float2(0,0), float2(0,0));
return DebugOutput(float3(depth,depth,depth));
}
@@ -176,8 +177,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scatteirng is enabled
if(ShouldHandleParallax())
{
GetDepth_Setup(IN.m_blendMask);
float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3();
@@ -218,13 +217,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// ------- Calculate Layer Blend Mask Values -------
// Now that any parallax has been calculated, we calculate the blend factors for any layers that are impacted by the parallax.
float3 blendMaskValues = GetBlendMaskValues(IN.m_uv[MaterialSrg::m_blendMaskUvIndex], IN.m_blendMask);
float3 blendWeights = GetBlendWeights(IN.m_uv[MaterialSrg::m_blendMaskUvIndex]);
// ------- Normal -------
float3 layer1_normalFactor = MaterialSrg::m_layer1_m_normalFactor * blendMaskValues.r;
float3 layer2_normalFactor = MaterialSrg::m_layer2_m_normalFactor * blendMaskValues.g;
float3 layer3_normalFactor = MaterialSrg::m_layer3_m_normalFactor * blendMaskValues.b;
float3 layer1_normalFactor = MaterialSrg::m_layer1_m_normalFactor * blendWeights.r;
float3 layer2_normalFactor = MaterialSrg::m_layer2_m_normalFactor * blendWeights.g;
float3 layer3_normalFactor = MaterialSrg::m_layer3_m_normalFactor * blendWeights.b;
float3x3 layer1_uvMatrix = MaterialSrg::m_layer1_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer1_m_uvMatrix : CreateIdentity3x3();
float3x3 layer2_uvMatrix = MaterialSrg::m_layer2_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer2_m_uvMatrix : CreateIdentity3x3();
float3x3 layer3_uvMatrix = MaterialSrg::m_layer3_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer3_m_uvMatrix : CreateIdentity3x3();
@@ -249,7 +248,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
float3 layer1_baseColor = BlendBaseColor(layer1_sampledColor, MaterialSrg::m_layer1_m_baseColor.rgb, MaterialSrg::m_layer1_m_baseColorFactor, o_layer1_o_baseColorTextureBlendMode, o_layer1_o_baseColor_useTexture);
float3 layer2_baseColor = BlendBaseColor(layer2_sampledColor, MaterialSrg::m_layer2_m_baseColor.rgb, MaterialSrg::m_layer2_m_baseColorFactor, o_layer2_o_baseColorTextureBlendMode, o_layer2_o_baseColor_useTexture);
float3 layer3_baseColor = BlendBaseColor(layer3_sampledColor, MaterialSrg::m_layer3_m_baseColor.rgb, MaterialSrg::m_layer3_m_baseColorFactor, o_layer3_o_baseColorTextureBlendMode, o_layer3_o_baseColor_useTexture);
float3 baseColor = BlendLayers(layer1_baseColor, layer2_baseColor, layer3_baseColor, blendMaskValues);
float3 baseColor = BlendLayers(layer1_baseColor, layer2_baseColor, layer3_baseColor, blendWeights);
if(o_parallax_highlightClipping && displacementIsClipped)
{
@@ -264,7 +263,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
float layer1_metallic = GetMetallicInput(MaterialSrg::m_layer1_m_metallicMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_metallicMapUvIndex], MaterialSrg::m_layer1_m_metallicFactor, o_layer1_o_metallic_useTexture);
float layer2_metallic = GetMetallicInput(MaterialSrg::m_layer2_m_metallicMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_metallicMapUvIndex], MaterialSrg::m_layer2_m_metallicFactor, o_layer2_o_metallic_useTexture);
float layer3_metallic = GetMetallicInput(MaterialSrg::m_layer3_m_metallicMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_metallicMapUvIndex], MaterialSrg::m_layer3_m_metallicFactor, o_layer3_o_metallic_useTexture);
metallic = BlendLayers(layer1_metallic, layer2_metallic, layer3_metallic, blendMaskValues);
metallic = BlendLayers(layer1_metallic, layer2_metallic, layer3_metallic, blendWeights);
}
// ------- Specular -------
@@ -272,7 +271,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
float layer1_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer1_m_specularF0Map, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularF0MapUvIndex], MaterialSrg::m_layer1_m_specularF0Factor, o_layer1_o_specularF0_useTexture);
float layer2_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer2_m_specularF0Map, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularF0MapUvIndex], MaterialSrg::m_layer2_m_specularF0Factor, o_layer2_o_specularF0_useTexture);
float layer3_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer3_m_specularF0Map, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularF0MapUvIndex], MaterialSrg::m_layer3_m_specularF0Factor, o_layer3_o_specularF0_useTexture);
float specularF0Factor = BlendLayers(layer1_specularF0Factor, layer2_specularF0Factor, layer3_specularF0Factor, blendMaskValues);
float specularF0Factor = BlendLayers(layer1_specularF0Factor, layer2_specularF0Factor, layer3_specularF0Factor, blendWeights);
surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
@@ -281,7 +280,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
float layer1_roughness = GetRoughnessInput(MaterialSrg::m_layer1_m_roughnessMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_roughnessMapUvIndex], MaterialSrg::m_layer1_m_roughnessFactor, MaterialSrg::m_layer1_m_roughnessLowerBound, MaterialSrg::m_layer1_m_roughnessUpperBound, o_layer1_o_roughness_useTexture);
float layer2_roughness = GetRoughnessInput(MaterialSrg::m_layer2_m_roughnessMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_roughnessMapUvIndex], MaterialSrg::m_layer2_m_roughnessFactor, MaterialSrg::m_layer2_m_roughnessLowerBound, MaterialSrg::m_layer2_m_roughnessUpperBound, o_layer2_o_roughness_useTexture);
float layer3_roughness = GetRoughnessInput(MaterialSrg::m_layer3_m_roughnessMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_roughnessMapUvIndex], MaterialSrg::m_layer3_m_roughnessFactor, MaterialSrg::m_layer3_m_roughnessLowerBound, MaterialSrg::m_layer3_m_roughnessUpperBound, o_layer3_o_roughness_useTexture);
surface.roughnessLinear = BlendLayers(layer1_roughness, layer2_roughness, layer3_roughness, blendMaskValues);
surface.roughnessLinear = BlendLayers(layer1_roughness, layer2_roughness, layer3_roughness, blendWeights);
surface.CalculateRoughnessA();
@@ -314,19 +313,19 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
float3 layer1_emissive = GetEmissiveInput(MaterialSrg::m_layer1_m_emissiveMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_emissiveMapUvIndex], MaterialSrg::m_layer1_m_emissiveIntensity, MaterialSrg::m_layer1_m_emissiveColor.rgb, o_layer1_o_emissiveEnabled, o_layer1_o_emissive_useTexture);
float3 layer2_emissive = GetEmissiveInput(MaterialSrg::m_layer2_m_emissiveMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_emissiveMapUvIndex], MaterialSrg::m_layer2_m_emissiveIntensity, MaterialSrg::m_layer2_m_emissiveColor.rgb, o_layer2_o_emissiveEnabled, o_layer2_o_emissive_useTexture);
float3 layer3_emissive = GetEmissiveInput(MaterialSrg::m_layer3_m_emissiveMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_emissiveMapUvIndex], MaterialSrg::m_layer3_m_emissiveIntensity, MaterialSrg::m_layer3_m_emissiveColor.rgb, o_layer3_o_emissiveEnabled, o_layer3_o_emissive_useTexture);
lightingData.emissiveLighting = BlendLayers(layer1_emissive, layer2_emissive, layer3_emissive, blendMaskValues);
lightingData.emissiveLighting = BlendLayers(layer1_emissive, layer2_emissive, layer3_emissive, blendWeights);
// ------- Occlusion -------
float layer1_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer1_m_diffuseOcclusionFactor, o_layer1_o_diffuseOcclusion_useTexture);
float layer2_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer2_m_diffuseOcclusionFactor, o_layer2_o_diffuseOcclusion_useTexture);
float layer3_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer3_m_diffuseOcclusionFactor, o_layer3_o_diffuseOcclusion_useTexture);
lightingData.diffuseAmbientOcclusion = BlendLayers(layer1_diffuseAmbientOcclusion, layer2_diffuseAmbientOcclusion, layer3_diffuseAmbientOcclusion, blendMaskValues);
lightingData.diffuseAmbientOcclusion = BlendLayers(layer1_diffuseAmbientOcclusion, layer2_diffuseAmbientOcclusion, layer3_diffuseAmbientOcclusion, blendWeights);
float layer1_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer1_m_specularOcclusionFactor, o_layer1_o_specularOcclusion_useTexture);
float layer2_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer2_m_specularOcclusionFactor, o_layer2_o_specularOcclusion_useTexture);
float layer3_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer3_m_specularOcclusionFactor, o_layer3_o_specularOcclusion_useTexture);
lightingData.specularOcclusion = BlendLayers(layer1_specularOcclusion, layer2_specularOcclusion, layer3_specularOcclusion, blendMaskValues);
lightingData.specularOcclusion = BlendLayers(layer1_specularOcclusion, layer2_specularOcclusion, layer3_specularOcclusion, blendWeights);
// ------- Clearcoat -------
@@ -385,11 +384,11 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// --- Blend Layers ---
surface.clearCoat.factor = BlendLayers(layer1_clearCoatFactor, layer2_clearCoatFactor, layer3_clearCoatFactor, blendMaskValues);
surface.clearCoat.roughness = BlendLayers(layer1_clearCoatRoughness, layer2_clearCoatRoughness, layer3_clearCoatRoughness, blendMaskValues);
surface.clearCoat.factor = BlendLayers(layer1_clearCoatFactor, layer2_clearCoatFactor, layer3_clearCoatFactor, blendWeights);
surface.clearCoat.roughness = BlendLayers(layer1_clearCoatRoughness, layer2_clearCoatRoughness, layer3_clearCoatRoughness, blendWeights);
// [GFX TODO][ATOM-14592] This is not the right way to blend the normals. We need to use ReorientTangentSpaceNormal(), and that requires GetClearCoatInputs() to return the normal in TS instead of WS.
surface.clearCoat.normal = BlendLayers(layer1_clearCoatNormal, layer2_clearCoatNormal, layer3_clearCoatNormal, blendMaskValues);
surface.clearCoat.normal = BlendLayers(layer1_clearCoatNormal, layer2_clearCoatNormal, layer3_clearCoatNormal, blendWeights);
surface.clearCoat.normal = normalize(surface.clearCoat.normal);
// manipulate base layer f0 if clear coat is enabled
@@ -107,7 +107,7 @@ PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace)
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, float3(0, 0, 0) };
PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents, 1);
GetDepth_Setup(IN.m_blendMask);
s_blendMaskFromVertexStream = IN.m_blendMask;
float depth;
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f74ffab6ee15906158d27cbd2e5556e8fcdfd7820c0d0fd4b403de8a7af81662
size 5651
oid sha256:6660fa05dbf1e90298472fb41d99fff80a80de64ee88d17af4d0df3bdafb1ff6
size 52877
@@ -134,8 +134,14 @@
"enable": true
},
"uv": {
"offsetU": -0.2800000011920929,
"rotateDegrees": 39.599998474121097
"center": [
0.10000000149011612,
0.20000000298023225
],
"offsetU": 0.23000000417232514,
"offsetV": -0.23999999463558198,
"rotateDegrees": 39.599998474121097,
"scale": 1.100000023841858
}
}
}
}
@@ -30,6 +30,7 @@
"layer2_parallax": {
"enable": true,
"factor": 0.05299999937415123,
"offset": -0.024000000208616258,
"textureMap": "TestData/Textures/cc0/Rock030_2K_Displacement.jpg"
},
"layer2_roughness": {
@@ -49,4 +50,4 @@
"pdo": true
}
}
}
}
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"general": {
"debugDrawMode": "BlendMaskValues"
"debugDrawMode": "BlendSource"
}
}
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:053a7cd73b37c815900f87abd524830e6f23eee75d3b72fb866e86498d528159
size 36156