Setting rotation of environment bitmap from Python

Hello,
I’m using Rhino 8 / Vray 6.20.04 / Python 3 to render images with different settings in a loop. Everything works fine with one exception. The code


import rh8VRay as vray

# the next commands are called in a loop with varying values of angle_degrees

plg = vray.Scene.Plugin("/Environment Bitmap/UVW#1")
vray.Scene.BeginChange()
plg.rotation_h = angle_degrees
vray.Scene.EndChange()
vray.RefreshUI()

updates the respective value in the Asset Editor but the updated value gets ignored by a subsequent render run. Only values for “Texture Placement” > “Rotate H” that have been manually edited in the Asset Editor are taken into account by the renderer..
Is there an explanation (and possibly a solution) for this behavior?

Kind regards
Michael

If anyone is interested in a workaround, here is the one that I’ve implemented. The Python function


import rh8VRay as vray
import cv2
import numpy as np

def create_rotated_image(infile, outfile, yaw_dec):
    hdr_in = cv2.imread(infile, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR)
    height, width, depth = hdr_in.shape
    hdr_out = np.roll(hdr_in, int(yaw_dec / 360 * width), axis=1)
    cv2.imwrite(outfile, hdr_out)

now calculates a HDR file whose pixels have been moved according to the required rotation. The rotation is performed around the vertical axis (yaw); if an addtional rotation around a horizontal axis should be applied the code would get a bit more complicated, but the principle stays the same.

Before each render call the image gets loaded into VRay’s options with


plg = vray.Scene.Plugin("/Environment Bitmap/Bitmap")
vray.Scene.BeginChange()
plg.file = rotated_image_filename
vray.Scene.EndChange()
vray.RefreshUI()​

It’s important to change the file name of the HDR file in each iteration step, since VRay wouldn’t load a supposedly already loaded image agian.

Kind regards
Michael

Hi,

the reason you see a change in the UI but not in the scene is because the UVW’s parameters are not direct scene parameters.
In other words. changing the rotation_h is display-only property, it is not a scene parameter. The actual parameter in the case of the environment texture is called UVWGenEnvironment.uvw_matrix
When you change the rotation from the UI, the UI takes that value and calculates the full transformation matrix, then only stores the value for display purposes. This was done long time ago, due to rounding errors when the value us pulled out from the matrix.
Furthermore rotation angles (so called Euler angles) in a matrix are not completely recoverable. You loose the 2pi multiple and/or the sign (for 3D transformations).

This is one really legacy thing, and it is on the roadmap to do a proper handler on that.
if you need some help with constructing the final matrix, let me know