[SOLVED] UV calculations in Material

Everything about the development of Urho3D.

[SOLVED] UV calculations in Material

PostPosted by flintza » 19 May 2016, 09:03

Hi all, I'm working in the Atomic Game Engine project, implementing in-editor lightmapping. I've checked and the core code I'm hitting is unchanged from Urho3D's, so I thought it would make more sense to ask about it here :)

Context
To give some context to my question, I'm currently at the point of applying a generated lightmap to objects by cloning their material and setting UV scale and offset accordingly.

I've added a second set of UV transform uniforms in Uniform.hlsl:
Code: Select all
uniform float4 cUOffset;
uniform float4 cVOffset;
uniform float4 cUOffsetLM;
uniform float4 cVOffsetLM;
uniform float4x3 cZone;


And added a transform function to be used in lightmap shaders (currently testing with LitSolid) in Transforms.hlsl:
Code: Select all
float2 GetTexCoord2(float2 iTexCoord)
{
    return float2(dot(iTexCoord, cUOffsetLM.xy) + cUOffsetLM.w, dot(iTexCoord, cVOffsetLM.xy) + cVOffsetLM.w);
};


In Material.h/cpp, I added methods similar to SetUVTransform but corresponding to the second set of UVs, moving the transform calculation into a separate method and calling it from both:

Code: Select all
void Material::SetUVTransform2(const Vector2& offset, float rotation, const Vector2& repeat)
{
    Matrix3x4 transform = CalculateUVTransform(offset, rotation, repeat);

    SetShaderParameter("UOffsetLM", Vector4(transform.m00_, transform.m01_, transform.m02_, transform.m03_));
    SetShaderParameter("VOffsetLM", Vector4(transform.m10_, transform.m11_, transform.m12_, transform.m13_));
}

Matrix3x4 Material::CalculateUVTransform(const Vector2& offset, float rotation, const Vector2& repeat)
{
    Matrix3x4 transform(Matrix3x4::IDENTITY);
    transform.m00_ = repeat.x_;
    transform.m11_ = repeat.y_;
    transform.m03_ = -0.5f * transform.m00_ + 0.5f;
    transform.m13_ = -0.5f * transform.m11_ + 0.5f;

    Matrix3x4 rotationMatrix(Matrix3x4::IDENTITY);
    rotationMatrix.m00_ = Cos(rotation);
    rotationMatrix.m01_ = Sin(rotation);
    rotationMatrix.m10_ = -rotationMatrix.m01_;
    rotationMatrix.m11_ = rotationMatrix.m00_;
    rotationMatrix.m03_ = 0.5f - 0.5f * (rotationMatrix.m00_ + rotationMatrix.m01_);
    rotationMatrix.m13_ = 0.5f - 0.5f * (rotationMatrix.m10_ + rotationMatrix.m11_);

    transform = rotationMatrix * transform;

    Matrix3x4 offsetMatrix = Matrix3x4::IDENTITY;
    offsetMatrix.m03_ = offset.x_;
    offsetMatrix.m13_ = offset.y_;

    return offsetMatrix * transform;
}


The scale and offset are calculated in the lightmapper and applied to each model (where rect corresponds to where the model's LM is in the full LM atlas):
Code: Select all
IntRect& rect = rects[i];
Vector2 scale((float)rect.Width() / atlasWidth, (float)rect.Height() / atlasHeight);
Vector2 offset((float)rect.left_ / atlasWidth, (float)rect.top_ / atlasHeight);

LMStaticModel* model = generators[i]->GetModel();
model->SetLightmapTexure(atlasTexture);
model->SetLightmapUVTransform(offset, 0, scale);


LMStaticModel::SetLightmapTexure and LMStaticModel::SetLightmapUVTransform just set these values on the cloned material.

The actual question, at last :)

This is my current lightmap atlas test case (automatically generated, but with numbers added for my sanity afterwards):
Image

As an example mapping the second, smaller cube in the atlas I would expect an offset of approx (0.6, 0.0) and a scale/repeat of approx (0.3, 0.3). Setting these values manually on the material's U/VOffsetLM I get the expected result:
Image
Image

However setting them through SetUVTransform2 (which uses the same transform calculation as SetUVTransform), the calculated values are not what I would expect, and the visual result is way off:
Image
Image
Image

So what is going on here? Is my understanding of UVs completely wrong (not impossible at all) or is that CalculateUVTransform wrong. It's been in Material.cpp as-is since before the Atomic fork, but I see Material::SetUVTransform isn't actually used anywhere so it's possible the calculation is wrong and it's never been noticed.
Last edited by flintza on 19 May 2016, 13:25, edited 1 time in total.
User avatar
flintza
New user
New user
 
Posts: 5
Joined: 11 Dec 2015, 14:57

Re: UV calculations in Material

PostPosted by cadaver » 19 May 2016, 12:41

This is some of Urho's oldest code. When I tested it, it added a counter-intuitive offset when I adjusted repeat. I no longer remember the rationale for that, so I just removed it :) The change is in master.
User avatar
cadaver
Urho3D author
Urho3D author
 
Posts: 1802
Joined: 16 Jan 2014, 14:52
Location: Finland

Re: UV calculations in Material

PostPosted by flintza » 19 May 2016, 13:05

Haha, so I'm not going nuts! :) Thanks, I'll adjust it my side and leave a note for when Josh merges back again.
User avatar
flintza
New user
New user
 
Posts: 5
Joined: 11 Dec 2015, 14:57


Return to Developer Talk

Who is online

Users browsing this forum: No registered users and 0 guests