Top Description Fields Constructors Methods
org.lwjgl.vulkan

public Class NVClipSpaceWScaling

extends Object
Class Inheritance
Imports
org.lwjgl.system.*

Virtual Reality (VR) applications often involve a post-processing step to apply a “barrel” distortion to the rendered image to correct the “pincushion” distortion introduced by the optics in a VR device. The barrel distorted image has lower resolution along the edges compared to the center. Since the original image is rendered at high resolution, which is uniform across the complete image, a lot of pixels towards the edges do not make it to the final post-processed image.

This extension provides a mechanism to render VR scenes at a non-uniform resolution, in particular a resolution that falls linearly from the center towards the edges. This is achieved by scaling the w coordinate of the vertices in the clip space before perspective divide. The clip space w coordinate of the vertices can be offset as of a function of x and y coordinates as follows:

w' = w + Ax + By

In the intended use case for viewport position scaling, an application should use a set of four viewports, one for each of the four quadrants of a Cartesian coordinate system. Each viewport is set to the dimension of the image, but is scissored to the quadrant it represents. The application should specify A and B coefficients of the w-scaling equation above, that have the same value, but different signs, for each of the viewports. The signs of A and B should match the signs of x and y for the quadrant that they represent such that the value of w' will always be greater than or equal to the original w value for the entire image. Since the offset to w, (Ax + By), is always positive, and increases with the absolute values of x and y, the effective resolution will fall off linearly from the center of the image to its edges.

Examples

VkViewport viewports[4];
VkRect2D scissors[4];
VkViewportWScalingNV scalings[4];

for (int i = 0; i < 4; i++) {
    int x = (i & 2) ? 0 : currentWindowWidth / 2;
    int y = (i & 1) ? 0 : currentWindowHeight / 2;

    viewports[i].x = 0;
    viewports[i].y = 0;
    viewports[i].width = currentWindowWidth;
    viewports[i].height = currentWindowHeight;
    viewports[i].minDepth = 0.0f;
    viewports[i].maxDepth = 1.0f;

    scissors[i].offset.x = x;
    scissors[i].offset.y = y;
    scissors[i].extent.width = currentWindowWidth/2;
    scissors[i].extent.height = currentWindowHeight/2;

    const float factor = 0.15;
    scalings[i].xcoeff = ((i & 2) ? -1.0 : 1.0) * factor;
    scalings[i].ycoeff = ((i & 1) ? -1.0 : 1.0) * factor;
}

VkPipelineViewportWScalingStateCreateInfoNV vpWScalingStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV };

vpWScalingStateInfo.viewportWScalingEnable = VK_TRUE;
vpWScalingStateInfo.viewportCount = 4;
vpWScalingStateInfo.pViewportWScalings = &scalings[0];

VkPipelineViewportStateCreateInfo vpStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
vpStateInfo.viewportCount = 4;
vpStateInfo.pViewports = &viewports[0];
vpStateInfo.scissorCount = 4;
vpStateInfo.pScissors = &scissors[0];
vpStateInfo.pNext = &vpWScalingStateInfo;

Example shader to read from a w-scaled texture:


// Vertex Shader
// Draw a triangle that covers the whole screen
const vec4 positions[3] = vec4[3](vec4(-1, -1, 0, 1),
                                  vec4( 3, -1, 0, 1),
                                  vec4(-1,  3, 0, 1));
out vec2 uv;
void main()
{
    vec4 pos = positions[ gl_VertexID ];
    gl_Position = pos;
    uv = pos.xy;
}

// Fragment Shader
uniform sampler2D tex;
uniform float xcoeff;
uniform float ycoeff;
out vec4 Color;
in vec2 uv;

void main()
{
    // Handle uv as if upper right quadrant
    vec2 uvabs = abs(uv);

    // unscale: transform w-scaled image into an unscaled image
    //   scale: transform unscaled image int a w-scaled image
    float unscale = 1.0 / (1 + xcoeff * uvabs.x + xcoeff * uvabs.y);
    //float scale = 1.0 / (1 - xcoeff * uvabs.x - xcoeff * uvabs.y);

    vec2 P = vec2(unscale * uvabs.x, unscale * uvabs.y);

    // Go back to the right quadrant
    P *= sign(uv);

    Color = texture(tex, P * 0.5 + 0.5);
}
VK_NV_clip_space_w_scaling
Name String
VK_NV_clip_space_w_scaling
Extension Type
Device extension
Registered Extension Number
88
Revision
1
Contact
Other Extension Metadata
Last Modified Date
2017-02-15
Contributors
  • Eric Werness, NVIDIA
  • Kedarnath Thangudu, NVIDIA

Field Summary

Modifier and TypeField and Description
public static final int
public static final String
public static final int
VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION

The extension specification version.

public static final int

Constructor Summary

AccessConstructor and Description
protected

Method Summary

Modifier and TypeMethod and Description
public static void
nvkCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, int firstViewport, int
the number of viewports whose parameters are updated by the command.
viewportCount
,
long pViewportWScalings)

Unsafe version of: CmdSetViewportWScalingNV

public static void
vkCmdSetViewportWScalingNV(VkCommandBuffer
the command buffer into which the command will be recorded.
commandBuffer
,
int
the index of the first viewport whose parameters are updated by the command.
firstViewport
,
VkViewportWScalingNV.Buffer
a pointer to an array of VkViewportWScalingNV structures specifying viewport parameters.
pViewportWScalings
)

Set the viewport W scaling dynamically for a command buffer.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NVback to summary
public static final int VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV

Extends VkDynamicState.

VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAMEback to summary
public static final String VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME

The extension name.

VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSIONback to summary
public static final int VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION

The extension specification version.

VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NVback to summary
public static final int VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV

Extends VkStructureType.

Constructor Detail

NVClipSpaceWScalingback to summary
protected NVClipSpaceWScaling()

Method Detail

nvkCmdSetViewportWScalingNVback to summary
public static void nvkCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, int firstViewport, int viewportCount, long pViewportWScalings)

Unsafe version of: CmdSetViewportWScalingNV

Parameters
viewportCount:int

the number of viewports whose parameters are updated by the command.

vkCmdSetViewportWScalingNVback to summary
public static void vkCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, int firstViewport, VkViewportWScalingNV.Buffer pViewportWScalings)

Set the viewport W scaling dynamically for a command buffer.

C Specification

To dynamically set the viewport W scaling parameters, call:


void vkCmdSetViewportWScalingNV(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkViewportWScalingNV*                 pViewportWScalings);
Description

The viewport parameters taken from element i of pViewportWScalings replace the current state for the viewport index firstViewport + i, for i in [0, viewportCount).

This command sets the viewport W scaling for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with DYNAMIC_STATE_VIEWPORT_W_SCALING_NV set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineViewportWScalingStateCreateInfoNV::pViewportWScalings values used to create the currently active pipeline.

Valid Usage
  • The sum of firstViewport and viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive
Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle
  • pViewportWScalings must be a valid pointer to an array of viewportCount VkViewportWScalingNV structures
  • commandBuffer must be in the recording state
  • The VkCommandPool that commandBuffer was allocated from must support graphics operations
  • This command must only be called outside of a video coding scope
  • viewportCount must be greater than 0
Host Synchronization
  • Host access to commandBuffer must be externally synchronized
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized
Command Properties
Command Buffer LevelsRender Pass ScopeVideo Coding ScopeSupported Queue TypesCommand Type
Primary SecondaryBothOutsideGraphicsState
See Also

VkViewportWScalingNV

Parameters
commandBuffer:VkCommandBuffer

the command buffer into which the command will be recorded.

firstViewport:int

the index of the first viewport whose parameters are updated by the command.

pViewportWScalings:VkViewportWScalingNV.Buffer

a pointer to an array of VkViewportWScalingNV structures specifying viewport parameters.