簡體   English   中英

着色器和結構

[英]Shaders & structs

編輯 2016 年 8 月 16 日

我終於設法讓它拋出一個錯誤,可能會暴露正在發生的事情。 在我最新的代碼編輯中,我添加了在片段着色器之間進行熱交換的功能。 這適用於具有單例統一的着色器,但交換到具有結構的着色器會引發以下錯誤:

未捕獲的類型錯誤:無法讀取未定義的屬性“x”

調用棧:

setValue3fv @ three.js:31915
THREE.WebGLUniforms.StructuredUniform.setValue @ three.js:32148
THREE.WebGLUniforms.WebGLUniforms.upload @ three.js:32285
setProgram @ three.js:26733 renderBufferDirect @ three.js:25492
renderObjects @ three.js:26303
render @ three.js:26044
draw @ VM160:191doStructs @ VM86:148

看起來它正在錯誤地構建結構制服(它試圖引用只有rg和 、 bTHREE.Color屬性value )。 我正在繼續挖掘,但也許這個新信息會觸發某人的燈泡。

原始郵政編碼

根據此處的對話,Three.js 能夠將struct用作着色器制服。 我現在正在嘗試使用具有結構的着色器,簡化到最低限度,但仍然無法將它們識別為結構。

在下面的小提琴中,只需將WITH_STRUCTS值更改為true / false並重新運行以查看差異。

我也試過這樣定義制服,但沒有什么區別。

uniforms: {
    "colorValues": {
        "color": { type: "c", value: new THREE.Color(0x00ff00) }
    },
    "opacityValues": {
        "opacity": { type: "f", value: 1.0 }
    }
}

我是否錯過了某些屬性,或者我是否完全錯誤地處理了這個問題?

jsFiddle: http : //jsfiddle.net/TheJim01/546syLur/

HTML:

<script src="http://threejs.org/build/three.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
<div id="host"></div>

<script>
// INITIALIZE
var WIDTH = window.innerWidth,
    HEIGHT = window.innerHeight,
    FOV = 35,
    NEAR = 1,
    FAR = 1000;

var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
document.getElementById('host').appendChild(renderer.domElement);

var camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 250;

var trackballControl = new THREE.TrackballControls(camera, renderer.domElement);
trackballControl.rotateSpeed = 5.0; // need to speed it up a little

var scene = new THREE.Scene();

var light = new THREE.PointLight(0xffffff, 1, Infinity);
light.position.copy(camera.position);

scene.add(light);

function draw(){
    light.position.copy(camera.position);
    renderer.render(scene, camera);
}
trackballControl.addEventListener('change', draw);

function navStartHandler(e) {
  renderer.domElement.addEventListener('mousemove', navMoveHandler);
  renderer.domElement.addEventListener('mouseup', navEndHandler);
}
function navMoveHandler(e) {
  trackballControl.update();
}
function navEndHandler(e) {
  renderer.domElement.removeEventListener('mousemove', navMoveHandler);
  renderer.domElement.removeEventListener('mouseup', navEndHandler);
}

renderer.domElement.addEventListener('mousedown', navStartHandler);
renderer.domElement.addEventListener('mousewheel', navMoveHandler);
</script>

<fieldset id="controls">
  <legend>Controls</legend>
  <input id="drawButton" type="button" value="DRAW" />
  <input id="useStructsCheck" type="checkbox" /><label for="useStructsCheck">Use Structs</label>
</fieldset>

CSS:

html, body{
    padding: 0;
    margin: 0;
    width: 100%;
    overflow: hidden;
}

#controls {
    position: absolute;
    top: 20px;
    left: 20px;
    z-index: 99;
    color: white;
    border-radius: 10px;
}

#host {
    width: 100%;
    height: 100%;
}

JavaScript:

// NOTE: To run this demo, you MUST use the HTTP protocol, not HTTPS!

var WITH_STRUCTS = false;

var vShaderCode = [
    "precision highp float;",
    "precision highp int;",

    "uniform mat4 modelViewMatrix;",
    "uniform mat4 projectionMatrix;",

    "attribute vec3 position;",

    "void main() {",
        "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
        "gl_Position = projectionMatrix * mvPosition;",
    "}"
].join("\n");

var fShaderCode_structs = [
    "precision highp float;",
    "precision highp int;",

    "struct ColorStruct{",
        "vec3 value;",
    "};",
    "struct OpacityStruct{",
        "float value;",
    "};",
    "uniform ColorStruct color;",
    "uniform OpacityStruct opacity;",

    "void main() {",
        "gl_FragColor = vec4(color.value, opacity.value);",
    "}"
].join("\n");

var fShaderCode_nostructs = [
    "precision highp float;",
    "precision highp int;",

    "uniform vec3 color;",
    "uniform float opacity;",

    "void main() {",
        "gl_FragColor = vec4(color, opacity);",
    "}"
].join("\n");

var geo = new THREE.BoxBufferGeometry(30, 30, 30);

var mat = new THREE.RawShaderMaterial({
        uniforms: {
        "color": { type: "c", value: new THREE.Color(0xff0000) },
            "opacity": { type: "1f", value: 1.0 },
            "color.value": { type: "c", value: new THREE.Color(0x00ff00) },
            "opacity.value": { type: "1f", value: 1.0 }
        },
        vertexShader: vShaderCode,
        fragmentShader: (WITH_STRUCTS) ? fShaderCode_structs : fShaderCode_nostructs
    });

var msh = new THREE.Mesh(geo, mat);
scene.add(msh);

draw();

// Draw button
// Making this an external function rather than referencing draw directly, in case we want to update draw with parameters.
function doDraw() {
  draw();
}
document.getElementById("drawButton").addEventListener("click", doDraw);

// Use Structs checkbox
function doStructs() {
  WITH_STRUCTS = !WITH_STRUCTS;
  if (WITH_STRUCTS) {
    mat.fragmentShader = fShaderCode_structs;
  }
  else {
    mat.fragmentShader = fShaderCode_nostructs;
  }
  mat.needsUpdate = true;
  draw();
}
document.getElementById("useStructsCheck").addEventListener("click", doStructs);

這是關於幾個小而愚蠢的錯誤如何使整個事情崩潰和燃燒的教訓。

我給我的單身制服命名和我的結構化制服一樣。 當統一解析器嘗試分配值時,它嘗試將單例值分配給結構對象。 那自然行不通,整個事情就崩潰了。

似乎“替代”統一定義也是要走的路。 我不確定為什么它最初不起作用,但我感覺這是由於命名不匹配,就像上面一樣。

這是工作代碼塊,我已經更新了原始帖子中鏈接的小提琴。

新的片段着色器(只有一個 WITH 結構)

var fShaderCode_structs = [
    "precision highp float;",
    "precision highp int;",

    "struct ColorStruct{",
        "vec3 cvalue;",
    "};",
    "struct OpacityStruct{",
        "float ovalue;",
    "};",
    "uniform ColorStruct colorS;",
    "uniform OpacityStruct opacityS;",

    "void main() {",
        "gl_FragColor = vec4(colorS.cvalue, opacityS.ovalue);",
    "}"
].join("\n");

新材料定義

var mat = new THREE.RawShaderMaterial({
    uniforms: {
        "color": { type: "c", value: new THREE.Color(0xff0000) },
        "opacity": { type: "1f", value: 1.0 },
        "colorS": {
            value: { type: "c", cvalue: new THREE.Color(0x00ff00) },
        },
        "opacityS": {
            value: { type: "1f", ovalue: 1.0 }
        }
    },
    vertexShader: vShaderCode,
    fragmentShader: (WITH_STRUCTS) ? fShaderCode_structs : fShaderCode_nostructs
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM