Muli3D 8 计算Shader中顶点属性相对于屏幕坐标的偏导数
记录一下,
在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, IEEEvoid 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 registersconst 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 成线性关系的东西,其实都是可以利用上面的来计算。
Muli3D 8 计算Shader中顶点属性相对于屏幕坐标的偏导数相关推荐
- Pick定理(一个计算点阵中顶点在格点上的多边形面积公式)
- 【OpenGL】向Shader中传递数据
传递顶点属性信息 之前讲过,vertex shader会被每个顶点调用,通常一个顶点会包含很多信息,例如顶点坐标.顶点法向量.纹理坐标等等,我们称这些信息为顶点的属性.在之前的OpenGL版本里,每个 ...
- Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画
上一节中说了,在 Surface Shader 中,添加顶点函数,我们可以在 顶点函数中获取到 顶点数据,比如顶点颜色.顶点坐标等. 这一节学习获取顶点坐标,并且修改顶点坐标,来实现顶点动画. 简单介 ...
- js计算对象数组中某个属性合计
js 计算对象数组中某个属性合计 countTotal调用示例: let arr = [{id: 0, price: 199.88},{id: 1, price: 299.88},{id: 2, pr ...
- shader 顶点属性——颜色
在shader我们会经常要自己定制一些输入变量到顶点着色器,全部的顶点属性在UnityCG.cginc 你可以在unity的安装目录下找到: 比如:D:\Program Files\Unity2018 ...
- Shader 中的颜色计算
下面介绍 Shader 中 gl_FragColor 的计算与转换: 一.颜色计算 1. 加 这里要讲讲三原色和三基色:三原色一般指的是红.绿.蓝三种,简称 RGB,这是加色系.就是光源只含有特定的波 ...
- Unity 3D 图形学 Shader之顶点与片段着色器(五)
通过实现一个只有颜色属性可调节的简单材质效果更好的了解顶点与片段着色器 一.顶点着色器 顶点着色器就是处理顶点的着色器,每个顶点都会执行一次顶点着色器.我们先认识下顶点函数的结构: 顶点着色器函数的名 ...
- Unity Shader 卡通渲染 (五):仿日式赛璐珞风格 Shader(顶点外扩描边)
上一篇传送门: https://blog.csdn.net/qq_27534999/article/details/101080649 一.赛璐璐风格简介 有些人可能会问,什么是赛璐珞风格? 赛璐珞是 ...
- android平台下OpenGL ES 3.0实例详解顶点属性、顶点数组
OpenGL ES 3.0学习实践 android平台下OpenGL ES 3.0从零开始 android平台下OpenGL ES 3.0绘制纯色背景 android平台下OpenGL ES 3.0绘 ...
最新文章
- php生成pdf乱码_php+tcpdf生成pdf: 中文乱码
- 【新产品发布】EVC9001 USB 隔离器
- 用maven创建Spring MVC项目
- 【机器学习算法-python实现】PCA 主成分分析、降维
- Redis入门(暂不更新)
- Chef是一个什么样的工具
- Linux版本的ActiveMQ安装过程
- SQLAlchemy schema.Column
- MOSS工作流任务权限控制
- IIS访问要求输入用户名密码
- Mac OS Catalina 如何连接老旧的惠普 HP Laser Jet 1020 plus 打印机
- 用pandas对分类变量作统计
- 靠写作杀出一条“血”路——我的2020年终总结
- 在 Activity 中添加 Menu 菜单
- lay-href页面不跳转
- 在c语言中保留字是有专门含义和作用的,c语言中的关键字和保留字的区别?
- 红米7 自编译不完美 twrp 可root手机
- 数据结构PTA习题:基础实验4-2.7 修理牧场 (25分)
- 在html插入数学公式,如何在Word中插入数学公式
- 关于抓取大众点评商户评论的爬虫那点事
热门文章
- HEVC(h265)学习
- 怎么做app开发?如何去开发适合自己企业的APP应用
- php 复制文件夹并压缩到最小_php压缩多个文件打包成zip并下载到本地
- memset 和 bzero的效率测试。
- Mysql创建Create Function
- Web全栈开发训练营
- pyinstaller打包exe文件的详细步骤及过程中遇到的问题
- 英伟达守望先锋巡回赛开启 上海/深圳/沈阳/重庆英雄齐聚
- 聊一聊Spring中@Transactional注解及其失效的七种场景
- 深入分析Android中Activity的onStop和onDestroy()回调延时及延时10s的问题