将像素转换为剪贴空间

时间:2019-07-18 17:38:57

标签: webgl shader glsles

与其为我的着色器提供-1到1的值,不如为2D画布上下文提供它们的像素值。因此,根据阅读的内容,我确实添加了一个统一变量,并将其设置为画布的大小,然后进行划分。

但是我一定错过了一些东西。渲染太大...

gl_.resolutionLocation = gl.getUniformLocation( gl_.program , "u_resolution" );
gl.uniform4f(gl_.resolutionLocation , game.w , game.h , game.w , game.h );

我的顶点着色器:

attribute vec4 position;
attribute vec2 texcoord;
uniform vec4 u_resolution;
uniform mat4 u_matrix;
varying vec3 v_texcoord;

void main() {
    vec4 zeroToOne = position / u_resolution ;
    gl_Position = u_matrix * zeroToOne ;
    v_texcoord = vec3(texcoord.xy, 1) * abs(position.x);
    v_texcoord = v_texcoord/u_resolution.xyz ;
}

我的片段着色器:

precision mediump float;
varying vec3 v_texcoord;
uniform sampler2D tex;
uniform float alpha;

void main()
{
    gl_FragColor = texture2DProj(tex, v_texcoord);
    gl_FragColor.rgb *= gl_FragColor.a ;
}

2 个答案:

答案 0 :(得分:0)

我假设u_matrix是模型矩阵。有了投影矩阵,而不是投影矩阵,其中包含视口的分辨率(u_resolution)。

您要应用orthographic projection,将坐标从(0,0)到u_resolution的范围投影到规范化的设备空间,形式为-1到1。实际上,gl_Position是剪辑空间坐标,但是如果.w分量为1,则.xyz的{​​{1}}分量等于规范化的设备空间坐标。进一步参见Perspective projection

首先,您必须通过模型矩阵(gl_Position)来转换position属性。在您提到的问题中,您以2D绘制,因此以下假设u_matrix为0,而position.z为1:

position.w

最后投影vec4 viewPos = u_matrix * position; 以裁剪空间:

viewPos.xy

答案 1 :(得分:0)

如果您希望使用像这样的代码来保持像素不变,那么在以像素为单位完成所有操作后,您希望将转换应用于剪贴空间。

换句话说,代码将类似于

<tr class="product_row">                                                
    <td class="small-check SerialNumber"><input class="chkIt" type="checkbox" name="products[product_id][]" value="76" qty="0" product_weight="0"></td>
    <td data-th="Product Name" class="fourth_i1">8 PACK SPECIALIST EMBOSSED SILVER FOIL 500 SHEET  BOX 12CM X 20CM</td>
    <td data-th="Part Number" class="grid-text">EMBOSS-Pre-Cut x 8 Pack</td>
    <td class="small-check MarkGift"><input class="chkItg" type="checkbox" name="gift[product_id][]" value="76"></td>
    <td data-th="Quantity" class="grid-text">
        <select name="products[quantity][76][]" class="change_product_price">
            <option>0</option>
            <option>1</option>
            <option>2</option>
            <option>3</option>              
        </select>  
        <input type="hidden" class="promo_min_quantity" name="promo_min_quantity" value="">
        <input type="hidden" class="promo_free_units" name="promo_free_units" value="0">                          
    </td>
    <td style="display:none;" class="grid-text"><span class="product_weight">5.8</span></td>
    <td data-th="Price / unit" class="grid-text">$<span class="product_price" prevvalue="180.00">180.00</span></td>
    <td data-th="Promo code" class="grid-text">N/A<!-- <input type="hidden" value="" name="products[promo_code][76][]" />--></td>
    <td data-th="Price" class="grid-text">$<span class="product_total_price">180.00</span></td>

</tr>

<tr class="product_row">                                                
    <td class="small-check SerialNumber"><input class="chkIt" type="checkbox" name="products[product_id][]" value="76" qty="0" product_weight="0"></td>
    <td data-th="Product Name" class="fourth_i1">12 PACK SPECIALIST EMBOSSED SILVER FOIL 500 SHEET  BOX 12CM X 20CM</td>
    <td data-th="Part Number" class="grid-text">EMBOSS-Pre-Cut x 8 Pack</td>
    <td class="small-check MarkGift"><input class="chkItg" type="checkbox" name="gift[product_id][]" value="78"></td>
    <td data-th="Quantity" class="grid-text">
        <select name="products[quantity][78][]" class="change_product_price">
            <option>0</option>
            <option>1</option>
            <option>2</option>
            <option>3</option>              
        </select>  
        <input type="hidden" class="promo_min_quantity" name="promo_min_quantity" value="">
        <input type="hidden" class="promo_free_units" name="promo_free_units" value="0">                          
    </td>
    <td style="display:none;" class="grid-text"><span class="product_weight">5.8</span></td>
    <td data-th="Price / unit" class="grid-text">$<span class="product_price" prevvalue="180.00">180.00</span></td>
    <td data-th="Promo code" class="grid-text">N/A<!-- <input type="hidden" value="" name="products[promo_code][78][]" />--></td>
    <td data-th="Price" class="grid-text">$<span class="product_total_price">180.00</span></td>

</tr>

所以换句话说,你想要

 rotatedPixelPosition = rotationMatrix * pixelPosition
 clipSpacePosition = (rotatedPixelPosition / resolution) * 2.0 - 1.0; 

如果执行此操作,并将u_matrix设置为identity,则如果position以像素为单位,则应该在像素位置看到这些位置。如果u_matrix严格是旋转矩阵,则位置将围绕左上角旋转,因为旋转始终发生在0附近,并且上面的转换将0置于左上角。

但是实际上,这里没有理由手动将像素转换为剪贴空间。您可以改为在同一矩阵中进行转换和旋转。 This article涵盖了该过程。它从平移,旋转,缩放和从像素到剪辑空间的转换(不带矩阵)开始,然后将其转换为可以使用单个矩阵进行所有合并的对象。

有效

vec4 rotatedPosition = u_matrix * position;
vec2 zeroToOne = rotatedPosition.xy / u_resolution.xy;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 minusOneToPlusOne = zeroToTwo - 1.0;
vec2 clipspacePositiveYDown = minusOneToPlusOne * vec2(1, -1);
gl_Position = vec4(clipspacePositiveYDown, 0, 1);

然后只需在着色器中

  matrix = scaleYByMinusMatrix *
           subtract1FromXYMatrix *
           scaleXYBy2Matrix *
           scaleXYBy1OverResolutionMatrix *
           translationInPixelSpaceMatrix *
           rotationInPixelSpaceMatrix *
           scaleInPixelSpaceMatrix;

这些前4个矩阵易于作为单个矩阵进行计算,通常称为正交投影,在这种情况下,它简化为

gl_Position = u_matrix * vec4(position, 0, 1);  

还有this article,它可以从WebGL中的canvas2D复制矩阵堆栈