private void CreateLight(RayTracingObject robj) { GameObject lightObj = new GameObject(); lightObj.transform.position = robj.pos; Light lightComp = lightObj.AddComponent <Light>(); lightComp.color = new Color(robj.lightColor.x, robj.lightColor.y, robj.lightColor.z); if (robj.l_type == LightType.point) { lightComp.type = UnityEngine.LightType.Point; lightObj.name = "PointLight"; _lightObjects[lightObj] = robj; } else if (robj.l_type == LightType.area) { lightComp.type = UnityEngine.LightType.Area; lightObj.name = "AreaLight"; lightComp.areaSize = new Vector2(robj.whrInfo.x, robj.whrInfo.y); _lightObjects[lightObj] = robj; } else { print("Create Light Object Failed!"); } }
private void CreateLight(RayTracingObject rObj) { GameObject lightObj = new GameObject(); lightObj.transform.position = rObj.pos; Light lightComp = lightObj.AddComponent <Light>(); lightComp.color = new Color(rObj.lightColor.x, rObj.lightColor.y, rObj.lightColor.z); switch (rObj.l_type) { case LightType.point: lightComp.type = UnityEngine.LightType.Point; lightObj.name = "PointLight"; _lightObjects[lightObj] = rObj; break; case LightType.area: lightComp.type = UnityEngine.LightType.Area; lightComp.name = "AreaLight"; lightComp.areaSize = new Vector2(rObj.whrInfo.x, rObj.whrInfo.y); _lightObjects[lightObj] = rObj; break; default: print("Create Line Object Failed !"); break; } }
private Vector3[] SampleLightPoint(RayTracingObject robj) { Vector3[] points = null; if (robj.l_type == LightType.point) { points = new Vector3[1]; points[0] = robj.pos; } else if (robj.l_type == LightType.area) { float width = robj.whrInfo.x; //x axis float height = robj.whrInfo.y; //y axis int sample = robj.nsample; points = new Vector3[sample * sample]; Vector3 leftTopPos = new Vector3(robj.pos.x - 0.5f * width, robj.pos.y - 0.5f * height, robj.pos.z); Vector2 ratio = new Vector2(width / sample, height / sample); for (int w = 0; w < sample; w++) { for (int h = 0; h < sample; h++) { points[w * sample + h] = new Vector3(leftTopPos.x + ratio.x * (w + 0.5f), leftTopPos.y + ratio.y * (h + 0.5f), robj.pos.z); } } } return(points); }
public static RayTracingObject ConvertSprite(SpriteRT sprite) { int r = sprite.TextureDimensions; float2 center = new float2(sprite.posMin) + new float2(r, r); RayTracingObject rt = new RayTracingObject(new float3(center.x, center.y, sprite.depth), r, 1, float3.zero, new float3(0.3f), 0.5f, new float3(0.0f), sprite.TextureIndex); return(rt); }
public static void UnregisterObject(RayTracingObject obj) { if (!(obj is RayTracingSphere)) { _rayTracingMeshs.Remove(obj); _meshObjectsNeedRebuilding = true; } else { _rayTracingSpheres.Remove((RayTracingSphere)obj); _rayTracingObjectToSphere.Remove((RayTracingSphere)obj); } }
// -------------------------------------------------------- // objs public static void RegisterObj(RayTracingObject obj) { if (_rayTracingObjs == null) { return; } if (obj != null) { _rayTracingObjs.Add(obj); _meshObjsNeedRebuilding = true; } }
public static void RegisterObject(RayTracingObject obj) { if (!(obj is RayTracingSphere)) { _rayTracingMeshs.Add(obj); _meshObjectsNeedRebuilding = true; } else { _rayTracingSpheres.Add((RayTracingSphere)obj); Sphere sphere = new Sphere(); _rayTracingObjectToSphere.Add((RayTracingSphere)obj, sphere); } }
private void RebuildMeshObjBuffers() { if (!_meshObjsNeedRebuilding) { return; } _meshObjsNeedRebuilding = false; _curSample = 0; _meshObjs.Clear(); _vertices.Clear(); _indices.Clear(); for (int i = 0; i < _rayTracingObjs.Count; i++) { RayTracingObject obj = _rayTracingObjs[i]; Mesh mesh = obj.GetMesh(); int firstVertex = _vertices.Count; _vertices.AddRange(mesh.vertices); int firstIndex = _indices.Count; var indices = mesh.GetIndices(0); _indices.AddRange(indices.Select(index => index + firstVertex)); _meshObjs.Add(new MeshObj() { local2WorldMatrix = obj.transform.localToWorldMatrix, indices_offset = firstIndex, indices_count = indices.Length }); } // create CreateComputeBuffer(ref _meshObjBuffer, _meshObjs, 72); CreateComputeBuffer(ref _vertexBuffer, _vertices, 12); CreateComputeBuffer(ref _indexBuffer, _indices, 4); }
private void CheckShadowRay(ref Ray ray, ref RaycastHit hit, ref Color albedo) { foreach (GameObject lObj in _lightObjects.Keys) { RayTracingObject lightObj = _lightObjects[lObj]; RayTracingObject hitObject = _objects[hit.transform.gameObject]; Vector3[] lightSamplePoint = SampleLightPoint(lightObj); foreach (Vector3 lightPos in lightSamplePoint) { if (!isInShadow(lightPos, ref hit)) { Vector3 light = lightPos - hit.point; Vector3 light_norm = Vector3.Normalize(light); Vector3 halfDir = Vector3.Normalize(-ray.direction + light_norm); float diffuse_scalar = Mathf.Max(0, Vector3.Dot(light_norm, hit.normal)); float specular_scalar = Mathf.Pow(Mathf.Max(0, Vector3.Dot(halfDir, hit.normal)), 6); if (hitObject.m_type == MaterialType.none) { Vector3 mapColor = getModelColor(ref hit); albedo += ToColor(lightObj.lightColor) * ToColor(diffuse_scalar * mapColor); } else if (hitObject.m_type == MaterialType.map) { Texture2D tex = hit.transform.GetComponent <MeshRenderer>().material.mainTexture as Texture2D; Vector2 pixelUV = hit.textureCoord; Vector3 mapColor = ToVector(tex.GetPixel((int)(pixelUV.x * tex.width), (int)(pixelUV.y * tex.height))); albedo += ToColor(lightObj.lightColor) * ToColor((diffuse_scalar * mapColor)); } else if (hitObject.m_type == MaterialType.kdks) { albedo += ToColor(lightObj.lightColor) * ToColor(diffuse_scalar * hitObject.mattr.kd + specular_scalar * hitObject.mattr.ks); } } } albedo /= lightSamplePoint.Length; } }
public void PreprocessModelMaterial() { foreach (GameObject obj in _objects.Keys) { RayTracingObject rObj = _objects[obj]; if (rObj.m_type == MaterialType.none) { Mesh mesh = obj.transform.GetComponent <MeshFilter>().mesh; matIndex = new byte[mesh.triangles.Length / 3]; int subMeshesNr = mesh.subMeshCount; for (int k = 0; k < mesh.triangles.Length / 3; k++) { int materialIdx = -1; int[] hittedTriangle = new int[] { mesh.triangles[k * 3], mesh.triangles[k * 3 + 1], mesh.triangles[k * 3 + 2] }; for (int i = 0; i < subMeshesNr; i++) { int[] tr = mesh.GetTriangles(i); for (int j = 0; j < tr.Length - 2; j++) { if (tr[j] == hittedTriangle[0] && tr[j + 1] == hittedTriangle[1] && tr[j + 2] == hittedTriangle[2]) { materialIdx = i; break; } } if (materialIdx != -1) { break; } } matIndex[k] = (byte)materialIdx; } } } }
public static int RegisterObject(RayTracingObject obj) { _rayTracingObjects.Add(obj); _meshObjectsNeedRebuilding = true; return(_rayTracingObjects.Count - 1); }
private bool ParseObject() { RayTracingObject robj = new RayTracingObject(); for (int i = _curIndex; i < _records.Count; i++) { string line = _records[i]; string[] tokens; if (line == KeyWord.K_WorldBegin) { continue; } else if (line == KeyWord.K_WorldEnd) { continue; } else if (line == KeyWord.K_AttributeBegin) { robj = new RayTracingObject(); } else if (line == KeyWord.K_AttributeEnd) { rayTracingInfo.objects.Add(robj); } else if (line.StartsWith(KeyWord.K_Translate)) { tokens = line.Split(' '); robj.pos = new Vector3(float.Parse(tokens[1]), float.Parse(tokens[2]), float.Parse(tokens[3])); } else if (line.StartsWith(KeyWord.K_Rotate)) { tokens = line.Split(' '); float mult = float.Parse(tokens[1]); //blender to unity yz opposite robj.rot = new Vector3(float.Parse(tokens[2]), float.Parse(tokens[4]), float.Parse(tokens[3])) * mult; } else if (line.StartsWith(KeyWord.K_Scale)) { tokens = line.Split(' '); robj.scale = new Vector3(float.Parse(tokens[1]), float.Parse(tokens[2]), float.Parse(tokens[3])); } else if (line.StartsWith(KeyWord.K_Shape)) { line = FormatAttributeInfo(line); tokens = line.Split(' '); for (int j = 0; j < tokens.Length; j += 2) { string token = tokens[j]; //none, sphere, cylinder, cone, plane, mesh if (token == "Shape") { if (tokens[j + 1] == "\"sphere\"") { robj.o_type = ObjectType.sphere; } else if (tokens[j + 1] == "\"cylinder\"") { robj.o_type = ObjectType.cylinder; } else if (tokens[j + 1] == "\"cone\"") { robj.o_type = ObjectType.cone; } else if (tokens[j + 1] == "\"plane\"") { robj.o_type = ObjectType.plane; } else { if (_debug) { Debug.Log("Invalid Shape Type!"); } return(false); } } else if (token == "\"floatradius\"") { robj.whrInfo.z = float.Parse(ExtractString(tokens[j + 1])); } else if (token == "\"floatymin\"") { robj.yminmax.x = float.Parse(ExtractString(tokens[j + 1])); } else if (token == "\"floatymax\"") { robj.yminmax.y = float.Parse(ExtractString(tokens[j + 1])); } else if (token == "\"floatwidth\"") { robj.whrInfo.x = float.Parse(ExtractString(tokens[j + 1])); } else if (token == "\"floatheight\"") { robj.whrInfo.y = float.Parse(ExtractString(tokens[j + 1])); } else { if (_debug) { Debug.Log("Invalid Shape Attribute!"); } return(false); } } } else if (line.StartsWith(KeyWord.K_Material)) { line = FormatAttributeInfo(line); tokens = line.Split(' '); for (int j = 0; j < tokens.Length; j++) { string token = tokens[j]; if (token == "Material") { if (tokens[j + 1] == "\"mirror\"") { robj.m_type = MaterialType.mirror; j++; } else if (tokens[j + 1] == "\"glass\"") { robj.m_type = MaterialType.glass; j++; } } else if (token == "\"colormap\"") { robj.m_type = MaterialType.map; robj.mattr.cmapName = Path.Combine(_rootFolder, ExtractString(tokens[++j])); } else if (token == "\"bumpmap\"") { robj.m_type = MaterialType.map; robj.mattr.bmapName = Path.Combine(_rootFolder, ExtractString(tokens[++j])); } else if (token == "\"colorKd\"") { robj.m_type = MaterialType.kdks; robj.mattr.kd = new Vector3(float.Parse(ExtractString(tokens[++j])), float.Parse(tokens[++j]) , float.Parse(ExtractString(tokens[++j]))); } else if (token == "\"colorKs\"") { robj.m_type = MaterialType.kdks; robj.mattr.ks = new Vector3(float.Parse(ExtractString(tokens[++j])), float.Parse(tokens[++j]) , float.Parse(ExtractString(tokens[++j]))); } else { if (_debug) { Debug.Log("Invalid Material Attribute!"); } return(false); } } } else if (line.StartsWith(KeyWord.K_Include)) { tokens = line.Split(' '); robj.o_type = ObjectType.mesh; robj.mattr.meshName = Path.Combine(_rootFolder, ExtractString(tokens[1])); } else if (line.StartsWith(KeyWord.K_LightSource)) { line = FormatAttributeInfo(line); tokens = line.Split(' '); for (int j = 0; j < tokens.Length; j++) { string token = tokens[j]; if (token == "LightSource") { if (tokens[j + 1] == "\"point\"") { robj.l_type = LightType.point; } else if (tokens[j + 1] == "\"area\"") { robj.l_type = LightType.area; } else { if (_debug) { Debug.Log("Invalid Light Type!"); } return(false); } j++; } else if (token == "\"colorL\"") { robj.lightColor = new Vector3(float.Parse(ExtractString(tokens[++j])) / 15f, float.Parse(tokens[++j]) / 15f , float.Parse(ExtractString(tokens[++j])) / 15f); } else if (token == "\"pointfrom\"") { robj.pos = new Vector3(float.Parse(ExtractString(tokens[++j])), float.Parse(tokens[++j]) , float.Parse(ExtractString(tokens[++j]))); } else if (token == "\"integernsamples\"") { robj.nsample = int.Parse(ExtractString(tokens[++j])); } else if (token == "\"floatwidth\"") { robj.whrInfo.x = float.Parse(ExtractString(tokens[++j])); } else if (token == "\"floatheight\"") { robj.whrInfo.y = float.Parse(ExtractString(tokens[++j])); } else { if (_debug) { Debug.Log("Invalid Material Attribute!"); } return(false); } } } else { if (_debug) { Debug.Log("Invalid Attribute!"); } return(false); } } return(true); }
public static void UnregisterObject(RayTracingObject obj) { rayTracingObjects.Remove(obj); transformsToWatch.Remove(obj.gameObject.transform); meshesRequireRebuilding = true; }
private void CreateObject(RayTracingObject rObj) { GameObject obj = null; float mult = 1.0f; switch (rObj.o_type) { case ObjectType.sphere: obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); obj.transform.position = rObj.pos; obj.transform.eulerAngles = rObj.rot; // default radius 0.5 mult = rObj.whrInfo.z / 0.5f; obj.transform.localScale = rObj.scale * mult; break; case ObjectType.cylinder: obj = GameObject.CreatePrimitive(PrimitiveType.Cylinder); obj.transform.position = rObj.pos; obj.transform.eulerAngles = rObj.rot; // delete default collider Destroy(obj.GetComponent <SphereCollider>()); obj.AddComponent <MeshCollider>(); // default yminmax +-1 radius 0.5 mult = rObj.whrInfo.z / 0.5f; obj.transform.localScale = new Vector3(rObj.scale.x * mult, rObj.scale.y * rObj.yminmax.y, rObj.scale.z * mult); break; case ObjectType.cone: //default radius 1 height 2 obj = Instantiate(Cone, rObj.pos, Quaternion.Euler(rObj.rot)); obj.transform.localScale = new Vector3(rObj.scale.x * rObj.whrInfo.z, rObj.scale.y * rObj.whrInfo.y / 2.0f, rObj.scale.z * rObj.whrInfo.z); //Special Get Child obj = obj.transform.GetChild(0).gameObject; break; case ObjectType.plane: // default size 10 * 10 obj = GameObject.CreatePrimitive(PrimitiveType.Plane); obj.transform.position = rObj.pos; obj.transform.eulerAngles = rObj.rot; obj.transform.localScale = new Vector3(rObj.scale.x * rObj.whrInfo.x / 10f, rObj.scale.y, rObj.scale.z * rObj.whrInfo.y / 10f); break; case ObjectType.mesh: //string rootFolder = Directory.GetParent(mattr.meshName).FullName; //loader.Load(rootFolder, Path.GetFileName(mattr.meshName)); //blender object obj = Instantiate(Model, rObj.pos, Quaternion.Euler(new Vector3(rObj.rot.x, 180, rObj.rot.z))); obj.transform.localScale = rObj.scale; //Special Get Child obj = obj.transform.GetChild(0).gameObject; break; default: print("Create Object Failed !"); return; } if (rObj.m_type == MaterialType.map) { Texture2D c_map = LoadImage(rObj.mattr.cmapName); Texture2D b_map = LoadImage(rObj.mattr.bmapName); Material mat = new Material(Shader.Find("Standard")); mat.SetTexture("_MainTex", c_map); mat.SetTexture("_BumpMap", b_map); obj.GetComponent <MeshRenderer>().material = mat; } //bind raytracinginfo to gameobject _objects[obj] = rObj; }
private bool Scatter(ref Ray ray, ref RaycastHit hit, ref Color albedo, ref Ray scattered, ref int depth, ref int reflCount, ref bool RayFromGlass, ref Collider GlassCollider) { RayTracingObject hitObject = _objects[hit.transform.gameObject]; if (hitObject.m_type == MaterialType.mirror) { Vector3 refl = Vector3.Reflect(ray.direction, hit.normal); scattered.origin = hit.point; scattered.direction = refl; albedo = new Color(0, 0, 0); return(Vector3.Dot(scattered.direction, hit.normal) > 0); } else if (hitObject.m_type == MaterialType.glass) { float refractRate = 1 / 1.5f; Vector3 outwardNormal; Vector3 rdir = ray.direction.normalized; Vector3 reflect = Vector3.Reflect(rdir.normalized, hit.normal.normalized); float ni_over_nt; albedo = new Color(0, 0, 0); Vector3 refract; float reflectProbe; float cosine; if (Vector3.Dot(rdir, hit.normal) > 0) { outwardNormal = -hit.normal.normalized; ni_over_nt = refractRate; cosine = refractRate * Vector3.Dot(rdir, hit.normal.normalized); } else { outwardNormal = hit.normal.normalized; ni_over_nt = 1.0f / refractRate; cosine = -Vector3.Dot(rdir, hit.normal.normalized); } if (Refract(rdir, outwardNormal, ni_over_nt, out refract)) { reflectProbe = Schlick(cosine, refractRate); } else { reflectProbe = 1; } //if (Random.Range(0, 1) < reflectProbe) //{ // scattered = new Ray(hit.point, reflect.normalized); //} //else //{ if (RayFromGlass == false) { scattered = new Ray(hit.point, refract.normalized); GlassCollider = hit.transform.gameObject.GetComponent <Collider>(); RayFromGlass = true; } else if (RayFromGlass == true) { scattered = new Ray(hit.point, refract.normalized); GlassCollider = null; RayFromGlass = false; } //} return(true); } else if (hitObject.m_type == MaterialType.none) { Vector3 target = hit.normal.normalized * 0.5f + new Vector3(Random.Range(-1, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; scattered.origin = hit.point; scattered.direction = target - hit.point; CheckShadowRay(ref ray, ref hit, ref albedo); albedo *= depthValue[reflCount++]; return(true); } else if (hitObject.m_type == MaterialType.map) { Vector3 target = hit.normal.normalized * 0.5f + new Vector3(Random.Range(-1, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; scattered.origin = hit.point; scattered.direction = target - hit.point; CheckShadowRay(ref ray, ref hit, ref albedo); albedo *= depthValue[reflCount++]; return(true); } else if (hitObject.m_type == MaterialType.kdks) { Vector3 target = hit.normal.normalized * 0.5f + new Vector3(Random.Range(-1, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; scattered.origin = hit.point; scattered.direction = target - hit.point; CheckShadowRay(ref ray, ref hit, ref albedo); albedo *= depthValue[reflCount++]; return(true); } return(false); }
public static void UnregisterObject(RayTracingObject obj) { rayTracingObjects.Remove(obj); }
//MESH STUFF public static void RegisterObject(RayTracingObject obj) { _rayTracingObjects.Add(obj); _meshObjectsNeedRebuilding = true; }
public static void UnregisterObject(RayTracingObject rayTracingObject) { _rayTracingObjects.Remove(rayTracingObject); _meshObjectNeedRebuild = true; }
//static function public static void RegisterObject(RayTracingObject rayTracingObject) { _rayTracingObjects.Add(rayTracingObject); _meshObjectNeedRebuild = true; }
public static RayTracingObject ConvertSphere(Sphere sphere) { RayTracingObject r = new RayTracingObject(sphere.position, sphere.radius, 0, sphere.albedo, sphere.specular, sphere.smoothness, sphere.emission, 0); return(r); }
public static void UnregisterObject(RayTracingObject obj) { _rayTracingObjects.Remove(obj); _meshObjectsNeedRebuilding = true; }
public static void RegisterObject(RayTracingObject obj) { rayTracingObjects.Add(obj); }