Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new shaders #118

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
346 changes: 217 additions & 129 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"version": "0.0.0-development",
"private": true,
"dependencies": {
"@babylonjs/core": "^4.2.2",
"@babylonjs/gui": "^4.2.2",
"@babylonjs/inspector": "^4.2.2",
"@babylonjs/loaders": "^4.2.2",
"@babylonjs/materials": "^4.2.2",
"@babylonjs/core": "^7.32.0",
"@babylonjs/gui": "^7.32.0",
"@babylonjs/inspector": "^7.32.0",
"@babylonjs/loaders": "^7.32.0",
"@babylonjs/materials": "^7.32.0",
"@dcl/schemas": "^11.5.0",
"@dcl/ui-env": "^1.2.0",
"@testing-library/jest-dom": "^5.15.0",
Expand Down Expand Up @@ -71,4 +71,4 @@
"printWidth": 120
},
"homepage": ""
}
}
88 changes: 44 additions & 44 deletions src/components/Preview/Preview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react'
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'
import classNames from 'classnames'
import { PreviewCamera, PreviewType, PreviewMessageType, sendMessage, PreviewEmote } from '@dcl/schemas'
import { useWindowSize } from '../../hooks/useWindowSize'
Expand Down Expand Up @@ -29,14 +29,51 @@ const Preview: React.FC = () => {
const showImage = !!image && !is3D && !isLoading
const showCanvas = is3D && !isLoading

// send a mesasge to the parent window when loaded or error occurs
useEffect(() => {
if (!isMessageSent) {
if (isLoaded) {
sendMessage(getParent(), PreviewMessageType.LOAD, null)
setIsMessageSent(true)
if (config?.type === PreviewType.AVATAR || (config?.emote && config.emote !== PreviewEmote.IDLE)) {
controller.current?.emote.play()
}
} else if (error) {
sendMessage(getParent(), PreviewMessageType.ERROR, { message: error })
setIsMessageSent(true)
}
}
}, [isLoaded, error, isMessageSent, controller, config?.type, config?.emote])

// when the config is being loaded again (because the was an update to some of the options) reset all the other loading flags
useEffect(() => {
if (isLoadingConfig) {
let shouldResetIsLoaded = false
if (!isLoadingModel) {
setIsLoadingModel(true)
shouldResetIsLoaded = true
}
if (isMessageSent) {
setIsMessageSent(false)
shouldResetIsLoaded = true
}
if (shouldResetIsLoaded && isLoaded) {
setIsLoaded(false)
}
}
}, [isLoadingConfig, isLoadingModel, isMessageSent, isLoaded])

// send ready message to parent
useReady()

useLayoutEffect(() => {
let removeEmoteEvents: () => unknown = () => {}
if (canvasRef.current && config) {
if (canvasRef?.current && config) {
let style: React.CSSProperties = { opacity: 1 } // fade in effect

// set background image
if (config.background.image) {
setImage(config.background.image)
if (config?.background?.image) {
setImage(config?.background?.image)
style.opacity = 1
// if rendering a texture, babylon won't render the background, so we do it by css
if (!config.background.transparent && config.type === PreviewType.TEXTURE) {
Expand All @@ -47,13 +84,13 @@ const Preview: React.FC = () => {
setStyle(style)

// load model or image (for texture only wearables)
if (config.type === PreviewType.TEXTURE) {
if (config?.type === PreviewType?.TEXTURE) {
setIs3D(false)
setIsLoadingModel(false)
setIsLoaded(true)
} else {
// preview models
render(canvasRef.current, config)
render(canvasRef?.current, config)
.then((newController) => {
// set new controller as current one
controller.current = newController
Expand All @@ -71,44 +108,7 @@ const Preview: React.FC = () => {
return () => {
removeEmoteEvents()
}
}, [canvasRef.current, config]) // eslint-disable-line

// send a mesasge to the parent window when loaded or error occurs
useEffect(() => {
if (!isMessageSent) {
if (isLoaded) {
sendMessage(getParent(), PreviewMessageType.LOAD, null)
setIsMessageSent(true)
if (config?.type === PreviewType.AVATAR || (config?.emote && config.emote !== PreviewEmote.IDLE)) {
controller.current?.emote.play()
}
} else if (error) {
sendMessage(getParent(), PreviewMessageType.ERROR, { message: error })
setIsMessageSent(true)
}
}
}, [isLoaded, error, isMessageSent, controller, config?.type, config?.emote])

// when the config is being loaded again (because the was an update to some of the options) reset all the other loading flags
useEffect(() => {
if (isLoadingConfig) {
let shouldResetIsLoaded = false
if (!isLoadingModel) {
setIsLoadingModel(true)
shouldResetIsLoaded = true
}
if (isMessageSent) {
setIsMessageSent(false)
shouldResetIsLoaded = true
}
if (shouldResetIsLoaded && isLoaded) {
setIsLoaded(false)
}
}
}, [isLoadingConfig, isLoadingModel, isMessageSent, isLoaded])

// send ready message to parent
useReady()
}, [canvasRef?.current, config]) // eslint-disable-line

return (
<div
Expand Down
134 changes: 134 additions & 0 deletions src/lib/babylon/explorer-alpha-shader/OutlineFragment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
export const customOutlineFragmentShader = `#version 300 es
precision highp float;

in vec4 pos;
in vec2 uv0;

uniform mat4 world;
uniform mat4 worldView;
uniform mat4 worldViewProjection;
uniform sampler2D sampler_MainTex;
uniform vec4 _LightColor0;
uniform vec4 _BaseColor;
uniform vec4 unity_AmbientEquator;
uniform vec4 envLightSource_SkyboxIntensity;
uniform float _Unlit_Intensity;
uniform float _Is_LightColor_Outline;
uniform vec4 sampler_MainTex_ST;
uniform vec4 _Outline_Color;
uniform float _Is_BlendBaseColor;
uniform float _Inverse_Clipping;
uniform float _Clipping_Level;

uniform sampler2D textureSampler;

// SH block feature
vec4 unity_SHAr = vec4( 0.00f, -0.00973f, 0.00f, 0.41196f );
vec4 unity_SHAg = vec4( 0.00f, 0.10704f, 0.00f, 0.30608f );
vec4 unity_SHAb = vec4( 0.00f, 0.12774f, 0.00f, 0.44097f );
vec4 unity_SHBr = vec4( 0.00f, 0.00f, 0.0337f, 0.00f );
vec4 unity_SHBg = vec4( 0.00f, 0.00f, 0.02523f, 0.00f );
vec4 unity_SHBb = vec4( 0.00f, 0.00f, 0.05021f, 0.00f );
vec4 unity_SHC = vec4( 0.0337f, 0.02523f, 0.05021f, 1.00f );

#define TRANSFORM_TEX(tex, name) ((tex.xy) * sampler_MainTex_ST.xy + sampler_MainTex_ST.zw)
//#define SAMPLE_MAINTEX(uv) texture(sampler_MainTex, uv)
#define SAMPLE_MAINTEX(uv) texture(textureSampler, uv)

out vec4 fragColor;

vec3 LinearToGammaSpace (vec3 linRGB)
{
linRGB = max(linRGB, vec3(0.0, 0.0, 0.0));
linRGB.r = pow(linRGB.r, 0.416666667);
linRGB.g = pow(linRGB.g, 0.416666667);
linRGB.b = pow(linRGB.b, 0.416666667);
// An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return max(1.055 * linRGB - 0.055, vec3(0.0));

// Exact version, useful for debugging.
//return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));
}

// normal should be normalized, w=1.0
vec3 SHEvalLinearL0L1(vec4 normal)
{
vec3 x;

// Linear (L1) + constant (L0) polynomial terms
x.r = dot(unity_SHAr, normal);
x.g = dot(unity_SHAg, normal);
x.b = dot(unity_SHAb, normal);

return x;
}

// normal should be normalized, w=1.0
vec3 SHEvalLinearL2(vec4 normal)
{
vec3 x1, x2;
// 4 of the quadratic (L2) polynomials
vec4 vB = normal.xyzz * normal.yzzx;
x1.r = dot(unity_SHBr, vB);
x1.g = dot(unity_SHBg, vB);
x1.b = dot(unity_SHBb, vB);

// Final (5th) quadratic (L2) polynomial
float vC = normal.x*normal.x - normal.y*normal.y;
x2 = unity_SHC.rgb * vC;

return x1 + x2;
}

// normal should be normalized, w=1.0
// output in active color space
vec3 ShadeSH9(vec4 normal)
{
// Linear + constant polynomial terms
vec3 res = SHEvalLinearL0L1(normal);

// Quadratic polynomials
res += SHEvalLinearL2(normal);

#ifdef UNITY_COLORSPACE_GAMMA
res = LinearToGammaSpace(res);
#endif

return res;
}

void main(void)
{
if (gl_FrontFacing)
discard;

vec4 objPos = world * vec4(0,0,0,1);

vec3 envLightSource_GradientEquator = unity_AmbientEquator.rgb;
vec3 envLightSource_SkyboxIntensity = max(ShadeSH9(vec4(0.0f, 0.0f, 0.0f, 1.0f)),ShadeSH9(vec4(0.0f, -1.0f, 0.0f, 1.0f))).rgb;
vec3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb * _Unlit_Intensity; // : envLightSource_GradientEquator*_Unlit_Intensity;

vec3 lightColor = _LightColor0.rgb;// >0.05f ? _LightColor0.rgb : ambientSkyColor.rgb;
float lightColorIntensity = (0.299f*lightColor.r + 0.587f*lightColor.g + 0.114f*lightColor.b);
lightColor = lightColorIntensity<1.0f ? lightColor : lightColor/lightColorIntensity;
lightColor = mix(vec3(1.0f, 1.0f, 1.0f), lightColor, _Is_LightColor_Outline);

vec2 Set_UV0 = uv0;

vec2 uv_maintex = TRANSFORM_TEX(Set_UV0, _MainTex);
uv_maintex = Set_UV0; // TEST
vec4 _MainTex_var = SAMPLE_MAINTEX(uv_maintex);

vec3 Set_BaseColor = _BaseColor.rgb*_MainTex_var.rgb;
vec3 _Is_BlendBaseColor_var = mix( _Outline_Color.rgb*lightColor, (_Outline_Color.rgb*Set_BaseColor*Set_BaseColor*lightColor), _Is_BlendBaseColor );

float Set_MainTexAlpha = _MainTex_var.a;
float _IsBaseMapAlphaAsClippingMask_var = Set_MainTexAlpha;
float _Inverse_Clipping_var = mix( _IsBaseMapAlphaAsClippingMask_var, (1.0f - _IsBaseMapAlphaAsClippingMask_var), _Inverse_Clipping );
float Set_Clipping = clamp((_Inverse_Clipping_var+_Clipping_Level), 0.0f, 1.0f);
if ((Set_MainTexAlpha - 0.5f) <= 0.0f)
discard;
vec4 Set_Outline_Color = vec4(_Is_BlendBaseColor_var,Set_Clipping);
fragColor = Set_Outline_Color;
//fragColor = _MainTex_var;
}`
24 changes: 24 additions & 0 deletions src/lib/babylon/explorer-alpha-shader/OutlineShader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ShaderMaterial, ShaderLanguage, Scene, Effect } from '@babylonjs/core'
import { customOutlineFragmentShader } from './OutlineFragment'
import { customOutlineVertexShader } from './OutlineVertex'

export function createOutlineShader(scene: Scene, shaderId: string) {
Effect.ShadersStore['customOutlineVertexShader'] = customOutlineVertexShader;
Effect.ShadersStore['customOutlineFragmentShader'] = customOutlineFragmentShader;
return new ShaderMaterial(
shaderId,
scene,
{
vertex: 'customOutlineVertexShader',
fragment: 'customOutlineFragmentShader',
},
{
attributes: ['position', 'normal'],
uniforms: ['worldViewProjection', '_BaseColor'],
uniformBuffers: undefined,
samplers: ['sampler_MainTex'],
defines: [],
shaderLanguage: ShaderLanguage.GLSL,
}
)
}
44 changes: 44 additions & 0 deletions src/lib/babylon/explorer-alpha-shader/OutlineVertex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
export const customOutlineVertexShader = `#version 300 es
precision highp float;

// Attributes
in vec3 position;
in vec2 uv;
in vec3 normal;
//in vec4 tangent;

// Uniforms
uniform mat4 worldView;
uniform mat4 worldViewProjection;
uniform float _Outline_Width;
uniform float _Nearest_Distance;
uniform float _Farthest_Distance;
uniform float _ZOverDrawMode;
uniform float _Offset_Z;

// Varying
out vec4 pos;
out vec2 uv0;

void main(void)
{
// gl_Position = worldViewProjection * vec4(position, 1.0);

// vUV = uv;

uv0 = uv;
vec4 objPos = worldViewProjection * vec4(0.0f,0.0f,0.0f,1.0f);

vec3 cameraPos = vec3(worldView[3][0], worldView[3][1], worldView[3][2]);
float Set_Outline_Width = (_Outline_Width*0.001f*smoothstep( _Farthest_Distance, _Nearest_Distance, distance(objPos.rgb,cameraPos)));
Set_Outline_Width *= (1.0f - _ZOverDrawMode);


vec4 _ClipCameraPos = worldViewProjection * vec4(cameraPos.xyz, 1.0f);

pos = worldViewProjection * vec4(position.xyz + normal*Set_Outline_Width,1.0f);
float fOffset_Z = _Offset_Z * 0.01f;
pos.z = pos.z + _Offset_Z * _ClipCameraPos.z;
gl_Position = pos;
// return o;
}`
12 changes: 12 additions & 0 deletions src/lib/babylon/explorer-alpha-shader/basic_fragment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const customBasicFragmentShader = `#version 300 es
precision highp float;

in vec2 vUV;

uniform sampler2D textureSampler;

out vec4 fragColor;

void main(void) {
fragColor = texture(textureSampler, vUV);
}`
18 changes: 18 additions & 0 deletions src/lib/babylon/explorer-alpha-shader/basic_vertex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const customBasicVertexShader = `#version 300 es
precision highp float;

// Attributes
in vec3 position;
in vec2 uv;

// Uniforms
uniform mat4 worldViewProjection;

// Varying
out vec2 vUV;

void main(void) {
gl_Position = worldViewProjection * vec4(position, 1.0);

vUV = uv;
}`
Loading