2014-11-21 2 views
11

Я пытаюсь получить this tutorial, но я столкнулся с двумя проблемами, одним из которых является следующее.Почему мне нужно определить значение точности в шейдерах webgl?

Когда я запускаю код, как есть, я получаю сообщение об ошибке в шейдере фрагмента: THREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:2: '' : No precision specified for (float). Так что я сделал, указав точность для каждого float/vector, который я определяю так varying highp vec3 vNormal. Это устраняет ошибку, но я не понимаю почему? Я не могу найти другого примера, в котором значения точности добавляются к объявлениям переменных. Может ли кто-нибудь объяснить, почему это происходит? Связано ли это с моим браузером (Chrome 38)?

+2

Получает ли это сообщение свет? http://stackoverflow.com/questions/5366416 – vabada

+0

В ответ на название вашего вопроса ответ в основном «потому что спецификация говорит так». WebGL основан на спецификации OpenGL ES 2.0, и для спецификации требуется указать точность. – gman

ответ

5

Ответ Джесси правилен тем, что большинство фрагментарных шейдеров задали точность по умолчанию в верхней части кода шейдера фрагмента.

Однако вы используете RawShaderMaterial файл 3.js, который не добавляет ни одной из встроенных форм, атрибутов и объявлений точности. Поэтому вы должны сами определить это.

С другой стороны, учебное пособие, с которым вы связались, использует файл ShaderMaterial от Three.js, поэтому у Three.js будет объявление точности заранее.

Если вы удалите униформу/атрибуты по умолчанию из вашего шейдерного кода и используете ShaderMaterial, вместо этого он будет работать без кода точности.

вершинных шейдеров

varying vec3 vNormal; 

void main() { 
    vNormal = normal; 
    gl_Position = projectionMatrix * 
       modelViewMatrix * 
       vec4(position,1.0); 
} 

Фрагмент шейдер

varying vec3 vNormal; 

void main() { 
    vec3 light = vec3(0.5, 0.2, 1.0); 

    // ensure it's normalized 
    light = normalize(light); 

    // calculate the dot product of 
    // the light to the vertex normal 
    float dProd = max(0.0, dot(vNormal, light)); 

    // feed into our frag colour 
    gl_FragColor = vec4(dProd, // R 
         dProd, // G 
         dProd, // B 
         1.0); // A 
} 

Обновление к материалу

// create the sphere's material 
var shaderMaterial = new THREE.ShaderMaterial({ 
    vertexShader: document.getElementById('vertex-shader').innerHTML, 
    fragmentShader: document.getElementById('fragment-shader').innerHTML 
}); 

Here - это скрипка вашего кода без деклараций точности.

+0

О, человек, я чувствую себя довольно глупым, потратив несколько часов на попытку выяснить, что случилось. Я понятия не имею, почему я использовал 'RawShaderMaterial()', который не был моим намерением. Большое спасибо за Вашу помощь! – Flavio

+0

@Flavio не проблема Я рад, что могу помочь :) – Anton

9

В шейдерах фрагментов WebGL отсутствует точность по умолчанию. (Высокая точность по умолчанию для вершинных шейдеров.) Самым простым решением является добавление

precision highp float; 

для всех ваших фрагментов шейдеров, что позволит устранить необходимость определения точности для всех плавающих векторных переменных точек, но в целом,

precision mediump float; 

будет предпочтительнее, для обеспечения эффективности. Я не советую lowp; хорошее мобильное оборудование сегодня даже не поддерживает его, и делает эквивалент typedeffing lowp для mediump.

+0

Прохладно большое спасибо за ответ, который объясняет многое. То, чего я до сих пор не понимаю, - это то, почему я никогда не вижу ни одной из этих деклараций точности в других шейдерных программах. Их даже нет в [учебнике] (http://aerotwist.com/tutorials/an-introduction-to-shaders-part-2/) Я пытался работать. – Flavio

+1

Вы не должны использовать 'highp', если не знаете, что вам это нужно. Большинство телефонов не могут поддерживать 'highp', поэтому ваш шейдер не будет работать на телефоне. Немногим шейдерам нужна 'highp', поэтому используйте' mediump'.Что касается того, почему вы не видите его в шейдерах, это потому, что three.js добавляет его в шейдеры, которые вы пишете. Установите [WebGL Inspector] (http://benvanik.github.io/WebGL-Inspector/), запустите приложение three.js, нажмите «захват» и «ui», затем нажмите «программы» и посмотрите на фактические шейдеры, которые были предоставлены WebGL тремя. js. Вы увидите, что они указывают точность. – gman

+0

@gman Что такое POS, чтобы полностью отключить шейдер вместо запуска highp как mediump? – Jessy

Смежные вопросы