c# - WebGL 为什么要渲染灰度纹理?
问题描述
我在飞机上渲染的纹理有问题。我将 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 信息的纹理格式。
由于您的像素格式是 bgra5551
,您可以使用PixelType.UNSIGNED_SHORT_5_5_5_1
(请参阅WebGL 规范 - 纹理对象):
await gl.TexImage2DAsync(Texture2DType.TEXTURE_2D, 0, PixelFormat.RGBA,
width, height, 0, PixelFormat.RGBA, PixelType.UNSIGNED_SHORT_5_5_5_1, buffer);
推荐阅读
- java - 如何更改具有初始化值的字段的值?
- r - 线条颜色交换ggplot
- android - 如何使用 AndroidDriver 在键盘中单击 Enter
? - javascript - 在 Safari 和 Firefox 中流式下载文件
- networking - 集群IP可以属于其他网络吗?
- laravel - 我想访问 auth()->user()-> 像 web.php 这样的路由?
- automation - 是否可以让 gitlab CI 触发另一个管道?
- python - 在 Python 中对更大数据集的字符串进行聚类并行化方法(使用 Levenshtein 作为距离)
- angular - 开玩笑,期待另一个异步回调不会被调用
- ios - 为什么我的单元测试失败,因为我的项目有领域对象?