Open JonathanLehner opened 5 years ago
Could you provide me your code and any associated data files (i.e. meshes and textures)? Basically, I need a minimal working example that reproduces this error to help you debug.
I can send you a colab tomorrow. essentially it is always when I add a material with a texture. it might be good to have an example about this, then you should encounter the error
Please do, since I haven't been able to replicate this issue on my end.
Here you go! It might have to do with the image that is used for the texture. It would be good to check if the texture file is ok, instead of letting the shader crash later https://colab.research.google.com/drive/10wAbtZC507cyY4hChIYsg3LrhE0SKLL_
On Tue, May 7, 2019 at 6:41 PM Matthew Matl notifications@github.com wrote:
Please do, since I haven't been able to replicate this issue on my end.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mmatl/pyrender/issues/23#issuecomment-490157532, or mute the thread https://github.com/notifications/unsubscribe-auth/AFQOPHG5D25DWNNLBKGZ3FDPUGWKVANCNFSM4HLDFDUA .
I also added the colab notebook to github https://github.com/JonathanLehner/Colab-collection/blob/master/python_render_with_separate_texture.ipynb So you can see the outputs there directly
On Tue, May 7, 2019 at 8:00 PM Jonathan Lehner jonathanslehner@gmail.com wrote:
Here you go! It might have to do with the image that is used for the texture. It would be good to check if the texture file is ok, instead of letting the shader crash later https://colab.research.google.com/drive/10wAbtZC507cyY4hChIYsg3LrhE0SKLL_
On Tue, May 7, 2019 at 6:41 PM Matthew Matl notifications@github.com wrote:
Please do, since I haven't been able to replicate this issue on my end.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mmatl/pyrender/issues/23#issuecomment-490157532, or mute the thread https://github.com/notifications/unsubscribe-auth/AFQOPHG5D25DWNNLBKGZ3FDPUGWKVANCNFSM4HLDFDUA .
I am having exactly the same issue with meshes that been exported from either trimesh
or libigl
.
# import/export with libigl wrapper functions
m = read_obj('mesh.obj')
write_obj('tmp.obj', V=m[0], F=m[3], TC=m[1], CN=m[2], FTC=m[4], FN=m[5])
The following code then produces the error, but not if I load the original mesh.obj
instead of tmp.obj
.
# load texture + get material
tex = cv.cvtColor(cv.imread('texture.png'), cv.COLOR_BGR2RGB)
tex = pyrender.Texture(source=tex, source_channels='RGB')
mat = pyrender.material.MetallicRoughnessMaterial(baseColorTexture=tex, wireframe=True)
# load mesh + view scene
t_mesh = trimesh.load('tmp.obj', process=False)
t_mesh = pyrender.Mesh.from_trimesh(t_mesh, material=mat)
scene = pyrender.Scene()
scene.add(t_mesh)
pyrender.Viewer(scene, use_raymond_lighting=True)
Not using any material removes the issue. Here's the faulty .obj renamed as a .txt. tmp.txt
Interestingly, importing and exporting the mesh with blender makes it usable again.
This seems to happen when HAS_BASE_COLOR_TEX
is true but TEXCOORD_0_LOC or TEXCOOR_1_LOC is False.
This happens when the mesh has no UVs defined but has a material with textures defined.
EDIT: This is quite strange. For the attached object, if I render just the sub-meshes that have materials then it renders fine. If I render together with the other meshes then it ignores all of the textures.
Fixed in https://github.com/mmatl/pyrender/pull/63, but I feel the shader flag logic should be more robust to these kinds of mistakes.
I have met the same issue, I just run the Minimal Example for 3D Viewer project in the Docs » User Guide » Quickstart. I used an obj model generated by Blender. What can I do? How can I make a customized obj model? Which software should I use?
Still having the same problem is there a fix to this?
Any fixes for this? I am using a simple Maya exported OBJ file. I used the quick start example. The texture information is in mtl file. How to use it?
How can fix this issue? I try to create Mesh in runtime by faces, vertices and uv's like this texture = Texture(source=self.image, source_channels="RGB") material = MetallicRoughnessMaterial(normalTexture=texture) primitives = [Primitive(positions=vertices, indices=self.faces, texcoord_0=self.uv_s, material=material)] pmesh = pyrender.Mesh(primitives=primitives) self.render_mesh_helper(pmesh)
Any ideas, what wrong?
Im having the same problem, just created a simple textured cube in blender and get the error when i try to load it with texture obj file seems fine:
`
newmtl Mat Ns 900.000000 Ka 1.000000 1.000000 1.000000 Kd 0.800000 0.800000 0.800000 Ks 0.500000 0.500000 0.500000 Ke 0.000000 0.000000 0.000000 Ni 1.450000 d 1.000000 illum 2 map_Kd aruco_text.png`
`
mtllib Aruco_marker.mtl o Cube_Tag v -1.000000 -0.100000 1.000000 v -1.000000 0.100000 1.000000 v -1.000000 -0.100000 -1.000000 v -1.000000 0.100000 -1.000000 v 1.000000 -0.100000 1.000000 v 1.000000 0.100000 1.000000 v 1.000000 -0.100000 -1.000000 v 1.000000 0.100000 -1.000000 vt 0.000000 0.001323 vt 0.000000 0.998677 vt 0.140584 0.998677 vt 0.140584 0.001323 vt 0.000000 0.001323 vt 0.000000 0.998677 vt 0.124668 0.998677 vt 0.124668 0.001323 vt 0.098143 0.001323 vt 0.098143 0.998677 vt 0.000000 0.998677 vt 0.000000 0.001323 vt 0.106101 0.001323 vt 0.106101 0.998677 vt 0.000000 0.998677 vt 1.000000 0.998677 vt 1.000000 0.001323 vt 1.000000 0.998677 vt 0.000000 0.001323 vt 1.000000 0.001323 vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 vn 0.0000 1.0000 0.0000 g Cube_Tag_Mat usemtl Mat s off f 1/1/1 2/2/1 4/3/1 3/4/1 f 3/5/2 4/6/2 8/7/2 7/8/2 f 7/9/3 8/10/3 6/11/3 5/12/3 f 5/13/4 6/14/4 2/2/4 1/1/4 f 3/15/5 7/16/5 5/17/5 1/1/5 f 8/18/6 4/6/6 2/19/6 6/20/6 `
Checking the Triangulate Faces
option in the blender while exporting as a wavefront obj file did the trick for me. Might or might not be helpful for others.
)
Hi, I met the same problem recently. When I loaded my .obj model with trimesh, and used the 'from_mesh' to construct a 'Mesh' object, it appears the 'undefined variable "uv_0"' error. I've loaded the .obj into all of the modeling software I have but it seems like there's no content or structure error in the .obj file.
Accidently I loaded another .obj with mixed data (say with 20 quad and 4 triangle faces), and it worked fine! So I assumed it's not a fault in pyrender but trimesh. I have not been deep into the cause but I guess trimesh mainly adopts triangle face so it's supposed to transfer the quads to tri by default. But when the model has mixed faces, it would process faces with another way. You can trace the way by 'faces have mixed data, using slow fallback!' in the source code of trimesh.
I solved this by adding a tri face manually cuz I noticed that the model loading function doesn't have an option to change the mode. The new adding face makes no effect other than making the model rendered correctly.
I'm not sure all the problems of yours are due to this. I will keep an eye on this and any new finding and suggestion is welcome.
Hi, there. I also meet the problem when offscreen render with texture, here is my code
tex = pyrender.Texture(source=Image.open('mytexture.png'), source_channels='RGB', width=width, height=height)
mat = pyrender.material.MetallicRoughnessMaterial(normalTexture=tex, wireframe=False)
ref_scan = load_obj(obj_path)
tri_mesh = trimesh.Trimesh(vertices=ref_scan['v'], faces=ref_scan['tri'])
mesh = pyrender.Mesh.from_trimesh(tri_mesh, material=mat, smooth=True)
# ...
r = pyrender.OffscreenRenderer(viewport_width = width,viewport_height = height)
color, depth = r.render(scene) # <-- ShaderCompilationError
When I do not set material=mat
for pyrender.Mesh.from_trimesh
, I can render the white model correctly, here is the output result:
But I get the same error when adding Texture
and Material
as the code above shown.
ShaderCompilationError: ('Shader compile failure (0): b"ERROR: 0:172: \'uv_0\' : undeclared identifier \\nERROR: 0:173: \'constructor\' : not enough data provided for construction \\nERROR: 0:174: \'constructor\' : not enough data provided for construction \\nERROR: 0:192: \'texture\' : no matching overloaded function found (using implicit conversion) \\nERROR: 0:192: \'texture\' : function is not known \\nERROR: 0:192: \'rgb\' : field selection requires structure, vector, or matrix on left hand side \\nERROR: 0:192: \'=\' : cannot convert from \'const highp float\' to \'3-component vector of highp float\'\\n\\n"', [b'#version 330 core\n///////////////////////////////////////////////////////////////////////////////\n// Structs\n///////////////////////////////////////////////////////////////////////////////\n\nstruct SpotLight {\n vec3 color;\n float intensity;\n float range;\n vec3 position;\n vec3 direction;\n float light_angle_scale;\n float light_angle_offset;\n\n #if 0\n sampler2D shadow_map;\n mat4 light_matrix;\n #endif\n};\n\nstruct DirectionalLight {\n vec3 color;\n float intensity;\n vec3 direction;\n\n #if 0\n sampler2D shadow_map;\n mat4 light_matrix;\n #endif\n};\n\nstruct PointLight {\n vec3 color;\n float intensity;\n float range;\n vec3 position;\n\n #if 0\n samplerCube shadow_map;\n #endif\n};\n\nstruct Material {\n vec3 emissive_factor;\n\n#if 1\n vec4 base_color_factor;\n float metallic_factor;\n float roughness_factor;\n#endif\n\n#if 0\n vec4 diffuse_factor;\n vec3 specular_factor;\n float glossiness_factor;\n#endif\n\n#if 1\n sampler2D normal_texture;\n#endif\n#if 0\n sampler2D occlusion_texture;\n#endif\n#if 0\n sampler2D emissive_texture;\n#endif\n#if 0\n sampler2D base_color_texture;\n#endif\n#if 0\n sampler2D metallic_roughness_texture;\n#endif\n#if 0\n sampler2D diffuse_texture;\n#endif\n#if 0\n sampler2D specular_glossiness;\n#endif\n};\n\nstruct PBRInfo {\n float nl;\n float nv;\n float nh;\n float lh;\n float vh;\n float roughness;\n float metallic;\n vec3 f0;\n vec3 c_diff;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Uniforms\n///////////////////////////////////////////////////////////////////////////////\nuniform Material material;\nuniform PointLight point_lights[4];\nuniform int n_point_lights;\nuniform DirectionalLight directional_lights[4];\nuniform int n_directional_lights;\nuniform SpotLight spot_lights[4];\nuniform int n_spot_lights;\nuniform vec3 cam_pos;\nuniform vec3 ambient_light;\n\n#if 0\nuniform samplerCube diffuse_env;\nuniform samplerCube specular_env;\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// Inputs\n///////////////////////////////////////////////////////////////////////////////\n\nin vec3 frag_position;\n#if 1\nin vec3 frag_normal;\n#endif\n#if 1\n#if 0\n#if 1\nin mat3 tbn;\n#endif\n#endif\n#endif\n#if 0\nin vec2 uv_0;\n#endif\n#if 0\nin vec2 uv_1;\n#endif\n#if 0\nin vec4 color_multiplier;\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// OUTPUTS\n///////////////////////////////////////////////////////////////////////////////\n\nout vec4 frag_color;\n\n///////////////////////////////////////////////////////////////////////////////\n// Constants\n///////////////////////////////////////////////////////////////////////////////\nconst float PI = 3.141592653589793;\nconst float min_roughness = 0.04;\n\n///////////////////////////////////////////////////////////////////////////////\n// Utility Functions\n///////////////////////////////////////////////////////////////////////////////\nvec4 srgb_to_linear(vec4 srgb)\n{\n#if 1\n // Fast Approximation\n //vec3 linOut = pow(srgbIn.xyz,vec3(2.2));\n //\n vec3 b_less = step(vec3(0.04045),srgb.xyz);\n vec3 lin_out = mix( srgb.xyz/vec3(12.92), pow((srgb.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), b_less );\n return vec4(lin_out, srgb.w);\n#else\n return srgb;\n#endif\n}\n\n// Normal computation\nvec3 get_normal()\n{\n#if 1\n#if 1\n vec3 pos_dx = dFdx(frag_position);\n vec3 pos_dy = dFdy(frag_position);\n vec3 tex_dx = dFdx(vec3(uv_0, 0.0));\n vec3 tex_dy = dFdy(vec3(uv_0, 0.0));\n vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n\n#if 1\n vec3 ng = normalize(frag_normal);\n#else\n vec3 = cross(pos_dx, pos_dy);\n#endif\n\n t = normalize(t - ng * dot(ng, t));\n vec3 b = normalize(cross(ng, t));\n mat3 tbn_n = mat3(t, b, ng);\n\n#else\n\n mat3 tbn_n = tbn;\n\n#endif\n\n vec3 n = texture(material.normal_texture, uv_0).rgb;\n n = normalize(tbn_n * ((2.0 * n - 1.0) * vec3(1.0, 1.0, 1.0)));\n return n; // TODO NORMAL MAPPING\n\n#else\n\n#if 1\n return frag_normal;\n#else\n return normalize(cam_pos - frag_position);\n#endif\n\n#endif\n}\n\n// Fresnel\nvec3 specular_reflection(PBRInfo info)\n{\n vec3 res = info.f0 + (1.0 - info.f0) * pow(clamp(1.0 - info.vh, 0.0, 1.0), 5.0);\n return res;\n}\n\n// Smith\nfloat geometric_occlusion(PBRInfo info)\n{\n float r = info.roughness + 1.0;\n float k = r * r / 8.0;\n float g1 = info.nv / (info.nv * (1.0 - k) + k);\n float g2 = info.nl / (info.nl * (1.0 - k) + k);\n //float k = info.roughness * sqrt(2.0 / PI);\n //float g1 = info.lh / (info.lh * (1.0 - k) + k);\n //float g2 = info.nh / (info.nh * (1.0 - k) + k);\n return g1 * g2;\n}\n\nfloat microfacet_distribution(PBRInfo info)\n{\n float a = info.roughness * info.roughness;\n float a2 = a * a;\n float nh2 = info.nh * info.nh;\n\n float denom = (nh2 * (a2 - 1.0) + 1.0);\n return a2 / (PI * denom * denom);\n}\n\nvec3 compute_brdf(vec3 n, vec3 v, vec3 l,\n float roughness, float metalness,\n vec3 f0, vec3 c_diff, vec3 albedo,\n vec3 radiance)\n{\n vec3 h = normalize(l+v);\n float nl = clamp(dot(n, l), 0.001, 1.0);\n float nv = clamp(abs(dot(n, v)), 0.001, 1.0);\n float nh = clamp(dot(n, h), 0.0, 1.0);\n float lh = clamp(dot(l, h), 0.0, 1.0);\n float vh = clamp(dot(v, h), 0.0, 1.0);\n\n PBRInfo info = PBRInfo(nl, nv, nh, lh, vh, roughness, metalness, f0, c_diff);\n\n // Compute PBR terms\n vec3 F = specular_reflection(info);\n float G = geometric_occlusion(info);\n float D = microfacet_distribution(info);\n\n // Compute BRDF\n vec3 diffuse_contrib = (1.0 - F) * c_diff / PI;\n vec3 spec_contrib = F * G * D / (4.0 * nl * nv + 0.001);\n\n vec3 color = nl * radiance * (diffuse_contrib + spec_contrib);\n return color;\n}\n\nfloat texture2DCompare(sampler2D depths, vec2 uv, float compare) {\n return compare > texture(depths, uv.xy).r ? 1.0 : 0.0;\n}\n\nfloat texture2DShadowLerp(sampler2D depths, vec2 size, vec2 uv, float compare) {\n vec2 texelSize = vec2(1.0)/size;\n vec2 f = fract(uv*size+0.5);\n vec2 centroidUV = floor(uv*size+0.5)/size;\n\n float lb = texture2DCompare(depths, centroidUV+texelSize*vec2(0.0, 0.0), compare);\n float lt = texture2DCompare(depths, centroidUV+texelSize*vec2(0.0, 1.0), compare);\n float rb = texture2DCompare(depths, centroidUV+texelSize*vec2(1.0, 0.0), compare);\n float rt = texture2DCompare(depths, centroidUV+texelSize*vec2(1.0, 1.0), compare);\n float a = mix(lb, lt, f.y);\n float b = mix(rb, rt, f.y);\n float c = mix(a, b, f.x);\n return c;\n}\n\nfloat PCF(sampler2D depths, vec2 size, vec2 uv, float compare){\n float result = 0.0;\n for(int x=-1; x<=1; x++){\n for(int y=-1; y<=1; y++){\n vec2 off = vec2(x,y)/size;\n result += texture2DShadowLerp(depths, size, uv+off, compare);\n }\n }\n return result/9.0;\n}\n\nfloat shadow_calc(mat4 light_matrix, sampler2D shadow_map, float nl)\n{\n // Compute light texture UV coords\n vec4 proj_coords = vec4(light_matrix * vec4(frag_position.xyz, 1.0));\n vec3 light_coords = proj_coords.xyz / proj_coords.w;\n light_coords = light_coords * 0.5 + 0.5;\n float current_depth = light_coords.z;\n float bias = max(0.001 * (1.0 - nl), 0.0001) / proj_coords.w;\n float compare = (current_depth - bias);\n float shadow = PCF(shadow_map, textureSize(shadow_map, 0), light_coords.xy, compare);\n if (light_coords.z > 1.0) {\n shadow = 0.0;\n }\n return shadow;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// MAIN\n///////////////////////////////////////////////////////////////////////////////\nvoid main()\n{\n\n vec4 color = vec4(vec3(0.0), 1.0);\n///////////////////////////////////////////////////////////////////////////////\n// Handle Metallic Materials\n///////////////////////////////////////////////////////////////////////////////\n#if 1\n // Compute metallic/roughness factors\n float roughness = material.roughness_factor;\n float metallic = material.metallic_factor;\n#if 0\n vec2 mr = texture(material.metallic_roughness_texture, uv_0).rg;\n roughness = roughness * mr.r;\n metallic = metallic * mr.g;\n#endif\n roughness = clamp(roughness, min_roughness, 1.0);\n metallic = clamp(metallic, 0.0, 1.0);\n // In convention, material roughness is perceputal roughness ^ 2\n float alpha_roughness = roughness * roughness;\n\n // Compute albedo\n vec4 base_color = material.base_color_factor;\n#if 0\n base_color = base_color * srgb_to_linear(texture(material.base_color_texture, uv_0));\n#endif\n\n // Compute specular and diffuse colors\n vec3 dialectric_spec = vec3(min_roughness);\n vec3 c_diff = mix(vec3(0.0), base_color.rgb * (1 - min_roughness), 1.0 - metallic);\n vec3 f0 = mix(dialectric_spec, base_color.rgb, metallic);\n\n // Compute normal\n vec3 n = normalize(get_normal());\n\n // Loop over lights\n for (int i = 0; i < n_directional_lights; i++) {\n vec3 direction = directional_lights[i].direction;\n vec3 v = normalize(cam_pos - frag_position); // Vector towards camera\n vec3 l = normalize(-1.0 * direction); // Vector towards light\n\n // Compute attenuation and radiance\n float attenuation = directional_lights[i].intensity;\n vec3 radiance = attenuation * directional_lights[i].color;\n\n // Compute outbound color\n vec3 res = compute_brdf(n, v, l, roughness, metallic,\n f0, c_diff, base_color.rgb, radiance);\n\n // Compute shadow\n#if 0\n float nl = clamp(dot(n,l), 0.0, 1.0);\n float shadow = shadow_calc(\n directional_lights[i].light_matrix,\n directional_lights[i].shadow_map,\n nl\n );\n res = res * (1.0 - shadow);\n#endif\n color.xyz += res;\n }\n\n for (int i = 0; i < n_point_lights; i++) {\n vec3 position = point_lights[i].position;\n vec3 v = normalize(cam_pos - frag_position); // Vector towards camera\n vec3 l = normalize(position - frag_position); // Vector towards light\n\n // Compute attenuation and radiance\n float dist = length(position - frag_position);\n float attenuation = point_lights[i].intensity / (dist * dist);\n vec3 radiance = attenuation * point_lights[i].color;\n\n // Compute outbound color\n vec3 res = compute_brdf(n, v, l, roughness, metallic,\n f0, c_diff, base_color.rgb, radiance);\n color.xyz += res;\n }\n for (int i = 0; i < n_spot_lights; i++) {\n vec3 position = spot_lights[i].position;\n vec3 v = normalize(cam_pos - frag_position); // Vector towards camera\n vec3 l = normalize(position - frag_position); // Vector towards light\n\n // Compute attenuation and radiance\n vec3 direction = spot_lights[i].direction;\n float las = spot_lights[i].light_angle_scale;\n float lao = spot_lights[i].light_angle_offset;\n float dist = length(position - frag_position);\n float cd = clamp(dot(direction, -l), 0.0, 1.0);\n float attenuation = clamp(cd * las + lao, 0.0, 1.0);\n attenuation = attenuation * attenuation * spot_lights[i].intensity;\n attenuation = attenuation / (dist * dist);\n vec3 radiance = attenuation * spot_lights[i].color;\n\n // Compute outbound color\n vec3 res = compute_brdf(n, v, l, roughness, metallic,\n f0, c_diff, base_color.rgb, radiance);\n#if 0\n float nl = clamp(dot(n,l), 0.0, 1.0);\n float shadow = shadow_calc(\n spot_lights[i].light_matrix,\n spot_lights[i].shadow_map,\n nl\n );\n res = res * (1.0 - shadow);\n#endif\n color.xyz += res;\n }\n color.xyz += base_color.xyz * ambient_light;\n\n // Calculate lighting from environment\n#if 0\n // TODO\n#endif\n\n // Apply occlusion\n#if 0\n float ao = texture(material.occlusion_texture, uv_0).r;\n color.xyz *= ao;\n#endif\n\n // Apply emissive map\n vec3 emissive = material.emissive_factor;\n#if 0\n emissive *= srgb_to_linear(texture(material.emissive_texture, uv_0)).rgb;\n#endif\n color.xyz += emissive * material.emissive_factor;\n\n#if 0\n color *= color_multiplier;\n#endif\n\n frag_color = clamp(vec4(pow(color.xyz, vec3(1.0/2.2)), color.a * base_color.a), 0.0, 1.0);\n\n#else\n // TODO GLOSSY MATERIAL BRDF\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// Handle Glossy Materials\n///////////////////////////////////////////////////////////////////////////////\n\n}\n'], GL_FRAGMENT_SHADER)
Any ideas?
Hi @doubleZ0108, Can you share your full code and the model files along with the texture files?
I will try to fix it on my machine.
@submagr Sorry for the late reply. I have send the code & model to your personal google email. Thanks for your work!
Any update on this?
I also meet the problem when converting a trimesh scene into pyrender and use OffscreenRenderer to render images. But this problem only happens to a few models in my workflow. For these cases, I can successfully use trimesh to render it (although it's much slower than pyrender). Hope to see some progress on this issue!!
Some code to render using trimesh
A good workaround I found for this is basically to just add a dummy texture to the trimesh object. This seems to define "uv_0" in the background. After that, adding textures to materials in Pyrender behaves as expected.
mesh_ = trimesh.load_mesh(mesh_fname)
#### Insert a placeholder texture into the trimesh object to prevent "no uv_0" variable bug when defining
# texture in pyrender - the UV map used in the placeholder texture will be transferred to PyRender####
# Placeholder texture
texture_image = np.ones((1, 1, 3), dtype=np.uint8) * 255
# Create a Trimesh texture
texture = trimesh.visual.texture.TextureVisuals(
uv=(mesh_.vertices[:, :2] - np.min(mesh_.vertices[:, :2], axis=0)) / np.ptp(mesh_.vertices[:, :2], axis=0),
image=texture_image
)
# Set the texture for the mesh
mesh_.visual = texture
Had the same issue, fixed by triangulating mesh during export from blender
('Shader compile failure (0): 0(337) : error C1503: undefined variable "uv_0"\n', ['#version 330 core\n///////////////////////////////////////////////////////////////////////////////\n// Structs\n///////////////////////////////////////////////////////////////////////////////\n\nstruct SpotLight {\n vec3 color;\n float intensity;\n float range;\n vec3 position;\n vec3 direction;\n float light_angle_scale;\n float light_angle_offset;\n\n #if 0\n sampler2D shadow_map;\n mat4 light_matrix;\n #endif\n};\n\nstruct DirectionalLight {\n vec3 color;\n float intensity;\n vec3 direction;\n\n #if 0\n sampler2D shadow_map;\n mat4 light_matrix;\n #endif\n};\n\nstruct PointLight {\n vec3 color;\n float intensity;\n float range;\n vec3 position;\n\n #if 0\n samplerCube shadow_map;\n #endif\n};\n\nstruct Material {\n vec3 emissive_factor;\n\n#if 1\n vec4 base_color_factor;\n float metallic_factor;\n float roughness_factor;\n#endif\n\n#if 0\n vec4 diffuse_factor;\n vec3 specular_factor;\n float glossiness_factor;\n#endif\n\n#if 0\n sampler2D normal_texture;\n#endif\n#if 0\n sampler2D occlusion_texture;\n#endif\n#if 0\n sampler2D emissive_texture;\n#endif\n#if 1\n sampler2D base_color_texture;\n#endif\n#if 0\n sampler2D metallic_roughness_texture;\n#endif\n#if 0\n sampler2D diffuse_texture;\n#endif\n#if 0\n sampler2D specular_glossiness;\n#endif\n};\n...