⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texture.java

📁 Sunflow是一个照片级的渲染系统
💻 JAVA
字号:
package org.sunflow.core;

import java.io.IOException;

import org.sunflow.image.Bitmap;
import org.sunflow.image.Color;
import org.sunflow.math.OrthoNormalBasis;
import org.sunflow.math.Vector3;
import org.sunflow.system.UI;
import org.sunflow.system.UI.Module;

/**
 * Represents a 2D texture, typically used by {@link Shader shaders}.
 */
public class Texture {
    private String filename;
    private boolean isLinear;
    private Bitmap bitmap;
    private int loaded;

    /**
     * Creates a new texture from the specfied file.
     * 
     * @param filename image file to load
     * @param isLinear is the texture gamma corrected already?
     */
    Texture(String filename, boolean isLinear) {
        this.filename = filename;
        this.isLinear = isLinear;
        loaded = 0;
    }

    private synchronized void load() {
        if (loaded != 0)
            return;
        try {
            UI.printInfo(Module.TEX, "Reading texture bitmap from: \"%s\" ...", filename);
            bitmap = new Bitmap(filename, isLinear);
            if (bitmap.getWidth() == 0 || bitmap.getHeight() == 0)
                bitmap = null;
        } catch (IOException e) {
            UI.printError(Module.TEX, "%s", e.getMessage());
        }
        loaded = 1;
    }

    public Bitmap getBitmap() {
        if (loaded == 0)
            load();
        return bitmap;
    }

    /**
     * Gets the color at location (x,y) in the texture. The lookup is performed
     * using the fractional component of the coordinates, treating the texture
     * as a unit square tiled in both directions. Bicubic filtering is performed
     * on the four nearest pixels to the lookup point.
     * 
     * @param x x coordinate into the texture
     * @param y y coordinate into the texture
     * @return filtered color at location (x,y)
     */
    public Color getPixel(float x, float y) {
        Bitmap bitmap = getBitmap();
        if (bitmap == null)
            return Color.BLACK;
        x = x - (int) x;
        y = y - (int) y;
        if (x < 0)
            x++;
        if (y < 0)
            y++;
        float dx = (float) x * (bitmap.getWidth() - 1);
        float dy = (float) y * (bitmap.getHeight() - 1);
        int ix0 = (int) dx;
        int iy0 = (int) dy;
        int ix1 = (ix0 + 1) % bitmap.getWidth();
        int iy1 = (iy0 + 1) % bitmap.getHeight();
        float u = dx - ix0;
        float v = dy - iy0;
        u = u * u * (3.0f - (2.0f * u));
        v = v * v * (3.0f - (2.0f * v));
        float k00 = (1.0f - u) * (1.0f - v);
        Color c00 = bitmap.getPixel(ix0, iy0);
        float k01 = (1.0f - u) * v;
        Color c01 = bitmap.getPixel(ix0, iy1);
        float k10 = u * (1.0f - v);
        Color c10 = bitmap.getPixel(ix1, iy0);
        float k11 = u * v;
        Color c11 = bitmap.getPixel(ix1, iy1);
        Color c = Color.mul(k00, c00);
        c.madd(k01, c01);
        c.madd(k10, c10);
        c.madd(k11, c11);
        return c;
    }

    public Vector3 getNormal(float x, float y, OrthoNormalBasis basis) {
        float[] rgb = getPixel(x, y).getRGB();
        return basis.transform(new Vector3(2 * rgb[0] - 1, 2 * rgb[1] - 1, 2 * rgb[2] - 1)).normalize();
    }

    public Vector3 getBump(float x, float y, OrthoNormalBasis basis, float scale) {
        Bitmap bitmap = getBitmap();
        if (bitmap == null)
            return basis.transform(new Vector3(0, 0, 1));
        float dx = 1.0f / (bitmap.getWidth() - 1);
        float dy = 1.0f / (bitmap.getHeight() - 1);
        float b0 = getPixel(x, y).getLuminance();
        float bx = getPixel(x + dx, y).getLuminance();
        float by = getPixel(x, y + dy).getLuminance();
        return basis.transform(new Vector3(scale * (bx - b0) / dx, scale * (by - b0) / dy, 1)).normalize();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -