@@ -11,7 +11,7 @@ import WebGLCapabilities from './utils/WebGLCapabilities.js';
1111import { GLFeatureName } from './utils/WebGLConstants.js' ;
1212import { WebGLBufferRenderer } from './WebGLBufferRenderer.js' ;
1313
14- import { warnOnce , warn , error } from '../../utils.js' ;
14+ import { isTypedArray , warnOnce , warn , error } from '../../utils.js' ;
1515import { WebGLCoordinateSystem , TimestampQuery } from '../../constants.js' ;
1616import WebGLTimestampQueryPool from './utils/WebGLTimestampQueryPool.js' ;
1717
@@ -1743,25 +1743,53 @@ class WebGLBackend extends Backend {
17431743
17441744 if ( binding . isUniformsGroup || binding . isUniformBuffer ) {
17451745
1746- const data = binding . buffer ;
1747- let { bufferGPU } = this . get ( data ) ;
1746+ const array = binding . buffer ;
1747+ let { bufferGPU } = this . get ( array ) ;
17481748
17491749 if ( bufferGPU === undefined ) {
17501750
17511751 // create
17521752
17531753 bufferGPU = gl . createBuffer ( ) ;
1754+
17541755 gl . bindBuffer ( gl . UNIFORM_BUFFER , bufferGPU ) ;
1755- gl . bufferData ( gl . UNIFORM_BUFFER , data , gl . DYNAMIC_DRAW ) ;
1756+ gl . bufferData ( gl . UNIFORM_BUFFER , array . byteLength , gl . DYNAMIC_DRAW ) ;
17561757
1757- this . set ( data , { bufferGPU } ) ;
1758+ this . set ( array , { bufferGPU } ) ;
17581759
17591760 } else {
17601761
1761- // update
1762-
17631762 gl . bindBuffer ( gl . UNIFORM_BUFFER , bufferGPU ) ;
1764- gl . bufferSubData ( gl . UNIFORM_BUFFER , 0 , data ) ;
1763+
1764+ }
1765+
1766+ // update
1767+
1768+ const updateRanges = binding . updateRanges ;
1769+
1770+ gl . bindBuffer ( gl . UNIFORM_BUFFER , bufferGPU ) ;
1771+
1772+ if ( updateRanges . length === 0 ) {
1773+
1774+ gl . bufferData ( gl . UNIFORM_BUFFER , array , gl . DYNAMIC_DRAW ) ;
1775+
1776+ } else {
1777+
1778+ const isTyped = isTypedArray ( array ) ;
1779+ const byteOffsetFactor = isTyped ? 1 : array . BYTES_PER_ELEMENT ;
1780+
1781+ for ( let i = 0 , l = updateRanges . length ; i < l ; i ++ ) {
1782+
1783+ const range = updateRanges [ i ] ;
1784+
1785+ const dataOffset = range . start * byteOffsetFactor ;
1786+ const size = range . count * byteOffsetFactor ;
1787+
1788+ const bufferOffset = dataOffset * ( isTyped ? array . BYTES_PER_ELEMENT : 1 ) ; // bufferOffset is always in bytes
1789+
1790+ gl . bufferSubData ( gl . UNIFORM_BUFFER , bufferOffset , array , dataOffset , size ) ;
1791+
1792+ }
17651793
17661794 }
17671795
@@ -1799,10 +1827,35 @@ class WebGLBackend extends Backend {
17991827
18001828 const bindingData = this . get ( binding ) ;
18011829 const bufferGPU = bindingData . bufferGPU ;
1802- const data = binding . buffer ;
1830+ const array = binding . buffer ;
1831+
1832+ const updateRanges = binding . updateRanges ;
18031833
18041834 gl . bindBuffer ( gl . UNIFORM_BUFFER , bufferGPU ) ;
1805- gl . bufferData ( gl . UNIFORM_BUFFER , data , gl . DYNAMIC_DRAW ) ;
1835+
1836+ if ( updateRanges . length === 0 ) {
1837+
1838+ gl . bufferData ( gl . UNIFORM_BUFFER , array , gl . DYNAMIC_DRAW ) ;
1839+
1840+ } else {
1841+
1842+ const isTyped = isTypedArray ( array ) ;
1843+ const byteOffsetFactor = isTyped ? 1 : array . BYTES_PER_ELEMENT ;
1844+
1845+ for ( let i = 0 , l = updateRanges . length ; i < l ; i ++ ) {
1846+
1847+ const range = updateRanges [ i ] ;
1848+
1849+ const dataOffset = range . start * byteOffsetFactor ;
1850+ const size = range . count * byteOffsetFactor ;
1851+
1852+ const bufferOffset = dataOffset * ( isTyped ? array . BYTES_PER_ELEMENT : 1 ) ; // bufferOffset is always in bytes
1853+
1854+ gl . bufferSubData ( gl . UNIFORM_BUFFER , bufferOffset , array , dataOffset , size ) ;
1855+
1856+ }
1857+
1858+ }
18061859
18071860 }
18081861
0 commit comments