Class NVClipSpaceWScaling


  • public class NVClipSpaceWScaling
    extends java.lang.Object
    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);
     }
    Name String
    VK_NV_clip_space_w_scaling
    Extension Type
    Device extension
    Registered Extension Number
    88
    Revision
    1
    Extension and Version Dependencies
    • Requires Vulkan 1.0
    Contact
    Last Modified Date
    2017-02-15
    Contributors
    • Eric Werness, NVIDIA
    • Kedarnath Thangudu, NVIDIA
    • Field Detail

      • VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION

        public static final int VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION
        The extension specification version.
        See Also:
        Constant Field Values
      • VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME

        public static final java.lang.String VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME
        The extension name.
        See Also:
        Constant Field Values
      • VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV

        public static final int VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV
        Extends VkStructureType.
        See Also:
        Constant Field Values
      • VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV

        public static final int VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV
        Extends VkDynamicState.
        See Also:
        Constant Field Values
    • Method Detail

      • nvkCmdSetViewportWScalingNV

        public static void nvkCmdSetViewportWScalingNV​(VkCommandBuffer commandBuffer,
                                                       int firstViewport,
                                                       int viewportCount,
                                                       long pViewportWScalings)
        Unsafe version of: CmdSetViewportWScalingNV
        Parameters:
        viewportCount - the number of viewports whose parameters are updated by the command.
      • vkCmdSetViewportWScalingNV

        public static void vkCmdSetViewportWScalingNV​(VkCommandBuffer commandBuffer,
                                                      int firstViewport,
                                                      VkViewportWScalingNV.Buffer pViewportWScalings)
        Set the viewport W scaling on a command buffer.
        C Specification

        If the bound pipeline state object was not created with the DYNAMIC_STATE_VIEWPORT_W_SCALING_NV dynamic state enabled, viewport W scaling parameters are specified using the pViewportWScalings member of VkPipelineViewportWScalingStateCreateInfoNV in the pipeline state object. If the pipeline state object was created with the DYNAMIC_STATE_VIEWPORT_W_SCALING_NV dynamic state enabled, the viewport transformation parameters are dynamically set and changed with the command:

        
         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).

        Valid Usage
        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
        • 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 ScopeSupported Queue TypesPipeline Type
        Primary SecondaryBothGraphics
        See Also

        VkViewportWScalingNV

        Parameters:
        commandBuffer - the command buffer into which the command will be recorded.
        firstViewport - the index of the first viewport whose parameters are updated by the command.
        pViewportWScalings - a pointer to an array of VkViewportWScalingNV structures specifying viewport parameters.