Skip to content

Commit

Permalink
refactor: split varyings and attributes from light
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuxudong committed Jul 17, 2024
1 parent 7403430 commit 1cbf9be
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 180 deletions.
14 changes: 0 additions & 14 deletions packages/shaderlab/src/shaders/Macros.glsl

This file was deleted.

17 changes: 8 additions & 9 deletions packages/shaderlab/src/shaders/Shadow.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
#include "Transform.glsl"
#include "Common.glsl"

#if defined(SCENE_SHADOW_TYPE) && defined(RENDERER_IS_RECEIVE_SHADOWS)
#define NEED_CALCULATE_SHADOWS
#endif


#ifdef NEED_CALCULATE_SHADOWS
#if SCENE_SHADOW_CASCADED_COUNT==1
#if SCENE_SHADOW_CASCADED_COUNT == 1

mat4 scene_ShadowMatrices[SCENE_SHADOW_CASCADED_COUNT + 1];
vec4 scene_ShadowSplitSpheres[4];
Expand Down Expand Up @@ -150,13 +155,7 @@
}


float sampleShadowMap(Varyings v) {
#if SCENE_SHADOW_CASCADED_COUNT == 1
vec3 shadowCoord = v.v_shadowCoord;
#else
vec3 shadowCoord = getShadowCoord(v.v_pos);
#endif

float sampleShadowMap(vec3 positionWS, vec3 shadowCoord) {
float attenuation = 1.0;
if(shadowCoord.z > 0.0 && shadowCoord.z < 1.0) {
#if SCENE_SHADOW_TYPE == 1
Expand All @@ -173,7 +172,7 @@
attenuation = mix(1.0, attenuation, scene_ShadowInfo.x);
}

float shadowFade = getShadowFade(v.v_pos);
float shadowFade = getShadowFade(positionWS);
attenuation = mix(1.0, mix(attenuation, 1.0, shadowFade), scene_ShadowInfo.x);

return attenuation;
Expand Down
4 changes: 0 additions & 4 deletions packages/shaderlab/src/shaders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import BlendShape from "./BlendShape.glsl";
import Common from "./Common.glsl";
import Fog from "./Fog.glsl";
import Light from "./Light.glsl";
import Macros from "./Macros.glsl";
import Normal from "./Normal.glsl";
import PBRSource from "./PBR.gs";
import Shadow from "./Shadow.glsl";
import ShadowSampleTent from "./ShadowSampleTent.glsl";
import Skin from "./Skin.glsl";
import Transform from "./Transform.glsl";
import Vertex from "./Vertex.glsl";
import shadingPBR from "./shadingPBR";

interface IShaderFragment {
Expand All @@ -26,9 +24,7 @@ const fragmentList: IShaderFragment[] = [
{ source: ShadowSampleTent, includeKey: "ShadowSampleTent.glsl" },
{ source: Shadow, includeKey: "Shadow.glsl" },
{ source: Transform, includeKey: "Transform.glsl" },
{ source: Vertex, includeKey: "Vertex.glsl" },
{ source: Skin, includeKey: "Skin.glsl" },
{ source: Macros, includeKey: "Macros.glsl" },

...shadingPBR
];
Expand Down
69 changes: 69 additions & 0 deletions packages/shaderlab/src/shaders/shadingPBR/BRDF.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,75 @@
#ifndef BRDF_INCLUDED
#define BRDF_INCLUDED

#define MIN_PERCEPTUAL_ROUGHNESS 0.045
#define MIN_ROUGHNESS 0.002025

#if defined(RENDERER_HAS_TANGENT) || defined(MATERIAL_ENABLE_ANISOTROPY) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE)
#define NEED_TANGENT
#endif

struct SurfaceData{
// common
vec3 albedoColor;
vec3 specularColor;
vec3 emissiveColor;
float metallic;
float roughness;
float f0;
float opacity;

// geometry
vec3 position;
vec3 normal;

#ifdef NEED_TANGENT
vec3 tangent;
vec3 bitangent;
#endif

vec3 viewDir;
};


struct BRDFData{
// common
vec3 diffuseColor;
vec3 specularColor;
float roughness;
float diffuseAO;
float specularAO;

// geometry
vec3 position;
vec3 normal;

#ifdef NEED_TANGENT
vec3 tangent;
vec3 bitangent;
#endif

vec3 viewDir;
float dotNV;

// Anisotropy
#ifdef MATERIAL_ENABLE_ANISOTROPY
float anisotropy;
vec3 anisotropicT;
vec3 anisotropicB;
vec3 anisotropicN;
#endif

// Clear coat
#ifdef MATERIAL_ENABLE_CLEAR_COAT
float clearCoat;
float clearCoatRoughness;
vec3 clearCoatNormal;
float clearCoatDotNV;
#endif
};



float F_Schlick(float f0, float dotLH) {
return f0 + 0.96 * (pow(1.0 - dotLH, 5.0));
}
Expand Down
35 changes: 24 additions & 11 deletions packages/shaderlab/src/shaders/shadingPBR/ForwardPassPBR.glsl
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
#ifndef FORWARD_PASS_PBR_INCLUDED
#define FORWARD_PASS_PBR_INCLUDED

#include "Macros.glsl"
#include "AttributesPBR.glsl"
#include "VaryingsPBR.glsl"
#include "Common.glsl"
#include "Vertex.glsl"
#include "Fog.glsl"

#include "MaterialInputPBR.glsl"
#include "LightDirectPBR.glsl"
#include "LightIndirectPBR.glsl"

#include "AttributesPBR.glsl"
#include "VaryingsPBR.glsl"
#include "VertexPBR.glsl"
#include "FragmentPBR.glsl"



Varyings PBRVertex(Attributes attributes) {
Varyings varyings;
Expand Down Expand Up @@ -56,19 +57,31 @@ Varyings PBRVertex(Attributes attributes) {
}

void PBRFragment(Varyings varyings) {
SurfaceData surfaceData;
BRDFData brdfData;
SurfaceData surfaceData = getSurfaceData(varyings, gl_FrontFacing);

initSurfaceData(varyings, surfaceData, gl_FrontFacing);
BRDFData brdfData;
// Can modify surfaceData here.
initBRDFData(varyings, surfaceData, brdfData, gl_FrontFacing);

vec4 color = vec4(0, 0, 0, surfaceData.opacity);

// Direct Light
evaluateDirectRadiance(varyings, brdfData, color.rgb);
// Get shadow attenuation
float shadowAttenuation = 1.0;
#if defined(SCENE_DIRECT_LIGHT_COUNT) && defined(NEED_CALCULATE_SHADOWS)
#if SCENE_SHADOW_CASCADED_COUNT == 1
vec3 shadowCoord = varyings.v_shadowCoord;
#else
vec3 shadowCoord = getShadowCoord(varyings.v_pos);
#endif
shadowAttenuation *= sampleShadowMap(varyings.v_pos, shadowCoord);
#endif

// Evaluate direct lighting
evaluateDirectRadiance(shadowAttenuation, brdfData, color.rgb);

// IBL
evaluateIBL(varyings, brdfData, color.rgb);
evaluateIBL(brdfData, color.rgb);

// Emissive
color.rgb += surfaceData.emissiveColor;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,6 @@

#include "Normal.glsl"

struct SurfaceData{
// common
vec3 albedoColor;
vec3 specularColor;
vec3 emissiveColor;
float metallic;
float roughness;
float f0;
float opacity;

// geometry
vec3 position;
vec3 normal;

#ifdef NEED_TANGENT
vec3 tangent;
vec3 bitangent;
#endif

vec3 viewDir;
};

struct BRDFData{
// common
vec3 diffuseColor;
vec3 specularColor;
float roughness;

// geometry
vec3 position;
vec3 normal;

#ifdef NEED_TANGENT
vec3 tangent;
vec3 bitangent;
#endif

vec3 viewDir;
float dotNV;

// Anisotropy
#ifdef MATERIAL_ENABLE_ANISOTROPY
float anisotropy;
vec3 anisotropicT;
vec3 anisotropicB;
vec3 anisotropicN;
#endif

// Clear coat
#ifdef MATERIAL_ENABLE_CLEAR_COAT
float clearCoat;
float clearCoatRoughness;
vec3 clearCoatNormal;
float clearCoatDotNV;
#endif
};

#define MIN_PERCEPTUAL_ROUGHNESS 0.045
#define MIN_ROUGHNESS 0.002025

float material_AlphaCutoff;
vec4 material_BaseColor;
float material_Metal;
Expand Down Expand Up @@ -126,35 +66,8 @@ float material_OcclusionTextureCoord;
#endif



float getAARoughnessFactor(vec3 normal) {
// Kaplanyan 2016, "Stable specular highlights"
// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
#ifdef HAS_DERIVATIVES
vec3 dxy = max( abs(dFdx(normal)), abs(dFdy(normal)) );
return max( max(dxy.x, dxy.y), dxy.z );
#else
return 0.0;
#endif
}

#ifdef MATERIAL_ENABLE_ANISOTROPY
// Aniso Bent Normals
// Mc Alley https://www.gdcvault.com/play/1022235/Rendering-the-World-of-Far
vec3 getAnisotropicBentNormal(BRDFData brdfData) {
vec3 anisotropyDirection = (brdfData.anisotropy >= 0.0) ? brdfData.anisotropicB : brdfData.anisotropicT;
vec3 anisotropicTangent = cross(anisotropyDirection, brdfData.viewDir);
vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection);
// reduce stretching for (roughness < 0.2), refer to https://advances.realtimerendering.com/s2018/Siggraph%202018%20HDRP%20talk_with%20notes.pdf 80
vec3 bentNormal = normalize( mix(brdfData.normal, anisotropicNormal, abs(brdfData.anisotropy) * saturate( 5.0 * brdfData.roughness)) );

return bentNormal;
}
#endif


void initSurfaceData(Varyings v, out SurfaceData surfaceData, bool isFrontFacing){
SurfaceData getSurfaceData(Varyings v, bool isFrontFacing){
SurfaceData surfaceData;
// common
vec4 baseColor = material_BaseColor;
float metallic = material_Metal;
Expand Down Expand Up @@ -242,8 +155,38 @@ void initSurfaceData(Varyings v, out SurfaceData surfaceData, bool isFrontFacing
#else
surfaceData.normal = getNormal(v, isFrontFacing);
#endif

return surfaceData;
}

float getAARoughnessFactor(vec3 normal) {
// Kaplanyan 2016, "Stable specular highlights"
// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
#ifdef HAS_DERIVATIVES
vec3 dxy = max( abs(dFdx(normal)), abs(dFdy(normal)) );
return max( max(dxy.x, dxy.y), dxy.z );
#else
return 0.0;
#endif
}

#ifdef MATERIAL_ENABLE_ANISOTROPY
// Aniso Bent Normals
// Mc Alley https://www.gdcvault.com/play/1022235/Rendering-the-World-of-Far
vec3 getAnisotropicBentNormal(BRDFData brdfData) {
vec3 anisotropyDirection = (brdfData.anisotropy >= 0.0) ? brdfData.anisotropicB : brdfData.anisotropicT;
vec3 anisotropicTangent = cross(anisotropyDirection, brdfData.viewDir);
vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection);
// reduce stretching for (roughness < 0.2), refer to https://advances.realtimerendering.com/s2018/Siggraph%202018%20HDRP%20talk_with%20notes.pdf 80
vec3 bentNormal = normalize( mix(brdfData.normal, anisotropicNormal, abs(brdfData.anisotropy) * saturate( 5.0 * brdfData.roughness)) );

return bentNormal;
}
#endif



void initGeometryData(SurfaceData surfaceData, inout BRDFData brdfData){
brdfData.position = surfaceData.position;
brdfData.normal = surfaceData.normal;
Expand Down Expand Up @@ -322,11 +265,34 @@ void initAnisotropyBRDFData(Varyings v, inout BRDFData brdfData){

}

void initAO(Varyings v, inout BRDFData brdfData){
float diffuseAO = 1.0;
float specularAO = 1.0;

#ifdef MATERIAL_HAS_OCCLUSION_TEXTURE
vec2 aoUV = v.v_uv;
#ifdef RENDERER_HAS_UV1
if(material_OcclusionTextureCoord == 1.0){
aoUV = v.v_uv1;
}
#endif
diffuseAO = ((texture2D(material_OcclusionTexture, aoUV)).r - 1.0) * material_OcclusionIntensity + 1.0;
#endif

#if defined(MATERIAL_HAS_OCCLUSION_TEXTURE) && defined(SCENE_USE_SPECULAR_ENV)
specularAO = saturate( pow( brdfData.dotNV + diffuseAO, exp2( - 16.0 * brdfData.roughness - 1.0 ) ) - 1.0 + diffuseAO );
#endif

brdfData.diffuseAO = diffuseAO;
brdfData.specularAO = specularAO;
}

void initBRDFData(Varyings v, SurfaceData surfaceData, out BRDFData brdfData, bool isFrontFacing){
initGeometryData(surfaceData, brdfData);
initCommonBRDFData(surfaceData, brdfData);
initClearCoatBRDFData(v, brdfData, isFrontFacing);
initAnisotropyBRDFData(v, brdfData);
initAO(v, brdfData);
}


Expand Down
Loading

0 comments on commit 1cbf9be

Please sign in to comment.