Updated displacement example
This commit is contained in:
parent
0ecff76c40
commit
2ec1a60535
16 changed files with 77 additions and 177 deletions
|
|
@ -12,12 +12,10 @@ if %ERRORLEVEL% EQU 0 (
|
||||||
xcopy "..\..\data\shaders\displacement\*.spv" "assets\shaders\displacement" /Y
|
xcopy "..\..\data\shaders\displacement\*.spv" "assets\shaders\displacement" /Y
|
||||||
|
|
||||||
mkdir "assets\textures"
|
mkdir "assets\textures"
|
||||||
xcopy "..\..\data\textures\stonewall_colormap_bc3.dds" "assets\textures" /Y
|
xcopy "..\..\data\textures\pattern_36_bc3.ktx" "assets\textures" /Y
|
||||||
xcopy "..\..\data\textures\stonewall_heightmap_rgba.dds" "assets\textures" /Y
|
|
||||||
|
|
||||||
|
|
||||||
mkdir "assets\models"
|
mkdir "assets\models"
|
||||||
xcopy "..\..\data\models\torus.obj" "assets\models" /Y
|
xcopy "..\..\data\models\plane.obj" "assets\models" /Y
|
||||||
|
|
||||||
mkdir "res\drawable"
|
mkdir "res\drawable"
|
||||||
xcopy "..\..\android\images\icon.png" "res\drawable" /Y
|
xcopy "..\..\android\images\icon.png" "res\drawable" /Y
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
layout (binding = 3) uniform sampler2D colorMap;
|
layout (binding = 2) uniform sampler2D colorMap;
|
||||||
|
|
||||||
layout (location = 0) in vec3 inNormal;
|
layout (location = 0) in vec3 inNormal;
|
||||||
layout (location = 1) in vec2 inUV;
|
layout (location = 1) in vec2 inUV;
|
||||||
|
|
@ -25,5 +25,5 @@ void main()
|
||||||
vec4 IAmbient = vec4(0.0, 0.0, 0.0, 1.0);
|
vec4 IAmbient = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
vec4 IDiffuse = vec4(1.0) * max(dot(inNormal, inLightVec), 0.0);
|
vec4 IDiffuse = vec4(1.0) * max(dot(inNormal, inLightVec), 0.0);
|
||||||
|
|
||||||
outFragColor = vec4((IAmbient + IDiffuse) * texture(colorMap, inUV));
|
outFragColor = vec4((IAmbient + IDiffuse) * vec4(texture(colorMap, inUV).rgb, 1.0));
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
|
@ -18,15 +18,15 @@ layout (location = 1) out vec2 outUV[3];
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
if (gl_InvocationID == 0)
|
if (gl_InvocationID == 0)
|
||||||
{
|
{
|
||||||
gl_TessLevelInner[0] = ubo.tessLevel;
|
gl_TessLevelInner[0] = ubo.tessLevel;
|
||||||
gl_TessLevelOuter[0] = ubo.tessLevel;
|
gl_TessLevelOuter[0] = ubo.tessLevel;
|
||||||
gl_TessLevelOuter[1] = ubo.tessLevel;
|
gl_TessLevelOuter[1] = ubo.tessLevel;
|
||||||
gl_TessLevelOuter[2] = ubo.tessLevel;
|
gl_TessLevelOuter[2] = ubo.tessLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
|
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
|
||||||
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
|
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
|
||||||
outUV[gl_InvocationID] = inUV[gl_InvocationID];
|
outUV[gl_InvocationID] = inUV[gl_InvocationID];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,11 @@ layout (location = 3) out vec3 outLightVec;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
||||||
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) + (gl_TessCoord.y * gl_in[1].gl_Position) + (gl_TessCoord.z * gl_in[2].gl_Position);
|
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) + (gl_TessCoord.y * gl_in[1].gl_Position) + (gl_TessCoord.z * gl_in[2].gl_Position);
|
||||||
outUV = gl_TessCoord.x * inUV[0] + gl_TessCoord.y * inUV[1] + gl_TessCoord.z * inUV[2];
|
outUV = gl_TessCoord.x * inUV[0] + gl_TessCoord.y * inUV[1] + gl_TessCoord.z * inUV[2];
|
||||||
outNormal = gl_TessCoord.x * inNormal[0] + gl_TessCoord.y * inNormal[1] + gl_TessCoord.z * inNormal[2];
|
outNormal = gl_TessCoord.x * inNormal[0] + gl_TessCoord.y * inNormal[1] + gl_TessCoord.z * inNormal[2];
|
||||||
|
|
||||||
gl_Position.xyz += normalize(outNormal) * (max(textureLod(displacementMap, outUV.st, 0.0).r, 0.45) * ubo.tessStrength);
|
gl_Position.xyz += normalize(outNormal) * (max(textureLod(displacementMap, outUV.st, 0.0).a, 0.0) * ubo.tessStrength);
|
||||||
|
|
||||||
outEyesPos = (gl_Position).xyz;
|
outEyesPos = (gl_Position).xyz;
|
||||||
outLightVec = normalize(ubo.lightPos.xyz - outEyesPos);
|
outLightVec = normalize(ubo.lightPos.xyz - outEyesPos);
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,7 +1,5 @@
|
||||||
glslangvalidator -V base.vert -o base.vert.spv
|
glslangvalidator -V base.vert -o base.vert.spv
|
||||||
glslangvalidator -V base.frag -o base.frag.spv
|
glslangvalidator -V base.frag -o base.frag.spv
|
||||||
glslangvalidator -V passthrough.tesc -o passthrough.tesc.spv
|
|
||||||
glslangvalidator -V passthrough.tese -o passthrough.tese.spv
|
|
||||||
glslangvalidator -V displacement.tesc -o displacement.tesc.spv
|
glslangvalidator -V displacement.tesc -o displacement.tesc.spv
|
||||||
glslangvalidator -V displacement.tese -o displacement.tese.spv
|
glslangvalidator -V displacement.tese -o displacement.tese.spv
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
|
||||||
|
|
||||||
layout (vertices = 3) out;
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 inNormal[];
|
|
||||||
layout (location = 1) in vec2 inTexCoord[];
|
|
||||||
layout (location = 0) out vec3 outNormal[3];
|
|
||||||
layout (location = 3) out vec2 oTexCoord[3];
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
if (gl_InvocationID == 0)
|
|
||||||
{
|
|
||||||
gl_TessLevelInner[0] = 1.0;
|
|
||||||
gl_TessLevelOuter[0] = 1.0;
|
|
||||||
gl_TessLevelOuter[1] = 1.0;
|
|
||||||
gl_TessLevelOuter[2] = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
|
|
||||||
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
|
|
||||||
oTexCoord[gl_InvocationID] = inTexCoord[gl_InvocationID];
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
|
@ -1,34 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
|
||||||
|
|
||||||
layout (triangles) in;
|
|
||||||
|
|
||||||
layout (binding = 1) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 projection;
|
|
||||||
mat4 model;
|
|
||||||
vec3 lightPos;
|
|
||||||
float tessAlpha;
|
|
||||||
float tessStrength;
|
|
||||||
} ubo;
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 inNormal[];
|
|
||||||
layout (location = 3) in vec2 inTexCoord[];
|
|
||||||
layout (location = 0) out vec3 outNormal;
|
|
||||||
layout (location = 1) out vec2 outTexCoord;
|
|
||||||
layout (location = 2) out vec3 outEyesPos;
|
|
||||||
layout (location = 3) out vec3 outLightVec;
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) + (gl_TessCoord.y * gl_in[1].gl_Position) + (gl_TessCoord.z * gl_in[2].gl_Position);
|
|
||||||
outNormal = gl_TessCoord.x * inNormal[0] + gl_TessCoord.y * inNormal[1] + gl_TessCoord.z * inNormal[2];
|
|
||||||
outTexCoord = gl_TessCoord.x * inTexCoord[0] + gl_TessCoord.y * inTexCoord[1] + gl_TessCoord.z * inTexCoord[2];
|
|
||||||
gl_Position.xyz += normalize(outNormal);
|
|
||||||
outEyesPos = (gl_Position).xyz;
|
|
||||||
outLightVec = normalize(ubo.lightPos - outEyesPos);
|
|
||||||
gl_Position = ubo.projection * ubo.model * gl_Position;
|
|
||||||
|
|
||||||
}
|
|
||||||
Binary file not shown.
BIN
data/textures/pattern_36_bc3.ktx
Normal file
BIN
data/textures/pattern_36_bc3.ktx
Normal file
Binary file not shown.
|
|
@ -36,11 +36,11 @@ class VulkanExample : public VulkanExampleBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct {
|
struct {
|
||||||
vkTools::VulkanTexture colorMap;
|
vkTools::VulkanTexture colorHeightMap;
|
||||||
vkTools::VulkanTexture heightMap;
|
|
||||||
} textures;
|
} textures;
|
||||||
public:
|
public:
|
||||||
bool splitScreen = true;
|
bool splitScreen = true;
|
||||||
|
bool displacement = true;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
VkPipelineVertexInputStateCreateInfo inputState;
|
VkPipelineVertexInputStateCreateInfo inputState;
|
||||||
|
|
@ -55,25 +55,21 @@ public:
|
||||||
vkTools::UniformData uniformDataTC, uniformDataTE;
|
vkTools::UniformData uniformDataTC, uniformDataTE;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
float tessLevel = 8.0;
|
float tessLevel = 64.0f;
|
||||||
} uboTC;
|
} uboTC;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
glm::vec4 lightPos = glm::vec4(0.0, -25.0, 0.0, 0.0);
|
glm::vec4 lightPos = glm::vec4(0.0f, -1.0f, 0.0f, 0.0f);
|
||||||
float tessAlpha = 1.0;
|
float tessAlpha = 1.0f;
|
||||||
float tessStrength = 1.0;
|
float tessStrength = 0.1f;
|
||||||
} uboTE;
|
} uboTE;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
VkPipeline solid;
|
VkPipeline solid;
|
||||||
VkPipeline wire;
|
VkPipeline wireframe;
|
||||||
VkPipeline solidPassThrough;
|
|
||||||
VkPipeline wirePassThrough;
|
|
||||||
} pipelines;
|
} pipelines;
|
||||||
VkPipeline *pipelineLeft = &pipelines.solidPassThrough;
|
|
||||||
VkPipeline *pipelineRight = &pipelines.solid;
|
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
VkDescriptorSet descriptorSet;
|
VkDescriptorSet descriptorSet;
|
||||||
|
|
@ -81,8 +77,8 @@ public:
|
||||||
|
|
||||||
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
|
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
|
||||||
{
|
{
|
||||||
zoom = -35;
|
zoom = -1.25f;
|
||||||
rotation = glm::vec3(-35.0, 0.0, 0);
|
rotation = glm::vec3(-20.0f, 45.0f, 0.0f);
|
||||||
enableTextOverlay = true;
|
enableTextOverlay = true;
|
||||||
title = "Vulkan Example - Tessellation shader displacement mapping";
|
title = "Vulkan Example - Tessellation shader displacement mapping";
|
||||||
// Support for tessellation shaders is optional, so check first
|
// Support for tessellation shaders is optional, so check first
|
||||||
|
|
@ -97,9 +93,7 @@ public:
|
||||||
// Clean up used Vulkan resources
|
// Clean up used Vulkan resources
|
||||||
// Note : Inherited destructor cleans up resources stored in base class
|
// Note : Inherited destructor cleans up resources stored in base class
|
||||||
vkDestroyPipeline(device, pipelines.solid, nullptr);
|
vkDestroyPipeline(device, pipelines.solid, nullptr);
|
||||||
vkDestroyPipeline(device, pipelines.wire, nullptr);
|
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
||||||
vkDestroyPipeline(device, pipelines.solidPassThrough, nullptr);
|
|
||||||
vkDestroyPipeline(device, pipelines.wirePassThrough, nullptr);
|
|
||||||
|
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
|
|
@ -112,20 +106,15 @@ public:
|
||||||
vkDestroyBuffer(device, uniformDataTE.buffer, nullptr);
|
vkDestroyBuffer(device, uniformDataTE.buffer, nullptr);
|
||||||
vkFreeMemory(device, uniformDataTE.memory, nullptr);
|
vkFreeMemory(device, uniformDataTE.memory, nullptr);
|
||||||
|
|
||||||
textureLoader->destroyTexture(textures.colorMap);
|
textureLoader->destroyTexture(textures.colorHeightMap);
|
||||||
textureLoader->destroyTexture(textures.heightMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadTextures()
|
void loadTextures()
|
||||||
{
|
{
|
||||||
textureLoader->loadTexture(
|
textureLoader->loadTexture(
|
||||||
getAssetPath() + "textures/stonewall_colormap_bc3.dds",
|
getAssetPath() + "textures/pattern_36_bc3.ktx",
|
||||||
VK_FORMAT_BC3_UNORM_BLOCK,
|
VK_FORMAT_BC3_UNORM_BLOCK,
|
||||||
&textures.colorMap);
|
&textures.colorHeightMap);
|
||||||
textureLoader->loadTexture(
|
|
||||||
getAssetPath() + "textures/stonewall_heightmap_rgba.dds",
|
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
|
||||||
&textures.heightMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reBuildCommandBuffers()
|
void reBuildCommandBuffers()
|
||||||
|
|
@ -164,10 +153,10 @@ public:
|
||||||
|
|
||||||
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
VkViewport viewport = vkTools::initializers::viewport(splitScreen ? (float)width / 2.0f : (float)width, (float)height, 0.0f, 1.0f);
|
VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
|
||||||
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
|
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
|
||||||
|
|
||||||
VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0);
|
VkRect2D scissor = vkTools::initializers::rect2D(splitScreen ? width / 2 : width, height, 0, 0);
|
||||||
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
||||||
|
|
||||||
vkCmdSetLineWidth(drawCmdBuffers[i], 1.0f);
|
vkCmdSetLineWidth(drawCmdBuffers[i], 1.0f);
|
||||||
|
|
@ -180,14 +169,13 @@ public:
|
||||||
|
|
||||||
if (splitScreen)
|
if (splitScreen)
|
||||||
{
|
{
|
||||||
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe);
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLeft);
|
|
||||||
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0);
|
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0);
|
||||||
viewport.x = float(width) / 2;
|
scissor.offset.x = width / 2;
|
||||||
|
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid);
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineRight);
|
|
||||||
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0);
|
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0);
|
||||||
|
|
||||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||||
|
|
@ -198,7 +186,7 @@ public:
|
||||||
|
|
||||||
void loadMeshes()
|
void loadMeshes()
|
||||||
{
|
{
|
||||||
loadMesh(getAssetPath() + "models/torus.obj", &meshes.object, vertexLayout, 0.25f);
|
loadMesh(getAssetPath() + "models/plane.obj", &meshes.object, vertexLayout, 0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupVertexDescriptions()
|
void setupVertexDescriptions()
|
||||||
|
|
@ -252,7 +240,7 @@ public:
|
||||||
std::vector<VkDescriptorPoolSize> poolSizes =
|
std::vector<VkDescriptorPoolSize> poolSizes =
|
||||||
{
|
{
|
||||||
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2),
|
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2),
|
||||||
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2)
|
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo descriptorPoolInfo =
|
VkDescriptorPoolCreateInfo descriptorPoolInfo =
|
||||||
|
|
@ -278,16 +266,11 @@ public:
|
||||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
|
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
|
||||||
1),
|
1),
|
||||||
// Binding 2 : Tessellation evaluation shader displacement map image sampler
|
// Binding 2 : Combined color (rgb) and height (alpha) map
|
||||||
vkTools::initializers::descriptorSetLayoutBinding(
|
vkTools::initializers::descriptorSetLayoutBinding(
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
|
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
2),
|
2),
|
||||||
// Binding 3 : Fragment shader color map image sampler
|
|
||||||
vkTools::initializers::descriptorSetLayoutBinding(
|
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
3),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo descriptorLayout =
|
VkDescriptorSetLayoutCreateInfo descriptorLayout =
|
||||||
|
|
@ -315,18 +298,11 @@ public:
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
||||||
|
|
||||||
// Displacement map image descriptor
|
// Color and height map image descriptor
|
||||||
VkDescriptorImageInfo texDescriptorDisplacementMap =
|
VkDescriptorImageInfo texDescriptor =
|
||||||
vkTools::initializers::descriptorImageInfo(
|
vkTools::initializers::descriptorImageInfo(
|
||||||
textures.heightMap.sampler,
|
textures.colorHeightMap.sampler,
|
||||||
textures.heightMap.view,
|
textures.colorHeightMap.view,
|
||||||
VK_IMAGE_LAYOUT_GENERAL);
|
|
||||||
|
|
||||||
// Color map image descriptor
|
|
||||||
VkDescriptorImageInfo texDescriptorColorMap =
|
|
||||||
vkTools::initializers::descriptorImageInfo(
|
|
||||||
textures.colorMap.sampler,
|
|
||||||
textures.colorMap.view,
|
|
||||||
VK_IMAGE_LAYOUT_GENERAL);
|
VK_IMAGE_LAYOUT_GENERAL);
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets =
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets =
|
||||||
|
|
@ -343,18 +319,12 @@ public:
|
||||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
1,
|
1,
|
||||||
&uniformDataTE.descriptor),
|
&uniformDataTE.descriptor),
|
||||||
// Binding 2 : Displacement map
|
// Binding 2 : Color and displacement map (alpha channel)
|
||||||
vkTools::initializers::writeDescriptorSet(
|
vkTools::initializers::writeDescriptorSet(
|
||||||
descriptorSet,
|
descriptorSet,
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
2,
|
2,
|
||||||
&texDescriptorDisplacementMap),
|
&texDescriptor),
|
||||||
// Binding 3 : Color map
|
|
||||||
vkTools::initializers::writeDescriptorSet(
|
|
||||||
descriptorSet,
|
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
||||||
3,
|
|
||||||
&texDescriptorColorMap),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL);
|
vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL);
|
||||||
|
|
@ -446,20 +416,7 @@ public:
|
||||||
// Wireframe pipeline
|
// Wireframe pipeline
|
||||||
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
|
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
|
||||||
rasterizationState.cullMode = VK_CULL_MODE_NONE;
|
rasterizationState.cullMode = VK_CULL_MODE_NONE;
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire));
|
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireframe));
|
||||||
|
|
||||||
// Pass through pipelines
|
|
||||||
// Load pass through tessellation shaders (Vert and frag are reused)
|
|
||||||
shaderStages[2] = loadShader(getAssetPath() + "shaders/displacement/passthrough.tesc.spv", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
|
|
||||||
shaderStages[3] = loadShader(getAssetPath() + "shaders/displacement/passthrough.tese.spv", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
|
|
||||||
// Solid
|
|
||||||
rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
|
|
||||||
rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;
|
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidPassThrough));
|
|
||||||
// Wireframe
|
|
||||||
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
|
|
||||||
rasterizationState.cullMode = VK_CULL_MODE_NONE;
|
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare and initialize uniform buffer containing shader uniforms
|
// Prepare and initialize uniform buffer containing shader uniforms
|
||||||
|
|
@ -492,7 +449,7 @@ public:
|
||||||
{
|
{
|
||||||
// Tessellation eval
|
// Tessellation eval
|
||||||
glm::mat4 viewMatrix = glm::mat4();
|
glm::mat4 viewMatrix = glm::mat4();
|
||||||
uboTE.projection = glm::perspective(glm::radians(45.0f), (float)(width* ((splitScreen) ? 0.5f : 1.0f)) / (float)height, 0.1f, 256.0f);
|
uboTE.projection = glm::perspective(glm::radians(45.0f), (float)(width) / (float)height, 0.1f, 256.0f);
|
||||||
viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom));
|
viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom));
|
||||||
|
|
||||||
float offset = 0.5f;
|
float offset = 0.5f;
|
||||||
|
|
@ -503,15 +460,27 @@ public:
|
||||||
uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
uboTE.lightPos.y = -0.5f - uboTE.tessStrength;
|
||||||
uint8_t *pData;
|
uint8_t *pData;
|
||||||
VK_CHECK_RESULT(vkMapMemory(device, uniformDataTE.memory, 0, sizeof(uboTE), 0, (void **)&pData));
|
VK_CHECK_RESULT(vkMapMemory(device, uniformDataTE.memory, 0, sizeof(uboTE), 0, (void **)&pData));
|
||||||
memcpy(pData, &uboTE, sizeof(uboTE));
|
memcpy(pData, &uboTE, sizeof(uboTE));
|
||||||
vkUnmapMemory(device, uniformDataTE.memory);
|
vkUnmapMemory(device, uniformDataTE.memory);
|
||||||
|
|
||||||
// Tessellation control
|
// Tessellation control
|
||||||
|
float savedLevel = uboTC.tessLevel;
|
||||||
|
if (!displacement)
|
||||||
|
{
|
||||||
|
uboTC.tessLevel = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkMapMemory(device, uniformDataTC.memory, 0, sizeof(uboTC), 0, (void **)&pData));
|
VK_CHECK_RESULT(vkMapMemory(device, uniformDataTC.memory, 0, sizeof(uboTC), 0, (void **)&pData));
|
||||||
memcpy(pData, &uboTC, sizeof(uboTC));
|
memcpy(pData, &uboTC, sizeof(uboTC));
|
||||||
vkUnmapMemory(device, uniformDataTC.memory);
|
vkUnmapMemory(device, uniformDataTC.memory);
|
||||||
|
|
||||||
|
if (!displacement)
|
||||||
|
{
|
||||||
|
uboTC.tessLevel = savedLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
|
|
@ -547,9 +516,7 @@ public:
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
vkDeviceWaitIdle(device);
|
|
||||||
draw();
|
draw();
|
||||||
vkDeviceWaitIdle(device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void viewChanged()
|
virtual void viewChanged()
|
||||||
|
|
@ -560,25 +527,17 @@ public:
|
||||||
void changeTessellationLevel(float delta)
|
void changeTessellationLevel(float delta)
|
||||||
{
|
{
|
||||||
uboTC.tessLevel += delta;
|
uboTC.tessLevel += delta;
|
||||||
// Clamp
|
|
||||||
uboTC.tessLevel = fmax(1.0, fmin(uboTC.tessLevel, 32.0));
|
uboTC.tessLevel = fmax(1.0, fmin(uboTC.tessLevel, 32.0));
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
updateTextOverlay();
|
updateTextOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void togglePipelines()
|
void changeTessellationStrength(float delta)
|
||||||
{
|
{
|
||||||
if (pipelineRight == &pipelines.solid)
|
uboTE.tessStrength += delta;
|
||||||
{
|
uboTE.tessStrength = fmax(0.0f, fmin(uboTE.tessStrength, 1.0f));
|
||||||
pipelineRight = &pipelines.wire;
|
updateUniformBuffers();
|
||||||
pipelineLeft = &pipelines.wirePassThrough;
|
updateTextOverlay();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pipelineRight = &pipelines.solid;
|
|
||||||
pipelineLeft = &pipelines.solidPassThrough;
|
|
||||||
}
|
|
||||||
reBuildCommandBuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleSplitScreen()
|
void toggleSplitScreen()
|
||||||
|
|
@ -588,21 +547,27 @@ public:
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleDisplacement()
|
||||||
|
{
|
||||||
|
displacement = !displacement;
|
||||||
|
updateUniformBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void keyPressed(uint32_t keyCode)
|
virtual void keyPressed(uint32_t keyCode)
|
||||||
{
|
{
|
||||||
switch (keyCode)
|
switch (keyCode)
|
||||||
{
|
{
|
||||||
case 0x6B:
|
case 0x6B:
|
||||||
case GAMEPAD_BUTTON_R1:
|
case GAMEPAD_BUTTON_R1:
|
||||||
changeTessellationLevel(0.25);
|
changeTessellationStrength(0.025);
|
||||||
break;
|
break;
|
||||||
case 0x6D:
|
case 0x6D:
|
||||||
case GAMEPAD_BUTTON_L1:
|
case GAMEPAD_BUTTON_L1:
|
||||||
changeTessellationLevel(-0.25);
|
changeTessellationStrength(-0.025);
|
||||||
break;
|
break;
|
||||||
case 0x57:
|
case 0x44:
|
||||||
case GAMEPAD_BUTTON_A:
|
case GAMEPAD_BUTTON_A:
|
||||||
togglePipelines();
|
toggleDisplacement();
|
||||||
break;
|
break;
|
||||||
case 0x53:
|
case 0x53:
|
||||||
case GAMEPAD_BUTTON_X:
|
case GAMEPAD_BUTTON_X:
|
||||||
|
|
@ -614,14 +579,14 @@ public:
|
||||||
virtual void getOverlayText(VulkanTextOverlay *textOverlay)
|
virtual void getOverlayText(VulkanTextOverlay *textOverlay)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::setprecision(2) << std::fixed << uboTC.tessLevel;
|
ss << std::setprecision(2) << std::fixed << uboTE.tessStrength;
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
textOverlay->addText("Tessellation level: " + ss.str() + " (Buttons L1/R1 to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Tessellation height: " + ss.str() + " (Buttons L1/R1)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
||||||
textOverlay->addText("Press \"Button A\" to toggle wireframe", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Press \"Button A\" to toggle displacement", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
|
||||||
textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 115.0f, VulkanTextOverlay::alignLeft);
|
||||||
#else
|
#else
|
||||||
textOverlay->addText("Tessellation level: " + ss.str() + " (NUMPAD +/- to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Tessellation height: " + ss.str() + " (numpad +/-)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
|
||||||
textOverlay->addText("Press \"w\" to toggle wireframe", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Press \"d\" to toggle displacement", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
|
||||||
textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 115.0f, VulkanTextOverlay::alignLeft);
|
textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 115.0f, VulkanTextOverlay::alignLeft);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 118 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 275 KiB After Width: | Height: | Size: 283 KiB |
Loading…
Add table
Add a link
Reference in a new issue