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

📄 shadingstate.java

📁 Sunflow是一个照片级的渲染系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.sunflow.core;

import java.util.Iterator;

import org.sunflow.core.primitive.TriangleMesh;
import org.sunflow.image.Color;
import org.sunflow.math.Matrix4;
import org.sunflow.math.OrthoNormalBasis;
import org.sunflow.math.Point2;
import org.sunflow.math.Point3;
import org.sunflow.math.QMC;
import org.sunflow.math.Vector3;

/**
 * Represents a point to be shaded and provides various options for the shading
 * of this point, including spawning of new rays.
 */
public final class ShadingState implements Iterable<LightSample> {
    private IntersectionState istate;
    private LightServer server;
    private float rx, ry;
    private Color result;
    private Point3 p;
    private Vector3 n;
    private Point2 tex;
    private Vector3 ng;
    private OrthoNormalBasis basis;
    private float cosND;
    private boolean behind;
    private float hitU, hitV;
    private Instance instance;
    private int primitiveID;
    private Ray r;
    private int d; // quasi monte carlo instance variables
    private int i; // quasi monte carlo instance variables
    private double qmcD0I;
    private double qmcD1I;
    private Shader shader;
    private Modifier modifier;
    private int diffuseDepth;
    private int reflectionDepth;
    private int refractionDepth;
    private boolean includeLights;
    private boolean includeSpecular;
    private LightSample lightSample;
    private PhotonStore map;

    static ShadingState createPhotonState(Ray r, IntersectionState istate, int i, PhotonStore map, LightServer server) {
        ShadingState s = new ShadingState(null, istate, r, i, 4);
        s.server = server;
        s.map = map;
        return s;

    }

    static ShadingState createState(IntersectionState istate, float rx, float ry, Ray r, int i, LightServer server) {
        ShadingState s = new ShadingState(null, istate, r, i, 4);
        s.server = server;
        s.rx = rx;
        s.ry = ry;
        return s;
    }

    static ShadingState createDiffuseBounceState(ShadingState previous, Ray r, int i) {
        ShadingState s = new ShadingState(previous, previous.istate, r, i, 2);
        s.diffuseDepth++;
        return s;
    }

    static ShadingState createGlossyBounceState(ShadingState previous, Ray r, int i) {
        ShadingState s = new ShadingState(previous, previous.istate, r, i, 2);
        s.includeLights = false;
        s.includeSpecular = false;
        s.reflectionDepth++;
        return s;
    }

    static ShadingState createReflectionBounceState(ShadingState previous, Ray r, int i) {
        ShadingState s = new ShadingState(previous, previous.istate, r, i, 2);
        s.reflectionDepth++;
        return s;
    }

    static ShadingState createRefractionBounceState(ShadingState previous, Ray r, int i) {
        ShadingState s = new ShadingState(previous, previous.istate, r, i, 2);
        s.refractionDepth++;
        return s;
    }

    static ShadingState createFinalGatherState(ShadingState state, Ray r, int i) {
        ShadingState finalGatherState = new ShadingState(state, state.istate, r, i, 2);
        finalGatherState.diffuseDepth++;
        finalGatherState.includeLights = false;
        finalGatherState.includeSpecular = false;
        return finalGatherState;
    }

    private ShadingState(ShadingState previous, IntersectionState istate, Ray r, int i, int d) {
        this.r = r;
        this.istate = istate;
        this.i = i;
        this.d = d;
        this.instance = istate.instance; // local copy
        this.primitiveID = istate.id;
        this.hitU = istate.u;
        this.hitV = istate.v;
        if (previous == null) {
            diffuseDepth = 0;
            reflectionDepth = 0;
            refractionDepth = 0;
        } else {
            diffuseDepth = previous.diffuseDepth;
            reflectionDepth = previous.reflectionDepth;
            refractionDepth = previous.refractionDepth;
            this.server = previous.server;
            this.map = previous.map;
            this.rx = previous.rx;
            this.ry = previous.ry;
            this.i += previous.i;
            this.d += previous.d;
        }
        behind = false;
        cosND = Float.NaN;
        includeLights = includeSpecular = true;
        qmcD0I = QMC.halton(this.d, this.i);
        qmcD1I = QMC.halton(this.d + 1, this.i);
        result = null;
    }

    final void setRay(Ray r) {
        this.r = r;
    }

    /**
     * Create objects needed for surface shading: point, normal, texture
     * coordinates and basis.
     */
    public final void init() {
        p = new Point3();
        n = new Vector3();
        tex = new Point2();
        ng = new Vector3();
        basis = null;
    }

    /**
     * Run the shader at this surface point.
     * 
     * @return shaded result
     */
    public final Color shade() {
        return server.shadeHit(this);
    }

    final void correctShadingNormal() {
        // correct shading normals pointing the wrong way
        if (Vector3.dot(n, ng) < 0) {
            n.negate();
            basis.flipW();
        }
    }

    /**
     * Flip the surface normals to ensure they are facing the current ray. This
     * method also offsets the shading point away from the surface so that new
     * rays will not intersect the same surface again by mistake.
     */
    public final void faceforward() {
        // make sure we are on the right side of the material
        if (r.dot(ng) < 0) {
        } else {
            // this ensure the ray and the geomtric normal are pointing in the
            // same direction
            ng.negate();
            n.negate();
            basis.flipW();
            behind = true;
        }
        cosND = Math.max(-r.dot(n), 0); // can't be negative
        // offset the shaded point away from the surface to prevent
        // self-intersection errors
        p.x += 0.001f * ng.x;
        p.y += 0.001f * ng.y;
        p.z += 0.001f * ng.z;
    }

    /**
     * Get x coordinate of the pixel being shaded.
     * 
     * @return pixel x coordinate
     */
    public final float getRasterX() {
        return rx;
    }

    /**
     * Get y coordinate of the pixel being shaded.
     * 
     * @return pixel y coordinate
     */
    public final float getRasterY() {
        return ry;
    }

    /**
     * Cosine between the shading normal and the ray. This is set by
     * {@link #faceforward()}.
     * 
     * @return cosine between shading normal and the ray
     */
    public final float getCosND() {
        return cosND;
    }

    /**
     * Returns true if the ray hit the surface from behind. This is set by
     * {@link #faceforward()}.
     * 
     * @return <code>true</code> if the surface was hit from behind.
     */
    public final boolean isBehind() {
        return behind;
    }

    final IntersectionState getIntersectionState() {
        return istate;
    }

    /**
     * Get u barycentric coordinate of the intersection point.
     * 
     * @return u barycentric coordinate
     */
    public final float getU() {
        return hitU;
    }

    /**
     * Get v barycentric coordinate of the intersection point.
     * 
     * @return v barycentric coordinate
     */
    public final float getV() {
        return hitV;
    }

    /**
     * Get the instance which was intersected
     * 
     * @return intersected instance object
     */
    public final Instance getInstance() {
        return instance;
    }

    /**
     * Get the primitive ID which was intersected
     * 
     * @return intersected primitive ID
     */
    public final int getPrimitiveID() {
        return primitiveID;
    }

    final void setResult(Color c) {
        result = c;
    }

    /**
     * Get the result of shading this point
     * 
     * @return shaded result
     */
    public final Color getResult() {
        return result;
    }

    final LightServer getLightServer() {
        return server;
    }

    /**
     * Add the specified light sample to the list of lights to be used
     * 
     * @param sample a valid light sample
     */
    public final void addSample(LightSample sample) {
        // add to list
        sample.next = lightSample;
        lightSample = sample;
    }

    /**
     * Get a QMC sample from an infinite sequence.
     * 
     * @param j sample number (starts from 0)
     * @param dim dimension to sample
     * @return pseudo-random value in [0,1)
     */
    public final double getRandom(int j, int dim) {
        switch (dim) {
            case 0:
                return QMC.mod1(qmcD0I + QMC.halton(0, j));
            case 1:
                return QMC.mod1(qmcD1I + QMC.halton(1, j));
            default:
                return QMC.mod1(QMC.halton(d + dim, i) + QMC.halton(dim, j));
        }
    }

    /**
     * Get a QMC sample from a finite sequence of n elements. This provides
     * better stratification than the infinite version, but does not allow for
     * adaptive sampling.
     * 
     * @param j sample number (starts from 0)
     * @param dim dimension to sample
     * @param n number of samples
     * @return pseudo-random value in [0,1)
     */
    public final double getRandom(int j, int dim, int n) {
        switch (dim) {
            case 0:
                return QMC.mod1(qmcD0I + (double) j / (double) n);
            case 1:
                return QMC.mod1(qmcD1I + QMC.halton(0, j));
            default:
                return QMC.mod1(QMC.halton(d + dim, i) + QMC.halton(dim - 1, j));
        }
    }

    /**
     * Checks to see if the shader should include emitted light.
     * 
     * @return <code>true</code> if emitted light should be included,
     *         <code>false</code> otherwise
     */
    public final boolean includeLights() {
        return includeLights;
    }

    /**
     * Checks to see if the shader should include specular terms.
     * 
     * @return <code>true</code> if specular terms should be included,
     *         <code>false</code> otherwise
     */
    public final boolean includeSpecular() {
        return includeSpecular;
    }

    /**
     * Get the shader to be used to shade this surface.
     * 
     * @return shader to be used
     */
    public final Shader getShader() {
        return shader;
    }

    /**
     * Record which shader should be executed for the intersected surface.
     * 
     * @param shader surface shader to use to shade the current intersection
     *            point
     */
    public final void setShader(Shader shader) {
        this.shader = shader;
    }

    final Modifier getModifier() {
        return modifier;
    }

    /**
     * Record which modifier should be applied to the intersected surface
     * 
     * @param modifier modifier to use the change this shading state
     */
    public final void setModifier(Modifier modifier) {
        this.modifier = modifier;
    }

    /**
     * Get the current total tracing depth. First generation rays have a depth
     * of 0.
     * 
     * @return current tracing depth
     */
    public final int getDepth() {
        return diffuseDepth + reflectionDepth + refractionDepth;
    }

    /**
     * Get the current diffuse tracing depth. This is the number of diffuse
     * surfaces reflected from.
     * 
     * @return current diffuse tracing depth
     */
    public final int getDiffuseDepth() {
        return diffuseDepth;
    }

    /**
     * Get the current reflection tracing depth. This is the number of specular
     * surfaces reflected from.
     * 
     * @return current reflection tracing depth
     */
    public final int getReflectionDepth() {
        return reflectionDepth;
    }

    /**
     * Get the current refraction tracing depth. This is the number of specular
     * surfaces refracted from.
     * 
     * @return current refraction tracing depth
     */

⌨️ 快捷键说明

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