Adding a factor for alpha affecting specular in the standard and enhanced pbr materials (#1474)

* Adding a factor for how much alpha should affect specular to standard and enhanced pbr. Currently blended and tinted transparency always assume that the geometry represents the surface, and the surface may just be transparent like glass. In this model, specular is unnaffected by alpha - perfectly clear glass still reflects light and obeys the Fresnel factor. However alpha may also represent the absence of a surface entirely for mateirals where cut-out alpha is a bad fit because of subpixel detail, like hair or cob webs. This change addresses that by allowing the alpha to also affect specular reflection if desired.

* Adding material for ASV test.
monroegm-disable-blank-issue-2
Ken Pruiksma 5 years ago committed by GitHub
parent 9aa44a56e7
commit a034500a10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -714,6 +714,19 @@
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"id": "alphaAffectsSpecular",
"displayName": "Alpha affects specular",
"description": "How much the alpha value should also affect specular reflection. This should be 0.0 for materials where light can transmit through their physical surface (like glass), but 1.0 when alpha determines the very presence of a surface (like hair or grass)",
"type": "float",
"min": 0.0,
"max": 1.0,
"defaultValue": 0.0,
"connection": {
"type": "ShaderInput",
"id": "m_opacityAffectsSpecularFactor"
}
}
],
"uv": [
@ -1669,4 +1682,3 @@
"UV1": "Unwrapped"
}
}

@ -55,6 +55,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
float m_anisotropicFactor; // Base layer anisotropic strength of deviation: negative = Bi-Normal direction, positive = Tangent direction
float m_opacityFactor;
float m_opacityAffectsSpecularFactor;
Texture2D m_opacityMap;
uint m_opacityMapUvIndex;

@ -331,7 +331,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent)
{
alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor);
}
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
@ -349,8 +350,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular
// to be added on top of the diffuse, but then the diffuse must be pre-multiplied.
// It's done this way because surface transparency doesn't really change specular response (eg, glass).
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
}
else if (o_opacity_mode == OpacityMode::TintedTransparent)
{
@ -367,7 +373,12 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0.
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else
@ -415,4 +426,3 @@ ForwardPassOutput EnhancedPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
return OUT;
}

@ -655,6 +655,19 @@
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"id": "alphaAffectsSpecular",
"displayName": "Alpha affects specular",
"description": "How much the alpha value should also affect specular reflection. This should be 0.0 for materials where light can transmit through their physical surface (like glass), but 1.0 when alpha determines the very presence of a surface (like hair or grass)",
"type": "float",
"min": 0.0,
"max": 1.0,
"defaultValue": 0.0,
"connection": {
"type": "ShaderInput",
"id": "m_opacityAffectsSpecularFactor"
}
}
],
"uv": [
@ -1187,4 +1200,3 @@
"UV1": "Unwrapped"
}
}

@ -50,6 +50,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
float4 m_pad2; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
float m_opacityFactor;
float m_opacityAffectsSpecularFactor;
Texture2D m_opacityMap;
uint m_opacityMapUvIndex;

@ -259,7 +259,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent)
{
alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor);
}
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
@ -274,8 +275,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular
// to be added on top of the diffuse, but then the diffuse must be pre-multiplied.
// It's done this way because surface transparency doesn't really change specular response (eg, glass).
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
}
else if (o_opacity_mode == OpacityMode::TintedTransparent)
{
@ -292,7 +298,12 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0.
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else

@ -0,0 +1,24 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.5906767249107361,
1.0,
0.11703670024871826,
1.0
],
"textureMap": "Textures/Default/default_basecolor.tif"
},
"opacity": {
"alphaSource": "Split",
"factor": 0.75,
"mode": "Blended",
"textureMap": "TestData/Textures/checker8x8_gray_512.png",
"alphaAffectsSpecular": 1.0
}
}
}
Loading…
Cancel
Save