public MainWindow() { InitializeComponent(); DateTime start = DateTime.Now; Scene.Scene scene = Scene.ReferenceScene; BitmapSource rt = RayTrace.Render(scene, 1000, 1000); image1.Source = rt; DateTime end = DateTime.Now; TimeSpan duration = end - start; textBox1.Text = rt.Width.ToString() + "x" + rt.Height.ToString() + " image took " + (duration.TotalMilliseconds / 1000.0).ToString("F2") + "s"; }
public override void CursorUpdate(World world, Player player, Vector2 cursorPosition) { WorldCamera camera = world.worldCamera; if (!camera.turning) { RayTrace rayTrace = camera.GetRayAtScreenPosition(cursorPosition - camera.worldContainer.GetPosition()); if (rayTrace.hit) { bool inRange = (rayTrace.hitPosition - player.worldPosition).sqrMagnitude < 25f; if (Input.GetKey(KeyCode.Mouse0) && inRange) { player.UseItem(Vector3Int.FloorToInt(rayTrace.hitTilePosition + rayTrace.hitDirection), Input.GetKeyDown(KeyCode.Mouse0)); } SetConstructionGuide(camera, player, rayTrace.hitTilePosition + Vector3.one * 0.5f, rayTrace.hitDirection, inRange); _previewSprite.isVisible = true; } } }
public override void CursorUpdate(World world, Player player, Vector2 cursorPosition) { WorldCamera camera = world.worldCamera; if (!camera.turning) { RayTrace rayTrace = camera.GetRayAtScreenPosition(cursorPosition - camera.worldContainer.GetPosition()); Tile tile = rayTrace.GetTileIn(world); if (tile != _lastTile) { _progress = 0f; _lastTile = tile; } if (rayTrace.hit) { bool inRange = (rayTrace.hitPosition - player.worldPosition).sqrMagnitude < 25f; if (Input.GetKey(KeyCode.Mouse0) && inRange) { bool clicked = _progress >= 1f; if (clicked) { _progress = 0f; } player.UseItem(rayTrace.hitTilePosition, clicked); // Input.GetKeyDown(KeyCode.Mouse0)); } SetConstructionGuide(camera, player, rayTrace.hitTilePosition, inRange, _progress); _previewSprite.isVisible = true; } } }
public VoxelBlock Raycast(Ray ray, out VoxelBlock emptyTargetedBlock) { VoxelBlock last = null; VoxelBlock ret = null; var traverser = new GridTraverser(); float?closest = null; foreach (VoxelTerrainChunk terr in TW.Data.Objects.Where(o => o is VoxelTerrainChunk)) { var trace = new RayTrace(); trace.Ray = ray; float?dist = trace.Ray.xna().Intersects(terr.GetBoundingBox().xna()); if (!dist.HasValue) { continue; } if (closest.HasValue && closest.Value < dist.Value) { continue; } trace.Start = dist.Value + 0.001f; traverser.NodeSize = terr.NodeSize; traverser.GridOffset = terr.WorldPosition; //TODO: fix multiple terrains var hit = false; VoxelTerrainChunk terr1 = terr; traverser.Traverse(trace, delegate(Point3 arg) { if (!terr1.InGrid(arg)) { return(true); } var voxelBlock = terr1.GetVoxelInternal(ref arg); if (voxelBlock == null) { return(false); } if (voxelBlock.Filled) { hit = true; ret = getChunkVoxelWrapper(terr1, arg); return(true); } last = getChunkVoxelWrapper(terr1, arg); return(false); }); if (hit) { closest = dist; } } emptyTargetedBlock = last; return(ret); }
public override void CursorUpdate(World world, Player player, Vector2 cursorPosition) { WorldCamera camera = world.worldCamera; List <ITarget> targets = world.targets; ITarget nearestTarget = null; Vector2 screenPositionA, screenPositionB; screenPositionA = new Vector2(1920f, 1080f); for (int index = 0; index < targets.Count; index++) { screenPositionB = camera.GetScreenPosition(targets[index].worldPosition) + camera.worldContainer.GetPosition(); float sqrMagnitude = (screenPositionB - cursorPosition).sqrMagnitude; //if ((screenPositionB.x > Menu.screenWidth * 0.5f || screenPositionB.x < Menu.screenWidth * -0.5f) || // (screenPositionB.y > Menu.screenHeight * 0.5f || screenPositionB.y < Menu.screenHeight * -0.5f)) if (sqrMagnitude > 4096f) { continue; } else if ((screenPositionA - cursorPosition).sqrMagnitude > sqrMagnitude) { nearestTarget = targets[index]; screenPositionA = screenPositionB; } } if (_currentTarget != nearestTarget) { _lastScreenPosition = position; _lastSize = size; _currentTarget = nearestTarget; _lastTime = menu.time; _targetInspector.InspectTarget(_currentTarget); } if (_currentTarget != null) { _targetScreenPosition = screenPositionA + nearestTarget.boundRect.position; _targetSize = nearestTarget.boundRect.size; if (Input.GetKey(KeyCode.Mouse0)) { player.UseItem(_currentTarget.worldPosition, Input.GetKeyDown(KeyCode.Mouse0)); } } else { _targetScreenPosition = cursorPosition; _targetSize = new Vector2(12f, 12f); if (Input.GetKey(KeyCode.Mouse0)) { RayTrace rayTrace = camera.GetRayAtScreenPosition(cursorPosition - camera.worldContainer.GetPosition()); Vector3 targetPosition = new Vector3(rayTrace.hitPosition.x, player.worldPosition.y, rayTrace.hitPosition.z); if (rayTrace.hit) { player.UseItem(targetPosition, Input.GetKeyDown(KeyCode.Mouse0)); } } } }
Color TraceColor(Vector3 startPos, Vector3 rayDir, int sample, int depth) { if (depth <= 0) { return(Color.black); } RayTrace.Ray ray = new RayTrace.Ray(startPos, rayDir, 1000); RayTrace.Intersect(ref ray); if (ray.geomID == RayTrace.Invalid) { return(skyColor); } else { SimpleModel model = scene.models[(int)ray.geomID]; SimpleMesh mesh = model.mesh; int t0 = mesh.triangles[ray.primID * 3 + 0]; int t1 = mesh.triangles[ray.primID * 3 + 1]; int t2 = mesh.triangles[ray.primID * 3 + 2]; Vector2 uv = RayTraceTool.Lerp(mesh.uv[t0], mesh.uv[t1], mesh.uv[t2], ray.u, ray.v); Color texColor = model.material.LinearSample(uv); if (!ignoreMaterialColor) { texColor *= model.material.GetColor(); } if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Opaque) { texColor.a = 1; } Vector3 hitPos = ray.pos + ray.dir * ray.length; Vector3 hitNormal = RayTraceTool.Lerp(mesh.normals[t0], mesh.normals[t1], mesh.normals[t2], ray.u, ray.v); hitNormal = (model.rst.rot * hitNormal); float transFactor = 1 - texColor.a; float glossiness = model.material.glossiness; float reflectFactor = Mathf.Lerp(0.2f * glossiness, 1f, model.material.metallic); if (reflectFactor > 0.01f) { reflectFactor = Fresnel_Schlick(Vector3.Dot(-rayDir, hitNormal), reflectFactor); } float grayscale = texColor.grayscale; float diffuseFactor = Mathf.Clamp01(1 - transFactor - reflectFactor); int transSample = (int)(sample * grayscale * transFactor); int reflectSample = (int)(sample * reflectFactor); int diffuseSample = (int)(sample * grayscale * diffuseFactor); Color finaleColor = Color.black; Color reflectColor = Color.black; { Color finalLightColor = Color.black;// GetAllLightsColor(model, hitPos, hitNormal) * (reflectFactor + scene.lights.Length);//光源直接贡献 if (reflectSample > 0) { Vector3 reflectDir = Vector3.Reflect(rayDir, hitNormal); Vector3[] dirs = RayTraceTool.GetRandomDirs_BlinnPhong_Importance2(hitNormal, reflectDir, glossiness, reflectSample); for (int i = 0; i < reflectSample; i++) { finalLightColor += TraceColor(hitPos + hitNormal * 0.01f, dirs[i], 1, depth - 1);//间接光贡献 } finalLightColor /= (reflectSample); } reflectColor = Color.Lerp(Color.white, texColor, model.material.metallic) * finalLightColor; } Color diffuseColor = Color.black; { Color finalLightColor = GetAllLightsColor(model, hitPos, hitNormal) * (diffuseSample + scene.lights.Length);//光源直接贡献 if (diffuseSample > 0) { Vector3 reflectDir = Vector3.Reflect(rayDir, hitNormal); Vector3[] dirs = RayTraceTool.GetRandomDirs_RoundProj(hitNormal, diffuseSample); for (int i = 0; i < diffuseSample; i++) { finalLightColor += TraceColor(hitPos + hitNormal * 0.01f, dirs[i], 1, depth - 1);//间接光贡献 } } finalLightColor /= (diffuseSample + scene.lights.Length); diffuseColor = texColor * finalLightColor; } //Color reflectColor = Color.black; //if(reflectFactor > 0.01f){ // Vector3 refDir = Vector3.Reflect(rayDir,hitNormal); // Color finalLightColor = TraceColor(hitPos + refDir * 0.01f, refDir,reflectSample ,depth - 1); // reflectColor = finalLightColor; //} finaleColor = reflectColor * reflectFactor + diffuseColor * diffuseFactor; if (texColor.a < 0.99f) { Color transColor = TraceColor(hitPos + rayDir * 0.01f, rayDir, transSample, depth); if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Alphablend) { finaleColor = finaleColor * texColor.a + transColor * (1 - texColor.a); } else if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Multiply) { finaleColor = finaleColor * transColor; } else if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Additive) { finaleColor = finaleColor + transColor; } } return(finaleColor); } }
public void Release() { RayTrace.Release(); SimpleMaterial.textures.Clear(); scene = null; }
public void Init() { Instance = this; updateProgress(0); HaltonTool.InitHaltonSequence(); Debug.Log("Start Time : " + Time.realtimeSinceStartup); scene = new SimpleScene(); RayTrace.Init(); SimpleMaterial.textures.Clear(); scene.lights = GameObject.FindObjectsOfType <Light>(); Camera cam = GetComponent <Camera>(); if (cam) { MeshRenderer[] renderers = GameObject.FindObjectsOfType <MeshRenderer>(); foreach (MeshRenderer r in renderers) { bool isLayerVisible = ((1 << r.gameObject.layer) & cam.cullingMask) != 0; if (r.isVisible && isLayerVisible) { MeshFilter filter = r.gameObject.GetComponent <MeshFilter>(); if (filter && filter.sharedMesh) { for (int i = 0; i < filter.sharedMesh.subMeshCount; i++) { Mesh mesh = filter.sharedMesh; int[] triangles = filter.sharedMesh.GetTriangles(i); RayTrace.AddMesh(filter.gameObject.transform, mesh.vertexCount, triangles.Length, mesh.vertices, triangles, 1); SimpleModel model = new SimpleModel(r.gameObject.transform, filter.sharedMesh, i, r.sharedMaterials[i]); model.lights = RayTraceTool.GetActivityLights(r, scene); scene.models.Add(model); } } } } Terrain[] terrains = GameObject.FindObjectsOfType <Terrain>(); foreach (Terrain terrain in terrains) { bool isLayerVisible = ((1 << terrain.gameObject.layer) & cam.cullingMask) != 0; if (terrain.gameObject.activeInHierarchy && isLayerVisible) { int w = terrain.terrainData.heightmapWidth; int h = terrain.terrainData.heightmapHeight; float realWidth = terrain.terrainData.size.x * (1 + 1f / w); float realHeight = terrain.terrainData.size.z * (1 + 1f / h); float[,] heights = terrain.terrainData.GetHeights(0, 0, w, h); Vector3[] vertices = new Vector3[w * h]; Vector2[] uvs = new Vector2[vertices.Length]; Vector3[] normals = new Vector3[vertices.Length]; int[] triangles = new int[(w - 1) * (h - 1) * 2 * 3]; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { Vector3 pos = new Vector3(i * realWidth / w, heights[j, i] * terrain.terrainData.size.y, j * realHeight / h); vertices[j * w + i] = pos; uvs[j * w + i] = new Vector2(i / (float)w, j / (float)h); normals[j * w + i] = terrain.terrainData.GetInterpolatedNormal(i / (float)w, j / (float)h); } } for (int i = 0; i < w - 1; i++) { for (int j = 0; j < h - 1; j++) { int index = (j * (w - 1) + i) * 6; triangles[index + 0] = (i + 0) + (j + 0) * w; triangles[index + 1] = (i + 1) + (j + 1) * w; triangles[index + 2] = (i + 1) + (j + 0) * w; triangles[index + 3] = (i + 0) + (j + 0) * w; triangles[index + 4] = (i + 0) + (j + 1) * w; triangles[index + 5] = (i + 1) + (j + 1) * w; } } RayTrace.AddMesh(terrain.transform, vertices.Length, triangles.Length, vertices, triangles, 1); SimpleModel model = new SimpleModel(); model.mesh = new SimpleMesh(triangles, uvs, vertices, normals); model.material = new SimpleTerrainMaterial(terrain.terrainData); model.rst = new RayTrace.RST(terrain.transform.rotation, terrain.transform.lossyScale, terrain.transform.position); model.lights.AddRange(scene.lights); scene.models.Add(model); } } } RayTrace.Commit(); texture = new Texture2D(width, height, TextureFormat.ARGB32, true); //viewResult.sharedMaterial.mainTexture = texture; }