📄 shadingstate.java
字号:
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 + -