我一直在努力将贴花投射到贴花边框封装的任何东西上。在阅读并尝试了大量的代码片段(通常是在HLSL中)之后,我在GLSL中有一些用于投影贴花的工作方法。
让我首先尝试解释一下我在做什么以及它是如何工作的(到目前为止)
以下代码现已修复并正常工作!
这一切都处于透视视图模式中
我将两件制服发送到片段着色器" tr"和" bl"。这些是边界框的两个角。我可以并将用硬编码尺寸替换它们,因为它们是贴花原始边界框的大小。 tr = vec3(.5,.5,.5)和br = vec3( - 。5,-.5,-.5)。我更愿意找到一种在贴花转换状态下进行位置测试的方法。 (最后更多关于这一点)。
为了清楚起见,添加此内容。从顶点程序发出的顶点是边界框乘以贴花矩阵而不是模型视图投影矩阵。我将其用于下一步:
使用该顶点,我从深度纹理中获取深度值,并使用它,使用投影矩阵的倒数计算世界空间中的位置。
接下来,我使用Decals矩阵的反转来转换此位置。 (将1,1,1立方体缩放,旋转并平移到其世界位置的矩阵。我认为通过使用贴花变换矩阵的逆,可以正确处理屏幕点的正确大小和旋转,但它是不
顶点程序:
//Decals color pass.
#version 330 compatibility
out mat4 matPrjInv;
out vec4 positionSS;
out vec4 positionWS;
out mat4 invd_mat;
uniform mat4 decal_matrix;
void main(void)
{
gl_Position = decal_matrix * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
positionWS = (decal_matrix * gl_Vertex);;
positionSS = gl_Position;
matPrjInv = inverse(gl_ModelViewProjectionMatrix);
invd_mat = inverse(decal_matrix);
}
片段计划:
#version 330 compatibility
layout (location = 0) out vec4 gPosition;
layout (location = 1) out vec4 gNormal;
layout (location = 2) out vec4 gColor;
uniform sampler2D depthMap;
uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform mat4 matrix;
uniform vec3 tr;
uniform vec3 bl;
in vec2 TexCoords;
in vec4 positionSS; // screen space
in vec4 positionWS; // world space
in mat4 invd_mat; // inverse decal matrix
in mat4 matPrjInv; // inverse projection matrix
void clip(vec3 v){
if (v.x > tr.x || v.x < bl.x ) { discard; }
if (v.y > tr.y || v.y < bl.y ) { discard; }
if (v.z > tr.z || v.z < bl.z ) { discard; }
}
vec2 postProjToScreen(vec4 position)
{
vec2 screenPos = position.xy / position.w;
return 0.5 * (vec2(screenPos.x, screenPos.y) + 1);
}
void main(){
// Calculate UVs
vec2 UV = postProjToScreen(positionSS);
// sample the Depth from the Depthsampler
float Depth = texture2D(depthMap, UV).x * 2.0 - 1.0;
// Calculate Worldposition by recreating it out of the coordinates and depth-sample
vec4 ScreenPosition;
ScreenPosition.xy = UV * 2.0 - 1.0;
ScreenPosition.z = (Depth);
ScreenPosition.w = 1.0f;
// Transform position from screen space to world space
vec4 WorldPosition = matPrjInv * ScreenPosition ;
WorldPosition.xyz /= WorldPosition.w;
WorldPosition.w = 1.0f;
// transform to decal original position and size.
// 1 x 1 x 1
WorldPosition = invd_mat * WorldPosition;
clip (WorldPosition.xyz);
// Get UV for textures;
WorldPosition.xy += 0.5;
WorldPosition.y *= -1.0;
vec4 bump = texture2D(normalMap, WorldPosition.xy);
gColor = texture2D(colorMap, WorldPosition.xy);
//Going to have to do decals in 2 passes..
//Blend doesn't work with GBUFFER.
//Lots more to sort out.
gNormal.xyz = bump;
gPosition = positionWS;
}
我尝试使用贴花和投影矩阵创建一个新的矩阵来构建一种&#34; lookat&#34;矩阵并将屏幕位置转换为转换状态后的贴花..我无法使其工作。有些地方我遗失了什么,但在哪里?我认为使用贴花矩阵的逆转换将处理转换并将屏幕位置置于适当的转换状态。想法?
更新了纹理UV的代码..您可能需要根据纹理是否在x或y上翻转来摆弄y和x。我还修复了剪辑子,以便它正常工作。实际上,这段代码现在有效。如果需要,我会更新更新,以便其他人不必经历我为使其工作所带来的痛苦。
要解决的一些问题是贴花相互叠加。顶部的那个写下面的那个。我想我必须将颜色和法线累积到默认的FBO中,然后在光照通过之前或期间将它们混合(添加)到GBUFFER纹理中。添加更多屏幕尺寸的纹理并不是一个好主意,因此我需要具有创造性并回收任何可以使用的纹理。
我发现贴花的解决方案相互叠加。
在绘制贴花时关闭深度遮罩并在之后重新打开int:
glDepthMask(GL_FALSE)
答案 0 :(得分:1)
void clip(vec3 v){
if (v.x > tr.x || v.x < bl.x ) { discard; }
if (v.y > tr.y || v.y < bl.y ) { discard; }
if (v.z > tr.z || v.z < bl.z ) { discard; }
}