Concerning dFd{x, y}() in GLSL
来源:互联网 发布:cydia4g软件源 编辑:程序博客网 时间:2024/05/17 08:55
dFdx(fragAttrib) and dFdy(fragAttrib) compute derivatives of certain given attribute between two adjacent fragments.
If currently being processed fragment is f(x, y), x and y refer to the position of this fragment in SCREEN SPACE, then
1. dFdx(fragAttrib) calculates the derivative of "fragAttrib" between f(x, y) and f(x+1, y), atually is the "fragAttrib" value of f(x+1, y)
subtracted by the value of "fragAttrib" of f(x, y);
2. dFdy(fragAttrib) calculates the derivative of "fragAttrib" between f(x, y) and f(x, y+1), atually is the "fragAttrib" value of f(x, y+1)
subtracted by the value of "fragAttrib" of f(x, y);
///////////////////////////////////////////////////////////////////////////////////////////////////////////
CAUTION!
1. Since dFd{x, y}() are used to compute derivatives, so if a constant is the parameter, the return value is permanently ZERO!
2. The prototype is genType dFd{x, y}(genType fragAttrib), so return value shares the same data-type with the parameter "fragAttrib".
///////////////////////////////////////////////////////////////////////////////////////////////////////////
TIP(s):
1. Usually a varying variable is used of being the parameter of dFd{x, y}();, like fragment position, tex coord, etc.
2. texture(tex, v2VarTC) equals to textureGrad(tex, v2VarTC, dFdx(v2VarTC), dFdy(v2VarTC)).
3. Yet unknown(yukk!).
///////////////////////////////////////////////////////////////////////////////////////////////////////////
E.G:
A shader like the following code for digital image processing. Here I use dFdx() and dFdy() to compute distance between 2 adjacent fragments(so-called pixels in D3D).
A full screen quad which has 4 vertices with position (-1, -1), (1, -1), (1, 1) and (-1, 1) is simply loaded to vertex shader as a platform for digital image processing.
#version 330
layout (location = 0) vec3 in v3Pos; // vertex position.
layout (location = 1) vec2 in v2TC; // vertex tex coord.
out vec3 v3VarPos;
out vec2 v2VarTC;
void main()
{
gl_Position = vec4(v3VarPos, 1.0);
v3VarPos = v3Pos;
v2VarTC = v2TC;
}
/*****************************************************************************************/
Here is the fragment shader:
#version 330
uniform sampler2D tex;
in vec3 v3VarPos; // After passed to fragment shader, this "v3VarPos" has been transformed into screen space(if transform is
// applied but currently no transform here), and interpolated, v3VarPos.xy refers to the coordinate of currently being processed
// fragment in screen space(normalized to [0, 1]);
in vec2 v3VarTC:
out v4FragColor;
void main()
{
if(v2VarTC.x >= 0.5)
v4FragColor = texture(tex, v2VarTC);
else
{
float fDDX = dFdx(v3VarPos.x); // fDDX = [v3VarPos.x of f(x+1, y)] - [v3VarPos.x of f(x, y)];
float fDDY = dFdy(v3VarPos.y); // fDDY = [v3VarPos.y of f(x, y+1)] - [v3VarPos.y of f(x, y)];
// So fDDX is the distance along X axis of screen space between two adjacent fragments, as well as f(x, y) and f(x+1, y);
// fDDY is the distance along Y axis of screen space between two adjacent fragments, as well as f(x, y) and f(x, y+1).
float f9K[9] = float[9](1, 2, 1, 0, 0, 0, -1, -2, -1); // A simple 3x3 horizontal Sobel edge detection kernel.
// 1 2 1
// 0 0 0
// -1 -2 -1
v4OutFragColor = f9K[0]*texture(tex, v2VarTC+vec2(-fDDX, fDDY)) + f9K[1]*texture(tex, v2VarTC+vec2(0, fDDY)) +
f9K[2]*texture(tex, v2VarTC+vec2( fDDX, fDDY)) +
f9K[3]*texture(tex, v2VarTC+vec2(-fDDX, 0)) + f9K[4]*texture(tex, v2VarTC) +
f9K[5]*texture(tex, v2VarTC+vec2( fDDX, 0)) +
f9K[6]*texture(tex, v2VarTC+vec2(-fDDX, -fDDY)) + f9K[7]*texture(tex, v2VarTC+vec2(0, -fDDY)) +
f9K[8]*texture(tex, v2VarTC+vec2( fDDX, -fDDY));
}
}
Result(Left half processed by horizontal Sobel, Right is the original texture)
Another by a Laplacian kernel:
// -1 -1 -1
// -1 8 -1
// -1 -1 -1
If currently being processed fragment is f(x, y), x and y refer to the position of this fragment in SCREEN SPACE, then
1. dFdx(fragAttrib) calculates the derivative of "fragAttrib" between f(x, y) and f(x+1, y), atually is the "fragAttrib" value of f(x+1, y)
subtracted by the value of "fragAttrib" of f(x, y);
2. dFdy(fragAttrib) calculates the derivative of "fragAttrib" between f(x, y) and f(x, y+1), atually is the "fragAttrib" value of f(x, y+1)
subtracted by the value of "fragAttrib" of f(x, y);
///////////////////////////////////////////////////////////////////////////////////////////////////////////
CAUTION!
1. Since dFd{x, y}() are used to compute derivatives, so if a constant is the parameter, the return value is permanently ZERO!
2. The prototype is genType dFd{x, y}(genType fragAttrib), so return value shares the same data-type with the parameter "fragAttrib".
///////////////////////////////////////////////////////////////////////////////////////////////////////////
TIP(s):
1. Usually a varying variable is used of being the parameter of dFd{x, y}();, like fragment position, tex coord, etc.
2. texture(tex, v2VarTC) equals to textureGrad(tex, v2VarTC, dFdx(v2VarTC), dFdy(v2VarTC)).
3. Yet unknown(yukk!).
///////////////////////////////////////////////////////////////////////////////////////////////////////////
E.G:
A shader like the following code for digital image processing. Here I use dFdx() and dFdy() to compute distance between 2 adjacent fragments(so-called pixels in D3D).
A full screen quad which has 4 vertices with position (-1, -1), (1, -1), (1, 1) and (-1, 1) is simply loaded to vertex shader as a platform for digital image processing.
#version 330
layout (location = 0) vec3 in v3Pos; // vertex position.
layout (location = 1) vec2 in v2TC; // vertex tex coord.
out vec3 v3VarPos;
out vec2 v2VarTC;
void main()
{
gl_Position = vec4(v3VarPos, 1.0);
v3VarPos = v3Pos;
v2VarTC = v2TC;
}
/*****************************************************************************************/
Here is the fragment shader:
#version 330
uniform sampler2D tex;
in vec3 v3VarPos; // After passed to fragment shader, this "v3VarPos" has been transformed into screen space(if transform is
// applied but currently no transform here), and interpolated, v3VarPos.xy refers to the coordinate of currently being processed
// fragment in screen space(normalized to [0, 1]);
in vec2 v3VarTC:
out v4FragColor;
void main()
{
if(v2VarTC.x >= 0.5)
v4FragColor = texture(tex, v2VarTC);
else
{
float fDDX = dFdx(v3VarPos.x); // fDDX = [v3VarPos.x of f(x+1, y)] - [v3VarPos.x of f(x, y)];
float fDDY = dFdy(v3VarPos.y); // fDDY = [v3VarPos.y of f(x, y+1)] - [v3VarPos.y of f(x, y)];
// So fDDX is the distance along X axis of screen space between two adjacent fragments, as well as f(x, y) and f(x+1, y);
// fDDY is the distance along Y axis of screen space between two adjacent fragments, as well as f(x, y) and f(x, y+1).
float f9K[9] = float[9](1, 2, 1, 0, 0, 0, -1, -2, -1); // A simple 3x3 horizontal Sobel edge detection kernel.
// 1 2 1
// 0 0 0
// -1 -2 -1
v4OutFragColor = f9K[0]*texture(tex, v2VarTC+vec2(-fDDX, fDDY)) + f9K[1]*texture(tex, v2VarTC+vec2(0, fDDY)) +
f9K[2]*texture(tex, v2VarTC+vec2( fDDX, fDDY)) +
f9K[3]*texture(tex, v2VarTC+vec2(-fDDX, 0)) + f9K[4]*texture(tex, v2VarTC) +
f9K[5]*texture(tex, v2VarTC+vec2( fDDX, 0)) +
f9K[6]*texture(tex, v2VarTC+vec2(-fDDX, -fDDY)) + f9K[7]*texture(tex, v2VarTC+vec2(0, -fDDY)) +
f9K[8]*texture(tex, v2VarTC+vec2( fDDX, -fDDY));
}
}
Result(Left half processed by horizontal Sobel, Right is the original texture)
Another by a Laplacian kernel:
// -1 -1 -1
// -1 8 -1
// -1 -1 -1
0 0
- Concerning dFd{x, y}() in GLSL
- learn x in y minutes
- Learn X in Y minutes
- dfd
- dfd
- dfd
- DFD
- dfd
- dfd
- dfd
- DFD
- DFD
- dfd
- dfd
- dfd
- dfd
- dfd
- dfd
- linux/videodev.h:没有那个文件或目录
- 3月11记
- BUPT OJ178 lili‘s number
- 谈谈换工作
- pat 1026
- Concerning dFd{x, y}() in GLSL
- The attempt to create vdi is failed
- 数数
- 股票F10资料离线文件包带股票F10关键字过滤软件下载–更新于2014年03月11日
- opencv2.2make出现的问题
- POJ 2955... dp
- 2013蓝桥杯【模拟赛】1的个数
- 昨天的错误修改后,make出现error: 'UINT64_C' was not declared in this scope
- scanf(),printf()和gets(),puts()在输入输出字符串时的区别