Hi Ats,
Ats wrote: ↑Sun Jan 04, 2026 7:41 pmDo I have to recalculate the TexCoord manually?
Simply swap the x and y components of the texture coordinates. For example, something like this:
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
<OnLoaded>
<SpawnModel Model="Demo"/>
</OnLoaded>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[// Toggle between solid & wireframe over time
DemoMaterial.Shading = frac(App.Time) > 0.5 ? 2 : 0;]]>
</Expression>
</ZExpression>
</OnUpdate>
<Content>
<Model Name="Demo" RotationVelocity="0.1 0.1 0">
<OnRender>
<UseMaterial Material="DemoMaterial"/>
<RenderMesh Mesh="DemoMesh"/>
</OnRender>
</Model>
<Mesh Name="DemoMesh">
<Producers>
<MeshBox XCount="3" YCount="3" Grid2DOnly="255"/>
<MeshBox XCount="3" YCount="3" Grid2DOnly="255"/>
<MeshExpression AutoNormals="0" HasTexCoords="255">
<Expression>
<![CDATA[// Swizzle texture coordinates
float x = TexCoord.X;
TexCoord.X = TexCoord.Y;
TexCoord.Y = x;
// Swizzle vertex coordinates ( and offset x )
x = V.X;
V.X = 2-V.Y;
V.Y = x;]]>
</Expression>
</MeshExpression>
<MeshCombine/>
<MeshTransform Comment="Center mesh" Position="-1 0 0"/>
</Producers>
</Mesh>
<Bitmap Name="DemoBitmap">
<Producers>
<BitmapExpression>
<Expression>
<![CDATA[//
float u = 1.0-X;
float v = 0.5-Y;
float s = frac((round(X*4)+round(Y*4))*0.5);
Pixel.R = u-v+s;
Pixel.G = v+u;
Pixel.B = 24-sqrt(u*u+v*v)*64;]]>
</Expression>
</BitmapExpression>
</Producers>
</Bitmap>
<Material Name="DemoMaterial" Shading="2">
<Textures>
<MaterialTexture Texture="DemoBitmap" TexCoords="1"/>
</Textures>
</Material>
</Content>
</ZApplication>
Ats wrote: ↑Sun Jan 04, 2026 7:41 pmBut now, the normal is also kind of broken on the edge of the symmetry.
Are you using the AutoNormals feature of MeshExpression? When combining multiple meshes their vertices stay separate from each other, even when they're at the exact same position. If you want the combined meshes to appear like a single surface, you can't rely ( solely ) on AutoNormals in that situation.
However, one cheap / hack-y fix is to "flatten" all normals for vertices that are at x=0 to the YZ-plane. Here's an example:
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" LightPosition="0.5 0.5 0.5" FileVersion="2">
<OnLoaded>
<ZLibrary>
<Source>
<![CDATA[//
vec3 normalize3(float x, float y, float z)
{
float s = sqrt(x*x+y*y+z*z);
return s ? vector3(x/s, y/s, z/s) : vector3(x, y, z);
}]]>
</Source>
</ZLibrary>
<SpawnModel Model="Demo"/>
</OnLoaded>
<Content>
<Model Name="Demo">
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[//
Demo.Rotation.Y = cos(App.Time)/16-0.0625;]]>
</Expression>
</ZExpression>
</OnUpdate>
<OnRender>
<RenderTransformGroup Translate="0 1.5 0">
<Children>
<RenderMesh Name="DemoRenderMesh" Mesh="DemoMesh"/>
</Children>
</RenderTransformGroup>
<RenderTransformGroup Translate="0 -1.5 0">
<Children>
<RenderMesh Name="DemoRenderMesh1" Mesh="DemoFixMesh"/>
</Children>
</RenderTransformGroup>
</OnRender>
</Model>
<Mesh Name="DemoMesh">
<Producers>
<MeshBox XCount="3" YCount="3" Grid2DOnly="255"/>
<MeshBox XCount="3" YCount="3" Grid2DOnly="255"/>
<MeshTransform Position="2 0 0" Rotation="0 0 0.25"/>
<MeshCombine/>
<MeshExpression>
<Expression>
<![CDATA[//
float x = (V.X-1)*PI/5;
float y = V.Y*PI/2;
V.X = V.X-1;
V.Y = sin(y)*cos(x);
V.Z = cos(y)*cos(x);]]>
</Expression>
</MeshExpression>
</Producers>
</Mesh>
<Mesh Name="DemoFixMesh">
<Producers>
<MeshBox XCount="3" YCount="3" Grid2DOnly="255"/>
<MeshBox XCount="3" YCount="3" Grid2DOnly="255"/>
<MeshTransform Position="2 0 0" Rotation="0 0 0.25"/>
<MeshCombine/>
<MeshExpression>
<Expression>
<![CDATA[//
float x = (V.X-1)*PI/5;
float y = V.Y*PI/2;
V.X = V.X-1;
V.Y = sin(y)*cos(x);
V.Z = cos(y)*cos(x);]]>
</Expression>
</MeshExpression>
<MeshExpression AutoNormals="0">
<Expression>
<![CDATA[//
if(V.X == 0)
{
N = normalize3(0, V.Y, V.Z);
}]]>
</Expression>
</MeshExpression>
</Producers>
</Mesh>
</Content>
</ZApplication>
K