Rasterization 学习笔记
======================Barycentric interpolation======================================
<1>2d/3d Check point in triangle test
float areas(vector p1;vector p2;vector p3)
{
return length(cross(p1-p2,p3-p2)) * 0.5f;
} int ptInTri(vector inpt;vector p1;vector p2; vector p3)
{
float s = areas(p1,p2,p3);
float s1 = areas(inpt,p2,p3) / s;
float s2 = areas(inpt,p3,p1) / s;
float s3 = areas(inpt,p1,p2) / s;
if(s1<0.0f || s1>1.0f)
{
return false;
}
if(s2 < 0.0f || s2 >)
{
return false;
}
if(s3 < 0.0f || s3 >)
{
return false;
}
float all = s1 + s2 + s3;
if (all-1.0f<0.000001f)
return true;
else
return false;
}
<2>2d check can use :
<test 3d in houdini found problem>
int ptInTri2(vector P;vector A;vector B; vector C)
{
vector u = B - A;
vector v = C - A;
vector w = P - A; vector vCrossW = cross(v, w);
vector vCrossU = cross(v, u); if (dot(vCrossW, vCrossU) < )
return false; vector uCrossW = cross(u, w);
vector uCrossV = cross(u, v); // Test sign of t
if (dot(uCrossW, uCrossV) < )
return false; float denom = length(uCrossV);
float r = length(vCrossW) / denom;
float t = length(uCrossW) / denom; return (r + t <= );
}
<3> Color Interpolation:

float areas(vector p1;vector p2;vector p3)
{
return length(cross(p1-p2,p3-p2)) * 0.5f;
} vector P = getInputP();
float s = areas(p1,p2,p3);
float s1 = areas(P,p2,p3) / s;
float s2 = areas(P,p3,p1) / s;
float s3 = areas(P,p1,p2) / s; vector PColor = p1.color * s1 + p2.color*s2 + p3.color*s3;
<4>we can use this method to getPointAt uv like maya function or houdini primuv();

float areas(vector p1;vector p2;vector p3)
{
return length(cross(p1-p2,p3-p2)) * 0.5f;
} vector getPointAtUV(float u;float v)
{
clamp(u,,);
clamp(v,,); // get current gdp's points
vector gdpPtsPos[];
for(int i=;i<;i++)
{
vector curl = point(,"P",i);
//printf("%f ,%f , %f \n",curl[0],curl[1],curl[2]);
append(gdpPtsPos,curl);
} vector p1 = gdpPtsPos[];
vector p2 = gdpPtsPos[];
vector p3 = gdpPtsPos[]; // tri area
float s = areas(p1,p2,p3);
// reverse to get base on u value float uArea = u * 0.5 / s; // reverse to get base on v value
float vArea = v * 0.5 / s ; // the w value
float wArea =;
if( - uArea - vArea < )
{
wArea = ;
}
else
{
wArea =( - u - v )*0.5 / s;
} //https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates //P=uA+vB+wC. vector retP = p1 * uArea + p2*vArea + p3*wArea;
return retP; } #define maxscatter 100000 for(int i=;i<maxscatter;i++)
{
float u = rand(i);
float v = rand(i*);
vector retPos = getPointAtUV(u,v);
addpoint(geoself(),retPos);
}
<4>Color Define:
(1)ARGB:uint32_t,也就是单位为uint8_t ,共4个,a ,r ,g ,b 0xFF FF FF FF (255,255,255,255)
// uint32_t c; A:(uint8_t) ( (c & 0xFF ) >>)
R:(uint8_t) ( (c & 0x00 FF ) >>)
G:(uint8_t) ( (c & 0x00 FF ) >>)
B:(uint8_t) ( (c & 0x00 FF) >>)
(2)从uint8_t r,g,b,a转换到uint32_t,用位和求回去
((uint32_t)a<<) | ((uint32_t)r<<) | ((uint32_t)g<<) | ((uint32_t)b<<)
(2)float color:sixteen bytes:
struct color{float a, float r,float g,float b}
转换成ARGB(uint32_t)颜色也简单.
color fc = {1.0f,0.5f,0.0f,1.0f};
uint8_t r = (uint8_t) (floorf(fc.r*255.0f))
uint8_t g = (uint8_t) (floorf(fc.g*255.0f))
uint8_t b = (uint8_t) (floorf(fc.b*255.0f))
uint8_t a = (uint8_t) (floorf(fc.a*255.0f))
=========================Rasterization==================================================
<1>Line:
画斜线没用到斜率方程,直接用的线性差值。

DrawApi.h
#ifndef DRAWAPI_H
#define DRAWAPI_H #include <QImage>
#include "LineSegment.h"
#include <glm/glm.hpp>
#include <iostream>
#include "MathUtility.h"
using namespace TopVertex;
class DrawApi
{
public:
template <typename T = glm::vec3>
static void drawLine(QImage &image ,LineSegment<T> &line,const glm::vec3 &color)
{ auto &sp = line.startPoint();
auto &ep = line.endPoint();
float m = line.getSlope(); if(line.getType() == LineSegment<T>::HORIZON)
{
std::cout << "write horizon line\n";
auto y = sp[];
for(int x=sp[] ; x <= ep[]; x++)
{
image.setPixel(x,y,qRgb(color[],color[],color[]));
}
return;
}
if(line.getType() == LineSegment<T>::VERTICAL)
{
std::cout << "write verticle line\n";
auto x = sp[];
auto y0 = sp[];
auto y1 = ep[];
if(y0 < y1)
{
for(int y=y0;y<=y1;y++)
{
image.setPixel(x,y,qRgb(color[],color[],color[]));
}
}
else
{
for(int y=y1;y<=y0;y++)
{
image.setPixel(x,y,qRgb(color[],color[],color[]));
}
}
return;
}
if(line.getType() == LineSegment<T>::NORMAL)
{
std::cout << "write normal line\n";
int startRow = ;
int endRow = ; if(sp[] < ep[])
{
startRow = sp[];
endRow = ep[];
}
else
{
startRow = ep[];
endRow = sp[];
}
for(int r = startRow;r<=endRow;r++)
{
auto bias = GLY_MATH::fit<float>(r,startRow,endRow,0.1f,1.0f);
auto pos = GLY_MATH::linearInterpolation(sp,ep,bias);
image.setPixel(pos[],pos[],qRgb(color[],color[],color[]));
}
return;
} }
}; #endif // DRAWAPI_H
LineSegment.h
#ifndef LINESEGMENT_H
#define LINESEGMENT_H
#include <algorithm>
#include <cmath>
#include <string>
#include <iostream>
#include <glm/glm.hpp>
template <typename T>
class LineSegment
{
public:
typedef T value_type;
enum TYPE{VERTICAL,HORIZON,NORMAL};
LineSegment(T startPoint,T endPoint):
mStartPoint(startPoint),mEndPoint(endPoint)
{
// LINE PROPERTY
evalLineProperty();
// LINE PROPERTY
}
LineSegment()=default;
void setPoints(const T &startPoint , const T &endPoint)
{
mStartPoint = startPoint;
mEndPoint = endPoint;
evalLineProperty();
}
inline T & operator[](int i)
{
if(i == )
{
return mStartPoint;
}
else if(i == )
{
return mEndPoint;
}
else
{
throw std::string("Can't get point over 2\n").c_str();
} }
TYPE getType();
T &startPoint();
T &endPoint();
T startPoint()const;
T endPoint()const;
float getSlope()const; template <typename T2,typename T3>
inline T2 intersect(const LineSegment<T3> &Line)
{
auto st_y = Line.startPoint()[]; // get line y value
auto it_x = (st_y - startPoint()[] + startPoint()[]*getSlope())/getSlope(); // y slope function get x pos
return T2(it_x,st_y);
} private:
void evalLineProperty()
{ auto x0 = mStartPoint[];
auto x1 = mEndPoint[]; if(x0 > x1)
{
swap(mStartPoint,mEndPoint);
} x0 = mStartPoint[];
x1 = mEndPoint[];
auto y0 = mStartPoint[];
auto y1 = mEndPoint[]; if(fabs(y1-y0) <= 0.0000001f) // horizon line slope = 0
{
mSlope = 0.0f;
mLineType = HORIZON;
}
else if(fabs(x1-x0) <= 0.000001f) // verticle line slope = 0
{
mSlope = 0.0f;
mLineType = VERTICAL;
}
else // slope !=0
{
mSlope = (y1 - y0) / (x1-x0);
mLineType = NORMAL;
}
} T mStartPoint;
T mEndPoint;
TYPE mLineType;
float mSlope;
}; template<typename T>
typename LineSegment<T>::TYPE LineSegment<T>::getType()
{
return mLineType;
} template<typename T>
float LineSegment<T>::getSlope() const
{
return mSlope;
} template<typename T>
T &LineSegment<T>::startPoint()
{
return mStartPoint;
} template<typename T>
T &LineSegment<T>::endPoint()
{
return mEndPoint;
} template<typename T>
T LineSegment<T>::startPoint()const
{
return mStartPoint;
} template<typename T>
T LineSegment<T>::endPoint()const
{
return mEndPoint;
} // ostream
inline std::ostream& operator<<(std::ostream &os,LineSegment<glm::vec3> line)
{
os << "Line start points:" << line.startPoint()[] << " " <<line.startPoint()[] << " "<<line.startPoint()[]
<< " | "
<< "end:" << line.endPoint()[]<< " "<< line.endPoint()[] << " "<< line.endPoint()[] ;
return os;
} inline std::ostream& operator<<(std::ostream &os,LineSegment<glm::vec2> line)
{
os << "Line start points:" << line.startPoint()[] << " " <<line.startPoint()[] << "|"
<< "end:" << line.endPoint()[]<< " "<< line.endPoint()[] ;
return os;
} #endif // LINESEGMENT_H
MathUtility.h
#ifndef MATHUTILITY_H
#define MATHUTILITY_H #include <string>
#include <vector>
#include <iostream>
#include <sstream>
using namespace std; namespace TopVertex
{
class GLY_MATH
{
public: template<typename T>
static T linearInterpolation(T val1 , T val2,float bias)
{
return val1*(-bias) + val2*bias;
} template<typename T>
static T min(T a, T b) {
if (a > b) {
return b;
} else {
return a;
}
} template<typename T>
static T max(T a, T b) {
if (a > b) {
return a;
} else {
return b;
}
} template<typename T>
static bool zero_compare(T a, double tol = 0.00001) {
return a >= -tol && a <= tol;
} // DO NOT USE THIS FIT TO FIT VECTOR VALUE
template<typename T>
static T fit(T var, T omin, T omax, T nmin, T nmax) {
T d = omax - omin;
if (zero_compare(d)) {
return (nmin + nmax) * 0.5;
}
if (omin < omax) {
if (var < omin) return nmin;
if (var > omax) return nmax;
} else {
if (var < omax) return nmax;
if (var > omin) return nmin;
}
return nmin + (nmax - nmin) * (var - omin) / d;
} //return -1 to 1
template<typename T>
static T fit_negate(T var, T omin, T omax) {
return fit(var, omin, omax, -1.0, 1.0);
} //string split
static std::vector<std::string> split_string(std::string &inputString, char &split_char) {
std::stringstream ss(inputString);
std::string sub_str;
std::vector<std::string> sp_strPath;
sp_strPath.clear();
while (getline(ss, sub_str, split_char)) {
sp_strPath.push_back(sub_str);
}
return sp_strPath;
} //value to string
template<typename T>
// T must be a value int/float/double
static std::string value_to_str(T &value) {
std::ostringstream os;
os << value;
return os.str();
} static int wang_inthash(int key) {
// From http://www.concentric.net/~Ttwang/tech/inthash.htm
key += ~(key << );
key ^= (key >> );
key += (key << );
key ^= (key >> );
key += ~(key << );
key ^= (key >> );
return key;
} static int fastRandomInt(int seed) {
int nseed = seed * +0XFFFFFFF;
return wang_inthash(nseed);
} static float fastRandom01(int seed)
{
return float(fastRandomInt(seed) % ) / 1000000.0f;
} };
} #endif // MATHUTILITY_H
Renderer.h
#ifndef RENDERER_H
#define RENDERER_H #include <QImage>
#include <iostream>
#include <glm/glm.hpp> using namespace std; class Renderer
{
public:
Renderer();
void render();
}; #endif // RENDERER_H
Renderer.cpp
#include "Renderer.h"
#include "DrawApi.h" Renderer::Renderer()
{ } void Renderer::render()
{ QImage image(,,QImage::Format_RGB32);
image.fill(Qt::gray);
glm::vec3 p0(,,);
glm::vec3 p1(,,);
glm::vec3 p2(,,); // write horizon line
glm::vec3 p3(,,);
glm::vec3 p4(,,);
auto hline1 = LineSegment<glm::vec3>(p3,p4);
DrawApi::drawLine(image,hline1,glm::vec3(,,)); // write verticle line
glm::vec3 p5(,,);
glm::vec3 p6(,,);
auto hline2 = LineSegment<glm::vec3>(p5,p6);
DrawApi::drawLine(image,hline2,glm::vec3(,,)); // write normal line
glm::vec3 p7(,,);
glm::vec3 p8(,,);
auto hline3 = LineSegment<glm::vec3>(p8,p7);
DrawApi::drawLine(image,hline3,glm::vec3(,,)); image.save("c:/Raster.jpg",,);
return ;
}
main.cpp
auto render = Renderer();
render.render();


以上的方法不过还是垃圾,因为还是循环像素row。对于以上的方法如果不考虑计算成本,直接暴力法循环row,
然后判断pixelPos是不是在triangle里面。是就给他画出来。
最好的方法:

线求交:

2,矩阵大法:
计算 :

rotate:


Scale:


translate:


得到的XF = 1*x + 0*y + 1*tx = x + tx;
得到的YF = 0*x + 1*y + 1*ty = y + ty;
总体带x,y,w

3d:


Orthographic Matrix:

Perspective Matrix

Viewport Transform:

Raster Pipeline:


..
Rasterization 学习笔记的更多相关文章
- DirectX 总结和DirectX 9.0 学习笔记
转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
随机推荐
- 【 强大的Mac/iOS开发工具】AppCode for Mac 2017.3
[简介] 最新的 AppCode 2017.3 版本,完全支持最新的Swift 4.0语言,这是一款JetBrain出品的强大的OS X 和 iOS开发工具,AppCode可以用于开发 Mac OS ...
- 2019.03.03 - Linux搭建go语言交叉环境
编译GO 1.6版本以上的需要依赖GO 1.4版本的二进制,并且需要把GOROOT_BOOTSTRAP的路径设置为1.4版本GO的根目录,这样它的bin目录就可以直接使用到1.4版本的GO 搭建go语 ...
- mysql 常用的命令集合
1.创建表 CREATE TABLE `cardPcitrue`( `id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT'编号', `cId` IN ...
- java读大文件最快性能【转】
java读大文件最快性能 完全引用自: 几种读大文件方法的效率对比测试 据说1.88g只要5秒左右,未亲测. /** * 读大文件 * BufferedReader + char[] * @throw ...
- 算法实践——舞蹈链(Dancing Links)算法求解数独
在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...
- SVN快速入门笔记【转】
1. SVN版本控制软件目的 协作开发 远程开发 版本回退 2. 什么是SVN subVersion 支持平台操作 支持版本回退 3. 获取SVN软件 属于C/S结构软件(客户端与服务端) serve ...
- Linux常用bash命令
目录 bash命令 基础操作 export | whereis | which | clear 文件操作 ls | touch | cat | more | head | tail | mv | cp ...
- c3p0配置之preferredTestQuery参数默认值探秘
http://www.mchange.com/projects/c3p0/ c3p0的配置参数preferredTestQuery用于检测数据库连接测试,检测数据库是否能连接成功. Default: ...
- pycharm上传代码到github
一.配置pycharm 点击create API,添加自己的github账号,切记将clone git 那个对勾去掉,不然会报: Successfully created project ‘…’ on ...
- 用Windows Media Service打造的流媒体点播
所谓流媒体是指采用流式传输的方式在Internet播放的媒体格式.和需要将整个视频文件全部下载之后才能观看的传统方式相比,流媒体技术是通过将视频文件经过特殊的压缩方式分成一个个的小数据包,由视频服务器 ...