📄 directionalspotlight.java
字号:
package org.sunflow.core.light;
import org.sunflow.SunflowAPI;
import org.sunflow.core.LightSample;
import org.sunflow.core.LightSource;
import org.sunflow.core.ParameterList;
import org.sunflow.core.Ray;
import org.sunflow.core.ShadingState;
import org.sunflow.image.Color;
import org.sunflow.math.OrthoNormalBasis;
import org.sunflow.math.Point3;
import org.sunflow.math.Vector3;
public class DirectionalSpotlight implements LightSource {
private Point3 src;
private Vector3 dir;
private OrthoNormalBasis basis;
private float r, r2;
private Color radiance;
public DirectionalSpotlight() {
src = new Point3(0, 0, 0);
dir = new Vector3(0, 0, -1);
dir.normalize();
basis = OrthoNormalBasis.makeFromW(dir);
r = 1;
r2 = r * r;
radiance = Color.WHITE;
}
public boolean update(ParameterList pl, SunflowAPI api) {
src = pl.getPoint("source", src);
dir = pl.getVector("dir", dir);
dir.normalize();
r = pl.getFloat("radius", r);
basis = OrthoNormalBasis.makeFromW(dir);
r2 = r * r;
radiance = pl.getColor("radiance", radiance);
return true;
}
public int getNumSamples() {
return 1;
}
public int getLowSamples() {
return 1;
}
public void getSamples(ShadingState state) {
if (Vector3.dot(dir, state.getGeoNormal()) < 0 && Vector3.dot(dir, state.getNormal()) < 0) {
// project point onto source plane
float x = state.getPoint().x - src.x;
float y = state.getPoint().y - src.y;
float z = state.getPoint().z - src.z;
float t = ((x * dir.x) + (y * dir.y) + (z * dir.z));
if (t >= 0.0) {
x -= (t * dir.x);
y -= (t * dir.y);
z -= (t * dir.z);
if (((x * x) + (y * y) + (z * z)) <= r2) {
Point3 p = new Point3();
p.x = src.x + x;
p.y = src.y + y;
p.z = src.z + z;
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), p));
dest.setRadiance(radiance, radiance);
dest.traceShadow(state);
state.addSample(dest);
}
}
}
}
public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power) {
float phi = (float) (2 * Math.PI * randX1);
float s = (float) Math.sqrt(1.0f - randY1);
dir.x = r * (float) Math.cos(phi) * s;
dir.y = r * (float) Math.sin(phi) * s;
dir.z = 0;
basis.transform(dir);
Point3.add(src, dir, p);
dir.set(this.dir);
power.set(radiance).mul((float) Math.PI * r2);
}
public float getPower() {
return radiance.copy().mul((float) Math.PI * r2).getLuminance();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -