def _load_noise_tex(self):
     """ Loads the default 4x4 noise tex """
     random.seed(42)
     img = PNMImage(4, 4, 3)
     for x in range(16):
         img.set_xel(x%4, x//4, random.random(), random.random(), random.random())
     tex = Texture("Random4x4")
     tex.load(img)
     self._pipeline.stage_mgr.add_input("Noise4x4", tex)
Exemple #2
0
 def create_noise_textures(self):
     # Always generate the same random textures
     seed(42)
     img = PNMImage(4, 4, 3)
     for x in range(4):
         for y in range(4):
             img.set_xel(x, y, random(), random(), random())
     tex = Texture("Rand4x4")
     tex.load(img)
     self._target.set_shader_input("Noise4x4", tex)
Exemple #3
0
    def generate_dataset_texture_into(self, dest_tex, z):
        resolution_vertical = dest_tex.get_y_size()
        resolution_horizontal = dest_tex.get_x_size()

        dest = PNMImage(resolution_vertical, resolution_horizontal, 1, 65535)

        for vert in range(resolution_vertical):
            for horiz in range(resolution_horizontal):
                vert_angle = vert / (resolution_vertical-1.0)
                vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0
                horiz_angle = horiz / (resolution_horizontal-1.0) * 360.0
                candela = self.get_candela_value(vert_angle, horiz_angle)
                dest.set_xel(vert, horiz, candela)

        dest_tex.load(dest, z, 0)
    def generate_dataset_texture_into(self, dest_tex, layer_index):
        resolution_vertical = dest_tex.get_y_size()
        resolution_horizontal = dest_tex.get_x_size()

        dest = PNMImage(resolution_vertical, resolution_horizontal, 1, 65535)

        for vert in range(resolution_vertical):
            for horiz in range(resolution_horizontal):
                vert_angle = vert / (resolution_vertical - 1.0)
                vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0
                horiz_angle = horiz / (resolution_horizontal - 1.0) * 360.0
                candela = self.get_candela_value(vert_angle, horiz_angle)
                dest.set_xel(vert, horiz, candela)

        dest_tex.load(dest, layer_index, 0)
            for i, s_nxv in enumerate(reversed(nxv_values)):
                if NxV >= s_nxv:
                    index = i
                    break
            index = len(nxv_values) - index - 1
            next_index = index + 1 if index < dest_size - 1 else index

            curr_nxv = nxv_values[index]
            next_nxv = nxv_values[next_index]

            lerp_factor = (NxV - curr_nxv) / max(1e-10, abs(next_nxv - curr_nxv))
            lerp_factor = max(0.0, min(1.0, lerp_factor))
            indices.append((index, next_index, lerp_factor))

        # Generate the final linear lut using the lerp weights
        for y in xrange(dest_h):
            for x in xrange(dest_size):
                curr_i, next_i, lerp = indices[x]
                curr_v = img.get_xel(curr_i, y)
                next_v = img.get_xel(next_i, y)
                dest.set_xel(x, y, curr_v * (1 - lerp) + next_v * lerp)


        out_name = config["out_name"].replace("{}", str(pass_index))
        dest.write(config["out_dir"] + "/" + out_name)

try:
    os.remove("scene.png")
except:
    pass
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 	 	    	 	
"""
from __future__ import division, print_function

import math
from panda3d.core import PNMImage

lut_size = 64
lut_cols = 8
lut_rows = (lut_size + lut_cols - 1) // lut_cols

img = PNMImage(lut_size * lut_cols, lut_size * lut_rows, 3, 2**16 - 1)

def to_linear(v):
    return float(v) / float(lut_size-1)

def to_linear_inv(v):
    return 1 - to_linear(v)

for r in range(lut_size):
    for g in range(lut_size):
        for b in range(lut_size):
            slice_offset_x = (b % lut_cols) * lut_size
            slice_offset_y = (b // lut_cols) * lut_size
            img.set_xel(r + slice_offset_x, g + slice_offset_y, 
                to_linear(r), to_linear_inv(g), to_linear(b))

img.write("DefaultLUT.png")
            for k in xrange(3):
                values[k].append(srgb_to_linear(line[k]))

        def to_linear(v):
            return float(v) / float(64 - 1)

        def to_linear_inv(v):
            return 1 - to_linear(v)

        def lookup_value(v, values):
            return values[int(v * (len(values) - 1))]

        # Generate lut
        img = PNMImage(64 * 8, 64 * 8, 3, 2**16 - 1)
        for r in xrange(64):
            for g in xrange(64):
                for b in xrange(64):
                    slice_offset_x = (b % 8) * 64
                    slice_offset_y = (b // 8) * 64

                    fr, fg, fb = to_linear(r), to_linear_inv(g), to_linear(b)

                    fr = lookup_value(fr, values[0])
                    fg = lookup_value(fg, values[1])
                    fb = lookup_value(fb, values[2])

                    img.set_xel(r + slice_offset_x, g + slice_offset_y, fr, fg, fb)

        img.write("film_luts/" + output_name + ".png")
Exemple #8
0
    def palettize(self, palette_img, create_rgb=True):
        """
        Runs all palettization procedures on the given PaletteImage.
        Creates an RGB version of the palette if requested.
            :palette_img: The PaletteImage you want to palettize.
            :create_rgb: Would you like to create an RGB variant of the palette? True by default.
        """
        # We need to know the palette's prior size
        if not palette_img.size_known:
            raise PalettizerException(
                "Palette image's size is not known, this is a fatal error!")

        palette_name = palette_img.basename

        if self.debug:
            print(
                f'[{palette_img.page.group.dirname}] Compiling {palette_name}..'
            )

        # Our max distortion is 1, as we do not want to resize the palette to be smaller accidentally
        max_distortion = 1

        # This array holds all of our PNMImage source textures
        imgs = []

        # We're going to check all of the source textures
        # so that we can load all of them and determine our palette's final size
        for placement in palette_img.placements:
            sources = placement.texture.sources

            # We need to know the size of all source textures
            # If a source texture's size is not known, that means that it has been defined but did not exist on the disk when creating textures.boo
            for source in sources:
                if not source.size_known:
                    print(
                        f'Warning: Size is not known for source {source.filename}, please consider fixing the texture path and re-running egg-palettize'
                    )

            # Source (original) full resolution texture size
            source = sources[0]
            x_size = source.x_size
            y_size = source.y_size

            # Prior texture position and size
            tex_position = placement.position
            tex_x_size = tex_position.x_size
            tex_y_size = tex_position.y_size

            # DISTORTER
            # Fold the points until they scream out
            # DISTORTER
            # Change the way it sounds

            # We need to calculate the maximum distortion for both our X and Y (U/V) coordinates
            if x_size != tex_x_size:
                x_distortion = x_size / tex_x_size

                if x_distortion > max_distortion:
                    max_distortion = x_distortion

            if y_size != tex_y_size:
                y_distortion = y_size / tex_y_size

                if y_distortion > max_distortion:
                    max_distortion = y_distortion

            # If we have more than one source, that means our texture
            # has been defined multiple times for the same group...
            # Panda3D uses the first source texture only, so that's what we'll do.
            # But we'll make sure to print a warning either way!
            if len(sources) > 1:
                source2 = sources[1]

                if source2.x_size != x_size or source2.y_size != y_size:
                    print(
                        f'Two different source textures are defined for {palette_name}: {source.filename} ({x_size} {y_size}) vs {source2.filename} ({source2.x_size} {source2.y_size})'
                    )

            # Time to load the source file from Pandora!
            img = self.read_texture(source.filename)

            # Add the source image to our list
            imgs.append(img)

        # Well, time to calculate the palette's final size!
        # We will multiply the current size with the highest distortion.
        # We do NOT calculate X and Y distortion separately.
        # Doing so would destroy the aspect ratio of the palette.
        current_x_size = palette_img.x_size
        current_y_size = palette_img.y_size
        new_x_size = round(current_x_size * max_distortion)
        new_y_size = round(current_y_size * max_distortion)

        # Power of two time!
        # It's easier for the game engine to load, as it does not have to scale it automatically.
        new_x_size, new_y_size = self.scale_power_of_2(new_x_size, new_y_size)

        # We've changed the palette size. It is necessary to recalculate our texture distortion.
        x_distortion = new_x_size / current_x_size
        y_distortion = new_y_size / current_y_size

        # Create our palette image with four channels.
        # We will cut down the last channel when necessary.
        # Having a fourth, empty channel would only increase the file size.
        new_image = PNMImage(new_x_size, new_y_size, 4)
        new_image.alpha_fill(1)

        # Textures with alpha always have four channels set (three for RGB and one for Alpha).
        has_alpha = palette_img.properties.effective_channels in (2, 4)
        rgb_only = palette_img.properties.format == TextureGlobals.F_alpha
        alpha_image = None

        # If necessary and possible, create an alpha image as well.
        # Textures with alpha always have four channels set (three for RGB and one for Alpha).
        if create_rgb and has_alpha and not rgb_only:
            alpha_image = PNMImage(new_x_size, new_y_size, 1)
            alpha_image.set_type(PalettizeGlobals.RGB_TYPE)

        for i, placement in enumerate(palette_img.placements):
            # Find the loaded source image from before...
            texture_img = imgs[i]

            # Calculate the placement of our image!
            tex_position = placement.placed

            # Determine the upper left and lower right corners
            # with some matrix magic.
            transform = placement.compute_tex_matrix()
            ul = transform.xform_point(LTexCoordd(0.0, 1.0))
            lr = transform.xform_point(LTexCoordd(1.0, 0.0))

            # Calculate the top, left, bottom and right corners.
            top = int(math.floor((1.0 - ul[1]) * new_y_size + 0.5))
            left = int(math.floor(ul[0] * new_x_size + 0.5))
            bottom = int(math.floor((1.0 - lr[1]) * new_y_size + 0.5))
            right = int(math.floor(lr[0] * new_x_size + 0.5))

            tex_x_size = right - left
            tex_y_size = bottom - top
            org_x_size = round(tex_position.x_size * x_distortion)
            org_y_size = round(tex_position.y_size * y_distortion)
            tex_x = round(tex_position.x * x_distortion)
            tex_y = round(tex_position.y * y_distortion)

            # Resize our image to the desired size.
            texture_img = self.resize_image(texture_img, tex_x_size,
                                            tex_y_size)

            for y in range(tex_y, tex_y + org_y_size):
                sy = y - top

                # UV wrapping modes - V component (for Y texture coordinate)
                if placement.placed.wrap_v == TextureGlobals.WM_clamp:
                    sy = max(min(sy, tex_y_size - 1), 0)
                elif placement.placed.wrap_v == TextureGlobals.WM_mirror:
                    sy = (tex_y_size * 2) - 1 - (
                        (-sy - 1) %
                        (tex_y_size * 2)) if sy < 0 else sy % (tex_y_size * 2)
                    sy = sy if sy < tex_y_size else 2 * tex_y_size - sy - 1
                elif placement.placed.wrap_v == TextureGlobals.WM_mirror_once:
                    sy = sy if sy < tex_y_size else 2 * tex_y_size - sy - 1

                    # Repeat texture
                    sy = tex_y_size - 1 - (
                        (-sy - 1) % tex_y_size) if sy < 0 else sy % tex_y_size
                elif placement.placed.wrap_v == TextureGlobals.WM_border_color:
                    if sy < 0 or sy >= tex_y_size:
                        continue
                else:
                    # Repeat texture
                    sy = tex_y_size - 1 - (
                        (-sy - 1) % tex_y_size) if sy < 0 else sy % tex_y_size

                for x in range(tex_x, tex_x + org_x_size):
                    sx = x - left

                    # UV wrapping modes - U component (for X texture coordinate)
                    if placement.placed.wrap_u == TextureGlobals.WM_clamp:
                        sx = max(min(sx, tex_x_size - 1), 0)
                    elif placement.placed.wrap_u == TextureGlobals.WM_mirror:
                        sx = (tex_x_size * 2) - 1 - (
                            (-sx - 1) %
                            (tex_x_size * 2)) if sx < 0 else sx % (tex_x_size *
                                                                   2)
                        sx = sx if sx < tex_x_size else 2 * tex_x_size - sx - 1
                    elif placement.placed.wrap_u == TextureGlobals.WM_mirror_once:
                        sx = sx if sx >= 0 else ~sx

                        # Repeat texture
                        sx = tex_x_size - 1 - (
                            (-sx - 1) %
                            tex_x_size) if sx < 0 else sx % tex_x_size
                    elif placement.placed.wrap_u == TextureGlobals.WM_border_color:
                        if sx < 0 or sx >= tex_x_size:
                            continue
                    else:
                        # Repeat texture
                        sx = tex_x_size - 1 - (
                            (-sx - 1) %
                            tex_x_size) if sx < 0 else sx % tex_x_size

                    new_image.set_xel(x, y, texture_img.get_xel(sx, sy))
                    new_image.set_alpha(x, y, texture_img.get_alpha(sx, sy))

                    if alpha_image:
                        alpha_image.set_gray(x, y,
                                             texture_img.get_alpha(sx, sy))

        return new_image, alpha_image, has_alpha, rgb_only
write_diff_img = False

img_a = PNMImage(source_a)
img_b = PNMImage(source_b)

w, h = img_a.get_x_size(), img_a.get_y_size()
img_dest = PNMImage(w, h, 3)

error_scale = 10.0

total_diff = 0.0

for x in xrange(w):
    for y in xrange(h):
        val_a = img_a.get_xel(x, y)
        val_b = img_b.get_xel(x, y)

        abs_diff = (val_a - val_b) * error_scale
        r, g, b = abs(abs_diff.x), abs(abs_diff.y), abs(abs_diff.z)

        img_dest.set_xel(x, y, r, g, b)
        total_diff += r + g + b

total_diff /= float(w * h)
total_diff /= error_scale

print("Average difference: ", total_diff, " in RGB: ", total_diff * 255)

img_dest.write("difference.png")
            for k in xrange(3):
                values[k].append(srgb_to_linear(line[k]))

        def to_linear(v):
            return float(v) / float(64-1)

        def to_linear_inv(v):
            return 1 - to_linear(v)

        def lookup_value(v, values):
            return values[int(v * (len(values) - 1) )]

        # Generate lut
        img = PNMImage(64 * 8, 64 * 8, 3, 2**16 - 1)
        for r in xrange(64):
            for g in xrange(64):
                for b in xrange(64):
                    slice_offset_x = (b % 8) * 64
                    slice_offset_y = (b // 8) * 64

                    fr, fg, fb = to_linear(r), to_linear_inv(g), to_linear(b)

                    fr = lookup_value(fr, values[0])
                    fg = lookup_value(fg, values[1])
                    fb = lookup_value(fb, values[2])

                    img.set_xel(r + slice_offset_x, g + slice_offset_y, fr, fg, fb)

        img.write("film_luts/" + output_name + ".png")
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

"""
from __future__ import division, print_function

import math
from panda3d.core import PNMImage

lut_size = 64
lut_cols = 8
lut_rows = (lut_size + lut_cols - 1) // lut_cols

img = PNMImage(lut_size * lut_cols, lut_size * lut_rows, 3, 2**16 - 1)

def to_linear(v):
    return float(v) / float(lut_size-1)

def to_linear_inv(v):
    return 1 - to_linear(v)

for r in range(lut_size):
    for g in range(lut_size):
        for b in range(lut_size):
            slice_offset_x = (b % lut_cols) * lut_size
            slice_offset_y = (b // lut_cols) * lut_size
            img.set_xel(r + slice_offset_x, g + slice_offset_y,
                to_linear(r), to_linear_inv(g), to_linear(b))

img.write("default_lut.png")
Exemple #12
0
# Ambient Occlusion, Roughness, Metallicity
# R: Ambient Occlusion
# G: Roughness, a.k.a. gloss map (if inverted); Gets multiplied with mat.roughness
# B: Metallicity; Gets multiplied with mat.metallic
metal_rough_pnm = PNMImage(texture_size, texture_size)
for x in range(texture_size):
    x_band = int(float(x) / float(texture_size) * (texture_bands_x))
    x_band_base = float(x_band) / float(texture_bands_x - 1)
    for y in range(texture_size):
        y_band = int(float(y) / float(texture_size) * (texture_bands_y))
        y_band_base = float(y_band) / float(texture_bands_y - 1)
        ambient_occlusion = 1.0
        roughness = x_band_base * 0.18 + 0.12  # 0.12 - 0.3
        metallicity = y_band_base * 0.1 + 0.88  # 0.1 - 0.98
        metal_rough_pnm.set_xel(x, y, (ambient_occlusion, roughness, metallicity))
metal_rough_tex = Texture("MetalRoughness")
metal_rough_tex.load(metal_rough_pnm)
ts = TextureStage('MetalRoughness') # a.k.a. Selector
ts.set_mode(TextureStage.M_selector)
card_np.set_texture(ts, metal_rough_tex)


# Normals
# RGB is the normalized normal vector (z is perpendicular to
# the surface) * 0.5 + 0.5
normal_pnm = PNMImage(texture_size, texture_size)
for x in range(texture_size):
    for y in range(texture_size):
        v = Vec3(gauss(0, 0.2), gauss(0, 0.2), 1)
        v.normalize()
            for i, s_nxv in enumerate(reversed(nxv_values)):
                if NxV >= s_nxv:
                    index = i
                    break
            index = len(nxv_values) - index - 1
            next_index = index + 1 if index < dest_size - 1 else index

            curr_nxv = nxv_values[index]
            next_nxv = nxv_values[next_index]

            lerp_factor = (NxV - curr_nxv) / max(1e-10,
                                                 abs(next_nxv - curr_nxv))
            lerp_factor = max(0.0, min(1.0, lerp_factor))
            indices.append((index, next_index, lerp_factor))

        # Generate the final linear lut using the lerp weights
        for y in xrange(dest_h):
            for x in xrange(dest_size):
                curr_i, next_i, lerp = indices[x]
                curr_v = img.get_xel(curr_i, y)
                next_v = img.get_xel(next_i, y)
                dest.set_xel(x, y, curr_v * (1 - lerp) + next_v * lerp)

        out_name = config["out_name"].replace("{}", str(pass_index))
        dest.write(config["out_dir"] + "/" + out_name)

try:
    os.remove("scene.png")
except:
    pass
Exemple #14
0
write_diff_img = False

img_a = PNMImage(source_a)
img_b = PNMImage(source_b)

w, h = img_a.get_x_size(), img_a.get_y_size()
img_dest = PNMImage(w, h, 3)

error_scale = 10.0

total_diff = 0.0

for x in xrange(w):
    for y in xrange(h):
        val_a = img_a.get_xel(x, y)
        val_b = img_b.get_xel(x, y)

        abs_diff = (val_a - val_b) * error_scale
        r, g, b = abs(abs_diff.x), abs(abs_diff.y), abs(abs_diff.z)

        img_dest.set_xel(x, y, r, g, b)
        total_diff += r + g + b

total_diff /= float(w * h)
total_diff /= error_scale

print("Average difference: ", total_diff, " in RGB: ", total_diff * 255)

img_dest.write("difference.png")