Opengl es glsl中偏导数的手动计算(与dFdx比较)
我假设dFdx(变量)可以通过手动实现,如下例所示:Opengl es glsl中偏导数的手动计算(与dFdx比较),opengl-es,glsl,shader,fragment-shader,Opengl Es,Glsl,Shader,Fragment Shader,我假设dFdx(变量)可以通过手动实现,如下例所示: #extension GL_OES_standard_derivatives : enable float circle (const vec2 st, float r) { return sin(300.0 * length(st)); } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; st.x *= u_resolution.x / u_r
#extension GL_OES_standard_derivatives : enable
float circle (const vec2 st, float r) {
return sin(300.0 * length(st));
}
void main() {
vec2 st = gl_FragCoord.xy / u_resolution.xy;
st.x *= u_resolution.x / u_resolution.y;
float dist = circle(st, 0.5);
float df;
df = dFdx(dist) * 100.0;
df = (circle(st + vec2(1.0 / u_resolution.x, 0.0), 0.5) - dist) * 100.0;
gl_FragColor = vec4(vec3(df), 1.0);
}
但是结果不同了,手动方式似乎很顺利,有人能解释一下吗
(手册)
(dFdx)你的假设并不完全正确 是计算两个相邻片段表达式的差(偏导数) 但是不,它并不总是当前片段和行中下一个片段的差异 考虑到差异,一次计算2x2平方的碎片。在该平方中,计算“左”和“右”碎片(
dFdx
)的差值。结果是“左”片段的dFdx
结果,以及“右”片段的invertieren结果:
有关详细规范,请参阅
float dist = circle(st, 0.5);
float dist_n = circle(st + offs_x, 0.5);
float dist_p = circle(st - offs_x, 0.5);
对于行中的偶数片段,必须计算下一个片段和当前片段表达式的差异:
df = (dist_n - dist) * 100.0;
df = (dist - dist_p) * 100.0;
对于行中的奇数片段,您必须计算当前片段和前一个片段的表达式之差:
df = (dist_n - dist) * 100.0;
df = (dist - dist_p) * 100.0;
请参见WebGL示例,该示例将左侧的dFdx
结果与右侧的模拟结果进行比较:
(函数loadscene(){
变量gl,canvas,prog,bufObj={};
函数渲染(deltaMS){
总图视口(0,0,vp_大小[0],vp_大小[1]);
总帐启用(总帐深度测试);
gl.clearColor(0.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
ShProg.用法(progDraw);
ShProg.SetF2(程序图,“u_分辨率”,vp_尺寸);
VertexBuffer.Draw(bufRect);
请求动画帧(渲染);
}
函数initScene(){
canvas=document.getElementById(“canvas”);
gl=canvas.getContext(“实验性webgl”);
//gl=canvas.getContext(“webgl2”);
如果(!gl)
返回null;
var standard_Derivations=gl.getExtension(“OES_standard_Derivations”);//dFdx,dFdy
if(!标准_导数)
警报(“无标准衍生产品支持(无dFdx、dFdy)”;
progDraw=ShProg.Create(
[{来源:“绘制着色器vs”,阶段:gl.VERTEX_shader},
{来源:“绘制着色器fs”,阶段:gl.FRAGMENT_shader}
] );
progDraw.inPos=gl.getAttribLocation(progDraw.progObj,“inPos”);
如果(progDraw.progObj==0)
返回;
bufRect=VertexBuffer.Create(
[{data:[-1,-1,1,-1,1,1],attrSize:2,attrLoc:progDraw.inPos}],
[ 0, 1, 2, 0, 2, 3 ] );
window.onresize=调整大小;
调整大小();
请求动画帧(渲染);
}
函数resize(){
//vp_大小=[gl.drawingBufferWidth,gl.drawingBufferHeight];
vp_size=[window.innerWidth,window.innerHeight]
vp_大小[0]=vp_大小[1]=Math.min(vp_大小[0],vp_大小[1]);
//vp_大小=[256,256]
canvas.width=vp_大小[0];
canvas.height=vp_大小[1];
}
变量ShProg={
创建:函数(着色器列表){
var shaderObjs=[];
for(变量i_sh=0;i_sh