我正在尝试在球体中使用此径向着色器,但未成功。问题与屏幕坐标有关。仅当球体位于屏幕中心时,着色器才起作用,就像显示以下图片一样:
如果我移动相机或物体,就会发生这种情况:
我发现,如果我将球体的位置转换为屏幕坐标,则着色器可以正常工作,就像我在此代码中显示的那样,使用函数cam.worldToScreen()
:
fbo.begin();
ofClear(0);
cam.begin();
shader.begin();
sphere.setRadius(10);
sphere.setPosition(v.x, v.y, v.z);
sphere.draw();
shader.end();
cam.end();
fbo.end();
depthFbo.begin();
ofClear(0);
fbo.getDepthTexture().draw(0,0);
ofSetColor(255);
depthFbo.end();
radialBuffer.begin();
ofClear(0);
radial.begin();
f = cam.worldToScreen(v);
radial.setUniform3f("ligthPos", f.x, f.y, f.z);
radial.setUniformTexture("depth", depthFbo.getTexture(), 1);
fbo.draw(0,0);
radial.end();
radialBuffer.end();
radialBuffer.draw(0,0);
这是着色器:
#version 150
in vec2 varyingtexcoord;
uniform sampler2DRect tex0;
uniform sampler2DRect depth;
uniform vec3 ligthPos;
float exposure = 0.19;
float decay = 0.9;
float density = 2.0;
float weight = 1.0;
int samples = 25;
out vec4 fragColor;
const int MAX_SAMPLES = 100;
void main()
{
// float sampleDepth = texture(depth, varyingtexcoord).r;
//
// vec4 H = vec4 (varyingtexcoord.x *2 -1, (1- varyingtexcoord.y)*2 -1, sampleDepth, 1);
//
// vec4 = mult(H, gl_ViewProjectionMatrix);
vec2 texCoord = varyingtexcoord;
vec2 deltaTextCoord = texCoord - ligthPos.xy;
deltaTextCoord *= 1.0 / float(samples) * density;
vec4 color = texture(tex0, texCoord);
float illuminationDecay = .6;
for(int i=0; i < MAX_SAMPLES; i++)
{
if(i == samples){
break;
}
texCoord -= deltaTextCoord;
vec4 sample = texture(tex0, texCoord);
sample *= illuminationDecay * weight;
color += sample;
illuminationDecay *= decay;
}
fragColor = color * exposure;
}
问题是我想将此效果应用于多个球体,但我不知道该怎么做,因为我将球体的位置像均匀变量一样传递给了径向着色器后期处理。
但是我实际上想要的是发现将这种着色器或其他着色器应用于网格的方式,而不是每次都处理此问题(着色器为什么没有统一的方法来确定对象的位置?这是什么?使着色器在屏幕坐标中起作用的方法是什么?怎么办?我需要一些光线,因为我感觉自己缺少一些东西。
这是我想做什么的说明图:
但是我想要后期处理着色器,该着色器可以具有对象的信息,而并不总是在屏幕的中心(在对象的中心就是我想要的)计算效果。 请提出任何建议