Is it possible to read a texture as data in a custom node HLSL code in Unreal Engine?

40 Views Asked by At

I have a python script that can serialize and de-serialize some data as an image:

from pydantic import BaseModel
import numpy as np
from pathlib import Path
import json
import matplotlib.pyplot as plt
from PIL import Image


class Wave(BaseModel):
    A: float
    omega: float
    k1: float
    k2: float
    phase: float


class Waves(BaseModel):
    waves: list[Wave]


class MinMax(BaseModel):
    min: float
    max: float



N_params = 5
N_waves = 35


def create_initial_config():
    A = np.random.random(N_waves)
    omega = np.random.random(N_waves)
    k1 = np.random.random(N_waves)
    k2 = np.random.random(N_waves)
    phase = np.random.random(N_waves)
    waves = Waves(waves=[Wave(A=A[i], omega=omega[i], k1=k1[i], k2=k2[i], phase=phase[i]) for i in range(N_waves)])
    with open("config.json", "w") as f:
        f.write(waves.json())


create_initial_config()


def array_to_image(a):
    # convert the array to bytes and then store the bytes as an image
    b = a.tobytes()
    image = Image.frombytes('L', (a.shape[1] * a.shape[0] * a.dtype.itemsize, 1), b)
    return image


def image_to_array(im, dtype, shape):
    # convert the image to bytes and then store the bytes as an array
    b = im.tobytes()
    a = np.frombuffer(b, dtype=dtype).reshape(shape)
    return a


def get_config():
    config_file = Path("config.json")
    text = config_file.read_text()
    json_data = json.loads(text)
    waves = Waves.model_validate(json_data)
    return waves


def serialize_config():
    waves = get_config()
    A = []
    omega = []
    k1 = []
    k2 = []
    phase = []
    for wave in waves.waves:
        A.append(wave.A)
        omega.append(wave.omega)
        k1.append(wave.k1)
        k2.append(wave.k2)
        phase.append(wave.phase)
    A = np.array(A).astype(np.float32)
    omega = np.array(omega).astype(np.float32)
    k1 = np.array(k1).astype(np.float32)
    k2 = np.array(k2).astype(np.float32)
    phase = np.array(phase).astype(np.float32)
    return A, omega, k1, k2, phase


def serialize_wave_data():
    A, omega, k1, k2, phase = serialize_config()
    output_array = np.vstack([A, omega, k1, k2, phase]).reshape((-1), order='F')
    output_array = output_array.astype(np.float32)
    image = array_to_image(np.atleast_2d(output_array))
    image.save("waves.png")


serialize_wave_data()


def deserialize_wave_data():
    image = Image.open("waves.png")
    arr = image_to_array(image, np.float32, (1, (5 * 35)))[0]
    A = arr[::5]
    omega = arr[1::5]
    k1 = arr[2::5]
    k2 = arr[3::5]
    phase = arr[4::5]

    A_orig, omega_orig, k1_orig, k2_orig, phase_orig = serialize_config()
    assert(np.array_equal(A, A_orig))
    assert(np.array_equal(omega, omega_orig))
    assert(np.array_equal(k1, k1_orig))
    assert(np.array_equal(k2, k2_orig))
    assert(np.array_equal(phase, phase_orig))



deserialize_wave_data()

The image just gets saved as a 1xN image of pixels enter image description here

I was hoping that in unreal engine I will be able to load this texture, and be able to cast it to a byte array and then be able to convert them back to doubles:

enter image description here

In the unreal HLSL code, how can I convert the texture into an array of floats? Or just get a pointer to the data behind the texture?

Thanks for any help

0

There are 0 best solutions below