Muli3D <8> 计算Shader中顶点属性相对于屏幕坐标的偏导数
2017-05-03 21:03
441 查看
记录一下,
在Muli3D中看到这样一个函数:
从函数的注释可以知道,这个函数主要的作用就是 《This functions computes the partial derivatives of a shader register with respect to the screen space coordinates.》
上面的 shader register,可以理解为 VS 输出的值的位置索引,那么这个就是计算 VS 输出的 值 关于 屏幕坐标x,y的偏导数,例如,VS输出了纹理左边,那么就可以计算出纹理坐标关于 屏幕坐标x,y的偏导数。
上面的代码其实就是一堆公式,下面的推导主要根据上面的注释提示的文章<MIP-Map Level Selection for Texture Mapping>和自己的一些理解:
现在用纹理坐标作为例子
1.
理解:深入探索透视纹理映射 : http://blog.csdn.net/aa20274270/article/details/51989103
知道
s' = S / Q
t' = T / Q
(如何理解,s' , t' 就是 投影变换之后 的 纹理坐标,s',t' 是与 1/z’ 成正比,这里的Q就是 z‘)
这里的S ,T 是与 x,y 与线性关系的, Q是z',那么也是与x,y 成线性关系的
得到
S = A * x + B * y + C
T = G * x + H * y + I
Q = D * x + E * y + F
现在 要求
∂s‘ / ∂x
=
∂(S / Q) / ∂x
= ∂( (A * x + B * y + C) / ( D * x + E * y +
F) ) / ∂x (根据 (u/v)'=(u'v-uv')/ v^2
,把y 当 常量得到就是 )
=
(A * x + B * y + C)' * ( D
* x + E * y + F) - (A * x + B * y
+ C) * ( D * x + E * y + F) '
/ Q^2
=
A * ( D * x + E * y + F)
- (A * x + B * y + C) * D / Q^2
=
( (AE - BD) * y + AF - CD ) / Q^2
而对于 ∂s‘ / ∂y, 计算方式是一样的。
直接给出
∂s‘ / ∂y
= ( (BD
- AE) * x + BF - CE ) / Q^2
上面的
A, B, C, D, E, F ....其实都是未知的,那么怎么求这些东西,
个人理解:
理解完 Partial Derivatives(偏导数) : http://blog.csdn.net/aa20274270/article/details/70158853
之后,就可以理解到
其实上面的
S = A * x + B * y + C --> S = ∂S / ∂x * x + ∂S
/ ∂y * y + S0
Q
= D * x + E * y + F --> Q =
∂Q / ∂x * x + ∂Q / ∂y * y + Q0
对应T也是一样的道理,现在应该差不多可以理解了吧。
上面的事那纹理坐标ST做例子,其实,对于任何的
与 x,y 成线性关系的东西,其实都是可以利用上面的来计算。
在Muli3D中看到这样一个函数:
/// This functions computes the partial derivatives of a shader register with respect to the screen space coordinates. /// @param[in] i_iRegister index of the source shader register. /// @param[out] o_vDdx partial derivative with respect to the x-screen space coordinate. /// @param[out] o_vDdy partial derivative with respect to the y-screen space coordinate. void GetDerivatives( uint32 i_iRegister, vector4 &o_vDdx, vector4 &o_vDdy ) const;
// Partial derivative equations taken from // "MIP-Map Level Selection for Texture Mapping", // Jon P. Ewins, Member, IEEE, Marcus D. Waller, // Martin White, and Paul F. Lister, Member, IEEE void IMuli3DPixelShader::GetDerivatives( uint32 i_iRegister, vector4 &o_vDdx, vector4 &o_vDdy ) const { o_vDdx = vector4( 0, 0, 0, 0 ); o_vDdy = vector4( 0, 0, 0, 0 ); if( i_iRegister < 0 || i_iRegister >= c_iPixelShaderRegisters ) return; const shaderreg &A = m_pTriangleInfo->ShaderOutputsDdx[i_iRegister]; const shaderreg &B = m_pTriangleInfo->ShaderOutputsDdy[i_iRegister]; // ShaderOutputs : Vertex shader output registers const shaderreg &C = m_pTriangleInfo->pBaseVertex->ShaderOutputs[i_iRegister]; const float32 D = m_pTriangleInfo->fWDdx; const float32 E = m_pTriangleInfo->fWDdy; const float32 F = m_pTriangleInfo->pBaseVertex->vPosition.w; const float32 fRelPixelX = m_pTriangleInfo->iCurPixelX - m_pTriangleInfo->pBaseVertex->vPosition.x; const float32 fRelPixelY = m_pTriangleInfo->iCurPixelY - m_pTriangleInfo->pBaseVertex->vPosition.y; const float32 fInvWSquare = m_pTriangleInfo->fCurPixelInvW * m_pTriangleInfo->fCurPixelInvW; // Compute partial derivative with respect to the x-screen space coordinate. switch( m_pVSOutputs[i_iRegister] ) { case m3dsrt_vector4: o_vDdx.w = ( (A.w * F - C.w * D) + (A.w * E - B.w * D) * fRelPixelY ) * fInvWSquare; case m3dsrt_vector3: o_vDdx.z = ( (A.z * F - C.z * D) + (A.z * E - B.z * D) * fRelPixelY ) * fInvWSquare; case m3dsrt_vector2: o_vDdx.y = ( (A.y * F - C.y * D) + (A.y * E - B.y * D) * fRelPixelY ) * fInvWSquare; case m3dsrt_float32: o_vDdx.x = ( (A.x * F - C.x * D) + (A.x * E - B.x * D) * fRelPixelY ) * fInvWSquare; case m3dsrt_unused: default: break; } // Compute partial derivative with respect to the y-screen space coordinate. switch( m_pVSOutputs[i_iRegister] ) { case m3dsrt_vector4: o_vDdy.w = ( (B.w * F - C.w * E) + (B.w * D - A.w * E) * fRelPixelX ) * fInvWSquare; case m3dsrt_vector3: o_vDdy.z = ( (B.z * F - C.z * E) + (B.z * D - A.z * E) * fRelPixelX ) * fInvWSquare; case m3dsrt_vector2: o_vDdy.y = ( (B.y * F - C.y * E) + (B.y * D - A.y * E) * fRelPixelX ) * fInvWSquare; case m3dsrt_float32: o_vDdy.x = ( (B.x * F - C.x * E) + (B.x * D - A.x * E) * fRelPixelX ) * fInvWSquare; case m3dsrt_unused: default: break; } }
从函数的注释可以知道,这个函数主要的作用就是 《This functions computes the partial derivatives of a shader register with respect to the screen space coordinates.》
上面的 shader register,可以理解为 VS 输出的值的位置索引,那么这个就是计算 VS 输出的 值 关于 屏幕坐标x,y的偏导数,例如,VS输出了纹理左边,那么就可以计算出纹理坐标关于 屏幕坐标x,y的偏导数。
上面的代码其实就是一堆公式,下面的推导主要根据上面的注释提示的文章<MIP-Map Level Selection for Texture Mapping>和自己的一些理解:
现在用纹理坐标作为例子
1.
理解:深入探索透视纹理映射 : http://blog.csdn.net/aa20274270/article/details/51989103
知道
s' = S / Q
t' = T / Q
(如何理解,s' , t' 就是 投影变换之后 的 纹理坐标,s',t' 是与 1/z’ 成正比,这里的Q就是 z‘)
这里的S ,T 是与 x,y 与线性关系的, Q是z',那么也是与x,y 成线性关系的
得到
S = A * x + B * y + C
T = G * x + H * y + I
Q = D * x + E * y + F
现在 要求
∂s‘ / ∂x
=
∂(S / Q) / ∂x
= ∂( (A * x + B * y + C) / ( D * x + E * y +
F) ) / ∂x (根据 (u/v)'=(u'v-uv')/ v^2
,把y 当 常量得到就是 )
=
(A * x + B * y + C)' * ( D
* x + E * y + F) - (A * x + B * y
+ C) * ( D * x + E * y + F) '
/ Q^2
=
A * ( D * x + E * y + F)
- (A * x + B * y + C) * D / Q^2
=
( (AE - BD) * y + AF - CD ) / Q^2
而对于 ∂s‘ / ∂y, 计算方式是一样的。
直接给出
∂s‘ / ∂y
= ( (BD
- AE) * x + BF - CE ) / Q^2
上面的
A, B, C, D, E, F ....其实都是未知的,那么怎么求这些东西,
个人理解:
理解完 Partial Derivatives(偏导数) : http://blog.csdn.net/aa20274270/article/details/70158853
之后,就可以理解到
其实上面的
S = A * x + B * y + C --> S = ∂S / ∂x * x + ∂S
/ ∂y * y + S0
Q
= D * x + E * y + F --> Q =
∂Q / ∂x * x + ∂Q / ∂y * y + Q0
对应T也是一样的道理,现在应该差不多可以理解了吧。
上面的事那纹理坐标ST做例子,其实,对于任何的
与 x,y 成线性关系的东西,其实都是可以利用上面的来计算。
相关文章推荐
- Unity3D ShaderLab <六>通过改变纹理的UV坐标实现简单的水流效果
- 计算任意一个UIView相对屏幕的坐标
- <Shader>简单的纹理坐标滚动(水波模型:脚本控制)
- Muli3D <6> Struct m3dtriangleinfo 的属性 fZDdx,fZDdy 的推导
- 计算任意一个UIView相对屏幕的坐标
- <h1>~<h6>、<a>、属性、相对路径
- Unity3D ShaderLab<二>Shader属性
- Unity3D ShaderLab<二>Shader属性
- <Win32_8>有意思的程序——抓取屏幕
- HTML <a> 标签的 href 属性 注意其URL分为绝对 相对 锚
- 计算任意一个UIView相对屏幕的坐标
- 使用List<Map>或者List<entityObject>计算指定属性的总和
- Android OpenGL20 世界坐标系,屏幕坐标系,纹理坐标系 <8>
- JS收集<8>:HTML控件的坐标
- IOS开发之绝对布局和相对布局(屏幕适配)<转>
- UNITY3D shader学习心得<一> properties属性接口
- 粒子系统基本原理 给出粒子中心点的坐标和粒子的大小,则很容易计算出粒子所需要的4个顶点的位置坐标。粒子系统由大量的粒子构成。每个粒子具有一组属性例如位置大小纹理颜色透明度运动速度加速度生命周期等属性。
- jquery 学习之二 属性---<类>
- jquery 学习之二 属性---<html代码>
- GDI+ 相对form窗口的坐标和相对于显示器的屏幕坐标的转换