[tydra] Fix connected texture outputChannel was not considered when

constructing tydra::UVTexture.
This commit is contained in:
Syoyo Fujita
2024-06-10 06:30:29 +09:00
parent 2c43e48b57
commit 03bc930f81
4 changed files with 195 additions and 32 deletions

View File

@@ -0,0 +1,120 @@
#usda 1.0
(
defaultPrim = "root"
doc = "Blender v4.1.1"
metersPerUnit = 1
upAxis = "Z"
)
def Xform "root" (
customData = {
dictionary Blender = {
bool generated = 1
}
}
)
{
def Xform "Grid"
{
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def Mesh "Grid_001" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform bool doubleSided = 1
float3[] extent = [(-1, -1, 0), (1, 1, 0)]
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4, 4, 4, 4]
int[] faceVertexIndices = [0, 1, 5, 4, 1, 2, 6, 5, 2, 3, 7, 6, 4, 5, 9, 8, 5, 6, 10, 9, 6, 7, 11, 10, 8, 9, 13, 12, 9, 10, 14, 13, 10, 11, 15, 14]
rel material:binding = </root/_materials/Material_001>
normal3f[] normals = [(0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 0.99999994), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)] (
interpolation = "faceVarying"
)
point3f[] points = [(-1, -1, 0), (-0.3333333, -1, 0), (0.33333337, -1, 0), (1, -1, 0), (-1, -0.3333333, 0), (-0.3333333, -0.3333333, 0), (0.33333337, -0.3333333, 0), (1, -0.3333333, 0), (-1, 0.33333337, 0), (-0.3333333, 0.33333337, 0), (0.33333337, 0.33333337, 0), (1, 0.33333337, 0), (-1, 1, 0), (-0.3333333, 1, 0), (0.33333337, 1, 0), (1, 1, 0)]
bool[] primvars:sharp_face = [1, 1, 1, 1, 1, 1, 1, 1, 1] (
interpolation = "uniform"
)
texCoord2f[] primvars:UVMap = [(0, 0), (0.33333334, 0), (0.33333334, 0.33333334), (0, 0.33333334), (0.33333334, 0), (0.6666667, 0), (0.6666667, 0.33333334), (0.33333334, 0.33333334), (0.6666667, 0), (1, 0), (1, 0.33333334), (0.6666666, 0.33333334), (0, 0.33333334), (0.33333334, 0.33333334), (0.33333334, 0.6666667), (0, 0.6666667), (0.33333334, 0.33333334), (0.6666667, 0.33333334), (0.6666667, 0.6666667), (0.33333334, 0.6666667), (0.6666667, 0.33333334), (1, 0.33333334), (1, 0.6666667), (0.6666666, 0.6666667), (0, 0.6666666), (0.33333334, 0.6666666), (0.33333334, 1), (0, 1), (0.33333334, 0.6666666), (0.6666667, 0.6666666), (0.6666667, 1), (0.33333334, 1), (0.6666667, 0.6666666), (1, 0.6666666), (1, 1), (0.6666666, 1)] (
interpolation = "faceVarying"
)
uniform token subdivisionScheme = "none"
}
}
def Scope "_materials"
{
def Material "Material_001"
{
token outputs:surface.connect = </root/_materials/Material_001/Principled_BSDF.outputs:surface>
def Shader "Principled_BSDF"
{
uniform token info:id = "UsdPreviewSurface"
float inputs:clearcoat = 0
float inputs:clearcoatRoughness = 0.03
float inputs:metallic.connect = </root/_materials/Material_001/Image_Texture.outputs:g>
float inputs:roughness.connect = </root/_materials/Material_001/Image_Texture.outputs:b>
float inputs:ior = 1.5
float inputs:opacity = 1
float inputs:specular = 0.5
token outputs:surface
}
def Shader "Image_Texture"
{
uniform token info:id = "UsdUVTexture"
asset inputs:file = @./textures/texture-cat.jpg@
token inputs:sourceColorSpace = "sRGB"
float2 inputs:st.connect = </root/_materials/Material_001/uvmap.outputs:result>
token inputs:wrapS = "repeat"
token inputs:wrapT = "repeat"
float outputs:b
float outputs:g
}
def Shader "uvmap"
{
uniform token info:id = "UsdPrimvarReader_float2"
token inputs:varname = "UVMap"
float2 outputs:result
}
}
}
def Xform "Camera"
{
matrix4d xformOp:transform = ( (0.6859206557273865, 0.7276763319969177, 0, 0), (-0.32401347160339355, 0.305420845746994, 0.8953956365585327, 0), (0.6515582203865051, -0.6141703724861145, 0.44527140259742737, 0), (7.358891487121582, -6.925790786743164, 4.958309173583984, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def Camera "Camera"
{
float2 clippingRange = (0.1, 100)
float focalLength = 0.5
float horizontalAperture = 0.36
float horizontalApertureOffset = 0
token projection = "perspective"
float verticalAperture = 0.2025
float verticalApertureOffset = 0
}
}
def Xform "Light"
{
matrix4d xformOp:transform = ( (-0.29086464643478394, 0.9551711678504944, -0.05518905818462372, 0), (-0.7711008191108704, -0.1998833566904068, 0.6045247316360474, 0), (0.5663931965827942, 0.21839119493961334, 0.7946722507476807, 0), (4.076245307922363, 1.0054539442062378, 5.903861999511719, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def SphereLight "Light"
{
float3[] extent = [(-0.1, -0.1, -0.1), (0.1, 0.1, 0.1)]
color3f inputs:color = (1, 1, 1)
float inputs:diffuse = 1
float inputs:exposure = 0
float inputs:intensity = 318.30988
bool inputs:normalize = 1
float inputs:radius = 0.1
float inputs:specular = 1
}
}
}

View File

@@ -4190,7 +4190,7 @@ nonstd::expected<bool, std::string> GetConnectedUVTexture(
}
if (tex_abs_path) {
(*tex_abs_path) = Path(prim_part, "");
(*tex_abs_path) = Path(prim_part, prop_part);
}
if (const Shader *pshader = prim->as<Shader>()) {
@@ -4570,23 +4570,35 @@ bool RenderSceneConverter::ConvertUVTexture(const RenderSceneConverterEnv &env,
}
//
// Set outputChannel
// Set authored outputChannels
//
if (texture.outputsRGB.authored()) {
tex.outputChannel = UVTexture::Channel::RGB;
} else if (texture.outputsA.authored()) {
tex.outputChannel = UVTexture::Channel::A;
} else if (texture.outputsR.authored()) {
tex.outputChannel = UVTexture::Channel::R;
} else if (texture.outputsG.authored()) {
tex.outputChannel = UVTexture::Channel::G;
} else if (texture.outputsB.authored()) {
tex.outputChannel = UVTexture::Channel::B;
} else {
PUSH_WARN("No valid output channel attribute authored. Default to RGB");
tex.outputChannel = UVTexture::Channel::RGB;
tex.authoredOutputChannels.insert(UVTexture::Channel::RGB);
}
if (texture.outputsA.authored()) {
tex.authoredOutputChannels.insert(UVTexture::Channel::A);
}
if (texture.outputsR.authored()) {
tex.authoredOutputChannels.insert(UVTexture::Channel::R);
}
if (texture.outputsG.authored()) {
tex.authoredOutputChannels.insert(UVTexture::Channel::G);
}
if (texture.outputsB.authored()) {
tex.authoredOutputChannels.insert(UVTexture::Channel::B);
}
#if 0 // TODO
if (tex.authoredOutputChannels.empty()) {
PUSH_WARN("No valid output channel attribute authored. Default to RGB");
tex.authoredOutputChannels.insert(UVTexture::Channel::RGB);
}
#endif
//
// Convert other UVTexture parameters
//
@@ -4753,7 +4765,7 @@ bool RenderSceneConverter::ConvertPreviewSurfaceShaderParam(
if (param.is_blocked()) {
PUSH_ERROR_AND_RETURN(fmt::format("{} attribute is blocked.", param_name));
} else if (param.is_connection()) {
DCOUT(fmt::format("{] is attribute connection.", param_name));
DCOUT(fmt::format("{} is attribute connection.", param_name));
const UsdUVTexture *ptex{nullptr};
const Shader *pshader{nullptr};
@@ -4783,13 +4795,32 @@ bool RenderSceneConverter::ConvertPreviewSurfaceShaderParam(
"Failed to convert UVTexture connected to {}", param_name));
}
// Extract connected outputChannel from prop part.
std::string prop_part = texPath.prop_part();
// TODO: Attribute type check.
if (prop_part == "outputs:r") {
rtex.connectedOutputChannel = tydra::UVTexture::Channel::R;
} else if (prop_part == "outputs:g") {
rtex.connectedOutputChannel = tydra::UVTexture::Channel::G;
} else if (prop_part == "outputs:b") {
rtex.connectedOutputChannel = tydra::UVTexture::Channel::B;
} else if (prop_part == "outputs:a") {
rtex.connectedOutputChannel = tydra::UVTexture::Channel::A;
} else if (prop_part == "outputs:rgb") {
rtex.connectedOutputChannel = tydra::UVTexture::Channel::RGB;
} else {
PUSH_ERROR_AND_RETURN(fmt::format("Unknown or invalid connection to a property of output channel: {}(Abs path {})", prop_part, texPath.full_path_name()));
}
uint64_t texId = textures.size();
textures.push_back(rtex);
textureMap.add(texId, shader_abs_path.prim_part() + "." + param_name);
DCOUT(fmt::format("TexId {} = {}",
shader_abs_path.prim_part() + ".diffuseColor", texId));
DCOUT(fmt::format("TexId {}.{} = {}",
shader_abs_path.prim_part(), param_name, texId));
dst_param.texture_id = int32_t(texId);
@@ -7005,8 +7036,16 @@ std::string DumpUVTexture(const UVTexture &texture, uint32_t indent) {
ss << "UVTexture {\n";
ss << pprint::Indent(indent + 1) << "primvar_name " << texture.varname_uv
<< "\n";
ss << pprint::Indent(indent + 1) << "outputChannel "
<< to_string(texture.outputChannel) << "\n";
ss << pprint::Indent(indent + 1) << "connectedOutputChannel ";
ss << to_string(texture.connectedOutputChannel) << "\n";
ss << pprint::Indent(indent + 1) << "authoredOutputChannels ";
for (const auto &c : texture.authoredOutputChannels) {
ss << to_string(c) << " ";
}
ss << "\n";
ss << pprint::Indent(indent + 1) << "bias " << texture.bias << "\n";
ss << pprint::Indent(indent + 1) << "scale " << texture.scale << "\n";
ss << pprint::Indent(indent + 1) << "wrapS " << to_string(texture.wrapS)

View File

@@ -1011,8 +1011,10 @@ struct UVTexture {
vec4 fetch_uvw_channel(size_t faceId, float varyu, float varyv, float varyw,
Channel channel);
// output channel info
Channel outputChannel{Channel::RGB};
// Connected output channel(determined by connectionPath in UsdPreviewSurface)
Channel connectedOutputChannel{Channel::RGB};
std::set<Channel> authoredOutputChannels; // Authored `output:***` attribute in UsdUVTexture
// bias and scale for texel value
vec4 bias{0.0f, 0.0f, 0.0f, 0.0f};

View File

@@ -861,17 +861,19 @@ static bool ToMaterialPrim(const RenderScene &scene, const std::string &abs_path
}
image_tex.wrapT.set_value(wrapS);
if (tex.outputChannel == UVTexture::Channel::R) {
image_tex.outputsR.set_authored(true);
} else if (tex.outputChannel == UVTexture::Channel::G) {
image_tex.outputsG.set_authored(true);
} else if (tex.outputChannel == UVTexture::Channel::B) {
image_tex.outputsB.set_authored(true);
} else if (tex.outputChannel == UVTexture::Channel::RGB) {
image_tex.outputsRGB.set_authored(true);
} else if (tex.outputChannel == UVTexture::Channel::RGBA) {
PUSH_ERROR_AND_RETURN("rgba texture is not supported yet.");
}
for (const auto &c : tex.authoredOutputChannels) {
if (c == UVTexture::Channel::R) {
image_tex.outputsR.set_authored(true);
} else if (c == UVTexture::Channel::G) {
image_tex.outputsG.set_authored(true);
} else if (c == UVTexture::Channel::B) {
image_tex.outputsB.set_authored(true);
} else if (c == UVTexture::Channel::RGB) {
image_tex.outputsRGB.set_authored(true);
} else if (c == UVTexture::Channel::RGBA) {
PUSH_ERROR_AND_RETURN("rgba texture is not supported yet.");
}
}
UsdTransform2d uv_xform;
uv_xform.name = "place2d_" + param_name;