Skip to content

Commit

Permalink
add raw codes from tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
teamclouday committed Sep 13, 2021
1 parent 890ea5e commit c0c8cd7
Show file tree
Hide file tree
Showing 16 changed files with 248 additions and 12 deletions.
8 changes: 8 additions & 0 deletions Assets/FromTutorial.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/FromTutorial/Scripts.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using UnityEngine;
using System.Linq;
using System.Collections.Generic;

public class RayTracer : MonoBehaviour
Expand Down Expand Up @@ -90,10 +91,15 @@ private void SetShaderParameters()
new Vector4(lightDir.x, lightDir.y, lightDir.z, DirectionalLight.intensity));
RayTracingShader.SetBuffer(0, "_Spheres", _sphereBuffer);
RayTracingShader.SetFloat("_Seed", Random.value);
SetComputeBuffer("_Spheres", _sphereBuffer);
SetComputeBuffer("_MeshObjects", _meshObjectBuffer);
SetComputeBuffer("_Vertices", _vertexBuffer);
SetComputeBuffer("_Indices", _indexBuffer);
}

private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
RebuildMeshObjectBuffers();
Render(destination);
}

Expand Down Expand Up @@ -167,7 +173,7 @@ private void SetupScene()
sphere.Albedo = metal ? Vector3.zero : new Vector3(color.r, color.g, color.b);
sphere.Specular = metal ? new Vector3(color.r, color.g, color.b) : Vector3.one * 0.04f;
// set emission
bool emit = Random.value < 0.8f;
bool emit = Random.value < 0.5f;
color = Random.ColorHSV();
sphere.Emission = emit ? new Vector3(color.r, color.g, color.b) : Vector3.zero;
// set smoothness
Expand All @@ -177,4 +183,97 @@ private void SetupScene()
_sphereBuffer = new ComputeBuffer(spheres.Count, Sphere.Size);
_sphereBuffer.SetData(spheres);
}

private static bool _meshObjectsNeedRebuilding = false;
private static List<RayTracingObject> _rayTracingObjects = new List<RayTracingObject>();

public static void RegisterObject(RayTracingObject obj)
{
_rayTracingObjects.Add(obj);
_meshObjectsNeedRebuilding = true;
}

public static void UnregisterObject(RayTracingObject obj)
{
_rayTracingObjects.Remove(obj);
_meshObjectsNeedRebuilding = true;
}

private static List<MeshObject> _meshObjects = new List<MeshObject>();
private static List<Vector3> _vertices = new List<Vector3>();
private static List<int> _indices = new List<int>();
private ComputeBuffer _meshObjectBuffer;
private ComputeBuffer _vertexBuffer;
private ComputeBuffer _indexBuffer;

private void RebuildMeshObjectBuffers()
{
if (!_meshObjectsNeedRebuilding)
{
return;
}
_meshObjectsNeedRebuilding = false;
_currentSample = 0;
// Clear all lists
_meshObjects.Clear();
_vertices.Clear();
_indices.Clear();
// Loop over all objects and gather their data
foreach (RayTracingObject obj in _rayTracingObjects)
{
Debug.Log(obj);
Mesh mesh = obj.GetComponent<MeshFilter>().sharedMesh;
// Add vertex data
int firstVertex = _vertices.Count;
_vertices.AddRange(mesh.vertices);
// Add index data - if the vertex buffer wasn't empty before, the
// indices need to be offset
int firstIndex = _indices.Count;
var indices = mesh.GetIndices(0);
_indices.AddRange(indices.Select(index => index + firstVertex));
// Add the object itself
_meshObjects.Add(new MeshObject()
{
localToWorldMatrix = obj.transform.localToWorldMatrix,
indices_offset = firstIndex,
indices_count = indices.Length
});
}
CreateComputeBuffer(ref _meshObjectBuffer, _meshObjects, 72);
CreateComputeBuffer(ref _vertexBuffer, _vertices, 12);
CreateComputeBuffer(ref _indexBuffer, _indices, 4);
}

private static void CreateComputeBuffer<T>(ref ComputeBuffer buffer, List<T> data, int stride)
where T : struct
{
// Do we already have a compute buffer?
if (buffer != null)
{
// If no data or buffer doesn't match the given criteria, release it
if (data.Count == 0 || buffer.count != data.Count || buffer.stride != stride)
{
buffer.Release();
buffer = null;
}
}
if (data.Count != 0)
{
// If the buffer has been released or wasn't there to
// begin with, create it
if (buffer == null)
{
buffer = new ComputeBuffer(data.Count, stride);
}
// Set data on the buffer
buffer.SetData(data);
}
}
private void SetComputeBuffer(string name, ComputeBuffer buffer)
{
if (buffer != null)
{
RayTracingShader.SetBuffer(0, name, buffer);
}
}
}
File renamed without changes.
16 changes: 16 additions & 0 deletions Assets/FromTutorial/Scripts/RayTracingObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using UnityEngine;

[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshFilter))]
public class RayTracingObject : MonoBehaviour
{
private void OnEnable()
{
RayTracer.RegisterObject(this);
}

private void OnDisable()
{
RayTracer.UnregisterObject(this);
}
}
11 changes: 11 additions & 0 deletions Assets/FromTutorial/Scripts/RayTracingObject.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ public struct Sphere
public Vector3 Albedo;
public Vector3 Specular;
public static readonly int Size = 56; // structure size
}

public struct MeshObject
{
public Matrix4x4 localToWorldMatrix;
public int indices_offset;
public int indices_count;
}
File renamed without changes.
8 changes: 8 additions & 0 deletions Assets/FromTutorial/Shaders.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ struct Sphere

StructuredBuffer<Sphere> _Spheres;

struct MeshObject
{
float4x4 localToWorldMatrix;
int indices_offset;
int indices_count;
};

StructuredBuffer<MeshObject> _MeshObjects;
StructuredBuffer<float3> _Vertices;
StructuredBuffer<int> _Indices;

Ray CreateRay(float3 origin, float3 direction)
{
Ray ray;
Expand Down Expand Up @@ -92,10 +103,10 @@ void IntersectGroundPlane(Ray ray, inout RayHit bestHit)
bestHit.dist = t;
bestHit.pos = ray.origin + t * ray.dir;
bestHit.norm = float3(0.0, 1.0, 0.0);
bestHit.albedo = float3(0.8, 0.8, 0.8);
bestHit.specular = float3(0.1, 0.1, 0.1);
bestHit.albedo = 1.0;
bestHit.specular = 0.1;
bestHit.emission = 0.0;
bestHit.smoothness = 0.0;
bestHit.smoothness = 0.5;
}
}

Expand All @@ -121,6 +132,64 @@ void IntersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
}
}

// intersection with triangle
bool IntersectTriangle_MT97(Ray ray, float3 vert0, float3 vert1, float3 vert2,
inout float t, inout float u, inout float v)
{
// find vectors for two edges sharing vert0
float3 edge1 = vert1 - vert0;
float3 edge2 = vert2 - vert0;
// begin calculating determinant - also used to calculate U parameter
float3 pvec = cross(ray.dir, edge2);
// if determinant is near zero, ray lies in plane of triangle
float det = dot(edge1, pvec);
// use backface culling
if (det < 1e-8)
return false;
float inv_det = 1.0f / det;
// calculate distance from vert0 to ray origin
float3 tvec = ray.origin - vert0;
// calculate U parameter and test bounds
u = dot(tvec, pvec) * inv_det;
if (u < 0.0 || u > 1.0f)
return false;
// prepare to test V parameter
float3 qvec = cross(tvec, edge1);
// calculate V parameter and test bounds
v = dot(ray.dir, qvec) * inv_det;
if (v < 0.0 || u + v > 1.0f)
return false;
// calculate t, ray intersects triangle
t = dot(edge2, qvec) * inv_det;
return true;
}

void IntersectMeshObject(Ray ray, inout RayHit bestHit, MeshObject meshObject)
{
uint offset = meshObject.indices_offset;
uint count = offset + meshObject.indices_count;
for (uint i = offset; i < count; i += 3)
{
float3 v0 = (mul(meshObject.localToWorldMatrix, float4(_Vertices[_Indices[i]], 1))).xyz;
float3 v1 = (mul(meshObject.localToWorldMatrix, float4(_Vertices[_Indices[i + 1]], 1))).xyz;
float3 v2 = (mul(meshObject.localToWorldMatrix, float4(_Vertices[_Indices[i + 2]], 1))).xyz;
float t, u, v;
if (IntersectTriangle_MT97(ray, v0, v1, v2, t, u, v))
{
if (t > 0 && t < bestHit.dist)
{
bestHit.dist = t;
bestHit.pos = ray.origin + t * ray.dir;
bestHit.norm = normalize(cross(v1 - v0, v2 - v0));
bestHit.albedo = 0.0f;
bestHit.specular = 0.65f;
bestHit.smoothness = 0.99f;
bestHit.emission = 0.0f;
}
}
}
}

float3x3 GetTangentSpace(float3 normal)
{
float3 help = float3(1.0, 0.0, 0.0);
Expand Down Expand Up @@ -159,11 +228,21 @@ RayHit Trace(Ray ray)
{
RayHit bestHit = CreateRayHit();
IntersectGroundPlane(ray, bestHit);
// spheres
uint num, stride;
_Spheres.GetDimensions(num, stride);
for (uint i = 0; i < num; i++)
uint count, stride, i;
// Trace ground plane
IntersectGroundPlane(ray, bestHit);
// Trace spheres
_Spheres.GetDimensions(count, stride);
for (i = 0; i < count; i++)
{
IntersectSphere(ray, bestHit, _Spheres[i]);
}
// Trace mesh objects
_MeshObjects.GetDimensions(count, stride);
for (i = 0; i < count; i++)
{
IntersectMeshObject(ray, bestHit, _MeshObjects[i]);
}
return bestHit;
}

Expand Down Expand Up @@ -210,7 +289,7 @@ float3 Shade(inout Ray ray, RayHit hit)
{
ray.energy = 0.0;
//return 0.0;
float skyAlpha = 0.5;
float skyAlpha = 1.0;
float raySampleScale = max(max(abs(ray.dir.x), abs(ray.dir.y)), abs(ray.dir.z));
return skyAlpha * _SkyboxTexture.SampleLevel(sampler_SkyboxTexture, ray.dir / raySampleScale, 0).xyz;
}
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions Assets/Scenes/Basic.unity
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
RayTracingShader: {fileID: 7200000, guid: 937c15c591618624e9c977b3e0632c0b, type: 3}
SkyboxTexture: {fileID: 8900000, guid: e8791888d6d354b48a57b55226d8d69d, type: 2}
SkyboxTexture: {fileID: 8900000, guid: b5048f0d8dca2ee41aaf9a2aecf4fa94, type: 2}
DirectionalLight: {fileID: 1184883991}
SphereRadiusMinMax: {x: 5, y: 30}
SphereNum: 10000
SpherePlacementRadius: 100
SphereSeed: 2021
SphereSeed: 2019
--- !u!114 &465702726
MonoBehaviour:
m_ObjectHideFlags: 0
Expand All @@ -241,7 +241,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
scrollSpeed: 0.5
dragSpeed: 0.1
keySpeed: 0.2
keySpeed: 0.4
--- !u!1 &1184883990
GameObject:
m_ObjectHideFlags: 0
Expand Down

0 comments on commit c0c8cd7

Please sign in to comment.