在片段着色器中将世界坐标映射到纹理的值 [英] map world coordinate to a texture's value in fragment shader

查看:162
本文介绍了在片段着色器中将世界坐标映射到纹理的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用threeJS将世界坐标映射到片段着色器中的纹理值.

生成的颜色"仅为黑色,但webgl不会返回任何错误.

这就是我得到的:

  • 在3D模式下,我在webgl中得到了什么(黑色切片而不是图像)
  • 在2D画布中,我应该在webgl中使用.

我的着色器:

<script id="vertShader" type="shader">

varying vec4 vPos;

void main() {
    vPos = modelViewMatrix * vec4(position, 1.0 );
    gl_Position = projectionMatrix *
                  modelViewMatrix * vec4(position, 1.0 );
}
</script>

<script id="fragShader" type="shader">

uniform mat4 rastoijk;
uniform sampler2D ijk;
uniform vec3 dimensionsIJK;

varying vec4 vPos;

void main(void) {
    // get IJK coordinates of current element
    vec4 ijkPos = rastoijk * vPos;
    //convert IJK coordinates to texture coordinates
    float sliceIndex = float(ijkPos[2])*(float(dimensionsIJK[0])*float(4))*float(dimensionsIJK[1]);
    float rowIndex = ijkPos[1]*(dimensionsIJK[0]*float(4));
    float colIndex = ijkPos[0]*float(4);
    vec2 textureCoordinates = vec2(colIndex, sliceIndex + rowIndex);
    vec3 color = texture2D( ijk, textureCoordinates ).rgb;

    gl_FragColor = vec4(color, 1.0);
  }
</script>

以及threeJS部分的相关部分:

  var mat = new THREE.ShaderMaterial({
        uniforms: {
            ijk: {type: 't', value: ijkRGBATex},
            dimensionsIJK: {type: 'v3', value: new THREE.Vector3( dimensions[0], dimensions[1], dimensions[2] )},
            rastoijk: {type: 'm4', value: new THREE.Matrix4().set(rasijk[0], rasijk[4], rasijk[8], rasijk[12],
                                         rasijk[1], rasijk[5], rasijk[9], rasijk[13],
                                         rasijk[2], rasijk[6], rasijk[10], rasijk[14],
                                         rasijk[3], rasijk[7], rasijk[11], rasijk[15])}
        },
        vertexShader: document.
                      getElementById('vertShader').text,
        fragmentShader: document.
                      getElementById('fragShader').text
    });

我的IJK纹理生成如下:

ijkRGBATex = new THREE.DataTexture( _imageRGBA, _dims[0].length * 4, _dims[1]*_dims[2], THREE.RGBAFormat );

其中:

var _dims = [numberCols, numberRows, numberSlices];
var _imageRGBA = new Float32Array(_dims[2] *_dims[1] * _dims[0] * 4);
  for(var i=0; i<_data.length; i++){
    _imageRGBA[4*i] = _imageRGBA[4*i + 1] = _imageRGBA[4*i + 2] = ((_data[i] - _min) / (_max - _min));
    _imageRGBA[4*i + 3] = 1;
  }

我尝试做的事情有道理吗?我不希望在那里进行校正,但是我的纹理中看不到任何白色像素,这是最有问题的.

最好

解决方案

问题是我们试图显示的纹理无效.关于此特定问题的新线程创建了:在threejs中从阵列生成纹理

I am trying to map a world coordinate to a texture's value in the fragment shader using threeJS.

The generated 'color' is only black but webgl doesn't return any error.

Here is what I get:

  • in the 3D, what I get in webgl (black slice instead of an image)
  • in the 2D canvas, what I should in webgl.

My shaders:

<script id="vertShader" type="shader">

varying vec4 vPos;

void main() {
    vPos = modelViewMatrix * vec4(position, 1.0 );
    gl_Position = projectionMatrix *
                  modelViewMatrix * vec4(position, 1.0 );
}
</script>

<script id="fragShader" type="shader">

uniform mat4 rastoijk;
uniform sampler2D ijk;
uniform vec3 dimensionsIJK;

varying vec4 vPos;

void main(void) {
    // get IJK coordinates of current element
    vec4 ijkPos = rastoijk * vPos;
    //convert IJK coordinates to texture coordinates
    float sliceIndex = float(ijkPos[2])*(float(dimensionsIJK[0])*float(4))*float(dimensionsIJK[1]);
    float rowIndex = ijkPos[1]*(dimensionsIJK[0]*float(4));
    float colIndex = ijkPos[0]*float(4);
    vec2 textureCoordinates = vec2(colIndex, sliceIndex + rowIndex);
    vec3 color = texture2D( ijk, textureCoordinates ).rgb;

    gl_FragColor = vec4(color, 1.0);
  }
</script>

and the relevant part of the threeJS part:

  var mat = new THREE.ShaderMaterial({
        uniforms: {
            ijk: {type: 't', value: ijkRGBATex},
            dimensionsIJK: {type: 'v3', value: new THREE.Vector3( dimensions[0], dimensions[1], dimensions[2] )},
            rastoijk: {type: 'm4', value: new THREE.Matrix4().set(rasijk[0], rasijk[4], rasijk[8], rasijk[12],
                                         rasijk[1], rasijk[5], rasijk[9], rasijk[13],
                                         rasijk[2], rasijk[6], rasijk[10], rasijk[14],
                                         rasijk[3], rasijk[7], rasijk[11], rasijk[15])}
        },
        vertexShader: document.
                      getElementById('vertShader').text,
        fragmentShader: document.
                      getElementById('fragShader').text
    });

and my IJK texture is generated as below:

ijkRGBATex = new THREE.DataTexture( _imageRGBA, _dims[0].length * 4, _dims[1]*_dims[2], THREE.RGBAFormat );

where:

var _dims = [numberCols, numberRows, numberSlices];
var _imageRGBA = new Float32Array(_dims[2] *_dims[1] * _dims[0] * 4);
  for(var i=0; i<_data.length; i++){
    _imageRGBA[4*i] = _imageRGBA[4*i + 1] = _imageRGBA[4*i + 2] = ((_data[i] - _min) / (_max - _min));
    _imageRGBA[4*i + 3] = 1;
  }

Does what I try to do make sense at all? I don't expect to have it correct there but I do not see any white pixels in my texture, which is the most problematic.

Best,

解决方案

issue is that the texture we are trying to display is not valid. New thread create about this specific issue: generate texture from array in threejs

这篇关于在片段着色器中将世界坐标映射到纹理的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆