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

📄 shadingstate.java

📁 Sunflow是一个照片级的渲染系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    public final int getRefractionDepth() {
        return refractionDepth;
    }

    /**
     * Get hit point.
     * 
     * @return hit point
     */
    public final Point3 getPoint() {
        return p;
    }

    /**
     * Get shading normal at the hit point. This may differ from the geometric
     * normal
     * 
     * @return shading normal
     */
    public final Vector3 getNormal() {
        return n;
    }

    /**
     * Get texture coordinates at the hit point.
     * 
     * @return texture coordinate
     */
    public final Point2 getUV() {
        return tex;
    }

    /**
     * Gets the geometric normal of the current hit point.
     * 
     * @return geometric normal of the current hit point
     */
    public final Vector3 getGeoNormal() {
        return ng;
    }

    /**
     * Gets the local orthonormal basis for the current hit point.
     * 
     * @return local basis or <code>null</code> if undefined
     */
    public final OrthoNormalBasis getBasis() {
        return basis;
    }

    /**
     * Define the orthonormal basis for the current hit point.
     * 
     * @param basis
     */
    public final void setBasis(OrthoNormalBasis basis) {
        this.basis = basis;
    }

    /**
     * Gets the ray that is associated with this state.
     * 
     * @return ray associated with this state.
     */
    public final Ray getRay() {
        return r;
    }

    /**
     * Get a transformation matrix that will transform camera space points into
     * world space.
     * 
     * @return camera to world transform
     */
    public final Matrix4 getCameraToWorld() {
        Camera c = server.getScene().getCamera();
        return c != null ? c.getCameraToWorld() : Matrix4.IDENTITY;
    }

    /**
     * Get a transformation matrix that will transform world space points into
     * camera space.
     * 
     * @return world to camera transform
     */
    public final Matrix4 getWorldToCamera() {
        Camera c = server.getScene().getCamera();
        return c != null ? c.getWorldToCamera() : Matrix4.IDENTITY;
    }

    /**
     * Get the three triangle corners in object space if the hit object is a
     * mesh, returns false otherwise.
     * 
     * @param p array of 3 points
     * @return <code>true</code> if the points were read succesfully,
     *         <code>false</code>otherwise
     */
    public final boolean getTrianglePoints(Point3[] p) {
        PrimitiveList prims = instance.getGeometry().getPrimitiveList();
        if (prims instanceof TriangleMesh) {
            TriangleMesh m = (TriangleMesh) prims;
            m.getPoint(primitiveID, 0, p[0] = new Point3());
            m.getPoint(primitiveID, 1, p[1] = new Point3());
            m.getPoint(primitiveID, 2, p[2] = new Point3());
            return true;
        }
        return false;
    }

    /**
     * Initialize the use of light samples. Prepares a list of visible lights
     * from the current point.
     */
    public final void initLightSamples() {
        server.initLightSamples(this);
    }

    /**
     * Add caustic samples to the current light sample set. This method does
     * nothing if caustics are not enabled.
     */
    public final void initCausticSamples() {
        server.initCausticSamples(this);
    }

    /**
     * Returns the color obtained by recursively tracing the specified ray. The
     * reflection is assumed to be glossy.
     * 
     * @param r ray to trace
     * @param i instance number of this sample
     * @return color observed along specified ray.
     */
    public final Color traceGlossy(Ray r, int i) {
        return server.traceGlossy(this, r, i);
    }

    /**
     * Returns the color obtained by recursively tracing the specified ray. The
     * reflection is assumed to be specular.
     * 
     * @param r ray to trace
     * @param i instance number of this sample
     * @return color observed along specified ray.
     */
    public final Color traceReflection(Ray r, int i) {
        return server.traceReflection(this, r, i);
    }

    /**
     * Returns the color obtained by recursively tracing the specified ray.
     * 
     * @param r ray to trace
     * @param i instance number of this sample
     * @return color observed along specified ray.
     */
    public final Color traceRefraction(Ray r, int i) {
        // this assumes the refraction ray is pointing away from the normal
        r.ox -= 0.002f * ng.x;
        r.oy -= 0.002f * ng.y;
        r.oz -= 0.002f * ng.z;
        return server.traceRefraction(this, r, i);
    }

    /**
     * Trace transparency, this is equivalent to tracing a refraction ray in the
     * incoming ray direction.
     * 
     * @return color observed behind the current shading point
     */
    public final Color traceTransparency() {
        return traceRefraction(new Ray(p.x, p.y, p.z, r.dx, r.dy, r.dz), 0);
    }

    /**
     * Trace a shadow ray against the scene, and computes the accumulated
     * opacity along the ray.
     * 
     * @param r ray to trace
     * @return opacity along the shadow ray
     */
    public final Color traceShadow(Ray r) {
        return server.getScene().traceShadow(r, istate);
    }

    /**
     * Records a photon at the specified location.
     * 
     * @param dir incoming direction of the photon
     * @param power photon power
     * @param diffuse diffuse reflectance at the given point
     */
    public final void storePhoton(Vector3 dir, Color power, Color diffuse) {
        map.store(this, dir, power, diffuse);
    }

    /**
     * Trace a new photon from the current location. This assumes that the
     * photon was reflected by a specular surface.
     * 
     * @param r ray to trace photon along
     * @param power power of the new photon
     */
    public final void traceReflectionPhoton(Ray r, Color power) {
        if (map.allowReflectionBounced())
            server.traceReflectionPhoton(this, r, power);
    }

    /**
     * Trace a new photon from the current location. This assumes that the
     * photon was refracted by a specular surface.
     * 
     * @param r ray to trace photon along
     * @param power power of the new photon
     */
    public final void traceRefractionPhoton(Ray r, Color power) {
        if (map.allowRefractionBounced()) {
            // this assumes the refraction ray is pointing away from the normal
            r.ox -= 0.002f * ng.x;
            r.oy -= 0.002f * ng.y;
            r.oz -= 0.002f * ng.z;
            server.traceRefractionPhoton(this, r, power);
        }
    }

    /**
     * Trace a new photon from the current location. This assumes that the
     * photon was reflected by a diffuse surface.
     * 
     * @param r ray to trace photon along
     * @param power power of the new photon
     */
    public final void traceDiffusePhoton(Ray r, Color power) {
        if (map.allowDiffuseBounced())
            server.traceDiffusePhoton(this, r, power);
    }

    /**
     * Returns the glboal diffuse radiance estimate given by the current
     * {@link GIEngine} if present.
     * 
     * @return global diffuse radiance estimate
     */
    public final Color getGlobalRadiance() {
        return server.getGlobalRadiance(this);
    }

    /**
     * Gets the total irradiance reaching the current point from diffuse
     * surfaces.
     * 
     * @param diffuseReflectance diffuse reflectance at the current point, can
     *            be used for importance tracking
     * @return indirect diffuse irradiance reaching the point
     */
    public final Color getIrradiance(Color diffuseReflectance) {
        return server.getIrradiance(this, diffuseReflectance);
    }

    /**
     * Trace a final gather ray and return the intersection result as a new
     * render state
     * 
     * @param r ray to shoot
     * @param i instance of the ray
     * @return new render state object corresponding to the intersection result
     */
    public final ShadingState traceFinalGather(Ray r, int i) {
        return server.traceFinalGather(this, r, i);
    }

    /**
     * Simple black and white ambient occlusion.
     * 
     * @param samples number of sample rays
     * @param maxDist maximum length of the rays
     * @return occlusion color
     */
    public final Color occlusion(int samples, float maxDist) {
        return occlusion(samples, maxDist, Color.WHITE, Color.BLACK);
    }

    /**
     * Ambient occlusion routine, returns a value between bright and dark
     * depending on the amount of geometric occlusion in the scene.
     * 
     * @param samples number of sample rays
     * @param maxDist maximum length of the rays
     * @param bright color when nothing is occluded
     * @param dark color when fully occluded
     * @return occlusion color
     */
    public final Color occlusion(int samples, float maxDist, Color bright, Color dark) {
        if (n == null) {
            // in case we got called on a geometry without orientation
            return bright;
        }
        // make sure we are on the right side of the material
        faceforward();
        OrthoNormalBasis onb = getBasis();
        Vector3 w = new Vector3();
        Color result = Color.black();
        for (int i = 0; i < samples; i++) {
            float xi = (float) getRandom(i, 0, samples);
            float xj = (float) getRandom(i, 1, samples);
            float phi = (float) (2 * Math.PI * xi);
            float cosPhi = (float) Math.cos(phi);
            float sinPhi = (float) Math.sin(phi);
            float sinTheta = (float) Math.sqrt(xj);
            float cosTheta = (float) Math.sqrt(1.0f - xj);
            w.x = cosPhi * sinTheta;
            w.y = sinPhi * sinTheta;
            w.z = cosTheta;
            onb.transform(w);
            Ray r = new Ray(p, w);
            r.setMax(maxDist);
            result.add(Color.blend(bright, dark, traceShadow(r)));
        }
        return result.mul(1.0f / samples);
    }

    /**
     * Computes a plain diffuse response to the current light samples and global
     * illumination.
     * 
     * @param diff diffuse color
     * @return shaded result
     */
    public final Color diffuse(Color diff) {
        // integrate a diffuse function
        Color lr = Color.black();
        if (diff.isBlack())
            return lr;
        for (LightSample sample : this)
            lr.madd(sample.dot(n), sample.getDiffuseRadiance());
        lr.add(getIrradiance(diff));
        return lr.mul(diff).mul(1.0f / (float) Math.PI);
    }

    /**
     * Computes a phong specular response to the current light samples and
     * global illumination.
     * 
     * @param spec specular color
     * @param power phong exponent
     * @param numRays number of glossy rays to trace
     * @return shaded color
     */
    public final Color specularPhong(Color spec, float power, int numRays) {
        // integrate a phong specular function
        Color lr = Color.black();
        if (!includeSpecular || spec.isBlack())
            return lr;
        // reflected direction
        float dn = 2 * cosND;
        Vector3 refDir = new Vector3();
        refDir.x = (dn * n.x) + r.dx;
        refDir.y = (dn * n.y) + r.dy;
        refDir.z = (dn * n.z) + r.dz;
        // direct lighting
        for (LightSample sample : this) {
            float cosNL = sample.dot(n);
            float cosLR = sample.dot(refDir);
            if (cosLR > 0)
                lr.madd(cosNL * (float) Math.pow(cosLR, power), sample.getSpecularRadiance());
        }
        // indirect lighting
        if (numRays > 0) {
            int numSamples = getDepth() == 0 ? numRays : 1;
            OrthoNormalBasis onb = OrthoNormalBasis.makeFromW(refDir);
            float mul = (2.0f * (float) Math.PI / (power + 1)) / numSamples;
            for (int i = 0; i < numSamples; i++) {
                // specular indirect lighting
                double r1 = getRandom(i, 0, numSamples);
                double r2 = getRandom(i, 1, numSamples);
                double u = 2 * Math.PI * r1;
                double s = (float) Math.pow(r2, 1 / (power + 1));
                double s1 = (float) Math.sqrt(1 - s * s);
                Vector3 w = new Vector3((float) (Math.cos(u) * s1), (float) (Math.sin(u) * s1), (float) s);
                w = onb.transform(w, new Vector3());
                float wn = Vector3.dot(w, n);
                if (wn > 0)
                    lr.madd(wn * mul, traceGlossy(new Ray(p, w), i));
            }
        }
        lr.mul(spec).mul((power + 2) / (2.0f * (float) Math.PI));
        return lr;
    }

    /**
     * Allows iteration over current light samples.
     */
    public Iterator<LightSample> iterator() {
        return new LightSampleIterator(lightSample);
    }

    private static class LightSampleIterator implements Iterator<LightSample> {
        private LightSample current;

        LightSampleIterator(LightSample head) {
            current = head;
        }

        public boolean hasNext() {
            return current != null;
        }

        public LightSample next() {
            LightSample c = current;
            current = current.next;
            return c;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

⌨️ 快捷键说明

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