Add refraction capabilities to RayTracerSimple

This commit is contained in:
Petar Kapriš 2022-12-27 15:54:16 +01:00 committed by Петар Каприш
parent 49284dfcf8
commit 8b512a5604
2 changed files with 31 additions and 2 deletions

View file

@ -74,6 +74,33 @@ public class RayTracerSimple extends RayTracer {
Color lightReflected = sample(Ray.pd(p, r), depthRemaining - 1);
result = result.add(material.reflective().mul(lightReflected));
}
if (material.refractive().notZero()) {
Vec3 b; // refracted light vector
double rInd = 1/material.refractiveIndex();
double iCosN = i.dot(n_);
if (iCosN < 0) {
rInd = 1/rInd;
}
Vec3 iProjection = n_.mul(iCosN);
Vec3 iRejection = i.sub(iProjection);
double iSinSqr = iRejection.lengthSquared()/i.lengthSquared();
double bSinSqr = iSinSqr*rInd*rInd;
if (bSinSqr > 1) {
b = r;
} else {
Vec3 bRejection = iRejection.inverse();
Vec3 bProjection = n_.mul(Math.sqrt(bRejection.lengthSquared()*(1-bSinSqr)/bSinSqr));
if (iCosN > 0) {
bProjection = bProjection.inverse();
}
b = bRejection.add(bProjection);
}
Color lightRefracted = sample(Ray.pd(p, b), depthRemaining - 1);
result = result.add(material.refractive().mul(lightRefracted));
}
return result;
}

View file

@ -8,7 +8,7 @@ import xyz.marsavic.gfxlab.graphics3d.Affine;
import xyz.marsavic.gfxlab.graphics3d.cameras.Perspective;
import xyz.marsavic.gfxlab.graphics3d.cameras.TransformedCamera;
import xyz.marsavic.gfxlab.graphics3d.raytracers.RayTracerSimple;
import xyz.marsavic.gfxlab.graphics3d.scene.DiscoRoom;
import xyz.marsavic.gfxlab.graphics3d.scene.RefractionTest;
import xyz.marsavic.gfxlab.gui.UtilsGL;
import xyz.marsavic.gfxlab.tonemapping.ColorTransform;
import xyz.marsavic.gfxlab.tonemapping.ToneMapping;
@ -34,10 +34,12 @@ public class GfxLab {
// e(Blobs::new, val(5), val(0.1), val(0.2)),
e(RayTracerSimple::new,
// e(RefractionTest::new),
e(DiscoRoom::new, val(16), val(16), val(0x3361EB272FEA4C62L)),
// e(DiscoRoom::new, val(16), val(16), val(0x3361EB272FEA4C62L)),
e(RefractionTest::new),
// e(Mirrors::new, val(3)),
e(TransformedCamera::new,
e(Perspective::new, val(1.0/3)),
// e(Orthographic::new),
e(Affine.IDENTITY
.then(Affine.translation(Vec3.xyz(0, 0, -4)))
// .then(Affine.rotationAboutY(0.03))