-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[wip] Initial extraction of scalar rt math #88
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
using System.Runtime.CompilerServices; | ||
using Raytracer.Geometry.Base.Geometries; | ||
using Raytracer.Geometry.Base.Hitable; | ||
using Raytracer.Geometry.Base.Models; | ||
using Raytracer.Geometry.Scenes; | ||
using Raytracer.Geometry.Utils; | ||
|
||
namespace Raytracer.Math | ||
{ | ||
public static class ScalarRayTracerMath | ||
{ | ||
public const int MaxDepth = 5; | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] | ||
public static Vec3 Point( | ||
in int x, | ||
in int y, | ||
in float width, | ||
in float height, | ||
in float halfWidth, | ||
in float halfHeight, | ||
in Camera cam) | ||
{ | ||
var recenterX = (x - halfWidth) / 2.0f / width; | ||
var recenterY = -(y - halfHeight) / 2.0f / height; | ||
|
||
return GeometryMath.Norm(cam.Forward + (recenterX * cam.Right + recenterY * cam.Up)); | ||
} | ||
|
||
public static Optional<Intersection> Intersect(in Ray ray, in MyScene scene) | ||
{ | ||
var closestDist = float.MaxValue; | ||
var closestInter = new Optional<Intersection>(); | ||
|
||
foreach (var thing in scene.Things) | ||
{ | ||
var inter = thing.Intersect(ray); | ||
if (inter.HasValue && inter.Value.Distance < closestDist) | ||
{ | ||
closestDist = inter.Value.Distance; | ||
closestInter = inter; | ||
} | ||
} | ||
|
||
return closestInter; | ||
} | ||
|
||
public static Optional<float> TestRay(in Ray ray, MyScene scene) | ||
{ | ||
var intersection = Intersect(ray, scene); | ||
return intersection.HasValue | ||
? new Optional<float>(intersection.Value.Distance) | ||
: new Optional<float>(); | ||
} | ||
|
||
public static Color TraceRay(in Ray ray, MyScene scene, int depth) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To publiczne zostawiłbym + point, reszta private ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jak nie będą potrzebne to można There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, to zrobię #87 i zobaczymy |
||
{ | ||
var intersection = Intersect(ray, scene); | ||
return intersection.HasValue | ||
? Shade(intersection.Value, scene, depth) | ||
: Color.Background; | ||
} | ||
|
||
|
||
public static Color Shade(in Intersection intersection, MyScene scene, int depth) | ||
{ | ||
var d = intersection.Ray.Direction; | ||
var pos = (intersection.Distance * d) + intersection.Ray.Start; | ||
var normal = intersection.Thing.Normal(pos); | ||
var reflectDir = d - (2.0f * GeometryMath.Dot(normal, d) * normal); | ||
var naturalColor = Color.Background + NaturalColor(intersection.Thing, pos, normal, reflectDir, scene); | ||
var reflectedColor = depth >= MaxDepth | ||
? Color.Gray | ||
: ReflectionColor(intersection.Thing, pos, reflectDir, scene, depth); | ||
return naturalColor + reflectedColor; | ||
} | ||
|
||
public static Color ReflectionColor(IHitable thing, in Vec3 pos, in Vec3 rd, MyScene scene, int depth) | ||
{ | ||
return GeometryMath.Scale( | ||
thing.Surface.Reflect(pos), | ||
TraceRay(new Ray(pos, rd), scene, depth + 1) | ||
); | ||
} | ||
|
||
public static Color AddLight(IHitable thing, in Vec3 pos, in Vec3 normal, in Vec3 rayDir, MyScene scene, | ||
Color col, | ||
Light light) | ||
{ | ||
var lightDir = light.Position - pos; | ||
var lightDirNorm = GeometryMath.Norm(lightDir); | ||
var nearIntersection = TestRay(new Ray(pos, lightDirNorm), scene); | ||
var isInShadow = nearIntersection.HasValue && nearIntersection.Value < GeometryMath.Mag(lightDir); | ||
if (isInShadow) return col; | ||
|
||
var illumination = GeometryMath.Dot(lightDirNorm, normal); | ||
var lightColor = illumination > 0.0f | ||
? GeometryMath.Scale(illumination, light.Color) | ||
: Color.DefaultColor; | ||
var specular = GeometryMath.Dot(lightDirNorm, GeometryMath.Norm(rayDir)); | ||
var surf = thing.Surface; | ||
var specularColor = specular > 0.0f | ||
? GeometryMath.Scale(GeometryMath.Pow(specular, surf.Roughness), light.Color) | ||
: Color.DefaultColor; | ||
|
||
return col + (surf.Diffuse(pos) * lightColor + surf.Specular(pos) * specularColor); | ||
} | ||
|
||
public static Color NaturalColor(IHitable thing, in Vec3 pos, in Vec3 norm, in Vec3 rd, MyScene scene) | ||
{ | ||
var col = Color.DefaultColor; | ||
foreach (var light in scene.Lights) | ||
col = AddLight(thing, pos, norm, rd, scene, col, light); | ||
return col; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nie wiem czy dzielenie przez 2 jest tutaj tak kosztowne, żeby to przesyłać wyliczone... wysyłałbym tylko
width
iheight