首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >不能用采样器显示纹理

不能用采样器显示纹理
EN

Stack Overflow用户
提问于 2016-01-25 00:39:29
回答 1查看 462关注 0票数 1

我试图显示一个加载了MTKTextureLoader的纹理,我有一个缓冲区来存储我的顶点坐标(我构建了两个三角形来在其中有一个矩形来显示我的图像),然后我有一个缓冲区来存储每个顶点的纹理坐标。

我做了一个取样器从我的纹理中采样数据,问题是我什么也没有得到(黑色图像)。

我提供了Swift代码,以防我的错误来自那里,但我认为它来自金属代码。如果您查看我的片段着色器,您将看到两个注释,它们显示了一些我无法理解的东西:

  • 如果我将坐标直接交给样本函数,它就会工作(用与给定坐标对应的颜色来表示三角形)。
  • 如果我把传递给采样器的坐标作为颜色分量,它也会显示一些相干的东西(三角形在给定坐标的函数中着色)。

所以它似乎不是来自采样器,也不是来自坐标,这是我不明白的。

这是我的Swift代码:

代码语言:javascript
运行
AI代码解释
复制
import Cocoa
import MetalKit
import Metal

class ViewController: NSViewController, MTKViewDelegate {

    var device:MTLDevice!
    var texture:MTLTexture!
    var commandQueue:MTLCommandQueue!
    var vertexBuffer:MTLBuffer!
    var vertexCoordinates:[Float] = [
        -1, 1, 0, 1,
        -1, -1, 0, 1,
        1, -1, 0,  1,

        1,-1,0,1,
        1,1,0,1,
        -1,1,0,1,

    ]

    var vertexUVBuffer:MTLBuffer!
    var vertexUVCoordinates:[Float] = [
    0,1,
    0,0,
    1,0,
    1,0,
    1,1,
    0,1
    ]

    var library:MTLLibrary!
    var defaultPipelineState:MTLRenderPipelineState!
    var samplerState:MTLSamplerState!

    @IBOutlet var metalView: MTKView!

    override func viewDidLoad() {
        super.viewDidLoad()

        device = MTLCreateSystemDefaultDevice()
        let textureLoader = MTKTextureLoader(device: device)

        metalView.device = device
        metalView.delegate = self
        metalView.preferredFramesPerSecond = 0
        metalView.sampleCount = 4



        texture = try! textureLoader.newTextureWithContentsOfURL(NSBundle.mainBundle().URLForResource("abeilles", withExtension: "jpg")!, options: [MTKTextureLoaderOptionAllocateMipmaps:NSNumber(bool: true)])

        commandQueue = device.newCommandQueue()
        library = device.newDefaultLibrary()


        vertexBuffer = device.newBufferWithBytes(&vertexCoordinates, length: sizeof(Float)*vertexCoordinates.count, options: [])
        vertexUVBuffer = device.newBufferWithBytes(&vertexUVCoordinates, length: sizeof(Float)*vertexUVCoordinates.count, options: [])



        let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
        renderPipelineDescriptor.vertexFunction = library.newFunctionWithName("passTroughVertex")
        renderPipelineDescriptor.fragmentFunction = library.newFunctionWithName("myFragmentShader")
        renderPipelineDescriptor.sampleCount = metalView.sampleCount
        renderPipelineDescriptor.colorAttachments[0].pixelFormat = metalView.colorPixelFormat
        defaultPipelineState = try! device.newRenderPipelineStateWithDescriptor(renderPipelineDescriptor)
        let samplerDescriptor = MTLSamplerDescriptor()
        samplerDescriptor.minFilter = .Linear
        samplerDescriptor.magFilter = .Linear
        samplerDescriptor.mipFilter = .Linear
        samplerDescriptor.sAddressMode = .ClampToEdge
        samplerDescriptor.rAddressMode = .ClampToEdge
        samplerDescriptor.tAddressMode = .ClampToEdge
        samplerDescriptor.normalizedCoordinates = true

        samplerState = device.newSamplerStateWithDescriptor(samplerDescriptor)
        metalView.draw()






        // Do any additional setup after loading the view.
    }

    func drawInMTKView(view: MTKView) {

        let commandBuffer = commandQueue.commandBuffer()
        let commandEncoder = commandBuffer.renderCommandEncoderWithDescriptor(metalView.currentRenderPassDescriptor!)
        commandEncoder.setRenderPipelineState(defaultPipelineState)

        commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 0)
        commandEncoder.setVertexBuffer(vertexUVBuffer, offset:0, atIndex:1)
        commandEncoder.setFragmentSamplerState(samplerState, atIndex: 0)
        commandEncoder.setFragmentTexture(texture, atIndex: 0)
        commandEncoder.drawPrimitives(MTLPrimitiveType.Triangle, vertexStart: 0, vertexCount: 6, instanceCount: 1)

        commandEncoder.endEncoding()
        commandBuffer.presentDrawable(metalView.currentDrawable!)
        commandBuffer.commit()

    }

    func mtkView(view: MTKView, drawableSizeWillChange size: CGSize) {
        // view.draw()
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}  

这是我的金属代码:

代码语言:javascript
运行
AI代码解释
复制
#include <metal_stdlib>
using namespace metal;


struct VertexOut {
    float4 position [[position]];
    float2 texCoord;
};


vertex VertexOut passTroughVertex(uint vid [[ vertex_id]],
                                  constant float4 *vertexPosition [[ buffer(0) ]],
                                  constant float2 *vertexUVPos [[ buffer(1)]]) {

    VertexOut vertexOut;
    vertexOut.position = vertexPosition[vid];
    vertexOut.texCoord = vertexUVPos[vid];
    return vertexOut;
}

fragment float4 myFragmentShader(VertexOut inFrag [[stage_in]],
                                 texture2d<float> myTexture [[ texture(0)]],
                                 sampler mySampler [[ sampler(0) ]]) {


    float4 myColor = myTexture.sample(mySampler,inFrag.texCoord);
    // myColor = myTexture.sample(mySampler,float2(1));
    // myColor = float4(inFrag.texCoord.r,inFrag.texCoord.g,0,1);

    return myColor;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-27 11:30:58

您正在为mipmap分配空间,但实际上并没有生成它们。医生说表示,当指定MTKTextureLoaderOptionAllocateMipmaps时,“在加载纹理时为纹理分配完整的mipmap级别,生成mipmap内容是您的责任。”

您的取样器配置会使最终的纹理在基本mipmap级别进行采样,只要纹理相对于屏幕上的rect很小,但是如果您输入更大的纹理,它就开始对mipmap堆栈的较小级别进行采样,获取所有黑色像素,然后将这些像素混合在一起,使图像变暗或使输出完全黑色。

在加载纹理之后,您应该使用-generateMipmapsForTexture:方法在MTLBlitCommandEncoder上生成完整的mipmap集。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34988206

复制
相关文章
Three TextureLoader纹理贴图不显示图片(显示黑色)的原因分析
问题在MeshLambertMaterial材质,把它改成MeshBasicMaterial即可显示图片。
Dawnzhang
2022/09/29
3.8K0
Metal Shading Language - 语法小结Metal Shading Language - 语法小结
纹理类型是一个句柄,指向一个一维/二维/三维的纹理数据;相当于OpenGL中的textureBufferID.
用户8893176
2021/08/09
1.1K0
Metal Shading Language - 语法小结Metal Shading Language - 语法小结
OpenGL学习笔记(二)——渲染管线&着色语言
导语 :渲染管线(渲染流水线),一般由显示芯片(GPU)内部处理图形信号的并行处理单元组成。这些并行处理单元两两之间相互独立。不同的型号硬件上独立处理单元的数量有很大差异。 与CPU串行执行不同,渲染
MelonTeam
2018/01/04
2.1K0
OpenGL学习笔记(二)——渲染管线&着色语言
Shader-基础纹理-遮罩纹理
遮罩纹理(mask texture)控制光照的强度,获得更加细腻的效果,通过遮罩纹理控制光照。在制作地形材质的时候混合多张图片,遮罩纹理控制如何混合这些纹理。 通过采样得到的纹素值与某种表面属性相乘,来更加精准的控制模型表面的各种属性。 在代码中添加了BumpMap来进行凹凸纹理效果,通过SpecularMask实现控制高光的光照
祝你万事顺利
2019/05/28
1.2K0
Shader-基础纹理-渐变纹理
一种基于冷暖色调的着色技术,通过渐变纹理控制漫反射光照。核心部分来说用过使用halfLambert构建一个纹理坐标,用这个纹理坐标来对渐变纹理进行采样。
祝你万事顺利
2019/05/28
1.2K0
不联网不插U盘就安全了?黑客能用声波攻击你的硬盘
《不联网不插U盘就安全了?黑客能用声波攻击你的硬盘》文章摘要:研究人员发现了一种利用声波攻击硬盘的方法,可以导致硬盘损坏和数据丢失。攻击者可以利用声波干扰机械硬盘的正常工作模式,使其产生暂时或者永久拒绝服务状态,从而阻止数据被访问。这种攻击方式需要物理接触硬盘,因此可以通过远离硬盘来避免受到攻击。研究人员建议使用加密等方法保护硬盘中的数据。
企鹅号小编
2018/01/04
1.9K0
不联网不插U盘就安全了?黑客能用声波攻击你的硬盘
WebGL2系列之采样器对象
如果我们希望从同一个图片多次读取像素信息,但是每次读取的时候使用的过滤方式不一样, 此时我们需要创建两个不同的纹理对象。
用户3158888
2019/09/09
7600
Direct3D 11 Tutorial 7:Texture Mapping and Constant Buffers_Direct3D 11 教程7:纹理映射和常量缓冲区
在上一个教程中,我们为项目引入了照明。 现在我们将通过向我们的立方体添加纹理来构建它。 此外,我们将介绍常量缓冲区的概念,并解释如何使用缓冲区通过最小化带宽使用来加速处理。
Zoctopus
2018/12/06
6080
纹理压缩
本文介绍了纹理压缩的基本概念、原理、常用压缩方式、压缩工具及相关技术标准,旨在帮助读者了解纹理压缩的基本知识,从而更好地进行纹理压缩相关的实践。
MelonTeam
2018/01/04
1.6K0
纹理压缩
12.QT-通过QOpenGLWidget显示YUV画面,通过QOpenGLTexture纹理渲染YUV
在上章11.QT-ffmpeg+QAudioOutput实现音频播放器,我们学习了如何播放音频,接下来我们便来学习如何通过opengl来显示YUV画面
诺谦
2020/11/04
3.9K0
12.QT-通过QOpenGLWidget显示YUV画面,通过QOpenGLTexture纹理渲染YUV
Pytorch的数据采样器
class torch.utils.data.Sampler(data_source)[source]
狼啸风云
2020/06/10
2K0
文字转语音,1行Python代码搞定,不联网也能用
开源项目:python-office的功能一直在更新中,今天给大家发布一个新功能:文字转语音。
程序员晚枫
2023/09/06
5220
文字转语音,1行Python代码搞定,不联网也能用
CUDA优化的冷知识18| texture和surface
https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html 来阅读原文。
GPUS Lady
2021/02/05
1.2K0
OpenGL ES _ 着色器_纹理图像
玩过游戏的同学们,都知道在游戏人物身上穿的那个叫皮肤,专业点将那个就叫做纹理图像。GLSL 支持在顶点和片段着色器使用纹理图像。
酷走天涯
2018/09/14
1.3K0
Shader-高级纹理-立方体纹理
是环境映射(EnvironmentMapping)一种实现方式。 纹理采样:对立方体采样需要提供一个三维的纹理坐标,这个三维纹理坐标表示了我们在世界空间下的一个3D、方向。
祝你万事顺利
2019/05/29
9010
Qt官方示例-字体采样器
❝预览系列字体的例子。❞   建立字体树显示。 QFontDatabase database; fontTree->setColumnCount(1); fontTree->setHeaderLabels(QStringList() << tr("Font")); foreach (QString family, database.families()) { const QStringList styles = database.styles(family); if (styles.i
Qt君
2023/03/17
4170
Qt官方示例-字体采样器
OpenGL(八)--纹理相关APIOpenGL(八)--纹理相关API
OpenGL(八)--纹理相关API 1. 原始图像数据 //存储图像数据所占内存大小 size = 图像的高度 * 图像的宽度 * 每个像素所占字节数 像素所占字节数:一般为4Byte,包含RGBA四个通道,每个通道为1Byte(8Bit) 2. 认识函数 像素存储方式 //改变像素存储方式 void glPixelStorei(GLenum pname,GLint param); //恢复像素存储方式 void glPixelStoref(GLenum pname,GLint param); /
用户8893176
2021/08/09
1.2K0
OpenGL(八)--纹理相关APIOpenGL(八)--纹理相关API
Metal入门教程总结
本文介绍Metal和Metal Shader Language,以及Metal和OpenGL ES的差异性,也是实现入门教程的心得总结。
落影
2018/08/21
5.1K0
Metal入门教程总结
纹理投影测试
GPU Gems3里有个不规则地形(X,Y,Z三个方向上都有面), 这时就没法简单地用X,Z坐标来计算UV了
逍遥剑客
2019/02/20
6630
点击加载更多

相似问题

采样器不包扎纹理

12

纹理采样器ID不映射到纹理单元

27

绑定OpenGL纹理采样器

10

对纹理采样器纹理单位值的困惑

13

纹理对象和采样器的多重纹理化理论

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档