schema.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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, BufferItemSize, 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 } from './util';
  12. import { TextureValues, TextureType, TextureFormat, TextureFilter, TextureKind } from '../webgl/texture';
  13. export type ValueKindType = {
  14. 'number': number
  15. 'string': string
  16. 'any': any
  17. }
  18. export type ValueKind = keyof ValueKindType
  19. //
  20. export type KindValue = {
  21. 'f': number
  22. 'i': number
  23. 'v2': Vec2
  24. 'v3': Vec3
  25. 'v4': Vec4
  26. 'm3': Mat3
  27. 'm4': Mat4
  28. 't2': number
  29. 'uint8': Uint8Array
  30. 'int8': Int8Array
  31. 'uint16': Uint16Array
  32. 'int16': Int16Array
  33. 'uint32': Uint32Array
  34. 'int32': Int32Array
  35. 'float32': Float32Array
  36. 'image-uint8': TextureImage<Uint8Array>
  37. 'image-float32': TextureImage<Float32Array>
  38. 'number': number
  39. 'string': string
  40. 'boolean': boolean
  41. 'any': any
  42. }
  43. export type Values<S extends RenderableSchema> = { [k in keyof S]: ValueCell<KindValue[S[k]['kind']]> }
  44. export function splitValues(schema: RenderableSchema, values: RenderableValues) {
  45. const attributeValues: AttributeValues = {}
  46. const defineValues: DefineValues = {}
  47. const textureValues: TextureValues = {}
  48. const uniformValues: UniformValues = {}
  49. Object.keys(values).forEach(k => {
  50. if (schema[k].type === 'attribute') attributeValues[k] = values[k]
  51. if (schema[k].type === 'define') defineValues[k] = values[k]
  52. if (schema[k].type === 'texture') textureValues[k] = values[k]
  53. if (schema[k].type === 'uniform') uniformValues[k] = values[k]
  54. })
  55. return { attributeValues, defineValues, textureValues, uniformValues }
  56. }
  57. export type Versions<T extends RenderableValues> = { [k in keyof T]: number }
  58. export function getValueVersions<T extends RenderableValues>(values: T) {
  59. const versions: Versions<any> = {}
  60. Object.keys(values).forEach(k => {
  61. versions[k] = values[k].ref.version
  62. })
  63. return versions as Versions<T>
  64. }
  65. //
  66. export type AttributeSpec<K extends ArrayKind> = { type: 'attribute', kind: K, itemSize: BufferItemSize, divisor: number }
  67. export function AttributeSpec<K extends ArrayKind>(kind: K, itemSize: BufferItemSize, divisor: number): AttributeSpec<K> {
  68. return { type: 'attribute', kind, itemSize, divisor }
  69. }
  70. export type UniformSpec<K extends UniformKind> = { type: 'uniform', kind: K }
  71. export function UniformSpec<K extends UniformKind>(kind: K): UniformSpec<K> {
  72. return { type: 'uniform', kind }
  73. }
  74. export type TextureSpec<K extends TextureKind> = { type: 'texture', kind: K, format: TextureFormat, dataType: TextureType, filter: TextureFilter }
  75. export function TextureSpec<K extends TextureKind>(kind: K, format: TextureFormat, dataType: TextureType, filter: TextureFilter): TextureSpec<K> {
  76. return { type: 'texture', kind, format, dataType, filter }
  77. }
  78. export type ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K }
  79. export function ElementsSpec<K extends ElementsKind>(kind: K): ElementsSpec<K> {
  80. return { type: 'elements', kind }
  81. }
  82. export type DefineSpec<K extends DefineKind> = { type: 'define', kind: K, options?: string[] }
  83. export function DefineSpec<K extends DefineKind>(kind: K, options?: string[]): DefineSpec<K> {
  84. return { type: 'define', kind, options }
  85. }
  86. export type ValueSpec<K extends ValueKind> = { type: 'value', kind: K }
  87. export function ValueSpec<K extends ValueKind>(kind: K): ValueSpec<K> {
  88. return { type: 'value', kind }
  89. }
  90. //
  91. export type RenderableSchema = {
  92. [k: string]: (
  93. AttributeSpec<ArrayKind> | UniformSpec<UniformKind> | TextureSpec<TextureKind> |
  94. ValueSpec<ValueKind> | DefineSpec<DefineKind> | ElementsSpec<ElementsKind>
  95. )
  96. }
  97. export type RenderableValues = { [k: string]: ValueCell<any> }
  98. //
  99. export const GlobalUniformSchema = {
  100. uModel: UniformSpec('m4'),
  101. uView: UniformSpec('m4'),
  102. uInvView: UniformSpec('m4'),
  103. uModelView: UniformSpec('m4'),
  104. uInvModelView: UniformSpec('m4'),
  105. uProjection: UniformSpec('m4'),
  106. // uLightPosition: Uniform('v3'),
  107. uLightColor: UniformSpec('v3'),
  108. uLightAmbient: UniformSpec('v3'),
  109. uPixelRatio: UniformSpec('f'),
  110. uViewportHeight: UniformSpec('f'),
  111. uHighlightColor: UniformSpec('v3'),
  112. uSelectColor: UniformSpec('v3'),
  113. uFogNear: UniformSpec('f'),
  114. uFogFar: UniformSpec('f'),
  115. uFogColor: UniformSpec('v3'),
  116. }
  117. export type GlobalUniformSchema = typeof GlobalUniformSchema
  118. export type GlobalUniformValues = { [k in keyof GlobalUniformSchema]: ValueCell<any> }
  119. export const InternalSchema = {
  120. dWebGL2: DefineSpec('boolean'),
  121. uObjectId: UniformSpec('i'),
  122. }
  123. export type InternalSchema = typeof InternalSchema
  124. export type InternalValues = { [k in keyof InternalSchema]: ValueCell<any> }
  125. export const ColorSchema = {
  126. aColor: AttributeSpec('float32', 3, 0),
  127. uColor: UniformSpec('v3'),
  128. uColorTexDim: UniformSpec('v2'),
  129. tColor: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
  130. dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'group_instance']),
  131. }
  132. export type ColorSchema = typeof ColorSchema
  133. export type ColorValues = Values<ColorSchema>
  134. export const SizeSchema = {
  135. aSize: AttributeSpec('float32', 1, 0),
  136. uSize: UniformSpec('f'),
  137. uSizeTexDim: UniformSpec('v2'),
  138. tSize: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  139. dSizeType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'group_instance']),
  140. }
  141. export type SizeSchema = typeof SizeSchema
  142. export type SizeValues = Values<SizeSchema>
  143. export const BaseSchema = {
  144. ...ColorSchema,
  145. aInstance: AttributeSpec('float32', 1, 1),
  146. aGroup: AttributeSpec('float32', 1, 0),
  147. aTransform: AttributeSpec('float32', 16, 1),
  148. uAlpha: UniformSpec('f'),
  149. uInstanceCount: UniformSpec('i'),
  150. uGroupCount: UniformSpec('i'),
  151. uMarkerTexDim: UniformSpec('v2'),
  152. tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  153. drawCount: ValueSpec('number'),
  154. instanceCount: ValueSpec('number'),
  155. dUseFog: DefineSpec('boolean'),
  156. }
  157. export type BaseSchema = typeof BaseSchema
  158. export type BaseValues = Values<BaseSchema>