我正在尝试像从Nvidia GPU Gems 3中提取的那样应用体积散射后处理,现在我有这样的东西:
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
{
// Calculate vector from pixel to light source in screen space.
half2 deltaTexCoord = (texCoord - ScreenLightPos.xy);
// Divide by number of samples and scale by control factor.
deltaTexCoord *= 1.0f / NUM_SAMPLES * Density;
// Store initial sample.
half3 color = tex2D(frameSampler, texCoord);
// Set up illumination decay factor.
half illuminationDecay = 1.0f;
// Evaluate summation from Equation 3 NUM_SAMPLES iterations.
for (int i = 0; i < NUM_SAMPLES; i++)
{
// Step sample location along ray.
texCoord -= deltaTexCoord;
// Retrieve sample at new location.
half3 sample = tex2D(frameSampler, texCoord);
// Apply sample attenuation scale/decay factors.
sample *= illuminationDecay * Weight;
// Accumulate combined color.
color += sample;
// Update exponential decay factor.
illuminationDecay *= Decay;
}
// Output final color with a further scale control factor.
return float4( color * Exposure, 1);
}
但是此着色器需要均匀的光位置,我在考虑是否可以使用后处理材料检测屏幕中光线的位置以及如何执行此操作。有什么想法吗?
相反,使用glUniform(在OpenGL应用程序中)将光线的位置传递到着色器中。您需要在着色器顶部附近声明光源位置:
uniform vec2 ScreenLightPos;
如果灯光从不移动,则可以使其在着色器中的位置恒定:
const vec2 ScreenLightPos = vec2(0.5, 0.5);
或者,如果灯光可预测地移动,您可以根据时间计算其位置:
vec2 ScreenLightPos = vec2(sin(time), cos(time));
基本上,您需要知道光源在之前的位置。无论您是进行后处理还是表面照明,都是如此。
如果没有[[绝对没有其他方法,则可以使用compute shader或更糟的是pixel reading来检测帧缓冲区上的明亮区域。这将非常慢,并且一旦确定了光线的位置,您仍然需要使用glUniform传递位置。如果甚至不是某种选择,则可以在着色器中使用嵌套循环在整个帧缓冲区中搜索亮点。我不会解释如何执行此操作,也不会解释为什么这是一个可怕的想法。