Skip to content

Commit

Permalink
model cartoon
Browse files Browse the repository at this point in the history
  • Loading branch information
ccsdu2004 committed Jan 10, 2022
1 parent f2f4e1c commit 7dfa9e5
Show file tree
Hide file tree
Showing 13 changed files with 386 additions and 0 deletions.
2 changes: 2 additions & 0 deletions demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ set(DEMOS
model-mesh
model-mesh-geom
model-mesh-tess
model-toon
model-outline
)

foreach(var IN LISTS DEMOS)
Expand Down
130 changes: 130 additions & 0 deletions demo/main-model-outline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <iostream>
#include <cstring>
#include <chrono>
#include <glm/mat4x4.hpp>
#include <glm/gtx/transform.hpp>
#include "VK_UniformBuffer.h"
#include "VK_Context.h"
#include "VK_Image.h"
#include "VK_Texture.h"

using namespace std;

VK_Context *context = nullptr;

struct UBO {
glm::mat4 projection;
glm::mat4 model;
glm::vec4 lightPos = glm::vec4(0.2f, 0.5f, 0.8f, 0.0f);
float outlineWidth = 0.01f;
};

uint32_t updateUniformBufferData(char *&data, uint32_t size)
{
assert(sizeof(UBO) == size);
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
glm::mat4 model = glm::identity<glm::mat4>();
model *= glm::scale(glm::vec3(1.5f, 1.5f, 1.5f));
model *= glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
model *= glm::rotate(glm::mat4(1.0f), time * glm::radians(30.0f), glm::vec3(0.0f, 1.0f, 0.0f));
auto view = glm::lookAt(glm::vec3(0.0f, 4.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
auto proj = glm::perspective(glm::radians(45.0f), context->getSwapChainExtent().width / (float)context->getSwapChainExtent().height, 0.1f, 10.0f);
proj[1][1] *= -1;

UBO ubo;
ubo.projection = proj * view;
ubo.model = model;
memcpy(data, &ubo, sizeof(UBO));
time = sin(time);
return sizeof(UBO);
}

void onFrameSizeChanged(int width, int height)
{
auto vp = VK_Viewports::createViewport(width, height);
VK_Viewports vps;
vps.addViewport(vp);
context->setViewports(vps);
}

int main()
{
VK_ContextConfig config;
config.debug = false;
config.name = "Model Outline";

context = createVkContext(config);
context->createWindow(480, 480, true);
context->setOnFrameSizeChanged(onFrameSizeChanged);

VK_Context::VK_Config vkConfig;
context->initVulkanDevice(vkConfig);

auto shaderSet = context->createShaderSet();
shaderSet->addShader("../shader/model-outline/vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderSet->addShader("../shader/model-outline/frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);

shaderSet->appendAttributeDescription(0, sizeof (float) * 3);
shaderSet->appendAttributeDescription(1, sizeof (float) * 2);
shaderSet->appendAttributeDescription(2, sizeof (float) * 3);

VkDescriptorSetLayoutBinding uniformBinding = VK_ShaderSet::createDescriptorSetLayoutBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT);
shaderSet->addDescriptorSetLayoutBinding(uniformBinding);

auto samplerBinding = VK_ShaderSet::createDescriptorSetLayoutBinding(1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
shaderSet->addDescriptorSetLayoutBinding(uniformBinding);
auto samplerCreateInfo = VK_Sampler::createSamplerCreateInfo();
auto samplerPtr = context->createSampler(samplerCreateInfo);
VkSampler sampler = samplerPtr->getSampler();
samplerBinding.pImmutableSamplers = &sampler;

shaderSet->addDescriptorSetLayoutBinding(samplerBinding);

if (!shaderSet->isValid()) {
std::cerr << "invalid shaderSet" << std::endl;
shaderSet->release();
context->release();
return -1;
}

auto ubo = context->createUniformBuffer(0, sizeof(UBO));
ubo->setWriteDataCallback(updateUniformBufferData);
context->addUniformBuffer(ubo);

auto buffer = context->createVertexBuffer("../model/pug.obj", true);
context->addBuffer(buffer);

auto image = context->createImage("../model/PUG_TAN.tga");

auto imageViewCreateInfo = VK_ImageView::createImageViewCreateInfo(image->getImage(),
VK_FORMAT_R8G8B8A8_SRGB);
auto imageView = context->createImageView(imageViewCreateInfo);
context->addImageView(imageView);

context->initVulkanContext(shaderSet);

auto rasterCreateInfo = context->getPipelineRasterizationStateCreateInfo();
rasterCreateInfo.cullMode = VK_CULL_MODE_NONE;
context->setPipelineRasterizationStateCreateInfo(rasterCreateInfo);

auto depthStencilState = context->getPipelineDepthStencilStateCreateInfo();
depthStencilState.back.compareOp = VK_COMPARE_OP_NOT_EQUAL;
depthStencilState.back.failOp = VK_STENCIL_OP_KEEP;
depthStencilState.back.depthFailOp = VK_STENCIL_OP_KEEP;
depthStencilState.back.passOp = VK_STENCIL_OP_REPLACE;
depthStencilState.front = depthStencilState.back;
depthStencilState.depthTestEnable = VK_FALSE;
context->setPipelineDepthStencilStateCreateInfo(depthStencilState);

context->initPipeline();
context->createCommandBuffers();

context->run();
context->release();

return 0;
}
150 changes: 150 additions & 0 deletions demo/main-model-toon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#include <iostream>
#include <cstring>
#include <chrono>
#include <glm/mat4x4.hpp>
#include <glm/gtx/transform.hpp>
#include "VK_UniformBuffer.h"
#include "VK_Context.h"
#include "VK_Image.h"
#include "VK_Texture.h"

using namespace std;

VK_Context *context = nullptr;

struct UBO {
glm::mat4 projection;
glm::mat4 model;
glm::vec4 lightPos = glm::vec4(0.2f, 0.5f, 1.2f, 0.0f);
};

uint32_t updateUniformBufferData(char *&data, uint32_t size)
{
assert(sizeof(UBO) == size);
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
glm::mat4 model = glm::identity<glm::mat4>();
model *= glm::scale(glm::vec3(1.5f, 1.5f, 1.5f));
model *= glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
model *= glm::rotate(glm::mat4(1.0f), time * glm::radians(30.0f), glm::vec3(0.0f, 1.0f, 0.0f));
auto view = glm::lookAt(glm::vec3(0.0f, 4.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
auto proj = glm::perspective(glm::radians(45.0f), context->getSwapChainExtent().width / (float)context->getSwapChainExtent().height, 0.1f, 10.0f);
proj[1][1] *= -1;

UBO ubo;
ubo.projection = proj * view;
ubo.model = model;
memcpy(data, &ubo, sizeof(UBO));
time = sin(time);
return sizeof(UBO);
}

uint32_t updateUniformBufferData2(char *&data, uint32_t size)
{
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
time = (std::cos(time) + 1.0) * 0.5;
memcpy(data, &time, size);
return size;
}

void onFrameSizeChanged(int width, int height)
{
auto vp = VK_Viewports::createViewport(width, height);
VK_Viewports vps;
vps.addViewport(vp);
context->setViewports(vps);
}

int main()
{
VK_ContextConfig config;
config.debug = false;
config.name = "Model Cartoon";

context = createVkContext(config);
context->createWindow(480, 480, true);
context->setOnFrameSizeChanged(onFrameSizeChanged);

VK_Context::VK_Config vkConfig;
context->initVulkanDevice(vkConfig);

auto shaderSet = context->createShaderSet();
shaderSet->addShader("../shader/model-toon/vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderSet->addShader("../shader/model-toon/frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);

shaderSet->appendAttributeDescription(0, sizeof (float) * 3);
shaderSet->appendAttributeDescription(1, sizeof (float) * 2);
shaderSet->appendAttributeDescription(2, sizeof (float) * 3);

VkDescriptorSetLayoutBinding uniformBinding = VK_ShaderSet::createDescriptorSetLayoutBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT);
shaderSet->addDescriptorSetLayoutBinding(uniformBinding);

auto samplerBinding = VK_ShaderSet::createDescriptorSetLayoutBinding(1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
shaderSet->addDescriptorSetLayoutBinding(uniformBinding);
auto samplerCreateInfo = VK_Sampler::createSamplerCreateInfo();
auto samplerPtr = context->createSampler(samplerCreateInfo);
VkSampler sampler = samplerPtr->getSampler();
samplerBinding.pImmutableSamplers = &sampler;

shaderSet->addDescriptorSetLayoutBinding(samplerBinding);

VkDescriptorSetLayoutBinding uniformBinding2 = VK_ShaderSet::createDescriptorSetLayoutBinding(2,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
shaderSet->addDescriptorSetLayoutBinding(uniformBinding2);

if (!shaderSet->isValid()) {
std::cerr << "invalid shaderSet" << std::endl;
shaderSet->release();
context->release();
return -1;
}

auto ubo = context->createUniformBuffer(0, sizeof(UBO));
ubo->setWriteDataCallback(updateUniformBufferData);
context->addUniformBuffer(ubo);

auto ubo2 = context->createUniformBuffer(2, sizeof(float));
ubo2->setWriteDataCallback(updateUniformBufferData2);
context->addUniformBuffer(ubo2);

auto buffer = context->createVertexBuffer("../model/pug.obj", true);
context->addBuffer(buffer);

auto image = context->createImage("../model/PUG_TAN.tga");

auto imageViewCreateInfo = VK_ImageView::createImageViewCreateInfo(image->getImage(),
VK_FORMAT_R8G8B8A8_SRGB);
auto imageView = context->createImageView(imageViewCreateInfo);
context->addImageView(imageView);

context->initVulkanContext(shaderSet);

auto rasterCreateInfo = context->getPipelineRasterizationStateCreateInfo();
rasterCreateInfo.cullMode = VK_CULL_MODE_NONE;
context->setPipelineRasterizationStateCreateInfo(rasterCreateInfo);

auto depthStencilState = context->getPipelineDepthStencilStateCreateInfo();
depthStencilState.stencilTestEnable = VK_TRUE;
depthStencilState.back.compareOp = VK_COMPARE_OP_ALWAYS;
depthStencilState.back.failOp = VK_STENCIL_OP_REPLACE;
depthStencilState.back.depthFailOp = VK_STENCIL_OP_REPLACE;
depthStencilState.back.passOp = VK_STENCIL_OP_REPLACE;
depthStencilState.back.compareMask = 0x0f;
depthStencilState.back.writeMask = 0xff;
depthStencilState.back.reference = 1;
depthStencilState.front = depthStencilState.back;
context->setPipelineDepthStencilStateCreateInfo(depthStencilState);

context->initPipeline();
context->createCommandBuffers();

context->run();
context->release();

return 0;
}
Binary file added screenshots/model-cartoon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/model-outline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shader/model-outline/frag.spv
Binary file not shown.
8 changes: 8 additions & 0 deletions shader/model-outline/outline.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColorMap;
layout (location = 0) out vec4 outFragColor;

void main()
{
outFragColor = vec4(0.3,0.3,0.6, 1.0);
}
23 changes: 23 additions & 0 deletions shader/model-outline/outline.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#version 450
layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;

layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 model;
vec4 lightPos;
float outlineWidth;
} ubo;

out gl_PerVertex
{
vec4 gl_Position;
};

void main()
{
vec4 pos = vec4(inPos.xyz + inNormal * ubo.outlineWidth,1.0);
gl_Position = ubo.projection * ubo.model * pos;
}
Binary file added shader/model-outline/vert.spv
Binary file not shown.
Binary file added shader/model-toon/frag.spv
Binary file not shown.
40 changes: 40 additions & 0 deletions shader/model-toon/toon.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#version 450

layout (binding = 1) uniform sampler2D samplerColorMap;
layout (binding = 2) uniform Time
{
float current;
} time;

layout (location = 0) in vec3 inNormal;
layout (location = 1) in vec3 inColor;
layout (location = 2) in vec3 inLightVec;
layout (location = 3) in vec2 inCoord;

layout (location = 0) out vec4 outFragColor;

void main()
{
vec3 color;
vec3 N = normalize(inNormal);
vec3 L = normalize(inLightVec);
float intensity = dot(N,L);

if(intensity > 0.95)
color = inColor * 1.2;
else if(intensity > 0.8)
color = inColor * 1.0;
else if(intensity > 0.6)
color = inColor * 0.6;
else if(intensity > 0.4)
color = inColor * 0.4;
else if(intensity > 0.25)
color = inColor * 0.4;
else
color = inColor * 0.1;

outFragColor = mix(texture(samplerColorMap,inCoord),vec4(color,1.0),time.current);
}



Loading

0 comments on commit 7dfa9e5

Please sign in to comment.