diff --git a/.all-contributorsrc b/.all-contributorsrc index 812d28a9e..ed6e0b1cb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -286,6 +286,15 @@ "contributions": [ "doc" ] + }, + { + "login": "Lutymane", + "name": "Lutymane", + "avatar_url": "https://avatars.githubusercontent.com/u/22231294?v=4", + "profile": "https://zeokku.com/", + "contributions": [ + "code" + ] } ], "skipCi": true, diff --git a/README.md b/README.md index 0c2a1c893..ba5f13aef 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Max Kaye

📖 +
Lutymane

💻 diff --git a/types/three/examples/jsm/postprocessing/ShaderPass.d.ts b/types/three/examples/jsm/postprocessing/ShaderPass.d.ts index 70c2db49b..ff67e99d6 100644 --- a/types/three/examples/jsm/postprocessing/ShaderPass.d.ts +++ b/types/three/examples/jsm/postprocessing/ShaderPass.d.ts @@ -1,11 +1,23 @@ -import { ShaderMaterial } from '../../../src/Three'; +import { + AvoidNullUniforms, + ExtractUniforms, + ShaderMaterial, + ShaderMaterialParameters, + TUniforms, +} from '../../../src/Three'; -import { Pass } from './Pass'; +import { FullScreenQuad, Pass } from './Pass'; -export class ShaderPass extends Pass { - constructor(shader: object, textureID?: string); +export type ShaderLike = { + fragmentShader: ShaderMaterial['fragmentShader']; + vertexShader?: ShaderMaterial['vertexShader']; + defines?: ShaderMaterial['defines']; +} & (Exclude extends never ? { uniforms: Uniforms } : { uniforms?: Uniforms }); + +export class ShaderPass> extends Pass { + constructor(shader: ShaderLike, textureID?: string); textureID: string; - uniforms: { [name: string]: { value: any } }; - material: ShaderMaterial; - fsQuad: object; + uniforms: AvoidNullUniforms; + material: ShaderMaterial; + fsQuad: FullScreenQuad; } diff --git a/types/three/src/materials/RawShaderMaterial.d.ts b/types/three/src/materials/RawShaderMaterial.d.ts index 96b531340..27913a7a1 100644 --- a/types/three/src/materials/RawShaderMaterial.d.ts +++ b/types/three/src/materials/RawShaderMaterial.d.ts @@ -1,5 +1,13 @@ -import { ShaderMaterialParameters, ShaderMaterial } from './ShaderMaterial'; +import { ShaderMaterialParameters, ShaderMaterial, TUniforms, ExtractUniforms } from './ShaderMaterial'; -export class RawShaderMaterial extends ShaderMaterial { - constructor(parameters?: ShaderMaterialParameters); +export type RawShaderMaterialParameters = ShaderMaterialParameters & { + vertexShader: string; + fragmentShader: string; +}; + +export class RawShaderMaterial< + T extends {} = TUniforms, + Uniforms extends TUniforms = ExtractUniforms, +> extends ShaderMaterial { + constructor(parameters?: RawShaderMaterialParameters); } diff --git a/types/three/src/materials/ShaderMaterial.d.ts b/types/three/src/materials/ShaderMaterial.d.ts index af861a972..34e945d13 100644 --- a/types/three/src/materials/ShaderMaterial.d.ts +++ b/types/three/src/materials/ShaderMaterial.d.ts @@ -2,29 +2,56 @@ import { IUniform } from '../renderers/shaders/UniformsLib'; import { MaterialParameters, Material } from './Material'; import { GLSLVersion } from '../constants'; -export interface ShaderMaterialParameters extends MaterialParameters { - uniforms?: { [uniform: string]: IUniform } | undefined; - vertexShader?: string | undefined; - fragmentShader?: string | undefined; - linewidth?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - lights?: boolean | undefined; - clipping?: boolean | undefined; - - extensions?: - | { - derivatives?: boolean | undefined; - fragDepth?: boolean | undefined; - drawBuffers?: boolean | undefined; - shaderTextureLOD?: boolean | undefined; - } - | undefined; - glslVersion?: GLSLVersion | undefined; +export interface TUniforms { + [uniform: string]: IUniform; } -export class ShaderMaterial extends Material { - constructor(parameters?: ShaderMaterialParameters); +// transform { uniform1: type1, uniform2: type2 } to { uniform1: { value: type1 }, ...} +export type WrapUniforms = { + [U in keyof T]: T[U] extends IUniform ? T[U] : IUniform; +}; + +// replace null types by any (typically used by textures) +export type AvoidNullUniforms = { + [U in keyof T]: IUniform; +}; + +export type ExtractUniforms = AvoidNullUniforms< + WrapUniforms ? U : T> +>; + +export interface ShaderMaterialParametersLike { + uniforms: Uniforms; +} + +export type ShaderMaterialParameters = MaterialParameters & + // if we have uniforms type defined in var declaration then this paramater is required + // keyof { [string] } will result in string | number, since uniform names can't be numbers we can safely determine the type + // check for extends never instead of extends number because never always extends everything + // uniforms: Type | undefined !== uniforms?: Type + (Exclude extends never ? { uniforms: Uniforms } : { uniforms?: Uniforms }) & { + vertexShader?: string; + fragmentShader?: string; + linewidth?: number; + wireframe?: boolean; + wireframeLinewidth?: number; + lights?: boolean; + clipping?: boolean; + + extensions?: { + derivatives?: boolean; + fragDepth?: boolean; + drawBuffers?: boolean; + shaderTextureLOD?: boolean; + }; + glslVersion?: GLSLVersion; + }; + +export class ShaderMaterial< + T extends {} = TUniforms, + Uniforms extends TUniforms = ExtractUniforms, +> extends Material { + constructor(parameters?: ShaderMaterialParameters); /** * @default 'ShaderMaterial' @@ -39,7 +66,10 @@ export class ShaderMaterial extends Material { /** * @default {} */ - uniforms: { [uniform: string]: IUniform }; + uniforms: AvoidNullUniforms; + // uniforms: Exclude extends never + // ? AvoidNullUniforms + // : Partial>; vertexShader: string; fragmentShader: string; @@ -96,7 +126,7 @@ export class ShaderMaterial extends Material { /** * @default undefined */ - index0AttributeName: string | undefined; + index0AttributeName?: string; /** * @default false @@ -110,6 +140,6 @@ export class ShaderMaterial extends Material { isShaderMaterial: boolean; - setValues(parameters: ShaderMaterialParameters): void; + setValues(parameters: ShaderMaterialParameters): void; toJSON(meta: any): any; }