From dd09252a0059a6fa2286cf9c0d725f246053e081 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Wed, 18 Dec 2024 20:17:16 +0800 Subject: [PATCH 01/35] feat: shaderlab pbr support refraction --- packages/core/src/material/PBRMaterial.ts | 137 +++++++++++++++++- .../gltf/extensions/GLTFExtensionSchema.ts | 11 ++ .../extensions/KHR_materials_transmission.ts | 23 +++ .../gltf/extensions/KHR_materials_volume.ts | 34 +++++ .../src/shaders/shadingPBR/BRDF.glsl | 7 + .../src/shaders/shadingPBR/BTDF.glsl | 54 +++++++ .../src/shaders/shadingPBR/FragmentPBR.glsl | 40 +++++ .../shaders/shadingPBR/LightDirectPBR.glsl | 6 + .../shaders/shadingPBR/LightIndirectPBR.glsl | 10 ++ .../src/shaders/shadingPBR/Refraction.glsl | 48 ++++++ .../src/shaders/shadingPBR/index.ts | 6 +- 11 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl create mode 100644 packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index d711947aa9..24109db9f1 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -1,6 +1,6 @@ import { MathUtil, Vector2, Vector3, Vector4, Color } from "@galacean/engine-math"; import { Engine } from "../Engine"; -import { ShaderProperty } from "../shader"; +import { ShaderMacro, ShaderProperty } from "../shader"; import { Shader } from "../shader/Shader"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; @@ -31,6 +31,14 @@ export class PBRMaterial extends PBRBaseMaterial { private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture"); + private _refractionEnabled = false; + private static _refactionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); + private static _transmissionProp = ShaderProperty.getByName("material_transmission"); + private static _transmissionTextureProp = ShaderProperty.getByName("material_TransmissionTexture"); + private static _attenuationColorProp = ShaderProperty.getByName("material_attenuationColor"); + private static _attenuationDistanceProp = ShaderProperty.getByName("material_attenuationDistance"); + private static _thicknessProp = ShaderProperty.getByName("material_thickness"); + private static _thicknessTextureProp = ShaderProperty.getByName("material_ThicknessTexture"); /** * Index Of Refraction. * @defaultValue `1.5` @@ -289,6 +297,122 @@ export class PBRMaterial extends PBRBaseMaterial { } } + /** + * Refraction switch. + */ + get enableRefraction(): boolean { + return this._refractionEnabled; + } + + set enableRefraction(value: boolean) { + if (value !== this._refractionEnabled) { + this._refractionEnabled = value; + if (value) { + this.shaderData.enableMacro(PBRMaterial._refactionMacro); + } else { + this.shaderData.enableMacro(PBRMaterial._refactionMacro); + } + } + } + + /** + * Transmission factor. + * @defaultValue `0.0` + */ + get transmission(): number { + return this.shaderData.getFloat(PBRMaterial._transmissionProp); + } + + set transmission(value: number) { + this.shaderData.setFloat(PBRMaterial._transmissionProp, value); + if (value) { + this.shaderData.enableMacro("MATERIAL_HAS_TRANSMISSION"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_TRANSMISSION"); + } + } + + /** + * Transmission texture. + * @remarks Use red channel, and multiply 'transmission'. + */ + get transmissionTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._transmissionTextureProp); + } + + set transmissionTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._transmissionTextureProp, value); + if (value) { + this.shaderData.enableMacro("MATERIAL_HAS_TRANSMISSION_TEXTURE"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_TRANSMISSION_TEXTURE"); + } + } + + /** + * Attenuation color. + * @defaultValue `[1,1,1]` + */ + get attenuationColor(): Color { + return this.shaderData.getColor(PBRMaterial._attenuationColorProp); + } + + set attenuationColor(value: Color) { + const attenuationColor = this.shaderData.getColor(PBRMaterial._attenuationColorProp); + if (value !== attenuationColor) { + attenuationColor.copyFrom(value); + } + } + + /** + * Attenuation distance, greater than 0.0. + * @defaultValue `infinity` + */ + get attenuationDistance(): number { + return this.shaderData.getFloat(PBRMaterial._attenuationDistanceProp); + } + + set attenuationDistance(value: number) { + if (value <= 0) { + throw new Error("attenuationDistance must be greater than 0.0"); + } + this.shaderData.setFloat(PBRMaterial._attenuationDistanceProp, value); + } + + /** + * Thickness, greater than or equal to 0.0. + * @defaultValue `0.0` + */ + get thickness(): number { + return this.shaderData.getFloat(PBRMaterial._thicknessProp); + } + + set thickness(value: number) { + value = Math.max(0, value); + this.shaderData.setFloat(PBRMaterial._thicknessProp, value); + if (value) { + this.shaderData.enableMacro("MATERIAL_HAS_THICKNESS"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_THICKNESS"); + } + } + + /** + * Thickness texture. + * @remarks Use green channel, and multiply 'thickness', range is 0.0 to 1.0. + */ + get thicknessTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._thicknessTextureProp); + } + + set thicknessTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._thicknessTextureProp, value); + if (value) { + this.shaderData.enableMacro("MATERIAL_HAS_THICKNESS_TEXTURE"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_THICKNESS_TEXTURE"); + } + } /** * Create a pbr metallic-roughness workflow material instance. * @param engine - Engine to which the material belongs @@ -304,6 +428,8 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); const sheenColor = new Color(0, 0, 0); shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); + const attenuationColor = new Color(1, 1, 1); + shaderData.setColor(PBRMaterial._attenuationColorProp, attenuationColor); // @ts-ignore this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); // @ts-ignore @@ -318,6 +444,15 @@ export class PBRMaterial extends PBRBaseMaterial { } } }; + // @ts-ignore + attenuationColor._onValueChanged = () => { + const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 1; + if (enableAbsorption) { + this.shaderData.enableMacro("MATERIAL_HAS_ABSORPTION"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_ABSORPTION"); + } + }; } private _onIridescenceRangeChanged(): void { diff --git a/packages/loader/src/gltf/extensions/GLTFExtensionSchema.ts b/packages/loader/src/gltf/extensions/GLTFExtensionSchema.ts index b0ee1c536a..5fd66d2d06 100644 --- a/packages/loader/src/gltf/extensions/GLTFExtensionSchema.ts +++ b/packages/loader/src/gltf/extensions/GLTFExtensionSchema.ts @@ -188,6 +188,16 @@ export interface IKHRMaterialsIridescence { iridescenceThicknessTexture?: ITextureInfo; } +/** + * Interfaces from the KHR_materials_volume extension + */ +export interface IKHRMaterialsVolume { + thicknessFactor?: number; + thicknessTexture?: ITextureInfo; + attenuationDistance?: number; + attenuationColor?: number[]; +} + export type GLTFExtensionSchema = | IKHRLightsPunctual_Light | IKHRMaterialsClearcoat @@ -207,4 +217,5 @@ export type GLTFExtensionSchema = | IKHRXmp_Node | IGalaceanAnimation | IKHRMaterialsIridescence + | IKHRMaterialsVolume | Object; diff --git a/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts b/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts index e69de29bb2..0bbdf30cb7 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts @@ -0,0 +1,23 @@ +import { PBRMaterial, Texture2D } from "@galacean/engine-core"; +import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; +import { registerGLTFExtension } from "../parser/GLTFParser"; +import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext"; +import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser"; +import { IKHRMaterialsTransmission } from "./GLTFExtensionSchema"; + +@registerGLTFExtension("KHR_materials_transmission", GLTFExtensionMode.AdditiveParse) +class KHR_materials_transmission extends GLTFExtensionParser { + override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsTransmission): void { + const { transmissionFactor = 0, transmissionTexture } = schema; + + material.transmission = transmissionFactor; + + if (transmissionTexture) { + GLTFMaterialParser._checkOtherTextureTransform(transmissionTexture, "Transmission texture"); + + context.get(GLTFParserType.Texture, transmissionTexture.index).then((texture) => { + material.transmissionTexture = texture; + }); + } + } +} diff --git a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts index e69de29bb2..889257c678 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts @@ -0,0 +1,34 @@ +import { PBRMaterial, Texture2D } from "@galacean/engine-core"; +import { Color } from "@galacean/engine-math"; +import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; +import { registerGLTFExtension } from "../parser/GLTFParser"; +import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext"; +import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser"; +import { IKHRMaterialsVolume } from "./GLTFExtensionSchema"; + +@registerGLTFExtension("KHR_materials_volume", GLTFExtensionMode.AdditiveParse) +class KHR_materials_volume extends GLTFExtensionParser { + override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsVolume): void { + const { thicknessFactor = 0, thicknessTexture, attenuationDistance = Infinity, attenuationColor } = schema; + + material.thickness = thicknessFactor; + material.attenuationDistance = attenuationDistance; + + if (attenuationColor) { + material.attenuationColor.set( + Color.linearToGammaSpace(attenuationColor[0]), + Color.linearToGammaSpace(attenuationColor[1]), + Color.linearToGammaSpace(attenuationColor[2]), + undefined + ); + } + + if (thicknessTexture) { + GLTFMaterialParser._checkOtherTextureTransform(thicknessTexture, "Thickness texture"); + + context.get(GLTFParserType.Texture, thicknessTexture.index).then((texture) => { + material.thicknessTexture = texture; + }); + } + } +} diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl index c8eb64615c..0244ca7d68 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl @@ -24,6 +24,7 @@ struct SurfaceData{ float specularAO; float f0; float opacity; + float IOR; // geometry vec3 position; @@ -64,6 +65,12 @@ struct SurfaceData{ vec3 sheenColor; #endif + #ifdef MATERIAL_ENABLE_SS_REFRACTION + vec3 attenuationColor; + float attenuationDistance; + float transmission; + float thickness; + #endif }; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl new file mode 100644 index 0000000000..2cf4d07f70 --- /dev/null +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -0,0 +1,54 @@ +#ifndef BTDF_INCLUDED +#define BTDF_INCLUDED + +#include "Refraction.glsl" + +sampler2D camera_OpaqueTexture; + +#ifdef MATERIAL_ENABLE_SS_REFRACTION + vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData, vec3 specularColor) { + RefractionModel ray; + #if defined(REFRACTION_SPHERE) + RefractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + #elif defined(REFRACTION_PLANE) + RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + #elif defined(REFRACTION_THIN) + RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, 0.005, ray); + #endif + //TODO: support cubemap refraction. + vec3 refractedRayExit = ray.position; + + // We calculate the screen space position of the refracted point + vec4 samplingPositionNDC = camera_ProjMat * camera_ViewMat * vec4( refractedRayExit, 1.0 ); + vec2 refractionCoords = (samplingPositionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5; + + // Absorption coefficient from Disney: http://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf + #ifdef MATERIAL_HAS_ABSORPTION + vec3 absorptionCoefficient = -log(clamp(surfaceData.attenuationColor, 1e-5f, 1.0f)) / max(1e-5f, surfaceData.attenuationDistance); + #ifdef MATERIAL_HAS_THICKNESS + vec3 transmittance = min(vec3(1.0), exp(-absorptionCoefficient * ray.dist)); + #else + vec3 transmittance = 1.0 - absorptionCoefficient; + #endif + #endif + + // Sample the opaque texture to get the transmitted light + vec4 getTransmission = texture2D(camera_OpaqueTexture, refractionCoords); + + vec3 refractionTransmitted = getTransmission.rgb; + refractionTransmitted *= brdfData.diffuseColor; + + // Use specularFGD as an approximation of the fresnel effect + // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf + vec3 specularFGD = envBRDFApprox(specularColor, surfaceData.roughness, surfaceData.dotNV); + refractionTransmitted *= (1.0 - specularFGD); + + #ifdef MATERIAL_HAS_ABSORPTION + refractionTransmitted *= transmittance; + #endif + + return refractionTransmitted; + } +#endif + +#endif \ No newline at end of file diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 0ec9afe48c..8989f55c89 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -62,6 +62,25 @@ float material_OcclusionTextureCoord; #endif #endif +#ifdef MATERIAL_ENABLE_SS_REFRACTION + vec3 material_attenuationColor; + float material_attenuationDistance; + + #ifdef MATERIAL_HAS_TRANSMISSION + float material_transmission; + #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE + sampler2D material_TransmissionTexture; + #endif + #endif + + #ifdef MATERIAL_HAS_THICKNESS + float material_thickness; + #ifdef MATERIAL_HAS_THICKNESS_TEXTURE + sampler2D material_ThicknessTexture; + #endif + #endif +#endif + // Texture #ifdef MATERIAL_HAS_BASETEXTURE sampler2D material_BaseTexture; @@ -292,6 +311,27 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #endif + #ifdef MATERIAL_ENABLE_SS_REFRACTION + surfaceData.attenuationColor = material_attenuationColor; + surfaceData.IOR = material_IOR; + surfaceData.attenuationDistance = max(material_attenuationDistance, 0.001); + + #ifdef MATERIAL_HAS_TRANSMISSION + surfaceData.transmission = material_transmission; + #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE + surfaceData.transmission *= texture2D(material_TransmissionTexture, uv).r; + #endif + #else + surfaceData.transmission = 1.0; + #endif + + #ifdef MATERIAL_HAS_THICKNESS + surfaceData.thickness = max(material_thickness, 0.0); + #ifdef MATERIAL_HAS_THICKNESS_TEXTURE + surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; + #endif + #endif + #endif // AO float diffuseAO = 1.0; float specularAO = 1.0; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl index f8ad6e77a4..aa078db500 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl @@ -19,6 +19,7 @@ #endif #include "BRDF.glsl" +#include "BTDF.glsl" #include "Light.glsl" #include "ReflectionLobe.glsl" @@ -37,6 +38,11 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat FUNCTION_DIFFUSE_LOBE(varyings, surfaceData, brdfData, attenuationIrradiance, diffuseColor); // Specular Lobe FUNCTION_SPECULAR_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, specularColor); + + #ifdef MATERIAL_ENABLE_SS_REFRACTION + diffuseColor *= (1.0 - surfaceData.transmission); + #endif + // Sheen Lobe FUNCTION_SHEEN_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, diffuseColor, specularColor); diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index e0f5780b58..dd8264ab71 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -105,8 +105,18 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, // IBL sheen FUNCTION_SHEEN_IBL(varyings, surfaceData, brdfData, radianceAttenuation, diffuseColor, specularColor); + #ifdef MATERIAL_ENABLE_SS_REFRACTION + vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData, specularColor); + refractionTransmitted *= surfaceData.transmission; + diffuseColor *= (1.0 - surfaceData.transmission); + #endif + color += diffuseColor + specularColor; + #ifdef MATERIAL_ENABLE_SS_REFRACTION + color.rgb += refractionTransmitted; + #endif + } diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl new file mode 100644 index 0000000000..f719be1c03 --- /dev/null +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -0,0 +1,48 @@ +#ifndef REFRACTION_INCLUDED +#define REFRACTION_INCLUDED + +#ifdef MATERIAL_ENABLE_SS_REFRACTION + +struct RefractionModel{ + float dist; // length of the transmission during refraction through the shape + vec3 position; // out ray position + vec3 direction; // out ray direction +}; + +//https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html + void RefractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModel ray){ + // Refracted ray + vec3 R1 = refract(V, normalWS, 1.0 / ior); + // Center of the tangent sphere + vec3 C = positionWS - normalWS * thickness * 0.5; + + // Second refraction (tangent sphere out) + float NoR1 = dot(normalWS, R1); + // Optical depth within the sphere + float dist = -NoR1 * thickness; + // Out hit point in the tangent sphere + vec3 P1 = positionWS + R1 * dist; + // Out normal + vec3 N1 = normalize(C - P1); + // Out refracted ray + vec3 R2 = refract(R1, N1, ior); + + ray.dist = dist; + ray.position = P1; + ray.direction = R2; +} + +void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModel ray){ + // Refracted ray + vec3 R = refract(V, normalWS, 1.0 / ior); + float NoR = dot(normalWS, R); + // Optical depth within the thin plane + float dist = thickness / max(-NoR, 0.001); + + ray.dist = dist; + ray.position = vec3(positionWS + R * dist); + ray.direction = V; +} +#endif + +#endif \ No newline at end of file diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/index.ts b/packages/shader-shaderlab/src/shaders/shadingPBR/index.ts index 2f34850456..3f374d2d7d 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/index.ts +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/index.ts @@ -8,6 +8,8 @@ import LightIndirectPBR from "./LightIndirectPBR.glsl"; import ReflectionLobe from "./ReflectionLobe.glsl"; import VaryingsPBR from "./VaryingsPBR.glsl"; import VertexPBR from "./VertexPBR.glsl"; +import Refraction from "./Refraction.glsl"; +import BTDF from "./BTDF.glsl"; export default [ { source: ForwardPassPBR, includeKey: "ForwardPassPBR.glsl" }, @@ -19,5 +21,7 @@ export default [ { source: VertexPBR, includeKey: "VertexPBR.glsl" }, { source: BRDF, includeKey: "BRDF.glsl" }, { source: LightIndirectFunctions, includeKey: "LightIndirectFunctions.glsl" }, - { source: ReflectionLobe, includeKey: "ReflectionLobe.glsl" } + { source: ReflectionLobe, includeKey: "ReflectionLobe.glsl" }, + { source: Refraction, includeKey: "Refraction.glsl" }, + { source: BTDF, includeKey: "BTDF.glsl" } ]; From 1fc002e5a88af407ab36182ec2d4b4bbe76e2378 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 19 Dec 2024 10:40:00 +0800 Subject: [PATCH 02/35] fix: disableMacro --- packages/core/src/material/PBRMaterial.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 24109db9f1..da11b21809 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -310,7 +310,7 @@ export class PBRMaterial extends PBRBaseMaterial { if (value) { this.shaderData.enableMacro(PBRMaterial._refactionMacro); } else { - this.shaderData.enableMacro(PBRMaterial._refactionMacro); + this.shaderData.disableMacro(PBRMaterial._refactionMacro); } } } From adfdfecaf30d01292c520150a0e90ef28cd093a8 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 19 Dec 2024 11:41:57 +0800 Subject: [PATCH 03/35] fix: name --- packages/core/src/material/PBRMaterial.ts | 8 ++++---- packages/shader-shaderlab/src/shaders/PBR.gs | 9 +++++++++ .../src/shaders/shadingPBR/FragmentPBR.glsl | 16 ++++++++-------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index da11b21809..8b9d08b767 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -33,11 +33,11 @@ export class PBRMaterial extends PBRBaseMaterial { private _refractionEnabled = false; private static _refactionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); - private static _transmissionProp = ShaderProperty.getByName("material_transmission"); + private static _transmissionProp = ShaderProperty.getByName("material_Transmission"); private static _transmissionTextureProp = ShaderProperty.getByName("material_TransmissionTexture"); - private static _attenuationColorProp = ShaderProperty.getByName("material_attenuationColor"); - private static _attenuationDistanceProp = ShaderProperty.getByName("material_attenuationDistance"); - private static _thicknessProp = ShaderProperty.getByName("material_thickness"); + private static _attenuationColorProp = ShaderProperty.getByName("material_AttenuationColor"); + private static _attenuationDistanceProp = ShaderProperty.getByName("material_AttenuationDistance"); + private static _thicknessProp = ShaderProperty.getByName("material_Thickness"); private static _thicknessTextureProp = ShaderProperty.getByName("material_ThicknessTexture"); /** * Index Of Refraction. diff --git a/packages/shader-shaderlab/src/shaders/PBR.gs b/packages/shader-shaderlab/src/shaders/PBR.gs index 8bea8bb27a..2ab62f21dc 100644 --- a/packages/shader-shaderlab/src/shaders/PBR.gs +++ b/packages/shader-shaderlab/src/shaders/PBR.gs @@ -54,6 +54,15 @@ Shader "PBR.gs" { material_SheenTexture("ColorTexture", Texture2D); material_SheenRoughnessTexture("RoughnessTexture", Texture2D); } + + Header("Refraction"){ + material_AttenuationColor("AttenuationColor", Color ) = (1, 1, 1, 1); + material_AttenuationDistance("AttenuationDistance", Range(0, 1, 0.01)) = 0; + material_Transmission("Transmission", Range(0, 1, 0.01)) = 0; + material_Thickness("Thickness", Range(0, 5, 0.01)) = 0; + material_TransmissionTexture("TransmissionTexture", Texture2D); + material_ThicknessTexture("ThicknessTexture", Texture2D); + } Header("Common") { material_AlphaCutoff( "AlphaCutoff", Range(0, 1, 0.01) ) = 0; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 8989f55c89..19355133a8 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -63,18 +63,18 @@ float material_OcclusionTextureCoord; #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - vec3 material_attenuationColor; - float material_attenuationDistance; + vec3 material_AttenuationColor; + float material_AttenuationDistance; #ifdef MATERIAL_HAS_TRANSMISSION - float material_transmission; + float material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE sampler2D material_TransmissionTexture; #endif #endif #ifdef MATERIAL_HAS_THICKNESS - float material_thickness; + float material_Thickness; #ifdef MATERIAL_HAS_THICKNESS_TEXTURE sampler2D material_ThicknessTexture; #endif @@ -312,12 +312,12 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - surfaceData.attenuationColor = material_attenuationColor; + surfaceData.attenuationColor = material_AttenuationColor; surfaceData.IOR = material_IOR; - surfaceData.attenuationDistance = max(material_attenuationDistance, 0.001); + surfaceData.attenuationDistance = max(material_AttenuationDistance, 0.001); #ifdef MATERIAL_HAS_TRANSMISSION - surfaceData.transmission = material_transmission; + surfaceData.transmission = material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE surfaceData.transmission *= texture2D(material_TransmissionTexture, uv).r; #endif @@ -326,7 +326,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_HAS_THICKNESS - surfaceData.thickness = max(material_thickness, 0.0); + surfaceData.thickness = max(material_Thickness, 0.0); #ifdef MATERIAL_HAS_THICKNESS_TEXTURE surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; #endif From ffa2912e1eb99259f549d563e0d2ec367843c983 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Fri, 20 Dec 2024 11:33:03 +0800 Subject: [PATCH 04/35] fix: refraction mode --- packages/core/src/material/PBRMaterial.ts | 88 +++++++++++++------ .../core/src/material/enums/Refraction.ts | 11 +++ .../src/shaders/shadingPBR/BTDF.glsl | 3 +- 3 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 packages/core/src/material/enums/Refraction.ts diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 8b9d08b767..fa689f4c3a 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -4,6 +4,8 @@ import { ShaderMacro, ShaderProperty } from "../shader"; import { Shader } from "../shader/Shader"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; +import { RefractionMode } from "./enums/Refraction"; +import { RenderQueueType } from "../shader/enums/RenderQueueType"; /** * PBR (Metallic-Roughness Workflow) Material. @@ -31,8 +33,16 @@ export class PBRMaterial extends PBRBaseMaterial { private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture"); - private _refractionEnabled = false; - private static _refactionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); + protected _refractionMode: RefractionMode; + protected static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); + private static _refractionSphereMacro: ShaderMacro = ShaderMacro.getByName("REFRACTION_SPHERE"); + private static _refractionPlaneMacro: ShaderMacro = ShaderMacro.getByName("REFRACTION_PLANE"); + private static _refractionThinMacro: ShaderMacro = ShaderMacro.getByName("REFRACTION_THIN"); + private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION"); + private static _thicknessMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS"); + private static _absorptionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_ABSORPTION"); + private static _thicknessTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS_TEXTURE"); + private static _transmissionTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION_TEXTURE"); private static _transmissionProp = ShaderProperty.getByName("material_Transmission"); private static _transmissionTextureProp = ShaderProperty.getByName("material_TransmissionTexture"); private static _attenuationColorProp = ShaderProperty.getByName("material_AttenuationColor"); @@ -299,20 +309,44 @@ export class PBRMaterial extends PBRBaseMaterial { /** * Refraction switch. + * @remarks Use refractionMode to set the refraction shape. */ - get enableRefraction(): boolean { - return this._refractionEnabled; + get refractionMode(): RefractionMode { + return this._refractionMode; } - set enableRefraction(value: boolean) { - if (value !== this._refractionEnabled) { - this._refractionEnabled = value; + set refractionMode(value: RefractionMode) { + if (value !== this._refractionMode) { if (value) { - this.shaderData.enableMacro(PBRMaterial._refactionMacro); + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.renderState.renderQueueType = RenderQueueType.Transparent; + this.renderState.blendState.targetBlendState.enabled = false; } else { - this.shaderData.disableMacro(PBRMaterial._refactionMacro); + this.shaderData.disableMacro(PBRMaterial._refractionMacro); + this.renderState.renderQueueType = RenderQueueType.Opaque; + this.renderState.blendState.targetBlendState.enabled = true; } } + this._refractionMode = value; + this.setRefractionMode(value); + } + + private setRefractionMode(refractionMode: RefractionMode): void { + this.shaderData.disableMacro(PBRMaterial._refractionSphereMacro); + this.shaderData.disableMacro(PBRMaterial._refractionPlaneMacro); + this.shaderData.disableMacro(PBRMaterial._refractionThinMacro); + + switch (refractionMode) { + case RefractionMode.Sphere: + this.shaderData.enableMacro(PBRMaterial._refractionSphereMacro); + break; + case RefractionMode.Plane: + this.shaderData.enableMacro(PBRMaterial._refractionPlaneMacro); + break; + case RefractionMode.Thin: + this.shaderData.enableMacro(PBRMaterial._refractionThinMacro); + break; + } } /** @@ -324,12 +358,13 @@ export class PBRMaterial extends PBRBaseMaterial { } set transmission(value: number) { - this.shaderData.setFloat(PBRMaterial._transmissionProp, value); - if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_TRANSMISSION"); + value = Math.max(0, Math.min(1, value)); + if (!!this.shaderData.getFloat(PBRMaterial._transmissionProp) !== !!value) { + this.shaderData.disableMacro(PBRMaterial._transmissionMacro); } else { - this.shaderData.disableMacro("MATERIAL_HAS_TRANSMISSION"); + this.shaderData.enableMacro(PBRMaterial._transmissionMacro); } + this.shaderData.setFloat(PBRMaterial._transmissionProp, value); } /** @@ -343,9 +378,9 @@ export class PBRMaterial extends PBRBaseMaterial { set transmissionTexture(value: Texture2D) { this.shaderData.setTexture(PBRMaterial._transmissionTextureProp, value); if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_TRANSMISSION_TEXTURE"); + this.shaderData.enableMacro(PBRMaterial._transmissionTextureMacro); } else { - this.shaderData.disableMacro("MATERIAL_HAS_TRANSMISSION_TEXTURE"); + this.shaderData.disableMacro(PBRMaterial._transmissionTextureMacro); } } @@ -373,9 +408,7 @@ export class PBRMaterial extends PBRBaseMaterial { } set attenuationDistance(value: number) { - if (value <= 0) { - throw new Error("attenuationDistance must be greater than 0.0"); - } + value = Math.max(0, value); this.shaderData.setFloat(PBRMaterial._attenuationDistanceProp, value); } @@ -389,12 +422,12 @@ export class PBRMaterial extends PBRBaseMaterial { set thickness(value: number) { value = Math.max(0, value); - this.shaderData.setFloat(PBRMaterial._thicknessProp, value); - if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_THICKNESS"); + if (!!this.shaderData.getFloat(PBRMaterial._thicknessProp) !== !!value) { + this.shaderData.disableMacro(PBRMaterial._thicknessMacro); } else { - this.shaderData.disableMacro("MATERIAL_HAS_THICKNESS"); + this.shaderData.enableMacro(PBRMaterial._thicknessMacro); } + this.shaderData.setFloat(PBRMaterial._thicknessProp, value); } /** @@ -408,9 +441,9 @@ export class PBRMaterial extends PBRBaseMaterial { set thicknessTexture(value: Texture2D) { this.shaderData.setTexture(PBRMaterial._thicknessTextureProp, value); if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_THICKNESS_TEXTURE"); + this.shaderData.enableMacro(PBRMaterial._thicknessTextureMacro); } else { - this.shaderData.disableMacro("MATERIAL_HAS_THICKNESS_TEXTURE"); + this.shaderData.disableMacro(PBRMaterial._thicknessTextureMacro); } } /** @@ -428,6 +461,9 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); const sheenColor = new Color(0, 0, 0); shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); + this.refractionMode = RefractionMode.Plane; + shaderData.setFloat(PBRMaterial._thicknessProp, 0); + shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); const attenuationColor = new Color(1, 1, 1); shaderData.setColor(PBRMaterial._attenuationColorProp, attenuationColor); // @ts-ignore @@ -448,9 +484,9 @@ export class PBRMaterial extends PBRBaseMaterial { attenuationColor._onValueChanged = () => { const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 1; if (enableAbsorption) { - this.shaderData.enableMacro("MATERIAL_HAS_ABSORPTION"); + this.shaderData.enableMacro(PBRMaterial._absorptionMacro); } else { - this.shaderData.disableMacro("MATERIAL_HAS_ABSORPTION"); + this.shaderData.disableMacro(PBRMaterial._absorptionMacro); } }; } diff --git a/packages/core/src/material/enums/Refraction.ts b/packages/core/src/material/enums/Refraction.ts new file mode 100644 index 0000000000..47df932ee5 --- /dev/null +++ b/packages/core/src/material/enums/Refraction.ts @@ -0,0 +1,11 @@ +/** + * Refraction mode. + */ +export enum RefractionMode { + /** Refraction shape is sphere */ + Sphere, + /** Refraction shape is plane */ + Plane, + /** Refraction shape is thin */ + Thin +} diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 2cf4d07f70..81f0aeff76 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -3,9 +3,8 @@ #include "Refraction.glsl" -sampler2D camera_OpaqueTexture; - #ifdef MATERIAL_ENABLE_SS_REFRACTION + sampler2D camera_OpaqueTexture; vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData, vec3 specularColor) { RefractionModel ray; #if defined(REFRACTION_SPHERE) From 1fc63b2da23f60a057fd5ac1882ce8e2776cc278 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Fri, 20 Dec 2024 14:16:04 +0800 Subject: [PATCH 05/35] fix: keep iridescenceRange unified --- packages/core/src/material/PBRMaterial.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index fa689f4c3a..c00a1cd809 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -466,8 +466,13 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); const attenuationColor = new Color(1, 1, 1); shaderData.setColor(PBRMaterial._attenuationColorProp, attenuationColor); + // @ts-ignore - this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); + this._iridescenceRange._onValueChanged = () => { + const iridescenceInfo = this.shaderData.getVector4(PBRMaterial._iridescenceInfoProp); + iridescenceInfo.z = this._iridescenceRange.x; + iridescenceInfo.w = this._iridescenceRange.y; + }; // @ts-ignore sheenColor._onValueChanged = () => { const enableSheen = sheenColor.r + sheenColor.g + sheenColor.b > 0; @@ -491,12 +496,6 @@ export class PBRMaterial extends PBRBaseMaterial { }; } - private _onIridescenceRangeChanged(): void { - const iridescenceInfo = this.shaderData.getVector4(PBRMaterial._iridescenceInfoProp); - iridescenceInfo.z = this._iridescenceRange.x; - iridescenceInfo.w = this._iridescenceRange.y; - } - /** * @inheritdoc */ From bab958203a0fea881a2d650f4dfa19719dc5969d Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Fri, 20 Dec 2024 14:24:59 +0800 Subject: [PATCH 06/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index c00a1cd809..1e4846f649 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -360,11 +360,13 @@ export class PBRMaterial extends PBRBaseMaterial { set transmission(value: number) { value = Math.max(0, Math.min(1, value)); if (!!this.shaderData.getFloat(PBRMaterial._transmissionProp) !== !!value) { - this.shaderData.disableMacro(PBRMaterial._transmissionMacro); - } else { - this.shaderData.enableMacro(PBRMaterial._transmissionMacro); + if (value) { + this.shaderData.enableMacro(PBRMaterial._transmissionMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._transmissionMacro); + } + this.shaderData.setFloat(PBRMaterial._transmissionProp, value); } - this.shaderData.setFloat(PBRMaterial._transmissionProp, value); } /** @@ -423,11 +425,13 @@ export class PBRMaterial extends PBRBaseMaterial { set thickness(value: number) { value = Math.max(0, value); if (!!this.shaderData.getFloat(PBRMaterial._thicknessProp) !== !!value) { - this.shaderData.disableMacro(PBRMaterial._thicknessMacro); - } else { - this.shaderData.enableMacro(PBRMaterial._thicknessMacro); + if (value) { + this.shaderData.enableMacro(PBRMaterial._thicknessMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._thicknessMacro); + } + this.shaderData.setFloat(PBRMaterial._thicknessProp, value); } - this.shaderData.setFloat(PBRMaterial._thicknessProp, value); } /** From 174e0e7ff3ca013c0475839d7732d9b3df64fcca Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Fri, 20 Dec 2024 14:35:42 +0800 Subject: [PATCH 07/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 1e4846f649..43be8a503e 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -359,13 +359,11 @@ export class PBRMaterial extends PBRBaseMaterial { set transmission(value: number) { value = Math.max(0, Math.min(1, value)); + this.shaderData.setFloat(PBRMaterial._transmissionProp, value); if (!!this.shaderData.getFloat(PBRMaterial._transmissionProp) !== !!value) { - if (value) { - this.shaderData.enableMacro(PBRMaterial._transmissionMacro); - } else { - this.shaderData.disableMacro(PBRMaterial._transmissionMacro); - } - this.shaderData.setFloat(PBRMaterial._transmissionProp, value); + this.shaderData.enableMacro(PBRMaterial._transmissionMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._transmissionMacro); } } @@ -424,13 +422,11 @@ export class PBRMaterial extends PBRBaseMaterial { set thickness(value: number) { value = Math.max(0, value); + this.shaderData.setFloat(PBRMaterial._thicknessProp, value); if (!!this.shaderData.getFloat(PBRMaterial._thicknessProp) !== !!value) { - if (value) { - this.shaderData.enableMacro(PBRMaterial._thicknessMacro); - } else { - this.shaderData.disableMacro(PBRMaterial._thicknessMacro); - } - this.shaderData.setFloat(PBRMaterial._thicknessProp, value); + this.shaderData.enableMacro(PBRMaterial._thicknessMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._thicknessMacro); } } From 47fb19738882074d3e2f0cbd342775af883c2040 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Fri, 20 Dec 2024 14:39:01 +0800 Subject: [PATCH 08/35] fix: refraction mode --- packages/core/src/material/PBRMaterial.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 43be8a503e..fb4be63c7d 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -326,9 +326,9 @@ export class PBRMaterial extends PBRBaseMaterial { this.renderState.renderQueueType = RenderQueueType.Opaque; this.renderState.blendState.targetBlendState.enabled = true; } + this._refractionMode = value; + this.setRefractionMode(value); } - this._refractionMode = value; - this.setRefractionMode(value); } private setRefractionMode(refractionMode: RefractionMode): void { From f9b748c9e6016a91c576623e0044181bcbe2e104 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 11:41:45 +0800 Subject: [PATCH 09/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 37 ++++++++++++------- .../core/src/material/enums/Refraction.ts | 8 ++-- .../shader-shaderlab/src/shaders/Common.glsl | 6 +++ .../src/shaders/shadingPBR/BTDF.glsl | 2 +- .../shaders/shadingPBR/LightDirectPBR.glsl | 1 - .../shaders/shadingPBR/LightIndirectPBR.glsl | 1 + .../src/shaders/shadingPBR/Refraction.glsl | 15 +++----- 7 files changed, 43 insertions(+), 27 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index fb4be63c7d..b31cecca4d 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -6,6 +6,8 @@ import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; import { RefractionMode } from "./enums/Refraction"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; +import { BlendMode } from "./enums/BlendMode"; +import { BaseMaterial } from "./BaseMaterial"; /** * PBR (Metallic-Roughness Workflow) Material. @@ -35,9 +37,6 @@ export class PBRMaterial extends PBRBaseMaterial { protected _refractionMode: RefractionMode; protected static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); - private static _refractionSphereMacro: ShaderMacro = ShaderMacro.getByName("REFRACTION_SPHERE"); - private static _refractionPlaneMacro: ShaderMacro = ShaderMacro.getByName("REFRACTION_PLANE"); - private static _refractionThinMacro: ShaderMacro = ShaderMacro.getByName("REFRACTION_THIN"); private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION"); private static _thicknessMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS"); private static _absorptionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_ABSORPTION"); @@ -320,31 +319,43 @@ export class PBRMaterial extends PBRBaseMaterial { if (value) { this.shaderData.enableMacro(PBRMaterial._refractionMacro); this.renderState.renderQueueType = RenderQueueType.Transparent; - this.renderState.blendState.targetBlendState.enabled = false; + if (this.isTransparent) { + this.renderState.renderQueueType = RenderQueueType.Transparent; + } else { + if (this.alphaCutoff) { + this.renderState.renderQueueType = RenderQueueType.Transparent; + } + } } else { this.shaderData.disableMacro(PBRMaterial._refractionMacro); - this.renderState.renderQueueType = RenderQueueType.Opaque; - this.renderState.blendState.targetBlendState.enabled = true; + this.isTransparent = this.isTransparent; + this.alphaCutoff = this.alphaCutoff; } + this.renderFace = this.renderFace; + this.blendMode = this.blendMode; + this._refractionMode = value; this.setRefractionMode(value); } } private setRefractionMode(refractionMode: RefractionMode): void { - this.shaderData.disableMacro(PBRMaterial._refractionSphereMacro); - this.shaderData.disableMacro(PBRMaterial._refractionPlaneMacro); - this.shaderData.disableMacro(PBRMaterial._refractionThinMacro); + this.shaderData.disableMacro("REFRACTION_SPHERE"); + this.shaderData.disableMacro("REFRACTION_PLANE"); + this.shaderData.disableMacro("REFRACTION_THIN"); switch (refractionMode) { + case RefractionMode.None: + this.shaderData.disableMacro(PBRMaterial._refractionMacro); + break; case RefractionMode.Sphere: - this.shaderData.enableMacro(PBRMaterial._refractionSphereMacro); + this.shaderData.enableMacro("REFRACTION_SPHERE"); break; case RefractionMode.Plane: - this.shaderData.enableMacro(PBRMaterial._refractionPlaneMacro); + this.shaderData.enableMacro("REFRACTION_PLANE"); break; case RefractionMode.Thin: - this.shaderData.enableMacro(PBRMaterial._refractionThinMacro); + this.shaderData.enableMacro("REFRACTION_THIN"); break; } } @@ -461,7 +472,7 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); const sheenColor = new Color(0, 0, 0); shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); - this.refractionMode = RefractionMode.Plane; + this.refractionMode = RefractionMode.None; shaderData.setFloat(PBRMaterial._thicknessProp, 0); shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); const attenuationColor = new Color(1, 1, 1); diff --git a/packages/core/src/material/enums/Refraction.ts b/packages/core/src/material/enums/Refraction.ts index 47df932ee5..bd418b0f41 100644 --- a/packages/core/src/material/enums/Refraction.ts +++ b/packages/core/src/material/enums/Refraction.ts @@ -2,10 +2,12 @@ * Refraction mode. */ export enum RefractionMode { - /** Refraction shape is sphere */ + /** No refraction. */ + None, + /** Refraction shape is sphere. */ Sphere, - /** Refraction shape is plane */ + /** Refraction shape is plane. */ Plane, - /** Refraction shape is thin */ + /** Refraction shape is thin. */ Thin } diff --git a/packages/shader-shaderlab/src/shaders/Common.glsl b/packages/shader-shaderlab/src/shaders/Common.glsl index 46ac04ad5f..83ff6b3dad 100644 --- a/packages/shader-shaderlab/src/shaders/Common.glsl +++ b/packages/shader-shaderlab/src/shaders/Common.glsl @@ -5,6 +5,7 @@ #define RECIPROCAL_PI 0.31830988618 #define EPSILON 1e-6 #define LOG2 1.442695 +#define FLT_MIN 1.175494351e-38 // Minimum normalized positive floating-point number #define saturate( a ) clamp( a, 0.0, 1.0 ) @@ -97,5 +98,10 @@ float remapDepthBufferLinear01(float z){ #define INVERSE_MAT(mat) inverseMat(mat) #endif +vec3 safeNormalize(vec3 inVec) +{ + float dp3 = max(float(FLT_MIN), dot(inVec, inVec)); + return inVec * inversesqrt(dp3); +} #endif \ No newline at end of file diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 81f0aeff76..69f669aa04 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -6,7 +6,7 @@ #ifdef MATERIAL_ENABLE_SS_REFRACTION sampler2D camera_OpaqueTexture; vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData, vec3 specularColor) { - RefractionModel ray; + RefractionModelResult ray; #if defined(REFRACTION_SPHERE) RefractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #elif defined(REFRACTION_PLANE) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl index aa078db500..f2191d3bb5 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl @@ -19,7 +19,6 @@ #endif #include "BRDF.glsl" -#include "BTDF.glsl" #include "Light.glsl" #include "ReflectionLobe.glsl" diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index dd8264ab71..e07f7dee35 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -15,6 +15,7 @@ #define FUNCTION_SHEEN_IBL evaluateSheenIBL #endif #include "BRDF.glsl" +#include "BTDF.glsl" #include "Light.glsl" #include "LightIndirectFunctions.glsl" diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index f719be1c03..0f879be8d0 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -3,27 +3,25 @@ #ifdef MATERIAL_ENABLE_SS_REFRACTION -struct RefractionModel{ +struct RefractionModelResult{ float dist; // length of the transmission during refraction through the shape vec3 position; // out ray position vec3 direction; // out ray direction }; //https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html - void RefractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModel ray){ + void RefractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ // Refracted ray vec3 R1 = refract(V, normalWS, 1.0 / ior); // Center of the tangent sphere vec3 C = positionWS - normalWS * thickness * 0.5; // Second refraction (tangent sphere out) - float NoR1 = dot(normalWS, R1); - // Optical depth within the sphere - float dist = -NoR1 * thickness; + float dist = dot(-normalWS, R1) * thickness; // Out hit point in the tangent sphere vec3 P1 = positionWS + R1 * dist; // Out normal - vec3 N1 = normalize(C - P1); + vec3 N1 = safeNormalize(C - P1); // Out refracted ray vec3 R2 = refract(R1, N1, ior); @@ -32,12 +30,11 @@ struct RefractionModel{ ray.direction = R2; } -void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModel ray){ +void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ // Refracted ray vec3 R = refract(V, normalWS, 1.0 / ior); - float NoR = dot(normalWS, R); // Optical depth within the thin plane - float dist = thickness / max(-NoR, 0.001); + float dist = thickness / max(dot(-normalWS, R), 0.001); ray.dist = dist; ray.position = vec3(positionWS + R * dist); From 76b40b1231af8c5f3e027f96e4b04a10e4855f91 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 11:53:37 +0800 Subject: [PATCH 10/35] fix: refraction --- .../shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index 0f879be8d0..131efad153 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -34,7 +34,7 @@ void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float // Refracted ray vec3 R = refract(V, normalWS, 1.0 / ior); // Optical depth within the thin plane - float dist = thickness / max(dot(-normalWS, R), 0.001); + float dist = thickness / max(dot(-normalWS, R), 1e-5f); ray.dist = dist; ray.position = vec3(positionWS + R * dist); From 3abe5c182f17ed7021d35940d4f0403929dcde10 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 14:25:44 +0800 Subject: [PATCH 11/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index b31cecca4d..85545c7009 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -316,24 +316,21 @@ export class PBRMaterial extends PBRBaseMaterial { set refractionMode(value: RefractionMode) { if (value !== this._refractionMode) { + const prevState = { + isTransparent: this.isTransparent, + alphaCutoff: this.alphaCutoff, + renderFace: this.renderFace, + blendMode: this.blendMode + }; + if (value) { this.shaderData.enableMacro(PBRMaterial._refractionMacro); - this.renderState.renderQueueType = RenderQueueType.Transparent; - if (this.isTransparent) { - this.renderState.renderQueueType = RenderQueueType.Transparent; - } else { - if (this.alphaCutoff) { - this.renderState.renderQueueType = RenderQueueType.Transparent; - } - } + this.renderState.renderQueueType = + this.isTransparent || this.alphaCutoff ? RenderQueueType.Transparent : RenderQueueType.Opaque; } else { this.shaderData.disableMacro(PBRMaterial._refractionMacro); - this.isTransparent = this.isTransparent; - this.alphaCutoff = this.alphaCutoff; + Object.assign(this, prevState); } - this.renderFace = this.renderFace; - this.blendMode = this.blendMode; - this._refractionMode = value; this.setRefractionMode(value); } From b81bbeb6b10f7d086663c877a481d296289e826a Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 14:30:07 +0800 Subject: [PATCH 12/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 85545c7009..ad7ddf475d 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -325,8 +325,9 @@ export class PBRMaterial extends PBRBaseMaterial { if (value) { this.shaderData.enableMacro(PBRMaterial._refractionMacro); - this.renderState.renderQueueType = - this.isTransparent || this.alphaCutoff ? RenderQueueType.Transparent : RenderQueueType.Opaque; + if (this.isTransparent || this.alphaCutoff) { + this.renderState.renderQueueType = RenderQueueType.Transparent; + } } else { this.shaderData.disableMacro(PBRMaterial._refractionMacro); Object.assign(this, prevState); From bcc9dafc614f7850da75b8ce085a7dffda61af27 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 15:35:49 +0800 Subject: [PATCH 13/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 23 ++++++++++++------- packages/core/src/material/index.ts | 1 + .../shader-shaderlab/src/shaders/Common.glsl | 4 ++-- .../src/shaders/shadingPBR/BTDF.glsl | 6 ++--- .../src/shaders/shadingPBR/FragmentPBR.glsl | 12 ++++++---- .../shaders/shadingPBR/LightDirectPBR.glsl | 2 +- .../src/shaders/shadingPBR/Refraction.glsl | 18 +++++++-------- 7 files changed, 39 insertions(+), 27 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index ad7ddf475d..1b9636cece 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -39,6 +39,7 @@ export class PBRMaterial extends PBRBaseMaterial { protected static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION"); private static _thicknessMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS"); + private _absorptionEnabled = null; private static _absorptionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_ABSORPTION"); private static _thicknessTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS_TEXTURE"); private static _transmissionTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION_TEXTURE"); @@ -320,11 +321,13 @@ export class PBRMaterial extends PBRBaseMaterial { isTransparent: this.isTransparent, alphaCutoff: this.alphaCutoff, renderFace: this.renderFace, - blendMode: this.blendMode + blendMode: this.blendMode, + renderQueueType: this.renderState.renderQueueType }; if (value) { this.shaderData.enableMacro(PBRMaterial._refractionMacro); + if (this.isTransparent || this.alphaCutoff) { this.renderState.renderQueueType = RenderQueueType.Transparent; } @@ -367,13 +370,13 @@ export class PBRMaterial extends PBRBaseMaterial { } set transmission(value: number) { - value = Math.max(0, Math.min(1, value)); - this.shaderData.setFloat(PBRMaterial._transmissionProp, value); + value = MathUtil.clamp(value, 0, 1); if (!!this.shaderData.getFloat(PBRMaterial._transmissionProp) !== !!value) { this.shaderData.enableMacro(PBRMaterial._transmissionMacro); } else { this.shaderData.disableMacro(PBRMaterial._transmissionMacro); } + this.shaderData.setFloat(PBRMaterial._transmissionProp, value); } /** @@ -431,12 +434,12 @@ export class PBRMaterial extends PBRBaseMaterial { set thickness(value: number) { value = Math.max(0, value); - this.shaderData.setFloat(PBRMaterial._thicknessProp, value); if (!!this.shaderData.getFloat(PBRMaterial._thicknessProp) !== !!value) { this.shaderData.enableMacro(PBRMaterial._thicknessMacro); } else { this.shaderData.disableMacro(PBRMaterial._thicknessMacro); } + this.shaderData.setFloat(PBRMaterial._thicknessProp, value); } /** @@ -471,6 +474,7 @@ export class PBRMaterial extends PBRBaseMaterial { const sheenColor = new Color(0, 0, 0); shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); this.refractionMode = RefractionMode.None; + shaderData.setFloat(PBRMaterial._transmissionProp, 0); shaderData.setFloat(PBRMaterial._thicknessProp, 0); shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); const attenuationColor = new Color(1, 1, 1); @@ -497,10 +501,13 @@ export class PBRMaterial extends PBRBaseMaterial { // @ts-ignore attenuationColor._onValueChanged = () => { const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 1; - if (enableAbsorption) { - this.shaderData.enableMacro(PBRMaterial._absorptionMacro); - } else { - this.shaderData.disableMacro(PBRMaterial._absorptionMacro); + if (enableAbsorption !== this._absorptionEnabled) { + this._absorptionEnabled = enableAbsorption; + if (enableAbsorption) { + this.shaderData.enableMacro(PBRMaterial._absorptionMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._absorptionMacro); + } } }; } diff --git a/packages/core/src/material/index.ts b/packages/core/src/material/index.ts index 2422f9867d..5fbf3c859b 100644 --- a/packages/core/src/material/index.ts +++ b/packages/core/src/material/index.ts @@ -8,3 +8,4 @@ export { PBRBaseMaterial } from "./PBRBaseMaterial"; export { PBRMaterial } from "./PBRMaterial"; export { PBRSpecularMaterial } from "./PBRSpecularMaterial"; export { UnlitMaterial } from "./UnlitMaterial"; +export { RefractionMode } from "./enums/Refraction"; diff --git a/packages/shader-shaderlab/src/shaders/Common.glsl b/packages/shader-shaderlab/src/shaders/Common.glsl index 83ff6b3dad..9388552531 100644 --- a/packages/shader-shaderlab/src/shaders/Common.glsl +++ b/packages/shader-shaderlab/src/shaders/Common.glsl @@ -5,7 +5,7 @@ #define RECIPROCAL_PI 0.31830988618 #define EPSILON 1e-6 #define LOG2 1.442695 -#define FLT_MIN 1.175494351e-38 // Minimum normalized positive floating-point number +#define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats #define saturate( a ) clamp( a, 0.0, 1.0 ) @@ -100,7 +100,7 @@ float remapDepthBufferLinear01(float z){ vec3 safeNormalize(vec3 inVec) { - float dp3 = max(float(FLT_MIN), dot(inVec, inVec)); + float dp3 = max(float(HALF_MIN), dot(inVec, inVec)); return inVec * inversesqrt(dp3); } diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 69f669aa04..32b3943cfe 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -12,10 +12,10 @@ #elif defined(REFRACTION_PLANE) RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #elif defined(REFRACTION_THIN) - RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, 0.005, ray); + RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #endif //TODO: support cubemap refraction. - vec3 refractedRayExit = ray.position; + vec3 refractedRayExit = ray.positionExit; // We calculate the screen space position of the refracted point vec4 samplingPositionNDC = camera_ProjMat * camera_ViewMat * vec4( refractedRayExit, 1.0 ); @@ -25,7 +25,7 @@ #ifdef MATERIAL_HAS_ABSORPTION vec3 absorptionCoefficient = -log(clamp(surfaceData.attenuationColor, 1e-5f, 1.0f)) / max(1e-5f, surfaceData.attenuationDistance); #ifdef MATERIAL_HAS_THICKNESS - vec3 transmittance = min(vec3(1.0), exp(-absorptionCoefficient * ray.dist)); + vec3 transmittance = min(vec3(1.0), exp(-absorptionCoefficient * ray.transmissionLength)); #else vec3 transmittance = 1.0 - absorptionCoefficient; #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 19355133a8..7ac998e7b4 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -67,7 +67,7 @@ float material_OcclusionTextureCoord; float material_AttenuationDistance; #ifdef MATERIAL_HAS_TRANSMISSION - float material_Transmission; + float material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE sampler2D material_TransmissionTexture; #endif @@ -186,6 +186,8 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ surfaceData.metallic = metallic; surfaceData.roughness = roughness; surfaceData.f0 = f0; + surfaceData.IOR = material_IOR; + #ifdef MATERIAL_IS_TRANSPARENT surfaceData.opacity = baseColor.a; @@ -313,8 +315,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #ifdef MATERIAL_ENABLE_SS_REFRACTION surfaceData.attenuationColor = material_AttenuationColor; - surfaceData.IOR = material_IOR; - surfaceData.attenuationDistance = max(material_AttenuationDistance, 0.001); + surfaceData.attenuationDistance = material_AttenuationDistance; #ifdef MATERIAL_HAS_TRANSMISSION surfaceData.transmission = material_Transmission; @@ -326,10 +327,13 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_HAS_THICKNESS - surfaceData.thickness = max(material_Thickness, 0.0); + surfaceData.thickness = max(material_Thickness, 0.0001); #ifdef MATERIAL_HAS_THICKNESS_TEXTURE surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; #endif + #if defined(REFRACTION_THIN) + surfaceData.thickness = 0.005; + #endif #endif #endif // AO diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl index f2191d3bb5..8eee34349d 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl @@ -38,7 +38,7 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat // Specular Lobe FUNCTION_SPECULAR_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, specularColor); - #ifdef MATERIAL_ENABLE_SS_REFRACTION + #if defined( MATERIAL_ENABLE_SS_REFRACTION ) && defined( MATERIAL_HAS_TRANSMISSION ) diffuseColor *= (1.0 - surfaceData.transmission); #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index 131efad153..f92380c868 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -4,9 +4,9 @@ #ifdef MATERIAL_ENABLE_SS_REFRACTION struct RefractionModelResult{ - float dist; // length of the transmission during refraction through the shape - vec3 position; // out ray position - vec3 direction; // out ray direction + float transmissionLength; // length of the transmission during refraction through the shape + vec3 positionExit; // out ray position + vec3 directionExit; // out ray direction }; //https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html @@ -25,9 +25,9 @@ struct RefractionModelResult{ // Out refracted ray vec3 R2 = refract(R1, N1, ior); - ray.dist = dist; - ray.position = P1; - ray.direction = R2; + ray.transmissionLength = dist; + ray.positionExit = P1; + ray.directionExit = R2; } void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ @@ -36,9 +36,9 @@ void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float // Optical depth within the thin plane float dist = thickness / max(dot(-normalWS, R), 1e-5f); - ray.dist = dist; - ray.position = vec3(positionWS + R * dist); - ray.direction = V; + ray.transmissionLength = dist; + ray.positionExit = vec3(positionWS + R * dist); + ray.directionExit = V; } #endif From b9b95588653940a3a93f28f13828ba1a4554e8c5 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 15:53:19 +0800 Subject: [PATCH 14/35] fix: refraction --- .../src/shaders/shadingPBR/BRDF.glsl | 3 +-- .../src/shaders/shadingPBR/BTDF.glsl | 5 ++--- .../src/shaders/shadingPBR/FragmentPBR.glsl | 18 +++++++++--------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl index 0244ca7d68..50ae62c19b 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl @@ -66,8 +66,7 @@ struct SurfaceData{ #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - vec3 attenuationColor; - float attenuationDistance; + vec3 absorptionCoefficient; float transmission; float thickness; #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 32b3943cfe..8d23811dc9 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -23,11 +23,10 @@ // Absorption coefficient from Disney: http://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf #ifdef MATERIAL_HAS_ABSORPTION - vec3 absorptionCoefficient = -log(clamp(surfaceData.attenuationColor, 1e-5f, 1.0f)) / max(1e-5f, surfaceData.attenuationDistance); #ifdef MATERIAL_HAS_THICKNESS - vec3 transmittance = min(vec3(1.0), exp(-absorptionCoefficient * ray.transmissionLength)); + vec3 transmittance = min(vec3(1.0), exp(-surfaceData.absorptionCoefficient * ray.transmissionLength)); #else - vec3 transmittance = 1.0 - absorptionCoefficient; + vec3 transmittance = 1.0 - surfaceData.absorptionCoefficient; #endif #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 7ac998e7b4..df8554379e 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -314,9 +314,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - surfaceData.attenuationColor = material_AttenuationColor; - surfaceData.attenuationDistance = material_AttenuationDistance; - + surfaceData.absorptionCoefficient = -log(clamp(material_AttenuationColor, 1e-5f, 1.0f)) / max(1e-5f, material_AttenuationDistance); #ifdef MATERIAL_HAS_TRANSMISSION surfaceData.transmission = material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE @@ -327,14 +325,16 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_HAS_THICKNESS - surfaceData.thickness = max(material_Thickness, 0.0001); - #ifdef MATERIAL_HAS_THICKNESS_TEXTURE - surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; - #endif #if defined(REFRACTION_THIN) surfaceData.thickness = 0.005; - #endif - #endif + #else + surfaceData.thickness = max(material_Thickness, 0.0001); + #ifdef MATERIAL_HAS_THICKNESS_TEXTURE + surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; + #endif + #endif + #endif + #endif // AO float diffuseAO = 1.0; From 84e2f0d28fa0306775612e03c5b2c7e8d5c4cf5b Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 16:09:04 +0800 Subject: [PATCH 15/35] fix: refraction mode --- .../loader/src/gltf/extensions/KHR_materials_transmission.ts | 5 ++--- packages/loader/src/gltf/extensions/KHR_materials_volume.ts | 3 ++- .../shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts b/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts index 0bbdf30cb7..babab9ac18 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts @@ -1,15 +1,14 @@ -import { PBRMaterial, Texture2D } from "@galacean/engine-core"; +import { PBRMaterial, Texture2D, RefractionMode } from "@galacean/engine-core"; import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; import { registerGLTFExtension } from "../parser/GLTFParser"; import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext"; import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser"; import { IKHRMaterialsTransmission } from "./GLTFExtensionSchema"; - @registerGLTFExtension("KHR_materials_transmission", GLTFExtensionMode.AdditiveParse) class KHR_materials_transmission extends GLTFExtensionParser { override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsTransmission): void { const { transmissionFactor = 0, transmissionTexture } = schema; - + material.refractionMode = RefractionMode.Plane; material.transmission = transmissionFactor; if (transmissionTexture) { diff --git a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts index 889257c678..a79f0fed8d 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts @@ -1,4 +1,4 @@ -import { PBRMaterial, Texture2D } from "@galacean/engine-core"; +import { PBRMaterial, Texture2D, RefractionMode } from "@galacean/engine-core"; import { Color } from "@galacean/engine-math"; import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; import { registerGLTFExtension } from "../parser/GLTFParser"; @@ -10,6 +10,7 @@ import { IKHRMaterialsVolume } from "./GLTFExtensionSchema"; class KHR_materials_volume extends GLTFExtensionParser { override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsVolume): void { const { thicknessFactor = 0, thicknessTexture, attenuationDistance = Infinity, attenuationColor } = schema; + material.refractionMode = RefractionMode.Plane; material.thickness = thicknessFactor; material.attenuationDistance = attenuationDistance; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index df8554379e..321be78edf 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -334,8 +334,8 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #endif #endif - #endif + // AO float diffuseAO = 1.0; float specularAO = 1.0; From e977cbc97f03bf085ee84b4b39a5a4ed7c5cf5c5 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 16:10:19 +0800 Subject: [PATCH 16/35] fix: refraction mode --- packages/loader/src/gltf/extensions/KHR_materials_volume.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts index a79f0fed8d..a91e164f8b 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts @@ -11,7 +11,6 @@ class KHR_materials_volume extends GLTFExtensionParser { override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsVolume): void { const { thicknessFactor = 0, thicknessTexture, attenuationDistance = Infinity, attenuationColor } = schema; material.refractionMode = RefractionMode.Plane; - material.thickness = thicknessFactor; material.attenuationDistance = attenuationDistance; From 4040c26b49c56b54dc200d07e7f0456011f7788e Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 19:21:14 +0800 Subject: [PATCH 17/35] fix: refraction shader --- .../shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl | 5 +++-- .../shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl | 6 +++--- .../src/shaders/shadingPBR/LightIndirectPBR.glsl | 4 ++-- .../src/shaders/shadingPBR/Refraction.glsl | 8 ++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl index 50ae62c19b..4c318fd502 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl @@ -77,6 +77,7 @@ struct BRDFData{ vec3 diffuseColor; vec3 specularColor; float roughness; + vec3 specularDFG; #ifdef MATERIAL_ENABLE_CLEAR_COAT vec3 clearCoatSpecularColor; @@ -393,9 +394,9 @@ void initBRDFData(SurfaceData surfaceData, out BRDFData brdfData){ brdfData.diffuseColor = albedoColor * ( 1.0 - specularStrength ); brdfData.specularColor = specularColor; #endif - brdfData.roughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(roughness + getAARoughnessFactor(surfaceData.normal), 1.0)); - + brdfData.specularDFG = envBRDFApprox(brdfData.specularColor, brdfData.roughness, surfaceData.dotNV); + #ifdef MATERIAL_ENABLE_CLEAR_COAT brdfData.clearCoatRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.clearCoatRoughness + getAARoughnessFactor(surfaceData.clearCoatNormal), 1.0)); brdfData.clearCoatSpecularColor = vec3(0.04); diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 8d23811dc9..d319571a4b 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -5,7 +5,7 @@ #ifdef MATERIAL_ENABLE_SS_REFRACTION sampler2D camera_OpaqueTexture; - vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData, vec3 specularColor) { + vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData) { RefractionModelResult ray; #if defined(REFRACTION_SPHERE) RefractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); @@ -32,13 +32,13 @@ // Sample the opaque texture to get the transmitted light vec4 getTransmission = texture2D(camera_OpaqueTexture, refractionCoords); - vec3 refractionTransmitted = getTransmission.rgb; refractionTransmitted *= brdfData.diffuseColor; // Use specularFGD as an approximation of the fresnel effect // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf - vec3 specularFGD = envBRDFApprox(specularColor, surfaceData.roughness, surfaceData.dotNV); + vec3 specularFGD = brdfData.specularDFG; + refractionTransmitted *= (1.0 - specularFGD); #ifdef MATERIAL_HAS_ABSORPTION diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index e07f7dee35..73572ba1f6 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -77,7 +77,7 @@ void evaluateSpecularIBL(Varyings varyings, SurfaceData surfaceData, BRDFData br vec3 speculaColor = brdfData.specularColor; #endif - outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * envBRDFApprox(speculaColor, brdfData.roughness, surfaceData.dotNV); + outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * brdfData.specularDFG; } void evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){ @@ -107,7 +107,7 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, FUNCTION_SHEEN_IBL(varyings, surfaceData, brdfData, radianceAttenuation, diffuseColor, specularColor); #ifdef MATERIAL_ENABLE_SS_REFRACTION - vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData, specularColor); + vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData); refractionTransmitted *= surfaceData.transmission; diffuseColor *= (1.0 - surfaceData.transmission); #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index f92380c868..3d5e0c2eac 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -6,7 +6,7 @@ struct RefractionModelResult{ float transmissionLength; // length of the transmission during refraction through the shape vec3 positionExit; // out ray position - vec3 directionExit; // out ray direction + // vec3 directionExit; // out ray direction }; //https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html @@ -23,11 +23,11 @@ struct RefractionModelResult{ // Out normal vec3 N1 = safeNormalize(C - P1); // Out refracted ray - vec3 R2 = refract(R1, N1, ior); + // vec3 R2 = refract(R1, N1, ior); ray.transmissionLength = dist; ray.positionExit = P1; - ray.directionExit = R2; + // ray.directionExit = R2; } void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ @@ -38,7 +38,7 @@ void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float ray.transmissionLength = dist; ray.positionExit = vec3(positionWS + R * dist); - ray.directionExit = V; + // ray.directionExit = V; } #endif From 420566db16006e42ba4714555a56f4ee8e8cc4c5 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 19:49:52 +0800 Subject: [PATCH 18/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 34 ++++++++----------- .../src/shaders/shadingPBR/BTDF.glsl | 6 ++-- .../src/shaders/shadingPBR/FragmentPBR.glsl | 4 +-- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 1b9636cece..621df16770 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -22,24 +22,18 @@ export class PBRMaterial extends PBRBaseMaterial { private static _anisotropyInfoProp = ShaderProperty.getByName("material_AnisotropyInfo"); private static _anisotropyTextureProp = ShaderProperty.getByName("material_AnisotropyTexture"); - private _anisotropyRotation: number = 0; - private static _iridescenceInfoProp = ShaderProperty.getByName("material_IridescenceInfo"); private static _iridescenceThicknessTextureProp = ShaderProperty.getByName("material_IridescenceThicknessTexture"); private static _iridescenceTextureProp = ShaderProperty.getByName("material_IridescenceTexture"); - private _iridescenceRange = new Vector2(100, 400); - private _sheenEnabled = false; private static _sheenColorProp = ShaderProperty.getByName("material_SheenColor"); private static _sheenRoughnessProp = ShaderProperty.getByName("material_SheenRoughness"); private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture"); - protected _refractionMode: RefractionMode; - protected static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); + private static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION"); private static _thicknessMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS"); - private _absorptionEnabled = null; private static _absorptionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_ABSORPTION"); private static _thicknessTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS_TEXTURE"); private static _transmissionTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION_TEXTURE"); @@ -49,6 +43,13 @@ export class PBRMaterial extends PBRBaseMaterial { private static _attenuationDistanceProp = ShaderProperty.getByName("material_AttenuationDistance"); private static _thicknessProp = ShaderProperty.getByName("material_Thickness"); private static _thicknessTextureProp = ShaderProperty.getByName("material_ThicknessTexture"); + + protected _refractionMode: RefractionMode; + private _anisotropyRotation: number = 0; + private _iridescenceRange = new Vector2(100, 400); + private _sheenEnabled = false; + private _absorptionEnabled = null; + /** * Index Of Refraction. * @defaultValue `1.5` @@ -326,13 +327,10 @@ export class PBRMaterial extends PBRBaseMaterial { }; if (value) { - this.shaderData.enableMacro(PBRMaterial._refractionMacro); - if (this.isTransparent || this.alphaCutoff) { this.renderState.renderQueueType = RenderQueueType.Transparent; } } else { - this.shaderData.disableMacro(PBRMaterial._refractionMacro); Object.assign(this, prevState); } this._refractionMode = value; @@ -341,22 +339,21 @@ export class PBRMaterial extends PBRBaseMaterial { } private setRefractionMode(refractionMode: RefractionMode): void { - this.shaderData.disableMacro("REFRACTION_SPHERE"); - this.shaderData.disableMacro("REFRACTION_PLANE"); - this.shaderData.disableMacro("REFRACTION_THIN"); - switch (refractionMode) { case RefractionMode.None: this.shaderData.disableMacro(PBRMaterial._refractionMacro); break; case RefractionMode.Sphere: - this.shaderData.enableMacro("REFRACTION_SPHERE"); + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.shaderData.enableMacro("REFRACTION_MODE", "SPHERE"); break; case RefractionMode.Plane: - this.shaderData.enableMacro("REFRACTION_PLANE"); + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.shaderData.enableMacro("REFRACTION_MODE", "PLANE"); break; case RefractionMode.Thin: - this.shaderData.enableMacro("REFRACTION_THIN"); + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.shaderData.enableMacro("REFRACTION_MODE", "THIN"); break; } } @@ -473,7 +470,6 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); const sheenColor = new Color(0, 0, 0); shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); - this.refractionMode = RefractionMode.None; shaderData.setFloat(PBRMaterial._transmissionProp, 0); shaderData.setFloat(PBRMaterial._thicknessProp, 0); shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); @@ -500,7 +496,7 @@ export class PBRMaterial extends PBRBaseMaterial { }; // @ts-ignore attenuationColor._onValueChanged = () => { - const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 1; + const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 0; if (enableAbsorption !== this._absorptionEnabled) { this._absorptionEnabled = enableAbsorption; if (enableAbsorption) { diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index d319571a4b..2b6c366823 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -7,11 +7,11 @@ sampler2D camera_OpaqueTexture; vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData) { RefractionModelResult ray; - #if defined(REFRACTION_SPHERE) + #if REFRACTION_MODE == SPHERE RefractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - #elif defined(REFRACTION_PLANE) + #elif REFRACTION_MODE == PLANE RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - #elif defined(REFRACTION_THIN) + #elif REFRACTION_MODE == THIN RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #endif //TODO: support cubemap refraction. diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 321be78edf..3ac731e2d9 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -325,7 +325,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_HAS_THICKNESS - #if defined(REFRACTION_THIN) + #if REFRACTION_MODE == THIN surfaceData.thickness = 0.005; #else surfaceData.thickness = max(material_Thickness, 0.0001); @@ -335,7 +335,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #endif #endif - + // AO float diffuseAO = 1.0; float specularAO = 1.0; From 4a3ce3eab7fdb93094170237a04f8b28672dc8a6 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 20:08:14 +0800 Subject: [PATCH 19/35] fix: refraction mode --- packages/core/src/material/PBRMaterial.ts | 69 ++++++++++++----------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 621df16770..311fa63e43 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -6,8 +6,6 @@ import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; import { RefractionMode } from "./enums/Refraction"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; -import { BlendMode } from "./enums/BlendMode"; -import { BaseMaterial } from "./BaseMaterial"; /** * PBR (Metallic-Roughness Workflow) Material. @@ -49,6 +47,7 @@ export class PBRMaterial extends PBRBaseMaterial { private _iridescenceRange = new Vector2(100, 400); private _sheenEnabled = false; private _absorptionEnabled = null; + private _lastRenderQueueType: RenderQueueType; /** * Index Of Refraction. @@ -318,43 +317,29 @@ export class PBRMaterial extends PBRBaseMaterial { set refractionMode(value: RefractionMode) { if (value !== this._refractionMode) { - const prevState = { - isTransparent: this.isTransparent, - alphaCutoff: this.alphaCutoff, - renderFace: this.renderFace, - blendMode: this.blendMode, - renderQueueType: this.renderState.renderQueueType - }; - if (value) { - if (this.isTransparent || this.alphaCutoff) { - this.renderState.renderQueueType = RenderQueueType.Transparent; - } + this.renderState.renderQueueType = RenderQueueType.Transparent; } else { - Object.assign(this, prevState); + this.renderState.renderQueueType = this._lastRenderQueueType ?? RenderQueueType.Opaque; } this._refractionMode = value; - this.setRefractionMode(value); + this._setRefractionMode(value); } } - private setRefractionMode(refractionMode: RefractionMode): void { - switch (refractionMode) { - case RefractionMode.None: - this.shaderData.disableMacro(PBRMaterial._refractionMacro); - break; - case RefractionMode.Sphere: - this.shaderData.enableMacro(PBRMaterial._refractionMacro); - this.shaderData.enableMacro("REFRACTION_MODE", "SPHERE"); - break; - case RefractionMode.Plane: - this.shaderData.enableMacro(PBRMaterial._refractionMacro); - this.shaderData.enableMacro("REFRACTION_MODE", "PLANE"); - break; - case RefractionMode.Thin: - this.shaderData.enableMacro(PBRMaterial._refractionMacro); - this.shaderData.enableMacro("REFRACTION_MODE", "THIN"); - break; + override set isTransparent(value: boolean) { + super.isTransparent = value; + this._lastRenderQueueType = this.renderState.renderQueueType; + if (this.refractionMode !== RefractionMode.None) { + this.renderState.renderQueueType = RenderQueueType.Transparent; + } + } + + override set alphaCutoff(value: number) { + super.alphaCutoff = value; + this._lastRenderQueueType = this.renderState.renderQueueType; + if (this.refractionMode !== RefractionMode.None) { + this.renderState.renderQueueType = RenderQueueType.Transparent; } } @@ -516,4 +501,24 @@ export class PBRMaterial extends PBRBaseMaterial { this.cloneTo(dest); return dest; } + + private _setRefractionMode(refractionMode: RefractionMode): void { + switch (refractionMode) { + case RefractionMode.None: + this.shaderData.disableMacro(PBRMaterial._refractionMacro); + break; + case RefractionMode.Sphere: + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.shaderData.enableMacro("REFRACTION_MODE", "SPHERE"); + break; + case RefractionMode.Plane: + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.shaderData.enableMacro("REFRACTION_MODE", "PLANE"); + break; + case RefractionMode.Thin: + this.shaderData.enableMacro(PBRMaterial._refractionMacro); + this.shaderData.enableMacro("REFRACTION_MODE", "THIN"); + break; + } + } } From 6b19600c5f773f020893d19c06328fb4ba5a74d3 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 20:12:08 +0800 Subject: [PATCH 20/35] fix: refraction --- packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl | 6 +++--- .../src/shaders/shadingPBR/FragmentPBR.glsl | 1 + .../shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 2b6c366823..8f56c7d523 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -8,11 +8,11 @@ vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData) { RefractionModelResult ray; #if REFRACTION_MODE == SPHERE - RefractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + refractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #elif REFRACTION_MODE == PLANE - RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #elif REFRACTION_MODE == THIN - RefractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #endif //TODO: support cubemap refraction. vec3 refractedRayExit = ray.positionExit; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 3ac731e2d9..c325e43471 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -326,6 +326,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #ifdef MATERIAL_HAS_THICKNESS #if REFRACTION_MODE == THIN + //https://zh.wikipedia.org/wiki/%E8%96%84%E8%86%9C%E5%85%89%E5%AD%A6 surfaceData.thickness = 0.005; #else surfaceData.thickness = max(material_Thickness, 0.0001); diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index 3d5e0c2eac..97f18fda4e 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -10,7 +10,7 @@ struct RefractionModelResult{ }; //https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html - void RefractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ + void refractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ // Refracted ray vec3 R1 = refract(V, normalWS, 1.0 / ior); // Center of the tangent sphere @@ -30,7 +30,7 @@ struct RefractionModelResult{ // ray.directionExit = R2; } -void RefractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ +void refractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ // Refracted ray vec3 R = refract(V, normalWS, 1.0 / ior); // Optical depth within the thin plane From 129ac02feb47af32f672da8f8b8809c0eb3cb7e8 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 20:34:59 +0800 Subject: [PATCH 21/35] fix: refraction value --- packages/core/src/material/PBRMaterial.ts | 19 ++++++++++++------- .../shader-shaderlab/src/shaders/Common.glsl | 1 + .../src/shaders/shadingPBR/BTDF.glsl | 4 ++-- .../src/shaders/shadingPBR/FragmentPBR.glsl | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 311fa63e43..e4e780e473 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -46,7 +46,7 @@ export class PBRMaterial extends PBRBaseMaterial { private _anisotropyRotation: number = 0; private _iridescenceRange = new Vector2(100, 400); private _sheenEnabled = false; - private _absorptionEnabled = null; + private _absorptionEnabled = true; private _lastRenderQueueType: RenderQueueType; /** @@ -354,9 +354,11 @@ export class PBRMaterial extends PBRBaseMaterial { set transmission(value: number) { value = MathUtil.clamp(value, 0, 1); if (!!this.shaderData.getFloat(PBRMaterial._transmissionProp) !== !!value) { - this.shaderData.enableMacro(PBRMaterial._transmissionMacro); - } else { - this.shaderData.disableMacro(PBRMaterial._transmissionMacro); + if (value > 0) { + this.shaderData.enableMacro(PBRMaterial._transmissionMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._transmissionMacro); + } } this.shaderData.setFloat(PBRMaterial._transmissionProp, value); } @@ -417,9 +419,11 @@ export class PBRMaterial extends PBRBaseMaterial { set thickness(value: number) { value = Math.max(0, value); if (!!this.shaderData.getFloat(PBRMaterial._thicknessProp) !== !!value) { - this.shaderData.enableMacro(PBRMaterial._thicknessMacro); - } else { - this.shaderData.disableMacro(PBRMaterial._thicknessMacro); + if (value > 0) { + this.shaderData.enableMacro(PBRMaterial._thicknessMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._thicknessMacro); + } } this.shaderData.setFloat(PBRMaterial._thicknessProp, value); } @@ -460,6 +464,7 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); const attenuationColor = new Color(1, 1, 1); shaderData.setColor(PBRMaterial._attenuationColorProp, attenuationColor); + shaderData.enableMacro(PBRMaterial._absorptionMacro); // @ts-ignore this._iridescenceRange._onValueChanged = () => { diff --git a/packages/shader-shaderlab/src/shaders/Common.glsl b/packages/shader-shaderlab/src/shaders/Common.glsl index 9388552531..ed43818846 100644 --- a/packages/shader-shaderlab/src/shaders/Common.glsl +++ b/packages/shader-shaderlab/src/shaders/Common.glsl @@ -6,6 +6,7 @@ #define EPSILON 1e-6 #define LOG2 1.442695 #define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats +#define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f) #define saturate( a ) clamp( a, 0.0, 1.0 ) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 8f56c7d523..add146ca97 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -37,9 +37,9 @@ // Use specularFGD as an approximation of the fresnel effect // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf - vec3 specularFGD = brdfData.specularDFG; + vec3 specularDFG = brdfData.specularDFG; - refractionTransmitted *= (1.0 - specularFGD); + refractionTransmitted *= (1.0 - specularDFG); #ifdef MATERIAL_HAS_ABSORPTION refractionTransmitted *= transmittance; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index c325e43471..0051ab0e42 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -314,7 +314,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - surfaceData.absorptionCoefficient = -log(clamp(material_AttenuationColor, 1e-5f, 1.0f)) / max(1e-5f, material_AttenuationDistance); + surfaceData.absorptionCoefficient = -log(material_AttenuationColor + HALF_EPS) / max(HALF_EPS, material_AttenuationDistance); #ifdef MATERIAL_HAS_TRANSMISSION surfaceData.transmission = material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE From 1ff952df57795950d3ba100da19f3d5d185552f7 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 24 Dec 2024 20:43:06 +0800 Subject: [PATCH 22/35] fix: refraction --- packages/core/src/material/PBRMaterial.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index e4e780e473..fbd6c8f53c 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -42,12 +42,12 @@ export class PBRMaterial extends PBRBaseMaterial { private static _thicknessProp = ShaderProperty.getByName("material_Thickness"); private static _thicknessTextureProp = ShaderProperty.getByName("material_ThicknessTexture"); - protected _refractionMode: RefractionMode; + private _refractionMode: RefractionMode; private _anisotropyRotation: number = 0; private _iridescenceRange = new Vector2(100, 400); private _sheenEnabled = false; private _absorptionEnabled = true; - private _lastRenderQueueType: RenderQueueType; + private _lastRenderQueueType = RenderQueueType.Opaque; /** * Index Of Refraction. @@ -320,7 +320,7 @@ export class PBRMaterial extends PBRBaseMaterial { if (value) { this.renderState.renderQueueType = RenderQueueType.Transparent; } else { - this.renderState.renderQueueType = this._lastRenderQueueType ?? RenderQueueType.Opaque; + this.renderState.renderQueueType = this._lastRenderQueueType; } this._refractionMode = value; this._setRefractionMode(value); From cf77ec4d9d29a6d0276b47727dfc3c1d13096e38 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Wed, 25 Dec 2024 22:28:15 +0800 Subject: [PATCH 23/35] feat: transmission --- .../shader-shaderlab/src/shaders/Common.glsl | 12 +++--- packages/shader-shaderlab/src/shaders/PBR.gs | 8 ++-- .../src/shaders/shadingPBR/BTDF.glsl | 35 ++++++++-------- .../src/shaders/shadingPBR/FragmentPBR.glsl | 40 +++++++++---------- .../src/shaders/shadingPBR/Refraction.glsl | 38 +++++++++--------- 5 files changed, 68 insertions(+), 65 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/Common.glsl b/packages/shader-shaderlab/src/shaders/Common.glsl index ed43818846..b245a1ca6c 100644 --- a/packages/shader-shaderlab/src/shaders/Common.glsl +++ b/packages/shader-shaderlab/src/shaders/Common.glsl @@ -6,7 +6,7 @@ #define EPSILON 1e-6 #define LOG2 1.442695 #define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats -#define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f) +// #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f) #define saturate( a ) clamp( a, 0.0, 1.0 ) @@ -99,10 +99,10 @@ float remapDepthBufferLinear01(float z){ #define INVERSE_MAT(mat) inverseMat(mat) #endif -vec3 safeNormalize(vec3 inVec) -{ - float dp3 = max(float(HALF_MIN), dot(inVec, inVec)); - return inVec * inversesqrt(dp3); -} +// vec3 safeNormalize(vec3 inVec) +// { +// float dp3 = max(float(HALF_MIN), dot(inVec, inVec)); +// return inVec * inversesqrt(dp3); +// } #endif \ No newline at end of file diff --git a/packages/shader-shaderlab/src/shaders/PBR.gs b/packages/shader-shaderlab/src/shaders/PBR.gs index 2ab62f21dc..e56a04d517 100644 --- a/packages/shader-shaderlab/src/shaders/PBR.gs +++ b/packages/shader-shaderlab/src/shaders/PBR.gs @@ -56,12 +56,12 @@ Shader "PBR.gs" { } Header("Refraction"){ - material_AttenuationColor("AttenuationColor", Color ) = (1, 1, 1, 1); - material_AttenuationDistance("AttenuationDistance", Range(0, 1, 0.01)) = 0; + // material_AttenuationColor("AttenuationColor", Color ) = (1, 1, 1, 1); + // material_AttenuationDistance("AttenuationDistance", Range(0, 1, 0.01)) = 0; material_Transmission("Transmission", Range(0, 1, 0.01)) = 0; - material_Thickness("Thickness", Range(0, 5, 0.01)) = 0; + // material_Thickness("Thickness", Range(0, 5, 0.01)) = 0; material_TransmissionTexture("TransmissionTexture", Texture2D); - material_ThicknessTexture("ThicknessTexture", Texture2D); + // material_ThicknessTexture("ThicknessTexture", Texture2D); } Header("Common") { diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index add146ca97..5859ede22e 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -7,11 +7,14 @@ sampler2D camera_OpaqueTexture; vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData) { RefractionModelResult ray; - #if REFRACTION_MODE == SPHERE - refractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - #elif REFRACTION_MODE == PLANE - refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - #elif REFRACTION_MODE == THIN + // #if REFRACTION_MODE == SPHERE + // refractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + // #elif REFRACTION_MODE == PLANE + // refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + // #elif REFRACTION_MODE == THIN + // refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + // #endif + #if REFRACTION_MODE == THIN refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); #endif //TODO: support cubemap refraction. @@ -19,16 +22,16 @@ // We calculate the screen space position of the refracted point vec4 samplingPositionNDC = camera_ProjMat * camera_ViewMat * vec4( refractedRayExit, 1.0 ); - vec2 refractionCoords = (samplingPositionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5; + vec2 refractionCoords = (samplingPositpbionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5; // Absorption coefficient from Disney: http://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf - #ifdef MATERIAL_HAS_ABSORPTION - #ifdef MATERIAL_HAS_THICKNESS - vec3 transmittance = min(vec3(1.0), exp(-surfaceData.absorptionCoefficient * ray.transmissionLength)); - #else - vec3 transmittance = 1.0 - surfaceData.absorptionCoefficient; - #endif - #endif + // #ifdef MATERIAL_HAS_ABSORPTION + // #ifdef MATERIAL_HAS_THICKNESS + // vec3 transmittance = min(vec3(1.0), exp(-surfaceData.absorptionCoefficient * ray.transmissionLength)); + // #else + // vec3 transmittance = 1.0 - surfaceData.absorptionCoefficient; + // #endif + // #endif // Sample the opaque texture to get the transmitted light vec4 getTransmission = texture2D(camera_OpaqueTexture, refractionCoords); @@ -41,9 +44,9 @@ refractionTransmitted *= (1.0 - specularDFG); - #ifdef MATERIAL_HAS_ABSORPTION - refractionTransmitted *= transmittance; - #endif + // #ifdef MATERIAL_HAS_ABSORPTION + // refractionTransmitted *= transmittance; + // #endif return refractionTransmitted; } diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 0051ab0e42..189e3c23cd 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -63,8 +63,8 @@ float material_OcclusionTextureCoord; #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - vec3 material_AttenuationColor; - float material_AttenuationDistance; + // vec3 material_AttenuationColor; + // float material_AttenuationDistance; #ifdef MATERIAL_HAS_TRANSMISSION float material_Transmission; @@ -73,12 +73,12 @@ float material_OcclusionTextureCoord; #endif #endif - #ifdef MATERIAL_HAS_THICKNESS - float material_Thickness; - #ifdef MATERIAL_HAS_THICKNESS_TEXTURE - sampler2D material_ThicknessTexture; - #endif - #endif + // #ifdef MATERIAL_HAS_THICKNESS + // float material_Thickness; + // #ifdef MATERIAL_HAS_THICKNESS_TEXTURE + // sampler2D material_ThicknessTexture; + // #endif + // #endif #endif // Texture @@ -314,7 +314,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - surfaceData.absorptionCoefficient = -log(material_AttenuationColor + HALF_EPS) / max(HALF_EPS, material_AttenuationDistance); + // surfaceData.absorptionCoefficient = -log(material_AttenuationColor + HALF_EPS) / max(HALF_EPS, material_AttenuationDistance); #ifdef MATERIAL_HAS_TRANSMISSION surfaceData.transmission = material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE @@ -324,17 +324,17 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ surfaceData.transmission = 1.0; #endif - #ifdef MATERIAL_HAS_THICKNESS - #if REFRACTION_MODE == THIN - //https://zh.wikipedia.org/wiki/%E8%96%84%E8%86%9C%E5%85%89%E5%AD%A6 - surfaceData.thickness = 0.005; - #else - surfaceData.thickness = max(material_Thickness, 0.0001); - #ifdef MATERIAL_HAS_THICKNESS_TEXTURE - surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; - #endif - #endif - #endif + // #ifdef MATERIAL_HAS_THICKNESS + // #if REFRACTION_MODE == THIN + // //https://zh.wikipedia.org/wiki/%E8%96%84%E8%86%9C%E5%85%89%E5%AD%A6 + // surfaceData.thickness = 0.005; + // #else + // surfaceData.thickness = max(material_Thickness, 0.0001); + // #ifdef MATERIAL_HAS_THICKNESS_TEXTURE + // surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; + // #endif + // #endif + // #endif #endif // AO diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index 97f18fda4e..408427a6bf 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -10,25 +10,25 @@ struct RefractionModelResult{ }; //https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html - void refractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ - // Refracted ray - vec3 R1 = refract(V, normalWS, 1.0 / ior); - // Center of the tangent sphere - vec3 C = positionWS - normalWS * thickness * 0.5; - - // Second refraction (tangent sphere out) - float dist = dot(-normalWS, R1) * thickness; - // Out hit point in the tangent sphere - vec3 P1 = positionWS + R1 * dist; - // Out normal - vec3 N1 = safeNormalize(C - P1); - // Out refracted ray - // vec3 R2 = refract(R1, N1, ior); - - ray.transmissionLength = dist; - ray.positionExit = P1; - // ray.directionExit = R2; -} +// void refractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out refractionModelResult ray){ +// // Refracted ray +// vec3 R1 = refract(V, normalWS, 1.0 / ior); +// // Center of the tangent sphere +// vec3 C = positionWS - normalWS * thickness * 0.5; + +// // Second refraction (tangent sphere out) +// float dist = dot(-normalWS, R1) * thickness; +// // Out hit point in the tangent sphere +// vec3 P1 = positionWS + R1 * dist; +// // Out normal +// vec3 N1 = safeNormalize(C - P1); +// // Out refracted ray +// // vec3 R2 = refract(R1, N1, ior); + +// ray.transmissionLength = dist; +// ray.positionExit = P1; +// // ray.directionExit = R2; +// } void refractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ // Refracted ray From 2764f86462a6126ea5ccfc555ce9b1f7c5639b0d Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Wed, 25 Dec 2024 23:02:27 +0800 Subject: [PATCH 24/35] feat: transmission --- packages/shader-shaderlab/src/shaders/PBR.gs | 4 --- .../src/shaders/shadingPBR/BTDF.glsl | 26 +++---------------- .../src/shaders/shadingPBR/FragmentPBR.glsl | 24 +---------------- .../src/shaders/shadingPBR/Refraction.glsl | 21 --------------- 4 files changed, 4 insertions(+), 71 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/PBR.gs b/packages/shader-shaderlab/src/shaders/PBR.gs index e56a04d517..4cded86dfa 100644 --- a/packages/shader-shaderlab/src/shaders/PBR.gs +++ b/packages/shader-shaderlab/src/shaders/PBR.gs @@ -56,12 +56,8 @@ Shader "PBR.gs" { } Header("Refraction"){ - // material_AttenuationColor("AttenuationColor", Color ) = (1, 1, 1, 1); - // material_AttenuationDistance("AttenuationDistance", Range(0, 1, 0.01)) = 0; material_Transmission("Transmission", Range(0, 1, 0.01)) = 0; - // material_Thickness("Thickness", Range(0, 5, 0.01)) = 0; material_TransmissionTexture("TransmissionTexture", Texture2D); - // material_ThicknessTexture("ThicknessTexture", Texture2D); } Header("Common") { diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 5859ede22e..dea984145e 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -7,31 +7,15 @@ sampler2D camera_OpaqueTexture; vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData) { RefractionModelResult ray; - // #if REFRACTION_MODE == SPHERE - // refractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - // #elif REFRACTION_MODE == PLANE - // refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - // #elif REFRACTION_MODE == THIN - // refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); - // #endif - #if REFRACTION_MODE == THIN - refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray); + #ifdef REFRACTION_MODE + refractionModelBox(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, 0.005, ray); #endif //TODO: support cubemap refraction. vec3 refractedRayExit = ray.positionExit; // We calculate the screen space position of the refracted point vec4 samplingPositionNDC = camera_ProjMat * camera_ViewMat * vec4( refractedRayExit, 1.0 ); - vec2 refractionCoords = (samplingPositpbionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5; - - // Absorption coefficient from Disney: http://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf - // #ifdef MATERIAL_HAS_ABSORPTION - // #ifdef MATERIAL_HAS_THICKNESS - // vec3 transmittance = min(vec3(1.0), exp(-surfaceData.absorptionCoefficient * ray.transmissionLength)); - // #else - // vec3 transmittance = 1.0 - surfaceData.absorptionCoefficient; - // #endif - // #endif + vec2 refractionCoords = (samplingPositionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5; // Sample the opaque texture to get the transmitted light vec4 getTransmission = texture2D(camera_OpaqueTexture, refractionCoords); @@ -43,10 +27,6 @@ vec3 specularDFG = brdfData.specularDFG; refractionTransmitted *= (1.0 - specularDFG); - - // #ifdef MATERIAL_HAS_ABSORPTION - // refractionTransmitted *= transmittance; - // #endif return refractionTransmitted; } diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 189e3c23cd..5174a196b6 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -62,23 +62,13 @@ float material_OcclusionTextureCoord; #endif #endif -#ifdef MATERIAL_ENABLE_SS_REFRACTION - // vec3 material_AttenuationColor; - // float material_AttenuationDistance; - +#ifdef MATERIAL_ENABLE_SS_REFRACTION #ifdef MATERIAL_HAS_TRANSMISSION float material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE sampler2D material_TransmissionTexture; #endif #endif - - // #ifdef MATERIAL_HAS_THICKNESS - // float material_Thickness; - // #ifdef MATERIAL_HAS_THICKNESS_TEXTURE - // sampler2D material_ThicknessTexture; - // #endif - // #endif #endif // Texture @@ -314,7 +304,6 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #ifdef MATERIAL_ENABLE_SS_REFRACTION - // surfaceData.absorptionCoefficient = -log(material_AttenuationColor + HALF_EPS) / max(HALF_EPS, material_AttenuationDistance); #ifdef MATERIAL_HAS_TRANSMISSION surfaceData.transmission = material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE @@ -324,17 +313,6 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ surfaceData.transmission = 1.0; #endif - // #ifdef MATERIAL_HAS_THICKNESS - // #if REFRACTION_MODE == THIN - // //https://zh.wikipedia.org/wiki/%E8%96%84%E8%86%9C%E5%85%89%E5%AD%A6 - // surfaceData.thickness = 0.005; - // #else - // surfaceData.thickness = max(material_Thickness, 0.0001); - // #ifdef MATERIAL_HAS_THICKNESS_TEXTURE - // surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g; - // #endif - // #endif - // #endif #endif // AO diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index 408427a6bf..d357dac234 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -9,27 +9,6 @@ struct RefractionModelResult{ // vec3 directionExit; // out ray direction }; -//https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html -// void refractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out refractionModelResult ray){ -// // Refracted ray -// vec3 R1 = refract(V, normalWS, 1.0 / ior); -// // Center of the tangent sphere -// vec3 C = positionWS - normalWS * thickness * 0.5; - -// // Second refraction (tangent sphere out) -// float dist = dot(-normalWS, R1) * thickness; -// // Out hit point in the tangent sphere -// vec3 P1 = positionWS + R1 * dist; -// // Out normal -// vec3 N1 = safeNormalize(C - P1); -// // Out refracted ray -// // vec3 R2 = refract(R1, N1, ior); - -// ray.transmissionLength = dist; -// ray.positionExit = P1; -// // ray.directionExit = R2; -// } - void refractionModelBox(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){ // Refracted ray vec3 R = refract(V, normalWS, 1.0 / ior); From 141095a1471e3436c27bc9cac7e7ab8baab1d34e Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 17:07:34 +0800 Subject: [PATCH 25/35] fix: transmission name --- packages/core/src/material/PBRMaterial.ts | 2 +- packages/shader-shaderlab/src/shaders/PBR.gs | 2 +- .../shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl | 2 +- .../shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl | 2 +- .../src/shaders/shadingPBR/FragmentPBR.glsl | 11 ++--------- .../src/shaders/shadingPBR/LightDirectPBR.glsl | 2 +- .../src/shaders/shadingPBR/LightIndirectPBR.glsl | 4 ++-- .../src/shaders/shadingPBR/Refraction.glsl | 2 +- 8 files changed, 10 insertions(+), 17 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index fbd6c8f53c..dcb5dd49a2 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -29,7 +29,7 @@ export class PBRMaterial extends PBRBaseMaterial { private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture"); - private static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_SS_REFRACTION"); + private static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_TRANSMISSION"); private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION"); private static _thicknessMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS"); private static _absorptionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_ABSORPTION"); diff --git a/packages/shader-shaderlab/src/shaders/PBR.gs b/packages/shader-shaderlab/src/shaders/PBR.gs index 4cded86dfa..ad6d98fc04 100644 --- a/packages/shader-shaderlab/src/shaders/PBR.gs +++ b/packages/shader-shaderlab/src/shaders/PBR.gs @@ -55,7 +55,7 @@ Shader "PBR.gs" { material_SheenRoughnessTexture("RoughnessTexture", Texture2D); } - Header("Refraction"){ + Header("Transmission"){ material_Transmission("Transmission", Range(0, 1, 0.01)) = 0; material_TransmissionTexture("TransmissionTexture", Texture2D); } diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl index 4c318fd502..53abfee4b2 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl @@ -65,7 +65,7 @@ struct SurfaceData{ vec3 sheenColor; #endif - #ifdef MATERIAL_ENABLE_SS_REFRACTION + #ifdef MATERIAL_ENABLE_TRANSMISSION vec3 absorptionCoefficient; float transmission; float thickness; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index dea984145e..815bc63191 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -3,7 +3,7 @@ #include "Refraction.glsl" -#ifdef MATERIAL_ENABLE_SS_REFRACTION +#ifdef MATERIAL_ENABLE_TRANSMISSION sampler2D camera_OpaqueTexture; vec3 evaluateRefraction(SurfaceData surfaceData, BRDFData brdfData) { RefractionModelResult ray; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl index 5174a196b6..3fbd0b619e 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl @@ -62,13 +62,11 @@ float material_OcclusionTextureCoord; #endif #endif -#ifdef MATERIAL_ENABLE_SS_REFRACTION - #ifdef MATERIAL_HAS_TRANSMISSION +#ifdef MATERIAL_ENABLE_TRANSMISSION float material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE sampler2D material_TransmissionTexture; #endif - #endif #endif // Texture @@ -303,16 +301,11 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){ #endif #endif - #ifdef MATERIAL_ENABLE_SS_REFRACTION - #ifdef MATERIAL_HAS_TRANSMISSION + #ifdef MATERIAL_ENABLE_TRANSMISSION surfaceData.transmission = material_Transmission; #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE surfaceData.transmission *= texture2D(material_TransmissionTexture, uv).r; #endif - #else - surfaceData.transmission = 1.0; - #endif - #endif // AO diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl index 8eee34349d..f6978206c0 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl @@ -38,7 +38,7 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat // Specular Lobe FUNCTION_SPECULAR_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, specularColor); - #if defined( MATERIAL_ENABLE_SS_REFRACTION ) && defined( MATERIAL_HAS_TRANSMISSION ) + #ifdef MATERIAL_ENABLE_TRANSMISSION diffuseColor *= (1.0 - surfaceData.transmission); #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index 73572ba1f6..32c6a6a081 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -106,7 +106,7 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, // IBL sheen FUNCTION_SHEEN_IBL(varyings, surfaceData, brdfData, radianceAttenuation, diffuseColor, specularColor); - #ifdef MATERIAL_ENABLE_SS_REFRACTION + #ifdef MATERIAL_ENABLE_TRANSMISSION vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData); refractionTransmitted *= surfaceData.transmission; diffuseColor *= (1.0 - surfaceData.transmission); @@ -114,7 +114,7 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, color += diffuseColor + specularColor; - #ifdef MATERIAL_ENABLE_SS_REFRACTION + #ifdef MATERIAL_ENABLE_TRANSMISSION color.rgb += refractionTransmitted; #endif diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl index d357dac234..91e3f1ebaf 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/Refraction.glsl @@ -1,7 +1,7 @@ #ifndef REFRACTION_INCLUDED #define REFRACTION_INCLUDED -#ifdef MATERIAL_ENABLE_SS_REFRACTION +#ifdef MATERIAL_ENABLE_TRANSMISSION struct RefractionModelResult{ float transmissionLength; // length of the transmission during refraction through the shape From 36c994c854bdaf0e452c98657ff98146eeba1b0d Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 17:47:41 +0800 Subject: [PATCH 26/35] fix: refraction name --- packages/core/src/material/PBRMaterial.ts | 10 ++-------- packages/core/src/material/enums/Refraction.ts | 2 -- .../src/gltf/extensions/KHR_materials_transmission.ts | 3 +-- .../loader/src/gltf/extensions/KHR_materials_volume.ts | 3 +-- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index dcb5dd49a2..85ff25902b 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -29,8 +29,7 @@ export class PBRMaterial extends PBRBaseMaterial { private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture"); - private static _refractionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_TRANSMISSION"); - private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_TRANSMISSION"); + private static _transmissionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_ENABLE_TRANSMISSION"); private static _thicknessMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS"); private static _absorptionMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_ABSORPTION"); private static _thicknessTextureMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_HAS_THICKNESS_TEXTURE"); @@ -459,6 +458,7 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); const sheenColor = new Color(0, 0, 0); shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); + this.refractionMode = RefractionMode.Plane; shaderData.setFloat(PBRMaterial._transmissionProp, 0); shaderData.setFloat(PBRMaterial._thicknessProp, 0); shaderData.setFloat(PBRMaterial._attenuationDistanceProp, Infinity); @@ -509,19 +509,13 @@ export class PBRMaterial extends PBRBaseMaterial { private _setRefractionMode(refractionMode: RefractionMode): void { switch (refractionMode) { - case RefractionMode.None: - this.shaderData.disableMacro(PBRMaterial._refractionMacro); - break; case RefractionMode.Sphere: - this.shaderData.enableMacro(PBRMaterial._refractionMacro); this.shaderData.enableMacro("REFRACTION_MODE", "SPHERE"); break; case RefractionMode.Plane: - this.shaderData.enableMacro(PBRMaterial._refractionMacro); this.shaderData.enableMacro("REFRACTION_MODE", "PLANE"); break; case RefractionMode.Thin: - this.shaderData.enableMacro(PBRMaterial._refractionMacro); this.shaderData.enableMacro("REFRACTION_MODE", "THIN"); break; } diff --git a/packages/core/src/material/enums/Refraction.ts b/packages/core/src/material/enums/Refraction.ts index bd418b0f41..e043ad6f49 100644 --- a/packages/core/src/material/enums/Refraction.ts +++ b/packages/core/src/material/enums/Refraction.ts @@ -2,8 +2,6 @@ * Refraction mode. */ export enum RefractionMode { - /** No refraction. */ - None, /** Refraction shape is sphere. */ Sphere, /** Refraction shape is plane. */ diff --git a/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts b/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts index babab9ac18..a1eeec8500 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_transmission.ts @@ -1,4 +1,4 @@ -import { PBRMaterial, Texture2D, RefractionMode } from "@galacean/engine-core"; +import { PBRMaterial, Texture2D } from "@galacean/engine-core"; import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; import { registerGLTFExtension } from "../parser/GLTFParser"; import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext"; @@ -8,7 +8,6 @@ import { IKHRMaterialsTransmission } from "./GLTFExtensionSchema"; class KHR_materials_transmission extends GLTFExtensionParser { override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsTransmission): void { const { transmissionFactor = 0, transmissionTexture } = schema; - material.refractionMode = RefractionMode.Plane; material.transmission = transmissionFactor; if (transmissionTexture) { diff --git a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts index a91e164f8b..479358c448 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_volume.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_volume.ts @@ -1,4 +1,4 @@ -import { PBRMaterial, Texture2D, RefractionMode } from "@galacean/engine-core"; +import { PBRMaterial, Texture2D } from "@galacean/engine-core"; import { Color } from "@galacean/engine-math"; import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; import { registerGLTFExtension } from "../parser/GLTFParser"; @@ -10,7 +10,6 @@ import { IKHRMaterialsVolume } from "./GLTFExtensionSchema"; class KHR_materials_volume extends GLTFExtensionParser { override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsVolume): void { const { thicknessFactor = 0, thicknessTexture, attenuationDistance = Infinity, attenuationColor } = schema; - material.refractionMode = RefractionMode.Plane; material.thickness = thicknessFactor; material.attenuationDistance = attenuationDistance; From 2928dcce597be137c0b45cb33f1e290736a491e3 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 19:23:56 +0800 Subject: [PATCH 27/35] fix: refraction mode --- packages/core/src/material/PBRMaterial.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 85ff25902b..a1365cb07c 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -329,7 +329,8 @@ export class PBRMaterial extends PBRBaseMaterial { override set isTransparent(value: boolean) { super.isTransparent = value; this._lastRenderQueueType = this.renderState.renderQueueType; - if (this.refractionMode !== RefractionMode.None) { + if (this.transmission > 0) { + // If transmission enabled, always use transparent queue to ensure get correct opaque texture this.renderState.renderQueueType = RenderQueueType.Transparent; } } @@ -337,7 +338,8 @@ export class PBRMaterial extends PBRBaseMaterial { override set alphaCutoff(value: number) { super.alphaCutoff = value; this._lastRenderQueueType = this.renderState.renderQueueType; - if (this.refractionMode !== RefractionMode.None) { + if (this.transmission > 0) { + // If transmission enabled, always use transparent queue to ensure get correct opaque texture this.renderState.renderQueueType = RenderQueueType.Transparent; } } @@ -355,6 +357,7 @@ export class PBRMaterial extends PBRBaseMaterial { if (!!this.shaderData.getFloat(PBRMaterial._transmissionProp) !== !!value) { if (value > 0) { this.shaderData.enableMacro(PBRMaterial._transmissionMacro); + this.renderState.renderQueueType = RenderQueueType.Transparent; } else { this.shaderData.disableMacro(PBRMaterial._transmissionMacro); } From 26c7fd56bec057db14a4049d5535fbdd5cfb4727 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 19:31:28 +0800 Subject: [PATCH 28/35] fix: refraction mode --- packages/core/src/material/PBRMaterial.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index a1365cb07c..711819d2d3 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -316,11 +316,6 @@ export class PBRMaterial extends PBRBaseMaterial { set refractionMode(value: RefractionMode) { if (value !== this._refractionMode) { - if (value) { - this.renderState.renderQueueType = RenderQueueType.Transparent; - } else { - this.renderState.renderQueueType = this._lastRenderQueueType; - } this._refractionMode = value; this._setRefractionMode(value); } @@ -328,7 +323,6 @@ export class PBRMaterial extends PBRBaseMaterial { override set isTransparent(value: boolean) { super.isTransparent = value; - this._lastRenderQueueType = this.renderState.renderQueueType; if (this.transmission > 0) { // If transmission enabled, always use transparent queue to ensure get correct opaque texture this.renderState.renderQueueType = RenderQueueType.Transparent; @@ -337,7 +331,6 @@ export class PBRMaterial extends PBRBaseMaterial { override set alphaCutoff(value: number) { super.alphaCutoff = value; - this._lastRenderQueueType = this.renderState.renderQueueType; if (this.transmission > 0) { // If transmission enabled, always use transparent queue to ensure get correct opaque texture this.renderState.renderQueueType = RenderQueueType.Transparent; From dd6e0ecd20496cf19ac246f80ebaed90e937211b Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 19:43:25 +0800 Subject: [PATCH 29/35] fix: refraction mode --- packages/core/src/material/PBRMaterial.ts | 67 +++++++++++++---------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 711819d2d3..81a260b945 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -1,11 +1,11 @@ -import { MathUtil, Vector2, Vector3, Vector4, Color } from "@galacean/engine-math"; +import { Color, MathUtil, Vector2, Vector3, Vector4 } from "@galacean/engine-math"; import { Engine } from "../Engine"; import { ShaderMacro, ShaderProperty } from "../shader"; import { Shader } from "../shader/Shader"; +import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; import { RefractionMode } from "./enums/Refraction"; -import { RenderQueueType } from "../shader/enums/RenderQueueType"; /** * PBR (Metallic-Roughness Workflow) Material. @@ -46,7 +46,6 @@ export class PBRMaterial extends PBRBaseMaterial { private _iridescenceRange = new Vector2(100, 400); private _sheenEnabled = false; private _absorptionEnabled = true; - private _lastRenderQueueType = RenderQueueType.Opaque; /** * Index Of Refraction. @@ -463,35 +462,11 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.enableMacro(PBRMaterial._absorptionMacro); // @ts-ignore - this._iridescenceRange._onValueChanged = () => { - const iridescenceInfo = this.shaderData.getVector4(PBRMaterial._iridescenceInfoProp); - iridescenceInfo.z = this._iridescenceRange.x; - iridescenceInfo.w = this._iridescenceRange.y; - }; + this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); // @ts-ignore - sheenColor._onValueChanged = () => { - const enableSheen = sheenColor.r + sheenColor.g + sheenColor.b > 0; - if (enableSheen !== this._sheenEnabled) { - this._sheenEnabled = enableSheen; - if (enableSheen) { - this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN"); - } else { - this.shaderData.disableMacro("MATERIAL_ENABLE_SHEEN"); - } - } - }; + sheenColor._onValueChanged = this._onSheenColorChanged.bind(this); // @ts-ignore - attenuationColor._onValueChanged = () => { - const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 0; - if (enableAbsorption !== this._absorptionEnabled) { - this._absorptionEnabled = enableAbsorption; - if (enableAbsorption) { - this.shaderData.enableMacro(PBRMaterial._absorptionMacro); - } else { - this.shaderData.disableMacro(PBRMaterial._absorptionMacro); - } - } - }; + attenuationColor._onValueChanged = this._attenuationColorChanged.bind(this); } /** @@ -503,6 +478,38 @@ export class PBRMaterial extends PBRBaseMaterial { return dest; } + private _onIridescenceRangeChanged(): void { + const iridescenceInfo = this.shaderData.getVector4(PBRMaterial._iridescenceInfoProp); + iridescenceInfo.z = this._iridescenceRange.x; + iridescenceInfo.w = this._iridescenceRange.y; + } + + private _onSheenColorChanged(): void { + const sheenColor = this.sheenColor; + const enableSheen = sheenColor.r + sheenColor.g + sheenColor.b > 0; + if (enableSheen !== this._sheenEnabled) { + this._sheenEnabled = enableSheen; + if (enableSheen) { + this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN"); + } else { + this.shaderData.disableMacro("MATERIAL_ENABLE_SHEEN"); + } + } + } + + private _attenuationColorChanged(): void { + const attenuationColor = this.attenuationColor; + const enableAbsorption = attenuationColor.r + attenuationColor.g + attenuationColor.b > 0; + if (enableAbsorption !== this._absorptionEnabled) { + this._absorptionEnabled = enableAbsorption; + if (enableAbsorption) { + this.shaderData.enableMacro(PBRMaterial._absorptionMacro); + } else { + this.shaderData.disableMacro(PBRMaterial._absorptionMacro); + } + } + } + private _setRefractionMode(refractionMode: RefractionMode): void { switch (refractionMode) { case RefractionMode.Sphere: From e9f348070b9b650bd766055530a73eb90239e5c1 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 19:52:53 +0800 Subject: [PATCH 30/35] fix: specular name --- packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl | 2 +- packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl | 2 +- .../src/shaders/shadingPBR/LightIndirectPBR.glsl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl index 53abfee4b2..312898468d 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl @@ -395,7 +395,7 @@ void initBRDFData(SurfaceData surfaceData, out BRDFData brdfData){ brdfData.specularColor = specularColor; #endif brdfData.roughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(roughness + getAARoughnessFactor(surfaceData.normal), 1.0)); - brdfData.specularDFG = envBRDFApprox(brdfData.specularColor, brdfData.roughness, surfaceData.dotNV); + brdfData.envSpecularDFG = envBRDFApprox(brdfData.specularColor, brdfData.roughness, surfaceData.dotNV); #ifdef MATERIAL_ENABLE_CLEAR_COAT brdfData.clearCoatRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.clearCoatRoughness + getAARoughnessFactor(surfaceData.clearCoatNormal), 1.0)); diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl index 815bc63191..bbc5fabde1 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BTDF.glsl @@ -24,7 +24,7 @@ // Use specularFGD as an approximation of the fresnel effect // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf - vec3 specularDFG = brdfData.specularDFG; + vec3 specularDFG = brdfData.envSpecularDFG; refractionTransmitted *= (1.0 - specularDFG); diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index 32c6a6a081..f5909b683d 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -77,7 +77,7 @@ void evaluateSpecularIBL(Varyings varyings, SurfaceData surfaceData, BRDFData br vec3 speculaColor = brdfData.specularColor; #endif - outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * brdfData.specularDFG; + outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * brdfData.envSpecularDFG; } void evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){ From d12ff04f6ab53062e89751c765219fec069fce6a Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 19:54:44 +0800 Subject: [PATCH 31/35] fix: specular name --- packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl index 312898468d..b885e33d34 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/BRDF.glsl @@ -77,7 +77,7 @@ struct BRDFData{ vec3 diffuseColor; vec3 specularColor; float roughness; - vec3 specularDFG; + vec3 envSpecularDFG; #ifdef MATERIAL_ENABLE_CLEAR_COAT vec3 clearCoatSpecularColor; From 9338ec26193e3d933ef3f0332bfbeafad845fe91 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 20:48:40 +0800 Subject: [PATCH 32/35] fix: diffuseColor mix refraction --- .../src/shaders/shadingPBR/LightIndirectPBR.glsl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index f5909b683d..f1096159c4 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -108,16 +108,11 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, #ifdef MATERIAL_ENABLE_TRANSMISSION vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData); - refractionTransmitted *= surfaceData.transmission; - diffuseColor *= (1.0 - surfaceData.transmission); + diffuseColor = mix(diffuseColor, refractionTransmitted, surfaceData.transmission); #endif color += diffuseColor + specularColor; - #ifdef MATERIAL_ENABLE_TRANSMISSION - color.rgb += refractionTransmitted; - #endif - } From 730548bc98821efb867ae4dd6d0a0e73d0306723 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 21:35:41 +0800 Subject: [PATCH 33/35] fix: diffuse and specular light --- .../shaders/shadingPBR/ForwardPassPBR.glsl | 16 ++++++++-- .../shaders/shadingPBR/LightDirectPBR.glsl | 30 ++++++++----------- .../shaders/shadingPBR/LightIndirectPBR.glsl | 11 ++----- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl index 8717574808..55628a0c2a 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl @@ -72,7 +72,9 @@ void PBRFragment(Varyings varyings) { // Can modify surfaceData here initBRDFData(surfaceData, brdfData); - vec4 color = vec4(0, 0, 0, surfaceData.opacity); + + vec3 totalDiffuseColor = vec3(0, 0, 0); + vec3 totalSpecularColor = vec3(0, 0, 0); // Get shadow attenuation float shadowAttenuation = 1.0; @@ -86,10 +88,18 @@ void PBRFragment(Varyings varyings) { #endif // Evaluate direct lighting - evaluateDirectRadiance(varyings, surfaceData, brdfData, shadowAttenuation, color.rgb); + evaluateDirectRadiance(varyings, surfaceData, brdfData, shadowAttenuation, totalDiffuseColor, totalSpecularColor); // IBL - evaluateIBL(varyings, surfaceData, brdfData, color.rgb); + evaluateIBL(varyings, surfaceData, brdfData, totalDiffuseColor, totalSpecularColor); + + #ifdef MATERIAL_ENABLE_TRANSMISSION + vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData); + totalDiffuseColor = mix(totalDiffuseColor, refractionTransmitted, surfaceData.transmission); + #endif + + // Final color + vec4 color = vec4((totalDiffuseColor + totalSpecularColor).rgb, surfaceData.opacity); // Emissive color.rgb += surfaceData.emissiveColor; diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl index f6978206c0..789ac7a8f1 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl @@ -22,7 +22,7 @@ #include "Light.glsl" #include "ReflectionLobe.glsl" -void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, vec3 incidentDirection, vec3 lightColor, inout vec3 color) { +void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, vec3 incidentDirection, vec3 lightColor, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) { vec3 diffuseColor = vec3(0); vec3 specularColor = vec3(0); @@ -37,25 +37,21 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat FUNCTION_DIFFUSE_LOBE(varyings, surfaceData, brdfData, attenuationIrradiance, diffuseColor); // Specular Lobe FUNCTION_SPECULAR_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, specularColor); - - #ifdef MATERIAL_ENABLE_TRANSMISSION - diffuseColor *= (1.0 - surfaceData.transmission); - #endif - // Sheen Lobe FUNCTION_SHEEN_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, diffuseColor, specularColor); - color += diffuseColor + specularColor; + totalDiffuseColor += diffuseColor; + totalSpecularColor += specularColor; } #ifdef SCENE_DIRECT_LIGHT_COUNT - void addDirectionalDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, DirectLight directionalLight, inout vec3 color) { + void addDirectionalDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, DirectLight directionalLight, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) { vec3 lightColor = directionalLight.color; vec3 direction = -directionalLight.direction; - FUNCTION_SURFACE_SHADING(varyings, surfaceData, brdfData, direction, lightColor, color); + FUNCTION_SURFACE_SHADING(varyings, surfaceData, brdfData, direction, lightColor, totalDiffuseColor, totalSpecularColor); } @@ -63,7 +59,7 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat #ifdef SCENE_POINT_LIGHT_COUNT - void addPointDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, PointLight pointLight, inout vec3 color) { + void addPointDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, PointLight pointLight, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) { vec3 lVector = pointLight.position - surfaceData.position; vec3 direction = normalize( lVector ); float lightDistance = length( lVector ); @@ -71,14 +67,14 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat vec3 lightColor = pointLight.color; lightColor *= clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0); - FUNCTION_SURFACE_SHADING(varyings, surfaceData, brdfData, direction, lightColor, color); + FUNCTION_SURFACE_SHADING(varyings, surfaceData, brdfData, direction, lightColor, totalDiffuseColor, totalSpecularColor); } #endif #ifdef SCENE_SPOT_LIGHT_COUNT - void addSpotDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, SpotLight spotLight, inout vec3 color) { + void addSpotDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, SpotLight spotLight, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) { vec3 lVector = spotLight.position - surfaceData.position; vec3 direction = normalize( lVector ); @@ -91,14 +87,14 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat vec3 lightColor = spotLight.color; lightColor *= spotEffect * decayEffect; - FUNCTION_SURFACE_SHADING(varyings, surfaceData, brdfData, direction, lightColor, color); + FUNCTION_SURFACE_SHADING(varyings, surfaceData, brdfData, direction, lightColor, totalDiffuseColor, totalSpecularColor); } #endif -void evaluateDirectRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, float shadowAttenuation, inout vec3 color){ +void evaluateDirectRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, float shadowAttenuation, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor){ #ifdef SCENE_DIRECT_LIGHT_COUNT for ( int i = 0; i < SCENE_DIRECT_LIGHT_COUNT; i ++ ) { @@ -117,7 +113,7 @@ void evaluateDirectRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData directionalLight.color *= shadowAttenuation; } #endif - addDirectionalDirectLightRadiance(varyings, surfaceData, brdfData, directionalLight, color ); + addDirectionalDirectLightRadiance(varyings, surfaceData, brdfData, directionalLight, totalDiffuseColor, totalSpecularColor ); } } @@ -135,7 +131,7 @@ void evaluateDirectRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData pointLight.position = scene_PointLightPosition[i]; pointLight.distance = scene_PointLightDistance[i]; #endif - addPointDirectLightRadiance(varyings, surfaceData, brdfData, pointLight, color ); + addPointDirectLightRadiance(varyings, surfaceData, brdfData, pointLight, totalDiffuseColor, totalSpecularColor); } } @@ -156,7 +152,7 @@ void evaluateDirectRadiance(Varyings varyings, SurfaceData surfaceData, BRDFData spotLight.angleCos = scene_SpotLightAngleCos[i]; spotLight.penumbraCos = scene_SpotLightPenumbraCos[i]; #endif - addSpotDirectLightRadiance( varyings, surfaceData, brdfData, spotLight, color ); + addSpotDirectLightRadiance( varyings, surfaceData, brdfData, spotLight, totalDiffuseColor, totalSpecularColor); } } diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index f1096159c4..fe9577fd52 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -90,7 +90,7 @@ void evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfD #endif } -void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, inout vec3 color){ +void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor){ vec3 diffuseColor = vec3(0); vec3 specularColor = vec3(0); @@ -105,15 +105,10 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, // IBL sheen FUNCTION_SHEEN_IBL(varyings, surfaceData, brdfData, radianceAttenuation, diffuseColor, specularColor); - - #ifdef MATERIAL_ENABLE_TRANSMISSION - vec3 refractionTransmitted = evaluateRefraction(surfaceData, brdfData); - diffuseColor = mix(diffuseColor, refractionTransmitted, surfaceData.transmission); - #endif - color += diffuseColor + specularColor; + totalDiffuseColor += diffuseColor; + totalSpecularColor += specularColor; } - #endif \ No newline at end of file From 0a776c48c718be32459324b4c47164a613011504 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 26 Dec 2024 21:41:55 +0800 Subject: [PATCH 34/35] fix: btdf --- .../shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl | 1 + .../src/shaders/shadingPBR/LightIndirectPBR.glsl | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl index 55628a0c2a..2550aaf08b 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl @@ -8,6 +8,7 @@ #include "VaryingsPBR.glsl" #include "LightDirectPBR.glsl" #include "LightIndirectPBR.glsl" +#include "BTDF.glsl" #include "VertexPBR.glsl" #include "FragmentPBR.glsl" diff --git a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl index fe9577fd52..d1e279d018 100644 --- a/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl +++ b/packages/shader-shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl @@ -15,7 +15,6 @@ #define FUNCTION_SHEEN_IBL evaluateSheenIBL #endif #include "BRDF.glsl" -#include "BTDF.glsl" #include "Light.glsl" #include "LightIndirectFunctions.glsl" From ce75450a57996fd369e8e35e5d8e33dbb32473bf Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 27 Dec 2024 00:47:19 +0800 Subject: [PATCH 35/35] refactor: opt code --- packages/core/src/material/BaseMaterial.ts | 106 +++++++++++---------- packages/core/src/material/PBRMaterial.ts | 19 +++- 2 files changed, 74 insertions(+), 51 deletions(-) diff --git a/packages/core/src/material/BaseMaterial.ts b/packages/core/src/material/BaseMaterial.ts index cf1aa7c6b7..874c4d70f3 100644 --- a/packages/core/src/material/BaseMaterial.ts +++ b/packages/core/src/material/BaseMaterial.ts @@ -24,11 +24,11 @@ export class BaseMaterial extends Material { protected static _emissiveColorProp: ShaderProperty = ShaderProperty.getByName("material_EmissiveColor"); protected static _emissiveTextureProp: ShaderProperty = ShaderProperty.getByName("material_EmissiveTexture"); - private static _alphaCutoffProp: ShaderProperty = ShaderProperty.getByName("material_AlphaCutoff"); + protected static _alphaCutoffProp: ShaderProperty = ShaderProperty.getByName("material_AlphaCutoff"); private static _alphaCutoffMacro: ShaderMacro = ShaderMacro.getByName("MATERIAL_IS_ALPHA_CUTOFF"); private _renderFace: RenderFace = RenderFace.Front; - private _isTransparent: boolean = false; + protected _isTransparent: boolean = false; private _blendMode: BlendMode = BlendMode.Normal; /** @@ -73,24 +73,7 @@ export class BaseMaterial extends Material { } set isTransparent(value: boolean) { - if (value !== this._isTransparent) { - this.setIsTransparent(0, value); - - const { shaderData } = this; - if (value) { - // Use alpha test queue to simulate transparent shadow - shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); - } else { - const alphaCutoff = shaderData.getFloat(BaseMaterial._alphaCutoffProp); - if (alphaCutoff) { - shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); - } else { - shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.Opaque); - } - } - - this._isTransparent = value; - } + this._seIsTransparent(value); } /** @@ -119,35 +102,7 @@ export class BaseMaterial extends Material { } set alphaCutoff(value: number) { - const { shaderData } = this; - if (shaderData.getFloat(BaseMaterial._alphaCutoffProp) !== value) { - if (value) { - shaderData.enableMacro(BaseMaterial._alphaCutoffMacro); - shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); - } else { - shaderData.disableMacro(BaseMaterial._alphaCutoffMacro); - if (this._isTransparent) { - shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); - } else { - shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.Opaque); - } - } - - const { renderStates } = this; - for (let i = 0, n = renderStates.length; i < n; i++) { - const renderState = renderStates[i]; - if (value > 0) { - renderState.renderQueueType = renderState.blendState.targetBlendState.enabled - ? RenderQueueType.Transparent - : RenderQueueType.AlphaTest; - } else { - renderState.renderQueueType = renderState.blendState.targetBlendState.enabled - ? RenderQueueType.Transparent - : RenderQueueType.Opaque; - } - } - shaderData.setFloat(BaseMaterial._alphaCutoffProp, value); - } + this._setAlphaCutoff(value); } /** @@ -279,4 +234,57 @@ export class BaseMaterial extends Material { target._isTransparent = this._isTransparent; target._blendMode = this._blendMode; } + + protected _seIsTransparent(value: boolean): void { + if (value !== this._isTransparent) { + this.setIsTransparent(0, value); + + const { shaderData } = this; + if (value) { + // Use alpha test queue to simulate transparent shadow + shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); + } else { + const alphaCutoff = shaderData.getFloat(BaseMaterial._alphaCutoffProp); + if (alphaCutoff) { + shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); + } else { + shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.Opaque); + } + } + + this._isTransparent = value; + } + } + + protected _setAlphaCutoff(value: number): void { + const { shaderData } = this; + if (shaderData.getFloat(BaseMaterial._alphaCutoffProp) !== value) { + if (value) { + shaderData.enableMacro(BaseMaterial._alphaCutoffMacro); + shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); + } else { + shaderData.disableMacro(BaseMaterial._alphaCutoffMacro); + if (this._isTransparent) { + shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.AlphaTest); + } else { + shaderData.setFloat(BaseMaterial._shadowCasterRenderQueueProp, RenderQueueType.Opaque); + } + } + + const { renderStates } = this; + for (let i = 0, n = renderStates.length; i < n; i++) { + const renderState = renderStates[i]; + if (value > 0) { + renderState.renderQueueType = renderState.blendState.targetBlendState.enabled + ? RenderQueueType.Transparent + : RenderQueueType.AlphaTest; + } else { + renderState.renderQueueType = renderState.blendState.targetBlendState.enabled + ? RenderQueueType.Transparent + : RenderQueueType.Opaque; + } + } + shaderData.setFloat(BaseMaterial._alphaCutoffProp, value); + } + } } diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 81a260b945..888b1b8f14 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -4,6 +4,7 @@ import { ShaderMacro, ShaderProperty } from "../shader"; import { Shader } from "../shader/Shader"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Texture2D } from "../texture/Texture2D"; +import { BaseMaterial } from "./BaseMaterial"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; import { RefractionMode } from "./enums/Refraction"; @@ -320,16 +321,30 @@ export class PBRMaterial extends PBRBaseMaterial { } } + /** + * @inheritdoc + */ + override get isTransparent(): boolean { + return this._isTransparent; + } + override set isTransparent(value: boolean) { - super.isTransparent = value; + this._seIsTransparent(value); if (this.transmission > 0) { // If transmission enabled, always use transparent queue to ensure get correct opaque texture this.renderState.renderQueueType = RenderQueueType.Transparent; } } + /** + * @inheritdoc + */ + override get alphaCutoff(): number { + return this.shaderData.getFloat(BaseMaterial._alphaCutoffProp); + } + override set alphaCutoff(value: number) { - super.alphaCutoff = value; + this._setAlphaCutoff(value); if (this.transmission > 0) { // If transmission enabled, always use transparent queue to ensure get correct opaque texture this.renderState.renderQueueType = RenderQueueType.Transparent;