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

Tangent-space vectors not updated when texture rotation is in effect #808

Closed
Epihaius opened this issue Dec 11, 2019 · 5 comments
Closed

Tangent-space vectors not updated when texture rotation is in effect #808

Epihaius opened this issue Dec 11, 2019 · 5 comments
Assignees
Labels
bug
Milestone

Comments

@Epihaius
Copy link
Contributor

@Epihaius Epihaius commented Dec 11, 2019

Hi,

When a texture rotation is applied to a model, its tangent-space vectors are not updated. This makes it seem as if the light source is rotated also, or as if the apparent depth is inverted (dents become bumps and vice-versa), depending on how you look at it.

The following code sample should reproduce this:

from panda3d.core import *
from direct.showbase.ShowBase import ShowBase


class MyApp(ShowBase):

    def __init__(self):

        ShowBase.__init__(self)
        self.disable_mouse()
        self.camera.set_y(-20.)

        # set up a light source
        p_light = PointLight("point_light")
        p_light.set_color((1., 1., 1., 1.))
        self.light = self.render.attach_new_node(p_light)
        self.light.set_pos(50., -30., 30.)
        self.render.set_light(self.light)
        self.render.set_shader_auto(True)
        self.render.set_shader_input("light", self.light)

        # load a model with tangent-space vectors; it has a normal map (normal_sphere.jpg)
        # and a color map (Brick_105.jpg) assigned to it
        self.model = model = self.loader.load_model("Square.bam", noCache=True).get_child(0)
        tex_attrib = model.get_state().get_attrib(TextureAttrib)
        self.ts_color = tex_attrib.get_on_stage(0)
        self.ts_normal = tex_attrib.get_on_stage(1)
        model.reparent_to(self.render)
        model.set_h(180.)
        self.angle = 0.

        # set up a task to rotate the model textures each frame
        self.task_mgr.add(self.__rotate_tex, "rotate_tex")

    def __rotate_tex(self, task):

        self.angle += 1.

        mat = Mat3.ident_mat()
        mat = mat * Mat3.translate_mat(-.5, -.5)
        mat = mat * Mat3.rotate_mat(self.angle)
        mat = mat * Mat3.translate_mat(.5, .5)
        xform = TransformState.make_mat3(mat)
        self.model.set_tex_transform(self.ts_color, xform)
        self.model.set_tex_transform(self.ts_normal, xform)

        return task.cont


app = MyApp()
app.run()

You should see a static square model with rotating color and normal maps, as if the apparent 3D-surface itself were rotating. This illusion is broken by the fact that the shading rotates along with the textures instead of respecting the (stationary) position of the light source.

Here are the resources used by the sample:

res.zip

The normal map used creates big dome-like bumps, while the light source is above and to the right of the model, so a shadow is generated at the bottom left hand side of each "dome". However, when a texture rotation is in effect, this shadow rotates along with the normal map.

As hinted at in this issue comment, this should be a bug in the ShaderGenerator.

@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Feb 29, 2020

The tangent and binormal vectors are meant to transform a normal from tangent space to model space. Since texture matrices change the tangent space, I suppose that the tangent frame should be transformed by the texture matrix as well.

I'm checking in something that fixes your use case, but I can't promise that it's entirely correct—in particular, I'm not sure that non-uniform scales are handled properly.

@rdb rdb closed this in 9431d50 Feb 29, 2020
@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Feb 29, 2020

As an interesting side-effect of my change, you can use the Z coordinate in the texture scale independently to scale the effect of the normal maps. I don't know whether this is correct or whether we should be ignoring the third dimension entirely, but I suppose it could be useful.

@Epihaius

This comment has been minimized.

Copy link
Contributor Author

@Epihaius Epihaius commented Mar 2, 2020

I'm checking in something that fixes your use case, but I can't promise that it's entirely correct—in particular, I'm not sure that non-uniform scales are handled properly.

If translation, rotation and uniform scales yield expected results, then most use cases should be covered, I think.

you can use the Z coordinate in the texture scale independently to scale the effect of the normal maps. I don't know whether this is correct or whether we should be ignoring the third dimension entirely, but I suppose it could be useful.

It's always nice to have an additional feature :) .

Thank you for fixing this!

@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Mar 2, 2020

If translation, rotation and uniform scales yield expected results, then most use cases should be covered, I think.

For the record, translations and uniform scales do not affect tangent space whatsoever :) It is only rotation and non-uniform scale that affect it.

@Epihaius

This comment has been minimized.

Copy link
Contributor Author

@Epihaius Epihaius commented Mar 3, 2020

Lol, you're right. Thanks for reminding me 😊.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.