【发布时间】:2021-10-30 10:53:28
【问题描述】:
我在平面上渲染的纹理有问题。我将 webgl 用于 blazor 服务器应用程序,并将 net5 用于后端。
那我在做什么?
- 我从一个文件中读取了一张图片(这个文件包含很多图片)+ 到目前为止效果很好。我返回一个整数数组。
- 我用它创建了一个纹理。
- 我将它渲染到飞机上。
问题:它以灰度而不是颜色呈现,我不知道为什么。
顶点着色器:
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 projection;
varying vec3 vNormal;
varying vec2 vUv;
void main() {
vUv = uv;
vNormal = (model * vec4(normal, 0.)).xyz;
gl_Position = projection * model * vec4(position, 1.);
}
片段着色器:
#ifdef GL_ES
precision highp float;
#endif
uniform vec3 lightDirection;
uniform float ambientLight;
uniform sampler2D diffuse;
varying vec3 vNormal;
varying vec2 vUv;
void main() {
float lightness = -clamp(dot(normalize(vNormal), normalize(lightDirection)), -1., 0.);
lightness = ambientLight + (1. - ambientLight) * lightness;
gl_FragColor = vec4(texture2D(diffuse, vUv).rgb * lightness, 1);
}
这是我构建的功能:
var gl = await this._canvasReference.CreateWebGLAsync(new WebGLContextAttributes
{
PreserveDrawingBuffer = true,
PowerPreference = WebGLContextAttributes.POWER_PREFERENCE_HIGH_PERFORMANCE
});
await gl.ClearColorAsync(0.1f, 0.1f, 0.3f, 1);
await gl.EnableAsync(EnableCap.DEPTH_TEST);
await gl.ClearAsync(BufferBits.COLOR_BUFFER_BIT | BufferBits.DEPTH_BUFFER_BIT);
await gl.EnableAsync(EnableCap.CULL_FACE);
await gl.FrontFaceAsync(FrontFaceDirection.CCW);
await gl.CullFaceAsync(Face.BACK);
//Init the shaders
_shaderProgram = await ShaderProgram.InitShaderProgram(
gl,
await File.ReadAllTextAsync("includes/shaders/basic.vert"),
await File.ReadAllTextAsync("includes/shaders/basic.frag"),
new List<string>() { "position", "normal", "uv" },
new List<string>() { "model", "projection", "ambientLight", "lightDirection", "diffuse" });
// Get geometry like plane from object files
var geometry = Geometry.ParseObjFile(await File.ReadAllTextAsync("includes/models/plane.obj"));
var texbuffer = await ArtworkProvider.GetStaticAsync(0x03AB);
_texture = await WebGLFramework.Texture.BuildLandAsync(gl, texbuffer);
//_texture = await WebGLFramework.Texture.BuildAsync(gl, _textureContainer.GetValueOrDefault(0), size, size);
_cylinderMesh = await Mesh.BuildAsync(gl, geometry, _texture);
_light = new Light();
await DrawSceneAsync();
最后是我的 BuildLandAsync 任务:
public static async Task<Texture> BuildLandAsync(WebGLContext gl, int[] buffer, int width = 44, int height = 44)
{
var texture = await gl.CreateTextureAsync();
await gl.BindTextureAsync(TextureType.TEXTURE_2D, texture);
await gl.TexImage2DAsync(Texture2DType.TEXTURE_2D, 0, PixelFormat.LUMINANCE, width, height, 0, PixelFormat.LUMINANCE, PixelType.UNSIGNED_BYTE, buffer);
await gl.TexParameterAsync(TextureType.TEXTURE_2D, TextureParameter.TEXTURE_MIN_FILTER, (int)TextureParameterValue.NEAREST);
await gl.TexParameterAsync(TextureType.TEXTURE_2D, TextureParameter.TEXTURE_MAG_FILTER, (int)TextureParameterValue.NEAREST);
await gl.TexParameterAsync(TextureType.TEXTURE_2D, TextureParameter.TEXTURE_WRAP_S, (int)TextureParameterValue.CLAMP_TO_EDGE);
await gl.TexParameterAsync(TextureType.TEXTURE_2D, TextureParameter.TEXTURE_WRAP_T, (int)TextureParameterValue.CLAMP_TO_EDGE);
return new Texture(gl, texture, width, height);
}
【问题讨论】:
-
纹理的像素格式为
PixelFormat.LUMINANCE。 “LUMINANCE”是一个灰度值。您必须使用带有 RGB 信息的纹理格式。 -
感谢您的回答。我选择 Luminance 是因为它是唯一有效的,因为数组没有足够的 rgb 或 rgba 结构值。意味着它是一个 bgra5551 的 ushort 数组,我将其转换为 webgl 可以处理的 argb32 int 数组。该错误意味着在将像素格式设置为 rgb 或 rgba 时需要 43 个字节和 44 个像素,而它只包含 19 行(0 像素)。