schema.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /**
  2. * Copyright (c) 2018-2021 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 { AttributeItemSize, ElementsKind, AttributeValues, AttributeKind, DataTypeArrayType } from '../webgl/buffer';
  8. import { UniformKind, UniformValues, UniformKindValue } from '../webgl/uniform';
  9. import { DefineKind, DefineValues } from '../shader-code';
  10. import { Mat4 } from '../../mol-math/linear-algebra';
  11. import { TextureValues, TextureType, TextureFormat, TextureFilter, TextureKind, TextureKindValue } from '../webgl/texture';
  12. import { Sphere3D } from '../../mol-math/geometry';
  13. export type ValueKindType = {
  14. 'number': number
  15. 'string': string
  16. 'boolean': boolean
  17. 'any': any
  18. 'unknown': unknown
  19. 'm4': Mat4,
  20. 'float32': Float32Array
  21. 'sphere': Sphere3D
  22. }
  23. export type ValueKind = keyof ValueKindType
  24. //
  25. export type KindValue = UniformKindValue & DataTypeArrayType & TextureKindValue & ValueKindType
  26. export type Values<S extends RenderableSchema> = { readonly [k in keyof S]: ValueCell<KindValue[S[k]['kind']]> }
  27. export type UnboxedValues<S extends RenderableSchema> = { readonly [k in keyof S]: KindValue[S[k]['kind']] }
  28. export function splitValues(schema: RenderableSchema, values: RenderableValues) {
  29. const attributeValues: AttributeValues = {};
  30. const defineValues: DefineValues = {};
  31. const textureValues: TextureValues = {};
  32. const uniformValues: UniformValues = {};
  33. const materialUniformValues: UniformValues = {};
  34. const bufferedUniformValues: UniformValues = {};
  35. Object.keys(schema).forEach(k => {
  36. const spec = schema[k];
  37. if (spec.type === 'attribute') attributeValues[k] = values[k];
  38. if (spec.type === 'define') defineValues[k] = values[k];
  39. // check if k exists in values to exclude global textures
  40. if (spec.type === 'texture' && values[k] !== undefined) textureValues[k] = values[k];
  41. // check if k exists in values to exclude global uniforms
  42. if (spec.type === 'uniform' && values[k] !== undefined) {
  43. if (spec.variant === 'material') materialUniformValues[k] = values[k];
  44. else if (spec.variant === 'buffered') bufferedUniformValues[k] = values[k];
  45. else uniformValues[k] = values[k];
  46. }
  47. });
  48. return { attributeValues, defineValues, textureValues, uniformValues, materialUniformValues, bufferedUniformValues };
  49. }
  50. export type Versions<T extends RenderableValues> = { [k in keyof T]: number }
  51. export function getValueVersions<T extends RenderableValues>(values: T) {
  52. const versions: Versions<any> = {};
  53. Object.keys(values).forEach(k => {
  54. versions[k] = values[k].ref.version;
  55. });
  56. return versions as Versions<T>;
  57. }
  58. //
  59. export type AttributeSpec<K extends AttributeKind> = { type: 'attribute', kind: K, itemSize: AttributeItemSize, divisor: number }
  60. export function AttributeSpec<K extends AttributeKind>(kind: K, itemSize: AttributeItemSize, divisor: number): AttributeSpec<K> {
  61. return { type: 'attribute', kind, itemSize, divisor };
  62. }
  63. export type UniformSpec<K extends UniformKind> = { type: 'uniform', kind: K, variant?: 'material' | 'buffered' }
  64. export function UniformSpec<K extends UniformKind>(kind: K, variant?: 'material' | 'buffered'): UniformSpec<K> {
  65. return { type: 'uniform', kind, variant };
  66. }
  67. export type TextureSpec<K extends TextureKind> = { type: 'texture', kind: K, format: TextureFormat, dataType: TextureType, filter: TextureFilter }
  68. export function TextureSpec<K extends TextureKind>(kind: K, format: TextureFormat, dataType: TextureType, filter: TextureFilter): TextureSpec<K> {
  69. return { type: 'texture', kind, format, dataType, filter };
  70. }
  71. export type ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K }
  72. export function ElementsSpec<K extends ElementsKind>(kind: K): ElementsSpec<K> {
  73. return { type: 'elements', kind };
  74. }
  75. export type DefineSpec<K extends DefineKind> = { type: 'define', kind: K, options?: string[] }
  76. export function DefineSpec<K extends DefineKind>(kind: K, options?: string[]): DefineSpec<K> {
  77. return { type: 'define', kind, options };
  78. }
  79. export type ValueSpec<K extends ValueKind> = { type: 'value', kind: K }
  80. export function ValueSpec<K extends ValueKind>(kind: K): ValueSpec<K> {
  81. return { type: 'value', kind };
  82. }
  83. //
  84. export type RenderableSchema = {
  85. readonly [k: string]: (
  86. AttributeSpec<AttributeKind> | UniformSpec<UniformKind> | TextureSpec<TextureKind> |
  87. ValueSpec<ValueKind> | DefineSpec<DefineKind> | ElementsSpec<ElementsKind>
  88. )
  89. }
  90. export type RenderableValues = { readonly [k: string]: ValueCell<any> }
  91. //
  92. export const GlobalUniformSchema = {
  93. uModel: UniformSpec('m4'),
  94. uView: UniformSpec('m4'),
  95. uInvView: UniformSpec('m4'),
  96. uModelView: UniformSpec('m4'),
  97. uInvModelView: UniformSpec('m4'),
  98. uProjection: UniformSpec('m4'),
  99. uInvProjection: UniformSpec('m4'),
  100. uModelViewProjection: UniformSpec('m4'),
  101. uInvModelViewProjection: UniformSpec('m4'),
  102. uIsOrtho: UniformSpec('f'),
  103. uPixelRatio: UniformSpec('f'),
  104. uViewport: UniformSpec('v4'),
  105. uViewOffset: UniformSpec('v2'),
  106. uDrawingBufferSize: UniformSpec('v2'),
  107. uCameraPosition: UniformSpec('v3'),
  108. uCameraDir: UniformSpec('v3'),
  109. uNear: UniformSpec('f'),
  110. uFar: UniformSpec('f'),
  111. uFogNear: UniformSpec('f'),
  112. uFogFar: UniformSpec('f'),
  113. uFogColor: UniformSpec('v3'),
  114. uTransparentBackground: UniformSpec('b'),
  115. uLightDirection: UniformSpec('v3[]'),
  116. uLightColor: UniformSpec('v3[]'),
  117. uAmbientColor: UniformSpec('v3'),
  118. uPickingAlphaThreshold: UniformSpec('f'),
  119. uInteriorDarkening: UniformSpec('f'),
  120. uInteriorColorFlag: UniformSpec('b'),
  121. uInteriorColor: UniformSpec('v3'),
  122. uHighlightColor: UniformSpec('v3'),
  123. uSelectColor: UniformSpec('v3'),
  124. uHighlightStrength: UniformSpec('f'),
  125. uSelectStrength: UniformSpec('f'),
  126. uMarkerPriority: UniformSpec('i'),
  127. uXrayEdgeFalloff: UniformSpec('f'),
  128. uRenderWboit: UniformSpec('b'),
  129. uMarkingDepthTest: UniformSpec('b'),
  130. uMarkingType: UniformSpec('i'),
  131. uPickType: UniformSpec('i'),
  132. } as const;
  133. export type GlobalUniformSchema = typeof GlobalUniformSchema
  134. export type GlobalUniformValues = Values<GlobalUniformSchema>
  135. export const GlobalTextureSchema = {
  136. tDepth: TextureSpec('texture', 'depth', 'ushort', 'nearest'),
  137. } as const;
  138. export type GlobalTextureSchema = typeof GlobalTextureSchema
  139. export type GlobalTextureValues = Values<GlobalTextureSchema>
  140. export const InternalSchema = {
  141. uObjectId: UniformSpec('i'),
  142. } as const;
  143. export type InternalSchema = typeof InternalSchema
  144. export type InternalValues = Values<InternalSchema>
  145. export const ColorSchema = {
  146. // aColor: AttributeSpec('float32', 3, 0), // TODO
  147. uColor: UniformSpec('v3', 'material'),
  148. uColorTexDim: UniformSpec('v2'),
  149. uColorGridDim: UniformSpec('v3'),
  150. uColorGridTransform: UniformSpec('v4'),
  151. tColor: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
  152. tPalette: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
  153. tColorGrid: TextureSpec('texture', 'rgb', 'ubyte', 'linear'),
  154. dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'groupInstance', 'vertex', 'vertexInstance', 'volume', 'volumeInstance', 'direct']),
  155. dUsePalette: DefineSpec('boolean'),
  156. } as const;
  157. export type ColorSchema = typeof ColorSchema
  158. export type ColorValues = Values<ColorSchema>
  159. export const SizeSchema = {
  160. // aSize: AttributeSpec('float32', 1, 0), // TODO
  161. uSize: UniformSpec('f', 'material'),
  162. uSizeTexDim: UniformSpec('v2'),
  163. tSize: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
  164. dSizeType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'groupInstance']),
  165. uSizeFactor: UniformSpec('f'),
  166. } as const;
  167. export type SizeSchema = typeof SizeSchema
  168. export type SizeValues = Values<SizeSchema>
  169. export const MarkerSchema = {
  170. uMarker: UniformSpec('f'),
  171. uMarkerTexDim: UniformSpec('v2'),
  172. tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  173. markerAverage: ValueSpec('number'),
  174. markerStatus: ValueSpec('number'),
  175. } as const;
  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. uOverpaintGridDim: UniformSpec('v3'),
  183. uOverpaintGridTransform: UniformSpec('v4'),
  184. tOverpaintGrid: TextureSpec('texture', 'rgba', 'ubyte', 'linear'),
  185. dOverpaintType: DefineSpec('string', ['groupInstance', 'volumeInstance']),
  186. } as const;
  187. export type OverpaintSchema = typeof OverpaintSchema
  188. export type OverpaintValues = Values<OverpaintSchema>
  189. export const TransparencySchema = {
  190. uTransparencyTexDim: UniformSpec('v2'),
  191. tTransparency: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  192. dTransparency: DefineSpec('boolean'),
  193. transparencyAverage: ValueSpec('number'),
  194. uTransparencyGridDim: UniformSpec('v3'),
  195. uTransparencyGridTransform: UniformSpec('v4'),
  196. tTransparencyGrid: TextureSpec('texture', 'alpha', 'ubyte', 'linear'),
  197. dTransparencyType: DefineSpec('string', ['groupInstance', 'volumeInstance']),
  198. } as const;
  199. export type TransparencySchema = typeof TransparencySchema
  200. export type TransparencyValues = Values<TransparencySchema>
  201. export const SubstanceSchema = {
  202. uSubstanceTexDim: UniformSpec('v2'),
  203. tSubstance: TextureSpec('image-uint8', 'rgba', 'ubyte', 'nearest'),
  204. dSubstance: DefineSpec('boolean'),
  205. uSubstanceGridDim: UniformSpec('v3'),
  206. uSubstanceGridTransform: UniformSpec('v4'),
  207. tSubstanceGrid: TextureSpec('texture', 'rgba', 'ubyte', 'linear'),
  208. dSubstanceType: DefineSpec('string', ['groupInstance', 'volumeInstance']),
  209. } as const;
  210. export type SubstanceSchema = typeof SubstanceSchema
  211. export type SubstanceValues = Values<SubstanceSchema>
  212. export const ClippingSchema = {
  213. uClippingTexDim: UniformSpec('v2'),
  214. tClipping: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
  215. dClipping: DefineSpec('boolean'),
  216. } as const;
  217. export type ClippingSchema = typeof ClippingSchema
  218. export type ClippingValues = Values<ClippingSchema>
  219. export const BaseSchema = {
  220. dGeometryType: DefineSpec('string', ['cylinders', 'directVolume', 'image', 'lines', 'mesh', 'points', 'spheres', 'text', 'textureMesh']),
  221. ...ColorSchema,
  222. ...MarkerSchema,
  223. ...OverpaintSchema,
  224. ...TransparencySchema,
  225. ...SubstanceSchema,
  226. ...ClippingSchema,
  227. dLightCount: DefineSpec('number'),
  228. dClipObjectCount: DefineSpec('number'),
  229. dClipVariant: DefineSpec('string', ['instance', 'pixel']),
  230. uClipObjectType: UniformSpec('i[]'),
  231. uClipObjectInvert: UniformSpec('b[]'),
  232. uClipObjectPosition: UniformSpec('v3[]'),
  233. uClipObjectRotation: UniformSpec('v4[]'),
  234. uClipObjectScale: UniformSpec('v3[]'),
  235. aInstance: AttributeSpec('float32', 1, 1),
  236. /**
  237. * final per-instance transform calculated for instance `i` as
  238. * `aTransform[i] = matrix * transform[i] * extraTransform[i]`
  239. */
  240. aTransform: AttributeSpec('float32', 16, 1),
  241. /**
  242. * final alpha, calculated as `values.alpha * state.alpha`
  243. */
  244. uAlpha: UniformSpec('f', 'material'),
  245. uMetalness: UniformSpec('f', 'material'),
  246. uRoughness: UniformSpec('f', 'material'),
  247. uBumpiness: UniformSpec('f', 'material'),
  248. uVertexCount: UniformSpec('i'),
  249. uInstanceCount: UniformSpec('i'),
  250. uGroupCount: UniformSpec('i'),
  251. uInvariantBoundingSphere: UniformSpec('v4'),
  252. drawCount: ValueSpec('number'),
  253. instanceCount: ValueSpec('number'),
  254. /** base alpha, see uAlpha */
  255. alpha: ValueSpec('number'),
  256. /** global transform, see aTransform */
  257. matrix: ValueSpec('m4'),
  258. /** base per-instance transform, see aTransform */
  259. transform: ValueSpec('float32'),
  260. /** additional per-instance transform, see aTransform */
  261. extraTransform: ValueSpec('float32'),
  262. /** denotes reflection in transform */
  263. hasReflection: ValueSpec('boolean'),
  264. /** bounding sphere taking aTransform into account and encompases all instances */
  265. boundingSphere: ValueSpec('sphere'),
  266. /** bounding sphere NOT taking aTransform into account */
  267. invariantBoundingSphere: ValueSpec('sphere'),
  268. } as const;
  269. export type BaseSchema = typeof BaseSchema
  270. export type BaseValues = Values<BaseSchema>