Skip to content

Commit

Permalink
feat: support KHR_materials_anisotropy
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuki Shimada committed Aug 5, 2023
1 parent b123d5b commit fa589d3
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 8 deletions.
19 changes: 19 additions & 0 deletions src/foundation/helpers/MaterialHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { MaterialRepository } from '../materials/core/MaterialRepository';
import { Vrm0xMaterialProperty } from '../../types';
import { Sampler } from '../textures/Sampler';
import {
dummyAnisotropyTexture,
dummyBlackTexture,
dummyBlueTexture,
dummyWhiteTexture,
Expand Down Expand Up @@ -117,6 +118,7 @@ function createPbrUberMaterial({
isSheen = false,
isSpecular = false,
isIridescence = false,
isAnisotropy = false,
isShadow = false,
useTangentAttribute = false,
useNormalTexture = true,
Expand All @@ -134,6 +136,7 @@ function createPbrUberMaterial({
(isSheen ? '+sheen' : '') +
(isSpecular ? '+specular' : '') +
(isIridescence ? '+iridescence' : '') +
(isAnisotropy ? '+anisotropy' : '') +
(useTangentAttribute ? '+tangentAttribute' : '') +
(useNormalTexture ? '' : '-normalTexture');

Expand Down Expand Up @@ -336,6 +339,21 @@ function createPbrUberMaterial({
max: Number.MAX_VALUE,
});
}
if (isAnisotropy) {
additionalShaderSemanticInfo.push({
semantic: ShaderSemantics.AnisotropyTexture,
componentType: ComponentType.Int,
compositionType: CompositionType.Texture2D,
stage: ShaderType.PixelShader,
isCustomSetting: true,
soloDatum: false,
updateInterval: ShaderVariableUpdateInterval.EveryTime,
initialValue: [textureSlotIdx++, dummyAnisotropyTexture],
min: 0,
max: Number.MAX_VALUE,
needUniformInDataTextureMode: true,
});
}

if (isShadow) {
additionalShaderSemanticInfo.push({
Expand Down Expand Up @@ -363,6 +381,7 @@ function createPbrUberMaterial({
isSheen,
isSpecular,
isIridescence,
isAnisotropy,
isShadow,
useTangentAttribute,
useNormalTexture,
Expand Down
6 changes: 5 additions & 1 deletion src/foundation/importer/ModelConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@ export class ModelConverter {
isSheen: Is.exist(materialJson?.extensions?.KHR_materials_sheen),
isSpecular: Is.exist(materialJson?.extensions?.KHR_materials_specular),
isIridescence: Is.exist(materialJson?.extensions?.KHR_materials_iridescence),
isAnisotropy: Is.exist(materialJson?.extensions?.KHR_materials_anisotropy),
isShadow: rnLoaderOptions.shadow ? true : false,
useTangentAttribute,
useNormalTexture,
Expand Down Expand Up @@ -2651,7 +2652,10 @@ function setup_KHR_materials_anisotropy(
const anisotropyRotation = Is.exist(KHR_materials_anisotropy.anisotropyRotation)
? KHR_materials_anisotropy.anisotropyRotation
: 0.0;
material.setParameter(ShaderSemantics.AnisotropyRotation, Vector2.fromCopy2(Math.cos(anisotropyRotation), Math.sin(anisotropyRotation)));
material.setParameter(
ShaderSemantics.AnisotropyRotation,
Vector2.fromCopy2(Math.cos(anisotropyRotation), Math.sin(anisotropyRotation))
);

const anisotropyTexture = KHR_materials_anisotropy.anisotropyTexture;
if (anisotropyTexture != null) {
Expand Down
6 changes: 6 additions & 0 deletions src/foundation/materials/contents/CustomMaterialContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class CustomMaterialContent extends AbstractMaterialContent {
isSheen,
isSpecular,
isIridescence,
isAnisotropy,
isShadow,
useTangentAttribute,
useNormalTexture,
Expand All @@ -44,6 +45,7 @@ export class CustomMaterialContent extends AbstractMaterialContent {
isSheen?: boolean;
isSpecular?: boolean;
isIridescence?: boolean;
isAnisotropy?: boolean;
isShadow?: boolean;
useTangentAttribute: boolean;
useNormalTexture: boolean;
Expand All @@ -64,6 +66,7 @@ export class CustomMaterialContent extends AbstractMaterialContent {
(isSpecular ? '+specular' : '') +
(isSheen ? '+sheen' : '') +
(isIridescence ? '+iridescence' : '') +
(isAnisotropy ? '+anisotropy' : '') +
(useTangentAttribute ? '+tangentAttribute' : ''),
{ isMorphing, isSkinning, isLighting }
);
Expand Down Expand Up @@ -135,6 +138,9 @@ export class CustomMaterialContent extends AbstractMaterialContent {
if (isIridescence) {
this.__definitions += '#define RN_USE_IRIDESCENCE\n';
}
if (isAnisotropy) {
this.__definitions += '#define RN_USE_ANISOTROPY\n';
}
if (isShadow) {
this.__definitions += '#define RN_USE_SHADOW_MAPPING\n';
}
Expand Down
4 changes: 4 additions & 0 deletions src/foundation/materials/core/DummyTextures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const dummyBlackTexture = new Texture();
export const dummyBlackCubeTexture = new CubeTexture();
export const sheenLutTexture = new Texture();
export const dummySRGBGrayTexture = new Texture();
export const dummyAnisotropyTexture = new Texture();

export async function initDefaultTextures() {
if (dummyWhiteTexture.isTextureReady) {
Expand All @@ -18,13 +19,15 @@ export async function initDefaultTextures() {
dummyBlackCubeTexture.tryToSetUniqueName('dummyBlackCubeTexture', true);
sheenLutTexture.tryToSetUniqueName('sheenLutTexture', true);
dummySRGBGrayTexture.tryToSetUniqueName('dummySRGBGrayTexture', true);
dummyAnisotropyTexture.tryToSetUniqueName('dummyAnisotropyTexture', true);

dummyWhiteTexture.generate1x1TextureFrom();
dummyBlueTexture.generate1x1TextureFrom('rgba(127.5, 127.5, 255, 1)');
dummyBlackTexture.generate1x1TextureFrom('rgba(0, 0, 0, 1)');
dummyBlackCubeTexture.load1x1Texture('rgba(0, 0, 0, 1)');
await sheenLutTexture.generateSheenLutTextureFromDataUri();
dummySRGBGrayTexture.generate1x1TextureFrom('rgba(186, 186, 186, 1)');
dummyAnisotropyTexture.generate1x1TextureFrom('rgba(255, 127.5, 255, 1)');
}

export const DefaultTextures = {
Expand All @@ -34,4 +37,5 @@ export const DefaultTextures = {
dummyBlackCubeTexture,
sheenLutTexture,
dummySRGBGrayTexture,
dummyAnisotropyTexture,
};
27 changes: 20 additions & 7 deletions src/webgl/shaderity_shaders/PbrSingleShader/PbrSingleShader.frag
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,19 @@ vec3 getNormalForEnv(mat3 rotEnvMatrix, vec3 normal_inWorld, float materialSID)
return normal_forEnv;
}

vec3 getReflection(mat3 rotEnvMatrix, vec3 viewDirection, vec3 normal_inWorld, float materialSID) {
vec3 getReflection(mat3 rotEnvMatrix, vec3 viewDirection, vec3 normal_inWorld, float materialSID, float perceptualRoughness, float anisotropy, vec3 anisotropyDirection) {
#ifdef RN_USE_ANISOTROPY

float tangentRoughness = mix(perceptualRoughness, 1.0, anisotropy * anisotropy);
vec3 anisotropicTangent = cross(anisotropyDirection, viewDirection);
vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection);
float bendFactor = 1.0 - anisotropy * (1.0 - perceptualRoughness);
float bendFactorPow4 = bendFactor * bendFactor * bendFactor * bendFactor;
vec3 bentNormal = normalize(mix(anisotropicNormal, normal_inWorld, bendFactorPow4));
vec3 reflection = rotEnvMatrix * reflect(-viewDirection, bentNormal);
#else
vec3 reflection = rotEnvMatrix * reflect(-viewDirection, normal_inWorld);
#endif
if (get_inverseEnvironment(materialSID, 0)) {
reflection.x *= -1.0;
}
Expand All @@ -396,15 +407,15 @@ vec3 IBLContribution(float materialSID, vec3 normal_inWorld, float NdotV, vec3 v
vec3 albedo, vec3 F0, float perceptualRoughness, float clearcoatRoughness, vec3 clearcoatNormal_inWorld,
float clearcoat, float VdotNc, vec3 geomNormal_inWorld, float cameraSID, float transmission, vec3 v_position_inWorld,
float thickness, vec3 sheenColor, float sheenRoughness, float albedoSheenScalingNdotV, float ior,
vec3 iridescenceFresnel, vec3 iridescenceF0, float iridescence)
vec3 iridescenceFresnel, vec3 iridescenceF0, float iridescence, float anisotropy, vec3 anisotropyDirection)
{
vec4 iblParameter = get_iblParameter(materialSID, 0);
float rot = iblParameter.w + 3.1415;
mat3 rotEnvMatrix = mat3(cos(rot), 0.0, -sin(rot), 0.0, 1.0, 0.0, sin(rot), 0.0, cos(rot));
ivec2 hdriFormat = get_hdriFormat(materialSID, 0);

vec3 normal_forEnv = getNormalForEnv(rotEnvMatrix, normal_inWorld, materialSID);
vec3 reflection = getReflection(rotEnvMatrix, viewDirection, normal_inWorld, materialSID);
vec3 reflection = getReflection(rotEnvMatrix, viewDirection, normal_inWorld, materialSID, perceptualRoughness, anisotropy, anisotropyDirection);

// IBL
#ifdef RN_USE_IRIDESCENCE
Expand Down Expand Up @@ -451,9 +462,8 @@ vec3 IBLContribution(float materialSID, vec3 normal_inWorld, float NdotV, vec3 v
#ifdef RN_USE_CLEARCOAT
float VdotNg = dot(geomNormal_inWorld, viewDirection);
vec3 clearcoatNormal_forEnv = getNormalForEnv(rotEnvMatrix, normal_inWorld, materialSID);
vec3 clearcoatReflection = getReflection(rotEnvMatrix, viewDirection, normal_inWorld, materialSID);
IblResult coatResult = getIBLRadianceGGX(materialSID, VdotNc, viewDirection, vec3(0.0), F0,
clearcoatRoughness, iblParameter, hdriFormat, rotEnvMatrix, clearcoatNormal_forEnv, clearcoatReflection);
clearcoatRoughness, iblParameter, hdriFormat, rotEnvMatrix, clearcoatNormal_forEnv, reflection);
vec3 coatLayer = coatResult.specular;

float clearcoatFresnel = 0.04 + (1.0 - 0.04) * pow(1.0 - abs(VdotNc), 5.0);
Expand Down Expand Up @@ -558,9 +568,12 @@ void main ()
direction = mat2(anisotropyRotation.x, anisotropyRotation.y, -anisotropyRotation.y, anisotropyRotation.x) * normalize(direction);
anisotropy *= anisotropyTex.b;
vec3 anisotropicT = normalize(TBN * vec3(direction, 0.0));
vec3 anisotropicB = normalize(cross(normal_geometric, anisotropicT));
vec3 anisotropicB = normalize(cross(geomNormal_inWorld, anisotropicT));
float BdotV = dot(anisotropicB, viewDirection);
float TdotV = dot(anisotropicT, viewDirection);
#else
float anisotropy = 0.0;
vec3 anisotropicB = vec3(0.0, 0.0, 0.0);
#endif

// Clearcoat
Expand Down Expand Up @@ -809,7 +822,7 @@ void main ()
vec3 ibl = IBLContribution(materialSID, normal_inWorld, NdotV, viewDirection,
albedo, F0, perceptualRoughness, clearcoatRoughness, clearcoatNormal_inWorld,
clearcoat, VdotNc, geomNormal_inWorld, cameraSID, transmission, v_position_inWorld.xyz, thickness,
sheenColor, sheenRoughness, albedoSheenScalingNdotV, ior, iridescenceFresnel, iridescenceF0, iridescence);
sheenColor, sheenRoughness, albedoSheenScalingNdotV, ior, iridescenceFresnel, iridescenceF0, iridescence, anisotropy, anisotropicB);

int occlusionTexcoordIndex = get_occlusionTexcoordIndex(materialSID, 0);
vec2 occlusionTexcoord = getTexcoord(occlusionTexcoordIndex);
Expand Down

0 comments on commit fa589d3

Please sign in to comment.