[英]Three.js - a vertex shader to color based on location of pixel on screen
使用Three.js,我編寫了一個頂點着色器,根據着色像素在屏幕上的象限,為平面中的每個點着色。
// vertex shader
uniform float width;
uniform float height;
varying float x;
varying float y;
void main()
{
vec4 v = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
x = v.x;
y = v.y;
gl_Position = v;
}
// fragment shader
varying float x;
varying float y;
void main()
{
gl_FragColor = vec4(x, y, 0.0, 1.0);
}
jsFiddle的實時示例: http : //jsfiddle.net/Stemkoski/ST4aM/
我想修改此着色器,以使x
在屏幕的左側等於0,在屏幕的右側等於1,類似地, y
等於頂部等於0,底部等於1。 我(錯誤地)假設這將涉及將x
和y
的值更改為x = vx / width
和y = vy / height
(其中width
和height
存儲窗口的寬度和高度)。 但是,通過此更改,在平面上放大和縮小時,每個屏幕像素處的顏色似乎都發生了變化。
如何修復着色器代碼以獲得所需的效果?
您的變量v
在剪輯空間中。 您需要應用透視圖划分,以將其映射到標准化設備坐標(NDC)空間,該空間的取值范圍為[-1,1]。 然后,您需要將該值映射到[0,1]范圍,如下所示:
vec4 v = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
x = v.x / v.z;
y = v.y / v.z;
gl_FragColor = vec4( 0.5 * x + 0.5, - 0.5 * y + 0.5, 0.0, 1.0 );
小提琴: http : //jsfiddle.net/ST4aM/4/
three.js r.62
只是WestLangley答案的補充。
我遇到了一個小錯誤,該錯誤表明我的頂點位置計算有點錯誤。 似乎在(-1.1,1.1)范圍內。 因此,經過實驗后,發現vz
並非完全正確,它取決於近場剪輯平面,人們通常在相機設置中將其保留為1。 因此,在vz
添加2似乎可以解決此問題。 我不明白為什么2而不是1。
x = v.x / (v.z + 2.0); // depth + 2 x near clip space plane dist (camera setting)
因此,如果您正在使用大型物體(如WestLangley的示例),則不會注意到它,但是如果物體較小且靠近相機,則錯誤將很明顯。
我已經修改了上面的示例,如果Y的位置不在(0,1)內,並且X的計算固定,則可以裁剪顏色。平面大小為20,相機距離為30。
它仍然不是完美的。 如果物體非常靠近相機,它仍然會弄亂位置,但這至少可以使它與中等大小的物體配合使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.