Created
April 17, 2020 12:35
-
-
Save HurricanKai/8b220ce6cbe7c1eb805dd1b246faee98 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using Unity.Burst; | |
using Unity.Collections; | |
using Unity.Entities; | |
using Unity.Jobs; | |
using Unity.Mathematics; | |
using Unity.Transforms; | |
using UnityEngine; | |
using static Unity.Mathematics.math; | |
using float3 = Unity.Mathematics.float3; | |
using float4x4 = Unity.Mathematics.float4x4; | |
[UpdateAfter(typeof(SetupOctreeWorldSystem))] | |
[UpdateInGroup(typeof(PresentationSystemGroup))] | |
public class HERORaytracingSystem : JobComponentSystem | |
{ | |
private SetupOctreeWorldSystem _setupOctreeWorldSystem; | |
public JobHandle LastHandle; | |
[BurstCompile] | |
struct HERORaytracingJob : IJobParallelFor | |
{ | |
public NativeArray<int> Texture; | |
public int height; | |
public int width; | |
public float imageAspectRatio; | |
public float scale; | |
public float3 orig; | |
public float4x4 cameraToWorld; | |
public float3 octreeOrigin; | |
[ReadOnly] public NativeList<OctreeNode> nodes; | |
public void Execute(int index) | |
{ | |
Color32 c; | |
var i = index % width; | |
var j = index / width; | |
/*var r = (float)i / width; | |
var g = (float)j / height; | |
var b = 0.2f; | |
Texture[index] = new Color32((byte)(r * 255), (byte)(g * 255), (byte)(b * 255), 255).AsInt32(); | |
*/ | |
var x = (2 * (i + 0.5f) / width - 1) * imageAspectRatio * scale; | |
var y = (1 - 2 * (j + 0.5f) / height) * (imageAspectRatio) * scale; | |
var dir = normalize(mul(cameraToWorld, float4(x, -y, -1, 0)).xyz); | |
/*var r = HERO.Raytrace(orig, dir, octreeOrigin, nodes); | |
if (r != null) | |
c = r.Value.AsColor32(); | |
else | |
c = Color.magenta;*/ | |
c = Raytrace(orig, dir); | |
Texture[index] = c.AsInt32(); | |
// Texture[index] = ((Color32)new Color(abs(dir.x), abs(dir.y), abs(dir.z), 255)).AsInt32(); | |
} | |
private Color32 Raytrace(float3 orig1, float3 dir) | |
{ | |
const int LoD = 10000; | |
const float min = 1f / LoD; | |
const float max = LoD; | |
Color32 c = Color.grey; | |
float depth = 0; | |
const int maxIterations = LoD / 400; | |
int i = 0; | |
for (; i < maxIterations; i++) { | |
float dist = sceneSDF(orig1 + depth * dir); | |
if (dist < min) { | |
// We're inside the scene surface! | |
c = Color.white; | |
break; | |
} | |
// Move along the view ray | |
depth += dist; | |
if (depth >= max) { | |
// Gone too far; give up | |
break; | |
} | |
} | |
c.r = (byte) (((float)i / (float) maxIterations) * 255); | |
return c; | |
} | |
private static float sceneSDF(float3 p) | |
{ | |
// var c = float3(250); | |
// p = abs(((p + 0.5f * c) % c) - 0.5f * c); | |
return length(p) - 1f; | |
} | |
} | |
[InternalBufferCapacity(0)] | |
public struct CameraTexture : ISystemStateBufferElementData | |
{ | |
public int Color; | |
} | |
protected override void OnCreate() | |
{ | |
base.OnCreate(); | |
_setupOctreeWorldSystem = World.GetOrCreateSystem<SetupOctreeWorldSystem>(); | |
} | |
protected override JobHandle OnUpdate(JobHandle inputDependencies) | |
{ | |
inputDependencies.Complete(); | |
JobHandle handle = default; | |
// Ensure buffer | |
Entities | |
.WithStructuralChanges() | |
.ForEach((Entity e, in CameraComponent cc) => | |
{ | |
var size = cc.ScreenHeight * cc.ScreenWidth; | |
if (!EntityManager.HasComponent<CameraTexture>(e)) | |
{ | |
EntityManager.AddBuffer<CameraTexture>(e); | |
} | |
var buffer = EntityManager.GetBuffer<CameraTexture>(e); | |
var sizeDiff = buffer.Length - size; | |
if (sizeDiff < 0) | |
{ | |
var toAdd = sizeDiff * -1; | |
var b = new NativeArray<CameraTexture>(toAdd, Allocator.Temp); | |
buffer.AddRange(b); | |
b.Dispose(); | |
} | |
else if (sizeDiff > 0) | |
{ | |
var toRemove = sizeDiff; | |
buffer.RemoveRange(buffer.Length - toRemove, toRemove); | |
} | |
}).Run(); | |
Entities | |
.WithStructuralChanges() | |
.WithAll<CameraTexture>() | |
.WithNone<CameraComponent>().ForEach( | |
(Entity e) => | |
{ | |
EntityManager.RemoveComponent<DynamicBuffer<CameraTexture>>(e); | |
}).Run(); | |
Entities.WithoutBurst().ForEach((ref DynamicBuffer<CameraTexture> buff, in CameraComponent cc) => | |
{ | |
var height = cc.ScreenHeight; | |
var width = cc.ScreenWidth; | |
var job = new HERORaytracingJob | |
{ | |
Texture = buff.Reinterpret<int>().AsNativeArray(), | |
height = height, | |
width = width, | |
imageAspectRatio = (float)height / (float)width, | |
scale = tan(degrees(cc.FoV * 0.5f)), | |
orig = cc.Origin, | |
cameraToWorld = cc.CameraToWorld, | |
nodes = _setupOctreeWorldSystem.Octree.Nodes, | |
octreeOrigin = _setupOctreeWorldSystem.Octree.Origin, | |
}; | |
var h = job.Schedule(height * width, 64, inputDependencies); | |
handle = JobHandle.CombineDependencies(h, handle); | |
}).Run(); | |
_setupOctreeWorldSystem.AddDependency(handle); | |
LastHandle = handle; | |
return handle; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment