ios - How to get fragment coordinate in fragment shader in Metal? -


this minimal metal shader pair renders simple interpolated gradient onto screen (when provided vertex quad/triangle) based on vertices' color attributes:

#include <metal_stdlib>  using namespace metal;  typedef struct {     float4 position [[position]];     float4  color; } vertex_t;  vertex vertex_t vertex_function(const device vertex_t *vertices [[buffer(0)]], uint vid [[vertex_id]]) {     return vertices[vid]; }  fragment half4 fragment_function(vertex_t interpolated [[stage_in]]) {     return half4(interpolated.color); } 

…with following vertices:

{   // x,    y,   z,   w,   r,   g,   b,            1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,     -1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,     -1.0,  1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,       1.0,  1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,      1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,     -1.0,  1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0 } 

so far good. renders well-known gradient triangle/quad.
1 find in pretty every single gpu helloworld tutorial.


i need have fragment shader instead of taking interpolated vertex color computes color based on fragments position on screen. receives screen-filling quad of vertices , uses fragment shader calculate actual colors.

from understanding position of vertex float4 first 3 elements being 3d vector , 4th element set 1.0.

so—i thought—it should easy modify above have reinterpret vertex' position color in fragment shader, right?

#include <metal_stdlib>  using namespace metal;  typedef struct {     float4 position [[position]]; } vertex_t;  vertex vertex_t vertex_function(const device vertex_t *vertices [[buffer(0)]], uint vid [[vertex_id]]) {     return vertices[vid]; }  fragment half4 fragment_function(vertex_t interpolated [[stage_in]]) {     float4 color = interpolated.position;     color += 1.0; // move range -1..1 0..2     color *= 0.5; // scale range 0..2 0..1     return half4(color); } 

…with following vertices:

{   // x,    y,   z,   w,      1.0, -1.0, 0.0, 1.0,     -1.0, -1.0, 0.0, 1.0,     -1.0,  1.0, 0.0, 1.0,       1.0,  1.0, 0.0, 1.0,      1.0, -1.0, 0.0, 1.0,     -1.0,  1.0, 0.0, 1.0, } 

i quite surprised find uniformly colored (yellow) screen being rendered, instead of gradient going red=0.0 red=1.0 in x-axis , green=0.0 green=1.0 in x-axis:

(expected render output vs. actual render output)

the interpolated.position appears yielding same value each fragment.

what doing wrong here?

ps: (while dummy fragment logic have been accomplished using vertex interpolation, actual fragment logic cannot.)

the interpolated.position appears yielding same value each fragment.

no, values large. variable [[position]] qualifier, in fragment shader, in pixel coordinates. divide render target dimensions, , you'll see want, except having invert green value, because metal's convention define upper-left origin this, not bottom-left.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -