public PhongShading(Bgr24Bitmap bitmap, Model model, ILighting lighting, bool d, bool n, bool s) : base(bitmap, model, lighting) { _d = d; _n = n; _s = s; _texturesEnabled = d || n || s; }
private Vector3 GetDiffusedTextureVector(Bgr24Bitmap texture, float x, float y, Vector3 normal) { if (texture == null) { return(new Vector3(0)); } var textureVector = Interpolate(texture, x, y); return(Vector3.Normalize(DiffuseColor) * Math.Max(Vector3.Dot(normal, Vector), 0) * textureVector); }
private Vector3 GetAmbientTextureVector(Bgr24Bitmap texture, float x, float y) { if (texture == null) { return(new Vector3(0)); } var textureVector = Interpolate(texture, x, y); return(Vector3.Normalize(AmbientColor) * textureVector); }
private Vector3 GetSpecularTextureVector(Bgr24Bitmap texture, float x, float y, Vector3 normal) { if (texture == null) { return(new Vector3(0)); } var reflectionVector = Vector3.Normalize(Vector3.Reflect(Vector, normal)); var textureVector = Interpolate(texture, x, y); // 𝑅 = 𝐿 − 2 ∙ (𝐿 ∙ 𝑁) ∙ 𝑁 return(Vector3.Normalize(SpecularColor) * (float)Math.Pow(Math.Max(Vector3.Dot(reflectionVector, new Vector3(0, 0, -1)), 0), GlossCoefficient) * textureVector); }
// Bilinear interpolation // z = (A(1 - x) + Bx)(1 - y) + (C(1 - x) + Dx)y // x = deltaX // y = deltaY private Vector3 Interpolate(Bgr24Bitmap texture, float x, float y) { int x1 = (int)x; int y1 = (int)y; float deltaX = x - x1; float deltaY = y - y1; var y0 = (1 - deltaX) * texture.GetVector(x1, y1) + deltaX * texture.GetVector(x1 + 1, y1); var y2 = (1 - deltaX) * texture.GetVector(x1, y1 + 1) + deltaX * texture.GetVector(x1 + 1, y1 + 1); return((1 - deltaX) * y0 + deltaX * y2); }
private Vector3?GetNormalTextureVector(Bgr24Bitmap texture, float x, float y, Matrix4x4 modelMatrix) { if (texture == null) { return(null); } var normal = Interpolate(texture, x, y); // 𝑁 = Ct * 2 - 1 normal -= new Vector3(byte.MaxValue) / 2; normal = Vector3.Normalize(normal); return(Vector3.Normalize(Vector3.TransformNormal(normal, modelMatrix))); }
public Renderer(WriteableBitmap baseBitmap, BaseLighting lighting) { bmp = new Bgr24Bitmap(baseBitmap); zBuf = new ZBuffer(baseBitmap.PixelWidth, baseBitmap.PixelHeight); // 4 stands for RGBA backBuffer = new byte[baseBitmap.PixelWidth * baseBitmap.PixelHeight * 4]; this.lighting = lighting; if (lighting.AmbientColor != null) { bgColor = lighting.AmbientColor.ToColor(); } else { lighting.AmbientColor = bgColor.ToVector3(); } }
async Task <bool> DrawMiniatureByMatrix(Matrix4x4 result, Matrix4x4 viewport) { List <Pixel> pixels = new List <Pixel>(); //double scale = 400; GraphObject graphObject_copy = (GraphObject)globalMiniature.Clone(); foreach (Group group in globalMiniature.Groups) { //result = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY(0), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale, (float)scale, (float)scale)); WriteableBitmap source = new WriteableBitmap(miniatureWidth, miniatureHeight, 96, 96, PixelFormats.Bgra32, null); Bgr24Bitmap bitmap = new Bgr24Bitmap(source); bitmap.Source.Lock(); graphObject_copy = (GraphObject)globalMiniature.Clone(); for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++) { Vertex vertex = graphObject_copy.Groups[0].Vertices[i]; Vector4 vector = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W); Vector4 vectorResult = Vector4.Transform(vector, result); vectorResult /= vertex.W; //vectorResult = Vector4.Transform(vectorResult, viewport); vertex.X = vectorResult.X; vertex.Y = vectorResult.Y; vertex.Z = vectorResult.Z; vertex.W = vectorResult.W; } for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++) { VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i]; Vector3 vector = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z); Vector3 vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result)); vertexNormal.X = vectorResult.X; vertexNormal.Y = vectorResult.Y; vertexNormal.Z = vectorResult.Z; } //VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i]; pixels = await GetListAsync(graphObject_copy.Groups[0], minDx, minDy, -1, miniatureWidth, miniatureHeight, bitmap); MiniatureModel.Source = bitmap.Source; bitmap.Source.Unlock(); //MiniatureModel.Source = PixelDrawing.GetBitmap(miniatureWidth, miniatureHeight, pixels); } return(true); }
async void DrawModel(GraphObject graphObject, Image targetPlace, int dx, int dy, double scale) { List <Pixel> pixels = new List <Pixel>(); GraphObject graphObject_copy = (GraphObject)graphObject.Clone(); Matrix4x4 result; foreach (Group group in graphObject.Groups) { WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null); Bgr24Bitmap bitmap = new Bgr24Bitmap(source); bitmap.Source.Lock(); result = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY(0), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale, (float)scale, (float)scale)); graphObject_copy = (GraphObject)graphObject.Clone(); for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++) { Vertex vertex = graphObject_copy.Groups[0].Vertices[i]; Vector4 vector = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W); Vector4 vectorResult = Vector4.Transform(vector, result); vertex.X = vectorResult.X; vertex.Y = vectorResult.Y; vertex.Z = vectorResult.Z; vertex.W = vectorResult.W; } for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++) { VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i]; Vector3 vector = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z); Vector3 vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result)); vertexNormal.X = vectorResult.X; vertexNormal.Y = vectorResult.Y; vertexNormal.Z = vectorResult.Z; } pixels = await GetListAsync(graphObject_copy.Groups[0], dx, dy, -1, windowWidth, windowHeight, bitmap); targetPlace.Source = bitmap.Source; bitmap.Source.Unlock(); //targetPlace.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels); } }
public GouraudShading(Bgr24Bitmap bitmap, Model model, ILighting lighting) : base(bitmap, model, lighting) { }
public PlaneShading(Bgr24Bitmap bitmap, Model model, ILighting lighting) : base(bitmap, model) { _lighting = lighting; _zBuffer = new ZBuffer(_bitmap.PixelWidth, _bitmap.PixelHeight); }
private async Task <List <Pixel> > GetListAsync(Group group, int dx, int dy, int viceVersa, int width, int height, Bgr24Bitmap bitmap) { return(await Task.Run(() => { List <Pixel> pixels = new List <Pixel>(); int count = 0; ZBuffer zBuf = new ZBuffer(width, height); Parallel.ForEach(group.Faces, face => { if (IsFaceVisible(group.Vertices, face)) { List <Pixel> pixelsForSide = new List <Pixel>(); List <Pixel> pixelsInSide = new List <Pixel>(); Vertex vertex0, vertex1; int index0, index1; Vector3 lightingVector = new Vector3(0, 0, 1); int ind0 = (face.FaceElements.ElementAt(0).VertexNormalIndex != null) ? (int)face.FaceElements.ElementAt(0).VertexNormalIndex : 1; Vector3 point0Normal = new Vector3(group.VertexNormals[ind0 - 1].X, group.VertexNormals[ind0 - 1].Y, group.VertexNormals[ind0 - 1].Z); int ind1 = (face.FaceElements.ElementAt(1).VertexNormalIndex != null) ? (int)face.FaceElements.ElementAt(1).VertexNormalIndex : 1; Vector3 point1Normal = new Vector3(group.VertexNormals[ind1 - 1].X, group.VertexNormals[ind1 - 1].Y, group.VertexNormals[ind1 - 1].Z); int ind2 = (face.FaceElements.ElementAt(2).VertexNormalIndex != null) ? (int)face.FaceElements.ElementAt(2).VertexNormalIndex : 1; Vector3 point2Normal = new Vector3(group.VertexNormals[ind2 - 1].X, group.VertexNormals[ind2 - 1].Y, group.VertexNormals[ind2 - 1].Z); Color color = Color.FromArgb(255, 255, 0, 0); Color point1Color = Lambert.GetPointColor(point0Normal, lightingVector, color); Color point2Color = Lambert.GetPointColor(point1Normal, lightingVector, color); Color point3Color = Lambert.GetPointColor(point2Normal, lightingVector, color); Color faceColor = PlaneShading.GetAverageColor(point1Color, point2Color, point3Color); for (int i = 0; i < face.FaceElements.Count - 1; i++) { index0 = (face.FaceElements.ElementAt(i).VertexIndex != -2) ? face.FaceElements.ElementAt(i).VertexIndex : (group.Vertices.Count - 1); index1 = (face.FaceElements.ElementAt(i + 1).VertexIndex != -2) ? face.FaceElements.ElementAt(i + 1).VertexIndex : (group.Vertices.Count - 1); vertex0 = group.Vertices.ElementAt(index0); vertex1 = group.Vertices.ElementAt(index1); pixelsForSide.AddRange(Bresenham.GetPixels((int)(vertex0.X + dx), (int)(vertex0.Y * viceVersa + dy), (int)(vertex0.Z), (int)(vertex1.X + dx), (int)(vertex1.Y * viceVersa + dy), (int)(vertex1.Z), windowWidth, windowHeight, bitmap, zBuf, faceColor)); } index0 = (face.FaceElements.ElementAt(0).VertexIndex != -2) ? face.FaceElements.ElementAt(0).VertexIndex : (group.Vertices.Count - 1); index1 = (face.FaceElements.ElementAt(face.FaceElements.Count - 1).VertexIndex != -2) ? face.FaceElements.ElementAt(face.FaceElements.Count - 1).VertexIndex : (group.Vertices.Count - 1); vertex0 = group.Vertices.ElementAt(index0); vertex1 = group.Vertices.ElementAt(index1); pixelsForSide.AddRange(Bresenham.GetPixels((int)(vertex0.X + dx), (int)(vertex0.Y *viceVersa + dy), vertex0.Z, (int)(vertex1.X + dx), (int)(vertex1.Y *viceVersa + dy), vertex1.Z, windowWidth, windowHeight, bitmap, zBuf, faceColor)); RastAlgorithm.DrawPixelForRasterization(pixelsForSide, bitmap, zBuf, faceColor); //pixels.AddRange(pixelsForSide); //pixelsInSide.AddRange(RastAlgorithm.DrawPixelForRasterization(pixelsForSide, bitmap, zBuf)); //pixels.AddRange(pixelsInSide); count++; } }); return pixels; })); }
public async void ImageButton_Click(object sender, RoutedEventArgs e) { Parser parser = new Parser(); GraphObject graphObject = parser.ParseFile(filePath); List <Pixel> pixels = new List <Pixel>(); if (!isApplyOptions) { double value = 5 * Math.PI / 180; GraphObject graphObject_copy = (GraphObject)graphObject.Clone(); Matrix4x4 result; foreach (Group group in graphObject.Groups) { while (value < 10000) { WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null); Bgr24Bitmap bitmap = new Bgr24Bitmap(source); bitmap.Source.Lock(); result = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY((float)(value)), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale * 2, (float)scale * 2, (float)scale * 2)); graphObject_copy = (GraphObject)graphObject.Clone(); for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++) { Vertex vertex = graphObject_copy.Groups[0].Vertices[i]; Vector4 vector = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W); Vector4 vectorResult = Vector4.Transform(vector, result); vertex.X = vectorResult.X; vertex.Y = vectorResult.Y; vertex.Z = vectorResult.Z; vertex.W = vectorResult.W; } for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++) { VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i]; Vector3 vector = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z); Vector3 vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result)); vertexNormal.X = vectorResult.X; vertexNormal.Y = vectorResult.Y; vertexNormal.Z = vectorResult.Z; } pixels = await GetListAsync(graphObject_copy.Groups[0], maxDx, maxDy, -1, windowWidth, windowHeight, bitmap); //GraphicModel.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels); value += 1 * Math.PI / 180; GraphicModel.Source = bitmap.Source; bitmap.Source.Unlock(); } } } else { TransformOptions options = GetUserOptions(scale * 2); GraphObject graphObject_copy = (GraphObject)graphObject.Clone(); Matrix4x4 result, viewport; foreach (Group group in graphObject.Groups) { WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null); Bgr24Bitmap bitmap = new Bgr24Bitmap(source); bitmap.Source.Lock(); result = GetOptionsMatrix(options, windowWidth, windowHeight); viewport = GetViewPort(0, 0, windowWidth, windowHeight); graphObject_copy = (GraphObject)graphObject.Clone(); for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++) { Vertex vertex = graphObject_copy.Groups[0].Vertices[i]; Vector4 vector = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W); Vector4 vectorResult = Vector4.Transform(vector, result); vectorResult /= vertex.W; //vectorResult = Vector4.Transform(vectorResult, viewport); vertex.X = vectorResult.X; vertex.Y = vectorResult.Y; vertex.Z = vectorResult.Z; vertex.W = vectorResult.W; } for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++) { VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i]; Vector3 vector = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z); Vector3 vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result)); vertexNormal.X = vectorResult.X; vertexNormal.Y = vectorResult.Y; vertexNormal.Z = vectorResult.Z; } pixels = await GetListAsync(graphObject_copy.Groups[0], maxDx, maxDy, -1, windowWidth, windowHeight, bitmap); GraphicModel.Source = bitmap.Source; bitmap.Source.Unlock(); //if (pixels != null) { GraphicModel.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels); } } } }
public BresenhamAlg(Bgr24Bitmap bitmap, Model model) { _bitmap = bitmap; _model = model; }
private void DrawButton_Click(object sender, RoutedEventArgs e) { try { textureEnabled(false); if (model != null) { WriteableBitmap source = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null); Bgr24Bitmap bitmap = new Bgr24Bitmap(source); ModelParams modelParams = GetModelsParams(); Model modelMain = model.Clone() as Model; CoordTransformations.TransformFromWorldToView(modelMain, modelParams); if (modelMain.CheckSize(width, height)) { Color color = Color.FromRgb(byte.Parse(colorRTextBox.Text), byte.Parse(colorGTextBox.Text), byte.Parse(colorBTextBox.Text)); Vector3 lighting = new Vector3(int.Parse(lightVectorXTextBox.Text), int.Parse(lightVectorYTextBox.Text), -int.Parse(lightVectorZTextBox.Text)); if (bresenhamRadioButton.IsChecked == true) { // lab 1-2 BresenhamAlg bresenham = new BresenhamAlg(bitmap, modelMain); bresenham.DrawModel(color); } else if (plainShadingRadioButton.IsChecked == true) { // lab 3 PlaneShading shader = new PlaneShading(bitmap, modelMain, new LambertLighting(lighting)); shader.DrawModel(color); } else if (phongShadingRadioButton.IsChecked == true) { textureEnabled(true); // затенение фонга Vector3 viewVector = new Vector3(int.Parse(colorRTextBox_View.Text), int.Parse(colorGTextBox_View.Text), int.Parse(colorBTextBox_View.Text)); Vector3 koef_a = new Vector3(float.Parse(colorRTextBox_A.Text), float.Parse(colorGTextBox_A.Text), float.Parse(colorBTextBox_A.Text)); Vector3 koef_d = new Vector3(float.Parse(colorRTextBox_D.Text), float.Parse(colorGTextBox_D.Text), float.Parse(colorBTextBox_D.Text)); Vector3 koef_s = new Vector3(float.Parse(colorRTextBox_S.Text), float.Parse(colorGTextBox_S.Text), float.Parse(colorBTextBox_S.Text)); Vector3 ambientColor = new Vector3(int.Parse(colorRTextBox_Ambient.Text), int.Parse(colorGTextBox_Ambient.Text), int.Parse(colorBTextBox_Ambient.Text)); Vector3 reflectionColor = new Vector3(int.Parse(colorRTextBox_Reflection.Text), int.Parse(colorGTextBox_Reflecion.Text), int.Parse(colorBTextBox_Reflection.Text)); float shiness = float.Parse(shinessBox.Text); bool d = false, n = false, s = false; if ((diffuseCheckBox != null && (bool)diffuseCheckBox.IsChecked)) { d = true; } if ((normalCheckBox != null && (bool)normalCheckBox.IsChecked)) { n = true; } if ((mirrorCheckBox != null && (bool)mirrorCheckBox.IsChecked)) { s = true; } var light = new PhongLighting(lighting, viewVector, koef_a, koef_d, koef_s, ambientColor, reflectionColor, shiness, d, n, s); //var light = new LambertLighting(lighting); PhongShading shader = new PhongShading(bitmap, modelMain, light, d, n, s); shader.DrawModel(color); } screenPictureBox.Source = bitmap.Source; } } else { MessageBox.Show("Load an object"); } } catch (Exception ex) { MessageBox.Show("Произошла ошибка! " + ex); } }