All Projects → Guarneri1743 → CPU-Rasterizer

Guarneri1743 / CPU-Rasterizer

Licence: MIT license
A tile based cpu rasterizer

Programming Languages

C++
36643 projects - #6 most used programming language
lua
6591 projects

Projects that are alternatives of or similar to CPU-Rasterizer

retro-ngon
A well-featured retro-oriented 3D software renderer for the HTML5 canvas.
Stars: ✭ 30 (+0%)
Mutual labels:  rendering, rasterizer
SHSoftwareRasterizer
软光栅器的简单实现
Stars: ✭ 31 (+3.33%)
Mutual labels:  rendering, rasterizer
ForkerRenderer
CPU-Based Software Forward / Deferred Rasterizer, A Tiny OpenGL (PBR, Soft Shadow, SSAO) 🐼
Stars: ✭ 17 (-43.33%)
Mutual labels:  rendering, rasterizer
Tinyrenderer
A brief computer graphics / rendering course
Stars: ✭ 11,776 (+39153.33%)
Mutual labels:  rendering, rasterizer
CompenNet
[CVPR'19] End-to-end Projector Photometric Compensation
Stars: ✭ 35 (+16.67%)
Mutual labels:  rendering
Blender Cli Rendering
Python scripts for rendering images using Blender 2.83 from command-line interface
Stars: ✭ 241 (+703.33%)
Mutual labels:  rendering
Express Ejs Layouts
Layout support for ejs in express.
Stars: ✭ 243 (+710%)
Mutual labels:  rendering
Render Py
A software 3D renderer written in Python. (Purely educational)
Stars: ✭ 240 (+700%)
Mutual labels:  rendering
glisph
Glyph rendering engine using OpenGL shading language for Common Lisp.
Stars: ✭ 32 (+6.67%)
Mutual labels:  rendering
nub
A rendering and interaction Processing library
Stars: ✭ 28 (-6.67%)
Mutual labels:  rendering
software-development-resources
Collection of links to great software development resources!
Stars: ✭ 20 (-33.33%)
Mutual labels:  rendering
Scriptablerenderpipeline
Scriptable Render Pipeline
Stars: ✭ 2,639 (+8696.67%)
Mutual labels:  rendering
aurum
Fast and concise declarative DOM rendering library for javascript
Stars: ✭ 17 (-43.33%)
Mutual labels:  rendering
Sheepit Client
Client for the free and distributed render farm "SheepIt Render Farm"
Stars: ✭ 244 (+713.33%)
Mutual labels:  rendering
RadeonProRenderUSD
This plug-in allows GPU or CPU accelerated viewport rendering on all OpenCL 1.2 hardware for the open source USD and Hydra system. You can build this plug-in as a USDView plug-in or a Houdini plug-in.
Stars: ✭ 161 (+436.67%)
Mutual labels:  rendering
Polymer
🎨 graphics + interaction engine
Stars: ✭ 243 (+710%)
Mutual labels:  rendering
Gg
Go Graphics - 2D rendering in Go with a simple API.
Stars: ✭ 3,162 (+10440%)
Mutual labels:  rendering
Photon-v2
A program that takes photographs of a virtual world.
Stars: ✭ 75 (+150%)
Mutual labels:  rendering
Simplerenderengine
Small C++14 render engine
Stars: ✭ 253 (+743.33%)
Mutual labels:  rendering
Usd Resources
A curated list of USD projects and resources
Stars: ✭ 250 (+733.33%)
Mutual labels:  rendering

CPU Rasterizer

A tile based cpu rasterizer

Platform

  • Windows
  • Linux
  • MacOS

Usage

  1. download zip or clone CPU-Rasterizer
  2. run 'setup.bat' or type 'premake vs2017/vs2019'
Hello Triangle
#include "CGL.h"
#include "HelloTriangleShader.hpp"

int main()
{
	size_t w = 600;
	size_t h = 400;
	// initialize window
	cglInitWindow("Demo", w, h);

	// set viewport
	cglSetViewPort(0, 0, w, h);

	// resize callback
	cglAddResizeEvent([](size_t resized_w, size_t resized_h, void* ud)
	{
		UNUSED(ud);
		cglSetViewPort(0, 0, resized_w, resized_h);
	}, nullptr);

	HelloTriangleShader shader;
	uint32_t shader_id;
	cglCreateProgram(&shader, shader_id);

	// a triangle 
	cglVert v1(cglVec4(-0.5f, -0.5f, 0.0f, 1.0f), cglVec3Zero, cglVec2Zero);
	cglVert v2(cglVec4(0.5f, -0.5f, 0.0f, 1.0f), cglVec3Zero, cglVec2Zero);
	cglVert v3(cglVec4(0.0f, 0.5f, 0.0f, 1.0f), cglVec3Zero, cglVec2Zero);

	std::vector<cglVert> vertex_buffer = {v1, v2, v3};
	std::vector<size_t> index_buffer = { 0, 1, 2 };

	auto vid = cglBindVertexBuffer(vertex_buffer);
	auto iid = cglBindIndexBuffer(index_buffer);

	// setup shader properties
	cglUniformMatrix4fv(shader_id, mat_model_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_view_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_projection_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_vp_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_mvp_prop, cglMat4Identity);

	cglDisable(cglPipelineFeature::kBlending);
	cglDisable(cglPipelineFeature::kFaceCulling);
	cglDepthFunc(cglCompareFunc::kAlways);

	// set background color
	cglSetClearColor(tinymath::kColorBlue);

	while (cglIsMainWindowOpen())
	{
		// clear window buffer
		cglClearMainWindow();

		// clear buffer
		cglClearBuffer(cglFrameContent::kColor | cglFrameContent::kDepth | cglFrameContent::kStencil);

		cglUseProgram(shader_id);

		cglUseVertexBuffer(vid);
		cglUseIndexBuffer(iid);

		// draw primitive
		cglDrawPrimitive();

		// fence primitive tasks
		cglFencePrimitives();

		// fence pixel tasks
		cglFencePixels();

		cglSwapBuffer(true);
	}

	cglCloseMainWindow();

	return 0;
}

Shader:

#pragma once
#include "Shader.hpp"

using namespace CpuRasterizor;
using namespace tinymath;

class HelloTriangleShader : public Shader
{
public:
	HelloTriangleShader() : Shader("sample_shader") {}

	v2f vertex_shader(const a2v& input) const
	{
		v2f o;
		auto opos = vec4f(input.position.x, input.position.y, input.position.z, 1.0f);
		auto m = model();
		auto vp = vp_matrix();
		auto wpos = m * opos;
		auto cpos = vp * wpos;
		o.position = cpos;
		return o;
	}

	Color fragment_shader(const v2f& input) const
	{
		UNUSED(input);

		// draw a white triangle
		return kColorWhite;
	}
};

Result:

overview

Texture Mapping
#include "CGL.h"
#include "HelloTextureShader.hpp"

int main()
{
	size_t w = 600;
	size_t h = 400;
	// initialize window
	cglInitWindow("Demo", w, h);

	// set viewport
	cglSetViewPort(0, 0, w, h);

	// resize callback
	cglAddResizeEvent([](size_t resized_w, size_t resized_h, void* ud)
	{
		UNUSED(ud);
		cglSetViewPort(0, 0, resized_w, resized_h);
	}, nullptr);

	HelloTextureShader shader;
	uint32_t shader_id;
	cglCreateProgram(&shader, shader_id);

	// a triangle 
	cglVert v1(cglVec4(-0.5f, -0.5f, 0.0f, 1.0f), cglVec3Zero, cglVec2(0.0f, 0.0f));
	cglVert v2(cglVec4(0.5f, -0.5f, 0.0f, 1.0f), cglVec3Zero, cglVec2(1.0f, 0.0f));
	cglVert v3(cglVec4(0.0f, 0.5f, 0.0f, 1.0f), cglVec3Zero, cglVec2(0.5f, 1.0f));

	std::vector<cglVert> vertex_buffer = { v1, v2, v3 };
	std::vector<size_t> index_buffer = { 0, 1, 2 };

	auto vid = cglBindVertexBuffer(vertex_buffer);
	auto iid = cglBindIndexBuffer(index_buffer);

	// setup shader properties
	cglUniformMatrix4fv(shader_id, mat_model_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_view_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_projection_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_vp_prop, cglMat4Identity);
	cglUniformMatrix4fv(shader_id, mat_mvp_prop, cglMat4Identity);

	cglDisable(cglPipelineFeature::kBlending);
	cglDisable(cglPipelineFeature::kFaceCulling);
	cglDepthFunc(cglCompareFunc::kAlways);

	auto tex = std::make_shared<Texture>(64, 64, cglTextureFormat::kRGB);

	// generate a checkerboard texture
	for (size_t r = 0; r < 64; ++r)
	{
		for (size_t c = 0; c < 64; ++c)
		{
			auto val = ((r & 0x8) == 0) ^ ((c & 0x8) == 0);
			tex->write(r, c, { (float)val, (float)val, (float)val, 1.0f});
		}
	}

	// todo: strinify the key
	shader.local_properties.set_texture(123, tex);

	// set background color
	cglSetClearColor(tinymath::kColorBlue);

	while (cglIsMainWindowOpen())
	{
		// clear window buffer
		cglClearMainWindow();

		// clear buffer
		cglClearBuffer(cglFrameContent::kColor | cglFrameContent::kDepth | cglFrameContent::kStencil);

		cglUseProgram(shader_id);

		cglUseVertexBuffer(vid);
		cglUseIndexBuffer(iid);

		// draw primitive
		cglDrawPrimitive();

		// fence primitive tasks
		cglFencePrimitives(); 

		// fence pixel tasks
		cglFencePixels(); 

		cglSwapBuffer(true);
	}

	cglCloseMainWindow();

	return 0;
}

Shader:

#pragma once
#include "Shader.hpp"

using namespace CpuRasterizor;
using namespace tinymath;

class HelloTextureShader : public Shader
{
public:
	HelloTextureShader() : Shader("sample_shader") {}

	v2f vertex_shader(const a2v& input) const
	{
		v2f o;
		auto opos = vec4f(input.position.x, input.position.y, input.position.z, 1.0f);
		auto m = model();
		auto vp = vp_matrix();
		auto wpos = m * opos;
		auto cpos = vp * wpos;
		o.position = cpos;
		o.uv = input.uv;
		return o;
	}

	Color fragment_shader(const v2f& input) const
	{
		UNUSED(input);

		// visualize uv
		//return input.uv;

		// sample texture
		Color c;
		if (local_properties.has_texture(123))
		{
			local_properties.get_texture(123)->sample(input.uv.x, input.uv.y, c);
		}

		return c;
	}
};

Result:

overview

UV can be visualized by:

Color fragment_shader(const v2f& input) const
{
	return input.uv;
}

Result:

overview

Simple Lighting
#include "CGL.h"
#include "HelloLightingShader.hpp"

HelloLightingShader shader;

cglVec3 spherical_coord(float theta, float phi)
{
	cglVec3 ret;
	ret.x = cglCos(theta) * cglCos(phi);
	ret.y = cglSin(theta);
	ret.z = cglCos(theta) * cglSin(phi);
	return cglNormalize(ret);
}

int main()
{
	size_t w = 600;
	size_t h = 400;
	// initialize window
	cglInitWindow("Demo", w, h);

	// set viewport
	cglSetViewPort(0, 0, w, h);

	// resize callback
	cglAddResizeEvent([](size_t resized_w, size_t resized_h, void* ud)
	{
		UNUSED(ud);
		cglSetViewPort(0, 0, resized_w, resized_h);
	}, nullptr);

	// setup shader properties
	cglVec3 cam_pos = cglVec3(1.5f, 1.5f, 1.5f);
	cglVec3 cube_pos = cglVec3Zero;
	cglVec3 light_direction;	

	float l_theta = 0.0f;
	float l_phi = 0.0f;

	light_direction.x = 0.0f;
	light_direction.y = 0.5f;
	light_direction.z = 1.0f;

	float near = 0.05f;
	float far = 100.0f;

	cglMat4 model = cglTranslation(cube_pos);
	cglMat4 view = cglLookat(cam_pos, cube_pos, cglVec3Up);
	cglMat4 proj = cglPerspective(60.0f, (float)w / (float)h, near, far);

	uint32_t shader_id;
	cglCreateProgram(&shader, shader_id);

	cglUniformMatrix4fv(shader_id, mat_model_prop, model);
	cglUniformMatrix4fv(shader_id, mat_view_prop, view);
	cglUniformMatrix4fv(shader_id, mat_projection_prop, proj);
	cglUniformMatrix4fv(shader_id, mat_vp_prop, proj * view);
	cglUniformMatrix4fv(shader_id, mat_mvp_prop, proj * view * model);
	cglUniform4fv(shader_id, cam_position_prop, cam_pos);
	cglUniform4fv(shader_id, albedo_prop, cglVec4(0.5f, 0.0f, 0.0f, 1.0f));
	cglUniform4fv(shader_id, light_direction_prop, light_direction);
	cglUniform4fv(shader_id, light_color_prop, cglVec4(1.0f, 1.0f, 1.0f, 1.0f));
	cglUniform1f(shader_id, light_intensity_prop, 1.0f);

	cglDisable(cglPipelineFeature::kBlending);
	cglEnable(cglPipelineFeature::kFaceCulling);
	cglCullFace(cglFaceCulling::Back);
	cglDepthFunc(cglCompareFunc::kLess);

	std::vector<Vertex> vert;
	std::vector<size_t> ind;

	// construct a sphere
	float step = TWO_PI / 64.0f;
	for (float phi = 0.0f; phi < TWO_PI; phi += step)
	{
		for (float theta = -HALF_PI; theta < HALF_PI; theta += step)
		{
			float phi0 = phi;
			float phi1 = phi + step;

			float theta0 = theta;
			float theta1 = theta + step;

			auto pos0 = spherical_coord(theta0, phi0);

			auto pos1 = spherical_coord(theta1, phi0);

			auto pos2 = spherical_coord(theta1, phi1);

			auto pos3 = spherical_coord(theta0, phi1);

			Vertex v0, v1, v2, v3;
			v0.position = pos0;
			v0.normal = pos0;
			v1.position = pos1;
			v1.normal = pos1;
			v2.position = pos2;
			v2.normal = pos2;
			v3.position = pos3;
			v3.normal = pos3;

			ind.push_back(vert.size());
			vert.push_back(v0);
			ind.push_back(vert.size());
			vert.push_back(v1);
			ind.push_back(vert.size());
			vert.push_back(v2);
			ind.push_back(vert.size());
			vert.push_back(v0);
			ind.push_back(vert.size());
			vert.push_back(v2);
			ind.push_back(vert.size());
			vert.push_back(v3);
		}
	}

	auto vid = cglBindVertexBuffer(vert);
	auto iid = cglBindIndexBuffer(ind);

	// set background color
	cglSetClearColor(tinymath::kColorBlue);

	while (cglIsMainWindowOpen())
	{
		// clear window buffer
		cglClearMainWindow();

		// clear buffer
		cglClearBuffer(cglFrameContent::kColor | cglFrameContent::kDepth | cglFrameContent::kStencil);

		// rotate light
		l_theta += 0.01f;
		l_phi += 0.01f;
		light_direction.x = cglCos(l_theta) * cglCos(l_phi);
		light_direction.y = cglSin (l_theta);
		light_direction.z = cglCos(l_theta) * cglSin(l_phi);
		light_direction = cglNormalize(light_direction);

		shader.local_properties.set_float4(light_direction_prop, light_direction);

		cglUseProgram(shader_id);

		cglUseVertexBuffer(vid);
		cglUseIndexBuffer(iid);

		// draw primitive
		cglDrawPrimitive();

		// fence primitive tasks
		cglFencePrimitives();

		// fence pixel tasks
		cglFencePixels();

		cglSwapBuffer(true);
	}

	cglCloseMainWindow();

	return 0;
}

Shader:

#pragma once
#include "Shader.hpp"

using namespace CpuRasterizor;
using namespace tinymath;

class HelloLightingShader : public Shader
{
public:
	HelloLightingShader() : Shader("sample_shader") {}

	v2f vertex_shader(const a2v& input) const
	{
		v2f o;
		auto opos = vec4f(input.position.x, input.position.y, input.position.z, 1.0f);
		auto m = model();
		auto vp = vp_matrix();
		auto wpos = m * opos;
		auto v = view();
		auto p = projection();
		auto cpos = vp * wpos;
		o.position = cpos;
		o.uv = input.uv;
		mat3x3 normal_matrix = mat4x4_to_mat3x3(transpose(inverse(m)));
		o.normal = normal_matrix * input.normal;
		return o;
	}

	Color fragment_shader(const v2f& input) const
	{
		vec4f albedo = local_properties.get_float4(albedo_prop);
		vec4f light_color = local_properties.get_float4(light_color_prop);
		float intensity = local_properties.get_float(light_intensity_prop);

		vec3f normal = input.normal;
		vec3f light_dir = local_properties.get_float4(light_direction_prop).xyz;
		float ndl = dot(normal, light_dir);

		return albedo * light_color * ndl * intensity;
	}
};

Result:

overview

Viewer

overview

MaterialEditor

overview

HDRI Tool

lookdev

Gallery

Physical based rendering Physical based rendering Image based lighting
Roughness Metallic MSAA
MSAA Pixel Derivative Clipping DebugView
MSAA Mipmap Clipping DebugView
Stencil test Depth test Blending
Per Sample Operation Per Sample Operation Blending
Point sampler Bilinear sampler
Texture Filtering Texture Filtering
Mipmap
MSAA

Features

  • tile based

  • fully parallel of triangle/pixel processing

  • vertex/fragment shader

  • cvv clipping

  • frustum culling

  • back-face culling

  • msaa (pixel frequency and subsample frequency)

  • perspective correct interpolation

  • early-z

  • alpha test

  • stencil test

  • depth test

  • alpha blending

  • texture sampler

  • cubemap sampler

  • pixel derivative

  • mipmap

  • segment drawer


Application

  • viewer

  • input manager

  • model importer

  • resource serialization & deserialization

  • hierarchical transform

  • roaming camera

  • material

  • texture

  • renderer

  • cook-torrance brdf

  • ibl baker

  • ibl

  • metallic workflow

  • gamma/linear workflow


Third Parties


Future Works

  • simd

  • premake --> cmake

  • cross platform

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].