How to apply Fur to Panda model?

Hello folks :slight_smile: , I just started working on Panda3D as I’ve seen it is a super cool engine and this is my first post here in the forum, Well as I am new here and in the 3D field in general, I want my panda model to look like in the image below. Still, I am not sure how to apply such a thing, is there something builtin in Panda3D which can provide fur? Or is there any code snippets ready to apply?

Hello, there is no built-in at the moment, but there are examples, in this thread you will find a way to implement something similar. However, please note that the code is partially outdated.

1 Like

Thank you for your fast answer :slight_smile:
Well, I’ve read the thread and apparently, the source code link is gone.
I did some other reaches and I found the following shader. i have applied it to my panda model but I can not see my panda any more. so do you have any idea why my model is hidden?

python code:

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

from scripts.utils.paths import Paths

class MyApp(ShowBase):
    def __init__(self):

        # Load the panda model
        self.panda_model = self.loader.loadModel("models/panda-model")

        # Set the panda model's position and scale
        self.panda_model.setPos(0, 190, 0)

        # Load the panda texture
        fur_image = "path/t/any/texture"
        panda_tex = self.loader.loadTexture(fur_image)

        vertex_shader = "path/t/vertex_shader"
        fragment_shader ="path/t/fragment_shader"
        shader = Shader.load(Shader.SLGLSL, vertex_shader, fragment_shader)
        self.panda_model.setShaderInput("color", panda_tex)
        self.panda_model.setShaderInput("fur", panda_tex)

        # Set the camera position and orientation, -10, 0), -90, 0)

        # Add some lighting to the scene
        self.ambient_light = AmbientLight("ambient_light")
        self.ambient_light.setColor((0.2, 0.2, 0.2, 1))
        self.ambient_light_np = self.render.attachNewNode(self.ambient_light)

        self.directional_light = DirectionalLight("directional_light")
        self.directional_light.setColor((0.8, 0.8, 0.8, 1))
        self.directional_light_np = self.render.attachNewNode(self.directional_light)
        self.directional_light_np.setHpr(45, -45, 0)

app = MyApp()

vertex shader:

#version 330

layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 p3d_MultiTexCoord0;
layout(location = 2) in float layer;
//layout(location = 3) in vec3 norm;

uniform mat4 p3d_ModelViewMatrix;
uniform mat4 p3d_ProjectionMatrix;
uniform vec3 displacement;

out vec2 fragTexCoord;
out float fragLayer;

void main(void) {
  vec3 layerDisplacement = pow(layer, 3.0) * vec3(1,1,1);
  vec4 newPos = vec4(pos + layerDisplacement, 1.0);
  gl_Position = p3d_ProjectionMatrix * p3d_ModelViewMatrix * newPos;

  fragTexCoord = p3d_MultiTexCoord0;
  fragLayer = layer;

fragment shader:

#version 330

in vec2 fragTexCoord;
in float fragLayer;

uniform sampler2D fur;
uniform sampler2D color;

out vec4 outputColor;

void main(void) {
  float fakeShadow = mix(0.4, 1.0, fragLayer);

  vec4 furData = texture(fur, fragTexCoord);
  vec4 furColor = texture(color, fragTexCoord) * fakeShadow;

  float visibility = (fragLayer > furData.r) ? 0.0 : furData.a;
  furColor.a = (fragLayer == 0.0) ? 1.0 : visibility;

  outputColor = furColor;

Are you seeing any errors in the console?

No, i don’t see any.
the only message in the consol is

Known pipe types:
(all display modules loaded.)

Hmm… Those “layout” qualifiers–what is their intended purpose? And what happens if you remove them?

to be honest I don’t know about the purpose of using them since i don’t have much experience in writing GLSL shaders.
I have removed them, but nothing happened no error appears nor the model.

Anyway, those shaders I’ve found them from the following repo: GitHub repo

Oh! One thing that I see missing is the application of the “View” matrix!

In your vertex-shader, instead of multiplying by first the model-matrix and then the projection-matrix, try multiplying by the model-view-projection-matrix, like so:

gl_Position = p3d_ModelViewProjectionMatrix * newPos;

I have tried that as well, still, no model is shown :frowning:
Thank you for helping me

Okay, in that case I’d suggest simplifying your shaders by commenting-out elements–replacing with simply dummy-elements where called for (e.g. “furColor.a = 1” instead of the full calculation)–and seeing whether the Panda appears. If it does, start then re-introducing elements until it stops appearing.

1 Like

OKay, I will do so, and inform you if i have found something :slight_smile:

1 Like

Okay, I found the problem, I believe:

In short, your shader is expecting the vertex-position to be given in an input named “pos”, but Panda3D provides it instead in an input named “p3d_Vertex”.

1 Like

Well, it worked well :slight_smile: Thank you.
apparently, the shader does not do anything related to fur as the panda looks flat sadly.

1 Like

It’s my pleasure to have helped! :slight_smile:

As to the fur effect, I suspect that one is intended to have multiple copies of the geometry, each with its own “layer” value. (You may want to specify their rendering-order too, such that the outer layers are rendered after the inner layers.)

1 Like