Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix VP2 rendering of UsdPreviewSurface with opacityThreshold #3947

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ limitations under the License.
<float name="roughness" ref="usdPreviewSurfaceLightingAPI2.specularRoughness"/>
<float3 name="specularColor" ref="usdPreviewSurfaceLightingAPI2.specularColor"/>
<float name="opacity" ref="opacityToTransparency.opacity"/>
<float name="opacityThreshold" ref="usdPreviewSurfaceLightingAPI2.opacityThreshold"/>
<bool name="useSpecularWorkflow" ref="usdPreviewSurfaceLightingAPI2.useSpecularWorkflow"/>

<!-- Maya Parameters for Lighting -->
Expand Down Expand Up @@ -86,6 +87,7 @@ limitations under the License.
<float3 name="specularColor" value="0.0,0.0,0.0"/>
<!-- The shader computes transparency from its "opacity" attribute. -->
<float name="opacity" value="1.0"/>
<float name="opacityThreshold" value="0.0"/>
<bool name="useSpecularWorkflow" value="false"/>

<!-- Default values for Maya-provided parameters. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ limitations under the License.
<float name="roughness" ref="usdPreviewSurfaceLightingAPI3.specularRoughness"/>
<float3 name="specularColor" ref="usdPreviewSurfaceLightingAPI3.specularColor"/>
<float name="opacity" ref="opacityToTransparency.opacity"/>
<float name="opacityThreshold" ref="usdPreviewSurfaceLightingAPI3.opacityThreshold"/>
<bool name="useSpecularWorkflow" ref="usdPreviewSurfaceLightingAPI3.useSpecularWorkflow"/>

<!-- Maya Parameters for Lighting -->
Expand Down Expand Up @@ -86,6 +87,7 @@ limitations under the License.
<float3 name="specularColor" value="0.0,0.0,0.0"/>
<!-- The shader computes transparency from its "opacity" attribute. -->
<float name="opacity" value="1.0"/>
<float name="opacityThreshold" value="0.0"/>
<bool name="useSpecularWorkflow" value="false"/>

<!-- Default values for Maya-provided parameters. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,15 +379,24 @@ surfaceShader(vec3 Peye, vec3 Neye,
float specularAmount
)
{
float opacity = 1.0 - transparency.r;
if (opacity < opacityThreshold) {
discard;
}

mayaSurfaceShaderOutput result;
result.outGlowColor = vec3(0.0);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
// Transparency and cutout.
float opacity = 1.0 - transparency.r;
if (opacityThreshold > 0.0) {
if (opacity < opacityThreshold) {
discard;
}
result.outTransparency = vec3(0.0);
result.outMatteOpacity = vec3(1.0);
} else {
result.outTransparency = transparency;
result.outMatteOpacity = vec3(opacity);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
}

// Evaluate all lights.
result.outColor = evaluateLights(
Expand All @@ -406,12 +415,6 @@ surfaceShader(vec3 Peye, vec3 Neye,
Peye,
Neye);

// Transparency
result.outTransparency = transparency;

result.outGlowColor = vec3(0.0, 0.0, 0.0);
result.outMatteOpacity = vec3(opacity);

return result;
}

Expand Down Expand Up @@ -733,15 +736,24 @@ surfaceShader(vec3 Peye, vec3 Neye,
float specularAmount
)
{
float opacity = 1.0 - transparency.r;
if (opacity < opacityThreshold) {
discard;
}

mayaSurfaceShaderOutput result;
result.outGlowColor = vec3(0.0);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
// Transparency and cutout.
float opacity = 1.0 - transparency.r;
if (opacityThreshold > 0.0) {
if (opacity < opacityThreshold) {
discard;
}
result.outTransparency = vec3(0.0);
result.outMatteOpacity = vec3(1.0);
} else {
result.outTransparency = transparency;
result.outMatteOpacity = vec3(opacity);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
}

// Evaluate all lights.
result.outColor = evaluateLights(
Expand All @@ -760,12 +772,6 @@ surfaceShader(vec3 Peye, vec3 Neye,
Peye,
Neye);

// Transparency
result.outTransparency = transparency;

result.outGlowColor = vec3(0.0, 0.0, 0.0);
result.outMatteOpacity = vec3(opacity);

return result;
}

Expand Down Expand Up @@ -1087,15 +1093,24 @@ surfaceShader(float3 Peye, float3 Neye,
float specularAmount
)
{
float opacity = 1.0 - transparency.r;
if (opacity < opacityThreshold) {
discard;
}

mayaSurfaceShaderOutput result;
result.outGlowColor = float3(0.0, 0.0, 0.0);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
// Transparency and cutout.
float opacity = 1.0 - transparency.r;
if (opacityThreshold > 0.0) {
if (opacity < opacityThreshold) {
discard;
}
result.outTransparency = float3(0.0, 0.0, 0.0);
result.outMatteOpacity = float3(1.0, 1.0, 1.0);
} else {
result.outTransparency = transparency;
result.outMatteOpacity = float3(opacity, opacity, opacity);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
}

// Evaluate all lights.
result.outColor = evaluateLights(
Expand All @@ -1114,12 +1129,6 @@ surfaceShader(float3 Peye, float3 Neye,
Peye,
Neye);

// Transparency
result.outTransparency = transparency;

result.outGlowColor = float3(0.0, 0.0, 0.0);
result.outMatteOpacity = float3(opacity, opacity, opacity);

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,15 +379,24 @@ surfaceShader(vec3 Peye, vec3 Neye,
float specularAmount
)
{
float opacity = 1.0 - transparency.r;
if (opacity < opacityThreshold) {
discard;
}

mayaSurfaceShaderOutput result;
result.outGlowColor = vec3(0.0);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
// Transparency and cutout.
float opacity = 1.0 - transparency.r;
if (opacityThreshold > 0.0) {
if (opacity < opacityThreshold) {
discard;
}
result.outTransparency = vec3(0.0);
result.outMatteOpacity = vec3(1.0);
} else {
result.outTransparency = transparency;
result.outMatteOpacity = vec3(opacity);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
}

// Evaluate all lights.
result.outColor = evaluateLights(
Expand All @@ -406,12 +415,6 @@ surfaceShader(vec3 Peye, vec3 Neye,
Peye,
Neye);

// Transparency
result.outTransparency = transparency;

result.outGlowColor = vec3(0.0, 0.0, 0.0);
result.outMatteOpacity = vec3(opacity);

return result;
}

Expand Down Expand Up @@ -733,15 +736,24 @@ surfaceShader(vec3 Peye, vec3 Neye,
float specularAmount
)
{
float opacity = 1.0 - transparency.r;
if (opacity < opacityThreshold) {
discard;
}

mayaSurfaceShaderOutput result;

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
result.outGlowColor = vec3(0.0);

// Transparency and cutout.
float opacity = 1.0 - transparency.r;
if (opacityThreshold > 0.0) {
if (opacity < opacityThreshold) {
discard;
}
result.outTransparency = vec3(0.0);
result.outMatteOpacity = vec3(1.0);
} else {
result.outTransparency = transparency;
result.outMatteOpacity = vec3(opacity);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
}

// Evaluate all lights.
result.outColor = evaluateLights(
Expand All @@ -760,12 +772,6 @@ surfaceShader(vec3 Peye, vec3 Neye,
Peye,
Neye);

// Transparency
result.outTransparency = transparency;

result.outGlowColor = vec3(0.0, 0.0, 0.0);
result.outMatteOpacity = vec3(opacity);

return result;
}

Expand Down Expand Up @@ -1087,15 +1093,24 @@ surfaceShader(float3 Peye, float3 Neye,
float specularAmount
)
{
float opacity = 1.0 - transparency.r;
if (opacity < opacityThreshold) {
discard;
}

mayaSurfaceShaderOutput result;

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
result.outGlowColor = float3(0.0, 0.0, 0.0);

// Transparency and cutout.
float opacity = 1.0 - transparency.r;
if (opacityThreshold > 0.0) {
if (opacity < opacityThreshold) {
discard;
}
result.outTransparency = float3(0.0, 0.0, 0.0);
result.outMatteOpacity = float3(1.0, 1.0, 1.0);
} else {
result.outTransparency = transparency;
result.outMatteOpacity = float3(opacity, opacity, opacity);

// Pre-multiply diffuse color by opacity if not done so already
diffuseColor *= opacity;
}

// Evaluate all lights.
result.outColor = evaluateLights(
Expand All @@ -1114,12 +1129,6 @@ surfaceShader(float3 Peye, float3 Neye,
Peye,
Neye);

// Transparency
result.outTransparency = transparency;

result.outGlowColor = float3(0.0, 0.0, 0.0);
result.outMatteOpacity = float3(opacity, opacity, opacity);

return result;
}

Expand Down
62 changes: 38 additions & 24 deletions lib/usd/pxrUsdPreviewSurface/usdPreviewSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ MStatus PxrMayaUsdPreviewSurface::initialize()

status = attributeAffects(opacityAttr, outTransparencyOnAttr);
CHECK_MSTATUS_AND_RETURN_IT(status);
status = attributeAffects(opacityThresholdAttr, outTransparencyOnAttr);
CHECK_MSTATUS_AND_RETURN_IT(status);

return status;
}
Expand Down Expand Up @@ -444,8 +446,8 @@ MStatus PxrMayaUsdPreviewSurface::compute(const MPlug& plug, MDataBlock& dataBlo
CHECK_MSTATUS(status);
const float opacityThreshold = opacityThresholdData.asFloat();

if (opacity < opacityThreshold) {
opacity = 0.0f;
if (opacityThreshold > 0.0f) {
opacity = (opacity < opacityThreshold) ? 0.0f : 1.0f;
}

const float transparency = 1.0f - opacity;
Expand All @@ -461,32 +463,44 @@ MStatus PxrMayaUsdPreviewSurface::compute(const MPlug& plug, MDataBlock& dataBlo
// details. We don't use the user-visible "outTransparency" attribute for transparency test
// because its value depends on upstream nodes and thus error-prone when the "opacity" plug
// is connected to certain textures. In that case, we should enable transparency.
bool opacityConnected = false;

const MObject opacityAttr
= depNodeFn.attribute(PxrMayaUsdPreviewSurfaceTokens->OpacityAttrName.GetText());
const MPlug opacityPlug(thisMObject(), opacityAttr);
if (opacityPlug.isConnected()) {
const MPlug sourcePlug = opacityPlug.source(&status);
CHECK_MSTATUS(status);
const MObject sourceNode = sourcePlug.node(&status);
CHECK_MSTATUS(status);

// Anim curve output will be evaluated to determine if transparency should be enabled.
if (!sourceNode.hasFn(MFn::kAnimCurve)) {
opacityConnected = true;
}
}
MObject opacityThresholdAttr = depNodeFn.attribute(
PxrMayaUsdPreviewSurfaceTokens->OpacityThresholdAttrName.GetText());
const MDataHandle opacityThresholdData
= dataBlock.inputValue(opacityThresholdAttr, &status);
CHECK_MSTATUS(status);
jufrantz marked this conversation as resolved.
Show resolved Hide resolved

float transparencyOn = false;
if (opacityConnected) {
transparencyOn = true;
} else {
const MDataHandle opacityData = dataBlock.inputValue(opacityAttr, &status);
CHECK_MSTATUS(status);
const float opacity = opacityData.asFloat();
if (opacity < 1.0f - std::numeric_limits<float>::epsilon()) {

// For masked transparency, we want VP2 to treat the shader as opaque.
if (opacityThresholdData.asFloat() <= 0.0f) {
bool opacityConnected = false;

const MObject opacityAttr
= depNodeFn.attribute(PxrMayaUsdPreviewSurfaceTokens->OpacityAttrName.GetText());
const MPlug opacityPlug(thisMObject(), opacityAttr);
if (opacityPlug.isConnected()) {
const MPlug sourcePlug = opacityPlug.source(&status);
CHECK_MSTATUS(status);
const MObject sourceNode = sourcePlug.node(&status);
CHECK_MSTATUS(status);

// Anim curve output will be evaluated to determine if transparency should be
// enabled.
if (!sourceNode.hasFn(MFn::kAnimCurve)) {
opacityConnected = true;
}
}

if (opacityConnected) {
transparencyOn = true;
} else {
const MDataHandle opacityData = dataBlock.inputValue(opacityAttr, &status);
CHECK_MSTATUS(status);
const float opacity = opacityData.asFloat();
if (opacity < 1.0f - std::numeric_limits<float>::epsilon()) {
transparencyOn = true;
}
}
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading