Using the box.egg.pz model to create the linear corridor. Now I want to add specific patches of textures at certain positions of the entire corridor as visual cues. In real life, this corridor will be mapped onto a 300 cm belt. I want to have 3 patches of textures on both the right and left wall witht he first texture starts from realworld 80 cm and the last texture ends at 220cm. All the textures have width of 20cm and they are interleaved by 40cm. I tried doing this with shaders along with the custom python code using panda3d. I realized in the fragment shader, there is an offset while calculating the y position. Also the last patch extends beyond the desire 220cm. Thanks in advance for any help or suggestions.
def setup_corridor(self):
"""Sets up the VR corridor environment by creating walls."""
self.left_wall = self.create_wall("left", scale=(0.5, self.corridor_length, 50), pos=(-100, 0, -20))
self.right_wall = self.create_wall("right", scale=(0.5, self.corridor_length, 50), pos=(100, 0, -20))
self.floor = self.create_wall("floor", scale=(200, self.corridor_length, 0.2), pos=(-100, 0, -20))
self.roof = self.create_wall("roof", scale=(200, self.corridor_length, 0.2), pos=(-100, 0, 30))
self.end_wall = self.create_wall("end", scale=(200, 0.5, 50), pos=(-100, self.corridor_length*2, -20))
self.walls = {
"left_wall": self.left_wall,
"right_wall": self.right_wall,
"floor": self.floor,
"roof": self.roof,
"end_wall": self.end_wall,
}
def create_wall(self, name, scale, pos):
"""Helper method to create and position a wall."""
wall_node = self.app.loader.loadModel("models/box")
wall_node.setScale(*scale)
wall_node.setPos(*pos)
wall_node.reparentTo(self.app.render)
return wall_node
def apply_textures(self, wall_texture_map):
for wall_name, tex_info in wall_texture_map.items():
node = self.walls.get(wall_name)
if not node:
continue
if isinstance(tex_info, dict):
vert_p = os.path.join("shaders", "wall_shader.vert")
frag_p = os.path.join("shaders", "wall_shader.frag")
node.setShader(Shader.load(Shader.SL_GLSL, vert_p, frag_p))
tex1 = self.textures.get("left_right_texture1")
tex2 = self.textures.get("left_right_texture2")
tex3 = self.textures.get("left_right_texture3")
base = self.textures.get("base_texture")
node.setShaderInput("patch1", tex1)
node.setShaderInput("patch2", tex2)
node.setShaderInput("patch3", tex3)
node.setShaderInput("baseTex", base)
node.setShaderInput("wallLength", self.corridor_length* 2)
node.setShaderInput("beltLength", 300.0)
node.setShaderInput("patchLen", 20.0)
node.setShaderInput("patchStride", 60.0)
node.setShaderInput("patchStart", 80.0)
else:
tex = self.textures.get(tex_info)
if tex:
node.setTexture(tex, 1)
else:
print(f"[WARN] Texture '{tex_info}' not found for '{wall_name}'")
and this is the fragment shader:
#version 150
in vec2 v_uv;
in float v_world_y;
uniform sampler2D patch1;
uniform sampler2D patch2;
uniform sampler2D patch3;
uniform sampler2D baseTex;
uniform float wallLength;
uniform float beltLength;
uniform float patchLen;
uniform float patchStride;
uniform float patchStart;
out vec4 fragColor;
void main() {
float t = (v_world_y + (wallLength * 0.5)) / wallLength;
float pos = t * beltLength;
// Try adding a small offset here to shift the 'pos' value
float adjusted_pos = pos - 80.0; // Try adding 80.0 to see if the red appears
if (adjusted_pos >= 80.0 && adjusted_pos <= 220.0) {
float p = adjusted_pos - patchStart;
float cyclePos = mod(p, patchStride);
int idx = int(floor(p / patchStride));
if (cyclePos < patchLen) {
if (idx == 0) fragColor = texture(patch1, v_uv);
else if (idx == 1) fragColor = texture(patch2, v_uv);
else if (idx == 2) fragColor = texture(patch3, v_uv);
return;
}
}
fragColor = texture(baseTex, v_uv);
}