public void Normalization() { var vector = new Vector3(0, 3, 4); var normalized = vector.Normalized(); Assert.AreEqual(0, normalized.x, Delta); Assert.AreEqual(0.6f, normalized.y, Delta); Assert.AreEqual(0.8f, normalized.z, Delta); }
public static Quaternion LookRotation(Vector3 direction, Vector3 up) { Vector3 directionNormalized = direction.Normalized(); // Rotate around up vector Vector3 directionProjected = (directionNormalized - up * Vector3.Dot(directionNormalized, up)).Normalized(); Vector3 forwardProjected = (Vector3.Forward - up * Vector3.Dot(Vector3.Forward, up)).Normalized(); float rotationAroundUpAngleHalf = (float) Math.Acos((Vector3.Dot(directionProjected, forwardProjected))) / 2; var rotationAroundUp = new Quaternion(up * (float) Math.Sin(rotationAroundUpAngleHalf), (float) Math.Cos(rotationAroundUpAngleHalf)); // Rotate around horizontal vector Vector3 rotationAxis = Vector3.Cross(directionNormalized, directionProjected); double angleHalf = Math.Acos(Vector3.Dot(directionNormalized, directionProjected)) / 2; var rotationAroundHorizontal = new Quaternion(rotationAxis * (float) Math.Sin(angleHalf), (float) Math.Cos(angleHalf)); return rotationAroundUp * rotationAroundHorizontal; }
void Render(int resolution) { Bitmap bmp = new Bitmap(resolution, resolution); for (int i = 0; i < resolution; i++) { for (int j = 0; j < resolution; j++) { bmp.SetPixel(i, j, Color.LightYellow); } } // let's say... kamera w 0,0,0, patrzy na 0,0,1 Sphere s1 = new Sphere() // VS hinted me this syntax... I didn't know it. { center = new Vector3(0, 0, 1), radius = 0.2f, color = new Vector3(1, 0, 0) }; Sphere s2 = new Sphere() // VS hinted me this syntax... I didn't know it. { center = new Vector3(0.15f, 0.2f, 1.1f), radius = 0.15f, color = new Vector3(1, 0f, 1) }; List <Sphere> spheres = new List <Sphere>(); spheres.Add(s1); spheres.Add(s2); PointLight pointLight = new PointLight(new Vector3(5, 40, 10), new Vector3(1, 1, 1)); Camera cam = new Camera(new Vector3(0, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0), resolution, resolution); Vector3 oneoneone = new Vector3(1, 1, 1); for (int i = -cam.xRes; i < cam.xRes; i++) { for (int j = -cam.yRes; j < cam.yRes; j++) { Vector3 targetPoint = cam.GetPointFromCenter( 2f / (float)(cam.xRes) * (float)i, 2f / (float)(cam.yRes) * (float)j); Ray r = new Ray(cam.position, targetPoint - cam.position); foreach (Sphere sphere in spheres) { Vector3 intersection = sphere.Intersects(r); if (intersection != null) { Vector3 normal = s1.CalculateNormal(intersection); Vector3 resultColor = oneoneone; Vector3 intersection_minus_cam_pos = intersection - cam.position; float ambientCoeff = 0.2f; float diffuseCoeff = 0.4f; float speculrCoeff = 0.4f; resultColor *= ambientCoeff; // initialized with 1,1,1 Vector3 intersectionToPointLight = (intersection - pointLight.position); resultColor += sphere.color * diffuseCoeff * (normal.Dot(intersectionToPointLight.Normalized())); // diffuse // specular: Vector3 reflectedVector = intersectionToPointLight - 2 * (intersectionToPointLight.Dot(normal)) * (normal); reflectedVector = reflectedVector.Normalized(); resultColor += oneoneone * speculrCoeff * (float)Math.Pow( reflectedVector.Dot(intersection_minus_cam_pos.Normalized()) , 40f); if (resultColor.x < 0) { resultColor.x = 0; } if (resultColor.y < 0) { resultColor.y = 0; } if (resultColor.z < 0) { resultColor.z = 0; } bmp.SetPixel(i + cam.xRes / 2, j + cam.yRes / 2, Color.FromArgb( (int)(resultColor.x * 255.0f), (int)(resultColor.y * 255.0f), (int)(resultColor.z * 255.0f) )); } } } } pictureBox1.Image = resolution == 1600?DownSampled(bmp):bmp; }