OpenGL - 如何通过着色器以像素化方式为对象着色?

比厄

我试图找出一种方法,通过使用着色器以像素化的方式照亮我的对象。

为了说明,我的目标是把这个:

在

进入这个:

出去

我已经尝试通过片段着色器寻找方法来做到这一点,但是,我无法访问片段的本地位置来确定它所属的“假像素”。我也有使用几何着色器为每个框创建顶点的想法,但我怀疑可能有更好的方法来做到这一点。可能吗?

编辑:这些是当前用于第一张图像所示对象的着色器:

顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTex;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out vec3 oColor; //Output of a color
out vec2 oTex; //Output of a Texture
out vec3 oPos; //Output of Position in space for light calculation
out vec3 oNormal; //Output of Normal vector for light calculation. 

void main(){
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    oColor = aColor;
    oTex = aTex;
    oPos = vec3(model * vec4(aPos, 1.0));
    oNormal = vec3(0, 0, -1); //Not being calculated at the moment.
}

片段着色器:

#version 330 core

in vec3 oColor;
in vec2 oTex;
in vec3 oPos;  
in vec3 oNormal;  

out vec4 FragColor;

uniform sampler2D tex;
uniform vec3 lightColor; //Color of the light on the scene, there's only one
uniform vec3 lightPos; //Position of the light on the scene

void main(){
   //Ambient Light Calculation
   float ambientStrength = 0.1;
   //vec3 ambient = ambientStrength * lightColor * vec3(texture(tex, oTex));
   vec3 ambient = ambientStrength * lightColor;

   //Diffuse Light Calculation
   float diffuseStrength = 1.0;
   vec3 norm = normalize(oNormal);
   vec3 lightDir = normalize(lightPos - oPos);

   float diff = max(dot(norm, lightDir), 0.0);
   //vec3 diffuse = diff * lightColor* vec3(texture(tex, oTex)) * diffuseStrength;
   vec3 diffuse = diff * lightColor;

   //Specular Light Calculation
   float specularStrength = 0.25;
   float shinnyness = 8;
   vec3 viewPos = vec3(0, 0, -10);

   vec3 viewDir = normalize(viewPos - oPos);
   vec3 reflectDir = reflect(-lightDir, norm);    

   float spec = pow(max(dot(viewDir, reflectDir), 0.0), shinnyness);
   vec3 specular = specularStrength * spec * lightColor;  

   //Result Light
   vec3 result = (ambient+diffuse+specular) * oColor;
   FragColor = vec4(result, 1.0f);
}

疯兔76

照明取决于oPos您需要“级联”位置。例如:

vec3 pos = vec3(round(oPos.xy * 10.0) / 10.0, oPos.z);

在下面使用pos代替oPos.

请注意,这仅适用oPos于视图空间中的位置,如果 oPos 坐标系的 XY 平面平行于视图的 XY 平面。


或者,您可以根据 计算 a 位置gl_FragCoord

添加具有屏幕分辨率的统一变量:

uniform vec2 resolution;

计算pos取决于resolutiongl_FragCoord

vec3 pos = vec3(round(20.0 * gl_FragCoord.xy/resolution.y) / 20.0, oPos.z);

如果要将内部方块与对象对齐,则需要引入纹理坐标。其中对象的左下角坐标为 (0, 0),右上角为 (1, 1)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章