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;
}