schema.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { ValueCell } from 'mol-util';
  7. import { ArrayKind, AttributeItemSize, ElementsKind, AttributeValues } from '../webgl/buffer';
  8. import { UniformKind, UniformValues } from '../webgl/uniform';
  9. import { DefineKind, DefineValues } from '../shader-code';
  10. import { Vec2, Vec3, Vec4, Mat3, Mat4 } from 'mol-math/linear-algebra';
  11. import { TextureImage, TextureVolume } from './util';
  12. import { TextureValues, TextureType, TextureFormat, TextureFilter, TextureKind, Texture } from '../webgl/texture';
  13. import { Sphere3D } from 'mol-math/geometry';
  14. export type ValueKindType = {
  15. 'number': number
  16. 'string': string
  17. 'boolean': string
  18. 'any': any
  19. 'm4': Mat4,
  20. 'float32': Float32Array
  21. 'sphere': Sphere3D
  22. }
  23. export type ValueKind = keyof ValueKindType
  24. //
  25. export type KindValue = {
  26. 'f': number
  27. 'i': number
  28. 'v2': Vec2
  29. 'v3': Vec3
  30. 'v4': Vec4
  31. 'm3': Mat3
  32. 'm4': Mat4
  33. 't': number
  34. 'uint8': Uint8Array
  35. 'int8': Int8Array
  36. 'uint16': Uint16Array
  37. 'int16': Int16Array
  38. 'uint32': Uint32Array
  39. 'int32': Int32Array
  40. 'float32': Float32Array
  41. 'image-uint8': TextureImage<Uint8Array>
  42. 'image-float32': TextureImage<Float32Array>
  43. 'volume-uint8': TextureVolume<Uint8Array>
  44. 'volume-float32': TextureVolume<Float32Array>
  45. 'texture': Texture
  46. 'texture2d': Texture
  47. 'texture3d': Texture
  48. 'number': number
  49. 'string': string
  50. 'boolean': boolean
  51. 'any': any
  52. 'sphere': Sphere3D
  53. }
  54. export type Values<S extends RenderableSchema> = { [k in keyof S]: ValueCell<KindValue[S[k]['kind']]> }
  55. export function splitValues(schema: RenderableSchema, values: RenderableValues) {
  56. const attributeValues: AttributeValues = {}
  57. const defineValues: DefineValues = {}
  58. const textureValues: TextureValues = {}
  59. const uniformValues: UniformValues = {}
  60. Object.keys(schema).forEach(k => {
  61. if (schema[k].type === 'attribute') attributeValues[k] = values[k]
  62. if (schema[k].type === 'define') defineValues[k] = values[k]
  63. if (schema[k].type === 'texture') textureValues[k] = values[k]
  64. if (schema[k].type === 'uniform') uniformValues[k] = values[k]
  65. })
  66. return { attributeValues, defineValues, textureValues, uniformValues }
  67. }
  68. export function splitKeys(schema: RenderableSchema) {
  69. const attributeKeys: string[] = []
  70. const defineKeys: string[] = []
  71. const textureKeys: string[] = []
  72. const uniformKeys: string[] = []
  73. Object.keys(schema).forEach(k => {
  74. if (schema[k].type === 'attribute') attributeKeys.push(k)
  75. if (schema[k].type === 'define') defineKeys.push(k)
  76. if (schema[k].type === 'texture') textureKeys.push(k)
  77. if (schema[k].type === 'uniform') uniformKeys.push(k)
  78. })
  79. return { attributeKeys, defineKeys, textureKeys, uniformKeys }
  80. }
  81. export type Versions<T extends RenderableValues> = { [k in keyof T]: number }
  82. export function getValueVersions<T extends RenderableValues>(values: T) {
  83. const versions: Versions<any> = {}
  84. Object.keys(values).forEach(k => {
  85. versions[k] = values[k].ref.version
  86. })
  87. return versions as Versions<T>
  88. }
  89. //
  90. export type AttributeSpec<K extends ArrayKind> = { type: 'attribute', kind: K, itemSize: AttributeItemSize, divisor: number }
  91. export function AttributeSpec<K extends ArrayKind>(kind: K, itemSize: AttributeItemSize, divisor: number): AttributeSpec<K> {
  92. return { type: 'attribute', kind, itemSize, divisor }
  93. }
  94. export type UniformSpec<K extends UniformKind> = { type: 'uniform', kind: K }
  95. export function UniformSpec<K extends UniformKind>(kind: K): UniformSpec<K> {
  96. return { type: 'uniform', kind }
  97. }
  98. export type TextureSpec<K extends TextureKind> = { type: 'texture', kind: K, format: TextureFormat, dataType: TextureType, filter: TextureFilter }
  99. export function TextureSpec<K extends TextureKind>(kind: K, format: TextureFormat, dataType: TextureType, filter: TextureFilter): TextureSpec<K> {
  100. return { type: 'texture', kind, format, dataType, filter }
  101. }
  102. export type ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K }
  103. export function ElementsSpec<K extends ElementsKind>(kind: K): ElementsSpec<K> {
  104. return { type: 'elements', kind }
  105. }
  106. export type DefineSpec<K extends DefineKind> = { type: 'define', kind: K, options?: string[] }
  107. export function DefineSpec<K extends DefineKind>(kind: K, options?: string[]): DefineSpec<K> {
  108. return { type: 'define', kind, options }
  109. }
  110. export type ValueSpec<K extends ValueKind> = { type: 'value', kind: K }
  111. export function ValueSpec<K extends ValueKind>(kind: K): ValueSpec<K> {
  112. return { type: 'value', kind }
  113. }
  114. //
  115. export type RenderableSchema = {
  116. [k: string]: (
  117. AttributeSpec<ArrayKind> | UniformSpec<UniformKind> | TextureSpec<TextureKind> |
  118. ValueSpec<ValueKind> | DefineSpec<DefineKind> | ElementsSpec<ElementsKind>
  119. )
  120. }
  121. export type RenderableValues = { [k: string]: ValueCell<any> }
  122. //
  123. export const GlobalUniformSchema = {
  124. uModel: UniformSpec('m4'),
  125. uView: UniformSpec('m4'),
  126. uInvView: UniformSpec('m4'),
  127. uModelView: UniformSpec('m4'),
  128. uInvModelView: UniformSpec('m4'),
  129. uProjection: UniformSpec('m4'),
  130. uInvProjection: UniformSpec('m4'),
  131. uModelViewProjection: UniformSpec('m4'),
  132. uInvModelViewProjection: UniformSpec('m4'),
  133. // uLightPosition: Uniform('v3'),
  134. uLightColor: UniformSpec('v3'),
  135. uLightAmbient: UniformSpec('v3'),
  136. uPixelRatio: UniformSpec('f'),
  137. uViewportHeight: UniformSpec('f'),
  138. uViewport: UniformSpec('v4'),
  139. uCameraPosition: UniformSpec('v3'),
  140. uFogNear: UniformSpec('f'),
  141. uFogFar: UniformSpec('f'),
  142. uFogColor: UniformSpec('v3'),
  143. uPickingAlphaThreshold: UniformSpec('f'),
  144. }
  145. export type GlobalUniformSchema = typeof GlobalUniformSchema
  146. export type GlobalUniformValues = { [k in keyof GlobalUniformSchema]: ValueCell<any> }
  147. export const InternalSchema = {
  148. uObjectId: UniformSpec('i'),
  149. uPickable: UniformSpec('i'),
  150. }
  151. export type InternalSchema = typeof InternalSchema
  152. export type InternalValues = { [k in keyof InternalSchema]: ValueCell<any> }
  153. export const ColorSchema = {
  154. // aColor: AttributeSpec('float32', 3, 0), // TODO
  155. uColor: UniformSpec('v3'),
  156. uColorTexDim: UniformSpec('v2'),
  157. tColor: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
  158. dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'group_instance']),
  159. }
  160. export type ColorSchema = typeof ColorSchema
  161. export type ColorValues = Values<ColorSchema>
  162. export const SizeSchema = {
  163. // aSize: AttributeSpec('float32', 1, 0), // TODO
  164. uSize: UniformSpec('f'),
  165. uSizeTexDim: UniformSpec('v2'),
  166. tSize: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  167. dSizeType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'group_instance']),
  168. uSizeFactor: UniformSpec('f'),
  169. }
  170. export type SizeSchema = typeof SizeSchema
  171. export type SizeValues = Values<SizeSchema>
  172. export const MarkerSchema = {
  173. uMarkerTexDim: UniformSpec('v2'),
  174. tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  175. }
  176. export type MarkerSchema = typeof MarkerSchema
  177. export type MarkerValues = Values<MarkerSchema>
  178. export const OverpaintSchema = {
  179. uOverpaintTexDim: UniformSpec('v2'),
  180. tOverpaint: TextureSpec('image-uint8', 'rgba', 'ubyte', 'nearest'),
  181. dOverpaint: DefineSpec('boolean'),
  182. }
  183. export type OverpaintSchema = typeof OverpaintSchema
  184. export type OverpaintValues = Values<OverpaintSchema>
  185. export const BaseSchema = {
  186. ...ColorSchema,
  187. ...MarkerSchema,
  188. ...OverpaintSchema,
  189. aInstance: AttributeSpec('float32', 1, 1),
  190. aGroup: AttributeSpec('float32', 1, 0),
  191. /**
  192. * final per-instance transform calculated for instance `i` as
  193. * `aTransform[i] = matrix * transform[i] * extraTransform[i]`
  194. */
  195. aTransform: AttributeSpec('float32', 16, 1),
  196. /**
  197. * final alpha, calculated as `values.alpha * state.alpha`
  198. */
  199. uAlpha: UniformSpec('f'),
  200. uInstanceCount: UniformSpec('i'),
  201. uGroupCount: UniformSpec('i'),
  202. uHighlightColor: UniformSpec('v3'),
  203. uSelectColor: UniformSpec('v3'),
  204. drawCount: ValueSpec('number'),
  205. instanceCount: ValueSpec('number'),
  206. /** base alpha, see uAlpha */
  207. alpha: ValueSpec('number'),
  208. /** global transform, see aTransform */
  209. matrix: ValueSpec('m4'),
  210. /** base per-instance transform, see aTransform */
  211. transform: ValueSpec('float32'),
  212. /** additional per-instance transform, see aTransform */
  213. extraTransform: ValueSpec('float32'),
  214. /** bounding sphere taking aTransform into account */
  215. boundingSphere: ValueSpec('sphere'),
  216. /** bounding sphere NOT taking aTransform into account */
  217. invariantBoundingSphere: ValueSpec('sphere'),
  218. dUseFog: DefineSpec('boolean'),
  219. }
  220. export type BaseSchema = typeof BaseSchema
  221. export type BaseValues = Values<BaseSchema>