Reorganised shaders
This commit is contained in:
parent
b75cee8638
commit
5306ce4535
12 changed files with 318 additions and 472 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
//! type chunk
|
||||||
|
|
||||||
layout( location = 0 ) uniform float u_Time;
|
layout( location = 0 ) uniform float u_Time;
|
||||||
layout( location = 1 ) uniform vec2 u_Resolution;
|
layout( location = 1 ) uniform vec2 u_Resolution;
|
||||||
layout( location = 2 ) uniform vec3 u_CamPos;
|
layout( location = 2 ) uniform vec3 u_CamPos;
|
||||||
|
@ -7,16 +9,7 @@ layout( location = 5 ) uniform float u_NearPlane;
|
||||||
layout( location = 6 ) uniform vec3 u_LightDir;
|
layout( location = 6 ) uniform vec3 u_LightDir;
|
||||||
layout( location = 7 ) uniform vec4 u_Render;
|
layout( location = 7 ) uniform vec4 u_Render;
|
||||||
|
|
||||||
vec3 camPos , lookAt , camUp;
|
|
||||||
float nearPlane;
|
|
||||||
|
|
||||||
layout( location = 0 ) out vec3 o_Color;
|
layout( location = 0 ) out vec3 o_Color;
|
||||||
layout( location = 1 ) out float o_Z;
|
layout( location = 1 ) out float o_Z;
|
||||||
|
|
||||||
void setCamFromUniforms( ) {
|
//! include lib/raymarching.glsl
|
||||||
camPos = u_CamPos;
|
|
||||||
lookAt = u_LookAt;
|
|
||||||
camUp = u_CamUp;
|
|
||||||
nearPlane = u_NearPlane;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
//! type fragment
|
//! type fragment
|
||||||
//! include dof-common.i.glsl
|
//! include chunks/dof.glsl
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
//! type fragment
|
//! type fragment
|
||||||
//! include dof-common.i.glsl
|
//! include chunks/dof.glsl
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
90
shaders/lib/raymarching.glsl
Normal file
90
shaders/lib/raymarching.glsl
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
//! type library
|
||||||
|
|
||||||
|
vec2 RM_Map( in vec3 pos );
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
vec3 RM_GetNormal(
|
||||||
|
in vec3 pos )
|
||||||
|
{
|
||||||
|
vec2 v = vec2( .0005 , 0 );
|
||||||
|
return normalize( vec3(
|
||||||
|
RM_Map( pos + v.xyy ).x - RM_Map( pos - v.xyy ).x ,
|
||||||
|
RM_Map( pos + v.yxy ).x - RM_Map( pos - v.yxy ).x ,
|
||||||
|
RM_Map( pos + v.yyx ).x - RM_Map( pos - v.yyx ).x ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
vec3 RM_Basic(
|
||||||
|
in vec3 origin ,
|
||||||
|
in vec3 direction ,
|
||||||
|
in int steps ,
|
||||||
|
in float factor ,
|
||||||
|
in float epsilon ,
|
||||||
|
in float dMin ,
|
||||||
|
in float dMax )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
float dist = dMin , mat = -1;
|
||||||
|
|
||||||
|
for ( ; i < steps ; ++ i ) {
|
||||||
|
vec2 res = RM_Map( origin + direction * dist );
|
||||||
|
if ( abs( res.x ) < epsilon || dist > dMax ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dist += res.x * factor;
|
||||||
|
mat = res.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec3( dist , dist >= dMax ? -1 : mat , i );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 RM_Advanced(
|
||||||
|
in vec3 origin ,
|
||||||
|
in vec3 direction ,
|
||||||
|
in int steps ,
|
||||||
|
in float factor ,
|
||||||
|
in float epsilon ,
|
||||||
|
in float dMin ,
|
||||||
|
in float dMax )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
float dist = dMin ,
|
||||||
|
omega = factor ,
|
||||||
|
cError = 1 / 0. ,
|
||||||
|
cDist = dMin ,
|
||||||
|
pRad = 0 ,
|
||||||
|
sLen = 0;
|
||||||
|
|
||||||
|
for ( ; i < steps ; ++ i ) {
|
||||||
|
vec2 res = RM_Map( origin + direction * dist );
|
||||||
|
float rad = abs( res.x );
|
||||||
|
|
||||||
|
bool sorFail = omega > 1 && ( rad + pRad ) < sLen;
|
||||||
|
if ( sorFail ) {
|
||||||
|
sLen -= omega * sLen;
|
||||||
|
omega = 1;
|
||||||
|
} else {
|
||||||
|
sLen = res.x * omega;
|
||||||
|
}
|
||||||
|
pRad = rad;
|
||||||
|
|
||||||
|
float error = rad / dist;
|
||||||
|
if ( !sorFail && error < cError ) {
|
||||||
|
cError = error;
|
||||||
|
cDist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !sorFail && error < epsilon || dist > dMax ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist += sLen;
|
||||||
|
}
|
||||||
|
if ( dist <= dMax && cError <= epsilon ) {
|
||||||
|
return vec3( cDist , RM_Map( origin + direction * cDist ).y , i );
|
||||||
|
}
|
||||||
|
return vec3( cDist , -1 , steps );
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! type library
|
||||||
|
|
||||||
struct T_BPMaterial
|
struct T_BPMaterial
|
||||||
{
|
{
|
||||||
vec3 cAlbedo, cSpecular;
|
vec3 cAlbedo, cSpecular;
|
111
shaders/lib/shading-pbr.glsl
Normal file
111
shaders/lib/shading-pbr.glsl
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
//! type library
|
||||||
|
//! include lib/utils.glsl
|
||||||
|
|
||||||
|
|
||||||
|
struct T_PBRMaterial
|
||||||
|
{
|
||||||
|
vec3 cAlbedo;
|
||||||
|
float roughness;
|
||||||
|
float metallic;
|
||||||
|
float subsurface;
|
||||||
|
float anisotropy;
|
||||||
|
float specular; // Specular strengh for non-metals
|
||||||
|
float specularTint; // Albedo color% in specular tint (non-metals)
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
float PBR_SchlickFresnel(
|
||||||
|
in float u )
|
||||||
|
{
|
||||||
|
const float m = clamp( 1 - u , 0 , 1 ) ,
|
||||||
|
m2 = m * m;
|
||||||
|
return m2 * m2 * m;
|
||||||
|
}
|
||||||
|
|
||||||
|
float PBR_GTR2Aniso(
|
||||||
|
in float nDotH ,
|
||||||
|
in float hDotX ,
|
||||||
|
in float hDotY ,
|
||||||
|
in float ax ,
|
||||||
|
in float ay )
|
||||||
|
{
|
||||||
|
float x = hDotX / ax , y = hDotY / ay ,
|
||||||
|
p = x * x + y * y + nDotH * nDotH;
|
||||||
|
return 1 / ( PI * ax * ay * p * p );
|
||||||
|
}
|
||||||
|
|
||||||
|
float PBR_SmithGGXAniso(
|
||||||
|
in float nDotV ,
|
||||||
|
in float vDotX ,
|
||||||
|
in float vDotY ,
|
||||||
|
in float ax ,
|
||||||
|
in float ay )
|
||||||
|
{
|
||||||
|
float x = vDotX * ax , y = vDotY * ay;
|
||||||
|
return 1 / ( nDotV + sqrt( x * x + y * y + nDotV * nDotV ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 PBR_Shade(
|
||||||
|
in T_PBRMaterial material ,
|
||||||
|
in vec3 camDir ,
|
||||||
|
in vec3 normal ,
|
||||||
|
in vec3 lightDir )
|
||||||
|
{
|
||||||
|
float nDotL = dot( normal , lightDir ) ,
|
||||||
|
nDotV = dot( normal , camDir );
|
||||||
|
if ( nDotL < 0 || nDotV < 0 ) {
|
||||||
|
return vec3( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 tangent = cross( vec3( 0 , 1 , 0 ) , normal );
|
||||||
|
if ( length( tangent ) == 0 ) {
|
||||||
|
tangent = cross( vec3( 1 , 0 , 0 ) , normal );
|
||||||
|
}
|
||||||
|
tangent = normalize( tangent );
|
||||||
|
vec3 bitangent = normalize( cross( normal , tangent ) );
|
||||||
|
|
||||||
|
vec3 halfVec = normalize( lightDir + camDir ) ,
|
||||||
|
tint = M_NormalizeColor( material.cAlbedo ) ,
|
||||||
|
cSpecular = mix( material.specular * .08 * mix(
|
||||||
|
vec3( 1 ) , tint , material.specularTint ) ,
|
||||||
|
material.cAlbedo , material.metallic );
|
||||||
|
//vec3 Csheen = mix(vec3(1), Ctint, sheenTint);
|
||||||
|
|
||||||
|
float nDotH = dot( normal , halfVec ) ,
|
||||||
|
lDotH = dot( lightDir , halfVec ) ,
|
||||||
|
|
||||||
|
// Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
|
||||||
|
// and mix in diffuse retro-reflection based on roughness
|
||||||
|
FL = PBR_SchlickFresnel( nDotL ) ,
|
||||||
|
FV = PBR_SchlickFresnel( nDotV ) ,
|
||||||
|
Fd90 = 0.5 + 2 * lDotH * lDotH * material.roughness ,
|
||||||
|
Fd = mix( 1 , Fd90 , FL ) * mix( 1 , Fd90 , FV ) ,
|
||||||
|
|
||||||
|
// Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
|
||||||
|
// 1.25 scale is used to (roughly) preserve albedo
|
||||||
|
// Fss90 used to "flatten" retroreflection based on roughness
|
||||||
|
Fss90 = lDotH * lDotH * material.roughness ,
|
||||||
|
Fss = mix( 1 , Fss90 , FL ) * mix( 1 , Fss90 , FV ) ,
|
||||||
|
ss = 1.25 * ( Fss * ( 1 / ( nDotL + nDotV ) - .5 ) + .5 ) ,
|
||||||
|
|
||||||
|
// Specular
|
||||||
|
aspect = sqrt( 1 - material.anisotropy * .9 ) ,
|
||||||
|
rsqr = material.roughness * material.roughness ,
|
||||||
|
ax = max( .001, rsqr / aspect ) ,
|
||||||
|
ay = max( .001, rsqr * aspect ) ,
|
||||||
|
Ds = PBR_GTR2Aniso( nDotH , dot( halfVec , tangent ) ,
|
||||||
|
dot( halfVec , bitangent ) , ax , ay ) ,
|
||||||
|
FH = PBR_SchlickFresnel( lDotH ) ,
|
||||||
|
Gs = PBR_SmithGGXAniso( nDotL , dot( lightDir , tangent ) ,
|
||||||
|
dot( lightDir , bitangent ) , ax , ay )
|
||||||
|
* PBR_SmithGGXAniso( nDotV , dot( camDir , tangent ) ,
|
||||||
|
dot( camDir , bitangent ) , ax , ay );
|
||||||
|
|
||||||
|
vec3 Fs = mix( cSpecular , vec3(1) , FH );
|
||||||
|
return nDotL * ( ( ( 1 / PI )
|
||||||
|
* mix( Fd , ss , material.subsurface )
|
||||||
|
* material.cAlbedo /* + Fsheen */)
|
||||||
|
* pow( 1 - material.metallic , 3 )
|
||||||
|
+ clamp( Gs , 0 , 1 ) * Fs * Ds );
|
||||||
|
}
|
|
@ -1,11 +1,30 @@
|
||||||
//! type library
|
//! type library
|
||||||
|
|
||||||
|
|
||||||
|
const float PI = 3.14159265;
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
float M_Hash( in vec2 p )
|
float M_Hash(
|
||||||
|
in vec2 p )
|
||||||
{
|
{
|
||||||
p = fract(p * vec2(5.3987, 5.4421));
|
p = fract(p * vec2(5.3987, 5.4421));
|
||||||
p += dot(p.yx, p.xy + vec2(21.5351, 14.3137));
|
p += dot(p.yx, p.xy + vec2(21.5351, 14.3137));
|
||||||
return fract(p.x * p.y * 95.4307);
|
return fract(p.x * p.y * 95.4307);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
float M_Luminosity(
|
||||||
|
in vec3 color )
|
||||||
|
{
|
||||||
|
return dot( color , vec3( .3 , .6 , .1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 M_NormalizeColor(
|
||||||
|
in vec3 color )
|
||||||
|
{
|
||||||
|
const float l = M_Luminosity( color );
|
||||||
|
return l > 0 ? ( color / l ) : vec3( 1 );
|
||||||
|
}
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
#define USE_GLOW
|
|
||||||
#define USE_MAP_MATERIAL
|
|
||||||
|
|
||||||
T_BPMaterial BPMaterials[1] = {
|
|
||||||
{ vec3( 1 , 1 , .4 ) * .1 , vec3( 1 , 1 , .4 ) , 40 , .1 }
|
|
||||||
};
|
|
||||||
|
|
||||||
T_PBRMaterialOld PBRMaterialsOld[1] = {
|
|
||||||
{
|
|
||||||
// Albedo / specular colors
|
|
||||||
vec3( 1 , 1 , 0 ) , vec3( 1 , 1 , .4 ) * .1 ,
|
|
||||||
// Roughness , anisotropy , subsurface , metallic
|
|
||||||
.8 , .8 , .1 , .9
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
T_PBRMaterial PBRMaterials[1] = {
|
|
||||||
{
|
|
||||||
// Albedo color
|
|
||||||
vec3( 1 , 1 , .4 ) ,
|
|
||||||
// Roughness , metallic , subsurface , anisotropy
|
|
||||||
.4 , .7 , 1 , .1 ,
|
|
||||||
// Specular strength / tint%
|
|
||||||
.5 , .5
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
vec3 Glow[1] = {
|
|
||||||
vec3( 2 , .4 , 5 ) * 4
|
|
||||||
};
|
|
||||||
|
|
||||||
void mapMaterial(
|
|
||||||
in int matIndex ,
|
|
||||||
out int type ,
|
|
||||||
out int tIndex ,
|
|
||||||
out int glowIndex )
|
|
||||||
{
|
|
||||||
if ( matIndex == 0 ) {
|
|
||||||
glowIndex = -1;
|
|
||||||
} else {
|
|
||||||
//type = 1;
|
|
||||||
glowIndex = 0;
|
|
||||||
}
|
|
||||||
type = 1;
|
|
||||||
tIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 map( vec3 pos )
|
|
||||||
{
|
|
||||||
pos = pos - vec3( 0 , 0 , 0 );
|
|
||||||
vec3 q = pos;
|
|
||||||
q.xy = mod( q.xy + 4. , 8. ) - 4.;
|
|
||||||
return vec2( length( q ) - 1.8 , step( 0. , 1.9 - length( pos.xy ) ) );
|
|
||||||
}
|
|
255
shaders/pbr.glsl
255
shaders/pbr.glsl
|
@ -1,255 +0,0 @@
|
||||||
//! type library
|
|
||||||
|
|
||||||
struct T_PBRMaterialOld
|
|
||||||
{
|
|
||||||
vec3 cAlbedo, cSpecular;
|
|
||||||
float roughness , anisotropy , subsurface , metallic;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct T_PBRPrecomputedOld
|
|
||||||
{
|
|
||||||
float nDotC;
|
|
||||||
float ffndc; // Fresnel from n.c
|
|
||||||
vec3 tangent, bitangent;
|
|
||||||
float specAlpha , viewSpecular;
|
|
||||||
float aAspectX , aAspectY; // Anisotropy
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
float PBR_FresnelFromOld( in float dotProduct ) {
|
|
||||||
float d = clamp( 1.0 - dotProduct , 0 , 1 ) , d2 = d * d;
|
|
||||||
return d2 * d2 * d;
|
|
||||||
}
|
|
||||||
|
|
||||||
float PBR_GetSpecularOld( in float cosine , in float alpha )
|
|
||||||
{
|
|
||||||
float cs = cosine * cosine;
|
|
||||||
float as = alpha * alpha;
|
|
||||||
return clamp( 1. / ( cosine + sqrt( cs + as - cs * as ) ) , 0 , 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Precompute some of the material's properties. This is independant of the
|
|
||||||
// light source.
|
|
||||||
T_PBRPrecomputedOld PBR_PrecomputeOld(
|
|
||||||
in T_PBRMaterialOld material ,
|
|
||||||
in vec3 rayDir ,
|
|
||||||
in vec3 normal )
|
|
||||||
{
|
|
||||||
T_PBRPrecomputedOld rv;
|
|
||||||
|
|
||||||
rv.nDotC = dot( normal , rayDir );
|
|
||||||
rv.ffndc = PBR_FresnelFromOld( rv.nDotC );
|
|
||||||
|
|
||||||
rv.tangent = cross( vec3( 0. , 1. , 0. ) , normal );
|
|
||||||
if ( length( rv.tangent ) == 0.0 ) {
|
|
||||||
rv.tangent = cross( vec3( 1. , 0. , 0. ) , normal );
|
|
||||||
}
|
|
||||||
rv.tangent = normalize( rv.tangent );
|
|
||||||
rv.bitangent = normalize( cross( normal , rv.tangent ) );
|
|
||||||
|
|
||||||
rv.specAlpha = pow( material.roughness * .5 + .5 , 2. );
|
|
||||||
rv.viewSpecular = PBR_GetSpecularOld( rv.nDotC , rv.specAlpha );
|
|
||||||
|
|
||||||
const float sRoughness = material.roughness * material.roughness;
|
|
||||||
const float aspect = sqrt( 1.0 - material.anisotropy * .9 );
|
|
||||||
rv.aAspectX = max( .001, sRoughness / aspect );
|
|
||||||
rv.aAspectY = max( .001, sRoughness * aspect );
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually compute a light source's contribution
|
|
||||||
vec3 PBR_ShadeOld(
|
|
||||||
in T_PBRMaterialOld material ,
|
|
||||||
in T_PBRPrecomputedOld precomputed ,
|
|
||||||
in vec3 rayDir ,
|
|
||||||
in vec3 normal ,
|
|
||||||
in vec3 lightDir )
|
|
||||||
{
|
|
||||||
const float nDotL = dot( normal , lightDir );
|
|
||||||
if ( nDotL <= 0. ) {
|
|
||||||
return vec3( 0. );
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: should be in common part
|
|
||||||
float lSpecular = dot( material.cSpecular , vec3( .3 , .6 , .1 ) );
|
|
||||||
vec3 cSpecular = lSpecular > 0 ? ( material.cSpecular / lSpecular ) : vec3( 1 );
|
|
||||||
|
|
||||||
const vec3 halfVec = normalize( lightDir + rayDir );
|
|
||||||
const float nDotH = dot( normal , halfVec );
|
|
||||||
const float lDotH = dot( lightDir , halfVec );
|
|
||||||
|
|
||||||
const float ffndl = PBR_FresnelFromOld( nDotL );
|
|
||||||
float grazingDiffuse = lDotH * lDotH * material.roughness;
|
|
||||||
float dSubsurface = mix( 1.0 , grazingDiffuse , ffndl )
|
|
||||||
* mix( 1.0 , grazingDiffuse , precomputed.ffndc );
|
|
||||||
dSubsurface = 1.25 * ( dSubsurface * ( 1.0 / ( nDotL + precomputed.nDotC ) - .5 ) + .5 );
|
|
||||||
grazingDiffuse = .5 + 2. * grazingDiffuse;
|
|
||||||
const float dFresnel = mix( 1.0 , grazingDiffuse , ffndl )
|
|
||||||
* mix( 1.0 , grazingDiffuse , precomputed.ffndc );
|
|
||||||
|
|
||||||
float specular = PBR_GetSpecularOld( nDotL , precomputed.specAlpha )
|
|
||||||
* precomputed.viewSpecular;
|
|
||||||
specular = mix( specular , 1.0 , PBR_FresnelFromOld( lDotH ) );
|
|
||||||
|
|
||||||
const vec3 d = vec3(
|
|
||||||
dot( halfVec , precomputed.tangent ) / precomputed.aAspectX ,
|
|
||||||
dot( halfVec , precomputed.bitangent ) / precomputed.aAspectY ,
|
|
||||||
nDotH );
|
|
||||||
const float ds = dot( d , d );
|
|
||||||
const float anisotropic = precomputed.aAspectX * precomputed.aAspectY
|
|
||||||
* ds * ds * 3.14159265;
|
|
||||||
|
|
||||||
return nDotL * ( material.cAlbedo
|
|
||||||
* mix( dFresnel , dSubsurface , material.subsurface )
|
|
||||||
* pow( 1.0 - material.metallic , 3 )
|
|
||||||
+ specular * cSpecular / anisotropic
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// YAY let's do it again!
|
|
||||||
|
|
||||||
const float PI = 3.14159265;
|
|
||||||
|
|
||||||
float PBR_SchlickFresnel( in float u )
|
|
||||||
{
|
|
||||||
const float m = clamp( 1 - u , 0 , 1 ) ,
|
|
||||||
m2 = m * m;
|
|
||||||
return m2 * m2 * m;
|
|
||||||
}
|
|
||||||
|
|
||||||
float PBR_GTR1( in float nDotH , in float a )
|
|
||||||
{
|
|
||||||
if (a >= 1) {
|
|
||||||
return 1/PI;
|
|
||||||
}
|
|
||||||
float a2 = a * a ,
|
|
||||||
t = 1 + ( a2 - 1 ) * nDotH * nDotH;
|
|
||||||
return ( a2 - 1 ) / ( PI * log( a2 ) * t );
|
|
||||||
}
|
|
||||||
|
|
||||||
float PBR_GTR2( in float nDotH , in float a )
|
|
||||||
{
|
|
||||||
float a2 = a * a ,
|
|
||||||
t = 1 + ( a2 - 1 ) * nDotH * nDotH;
|
|
||||||
return a2 / ( PI * t * t );
|
|
||||||
}
|
|
||||||
|
|
||||||
float PBR_GTR2Aniso( in float nDotH ,
|
|
||||||
in float hDotX ,
|
|
||||||
in float hDotY ,
|
|
||||||
in float ax ,
|
|
||||||
in float ay )
|
|
||||||
{
|
|
||||||
float x = hDotX / ax , y = hDotY / ay ,
|
|
||||||
p = x * x + y * y + nDotH * nDotH;
|
|
||||||
return 1 / ( PI * ax * ay * p * p );
|
|
||||||
}
|
|
||||||
|
|
||||||
float PBR_SmithGGX( in float nDotV , in float alpha )
|
|
||||||
{
|
|
||||||
float a = alpha * alpha , b = nDotV * nDotV;
|
|
||||||
return 1 / ( nDotV + sqrt( a + b - a * b ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
float PBR_SmithGGXAniso( in float nDotV ,
|
|
||||||
in float vDotX ,
|
|
||||||
in float vDotY ,
|
|
||||||
in float ax ,
|
|
||||||
in float ay )
|
|
||||||
{
|
|
||||||
float x = vDotX * ax , y = vDotY * ay;
|
|
||||||
return 1 / ( nDotV + sqrt( x * x + y * y + nDotV * nDotV ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 NormalizeColor( in vec3 color )
|
|
||||||
{
|
|
||||||
float l = dot( color , vec3( .3 , .6 , .1 ) );
|
|
||||||
return l > 0 ? ( color / l ) : vec3( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct T_PBRMaterial
|
|
||||||
{
|
|
||||||
vec3 cAlbedo;
|
|
||||||
float roughness;
|
|
||||||
float metallic;
|
|
||||||
float subsurface;
|
|
||||||
float anisotropy;
|
|
||||||
float specular; // Specular strengh for non-metals
|
|
||||||
float specularTint; // Albedo color% in specular tint (non-metals)
|
|
||||||
};
|
|
||||||
|
|
||||||
vec3 PBR_Shade( in T_PBRMaterial material ,
|
|
||||||
in vec3 camDir ,
|
|
||||||
in vec3 normal ,
|
|
||||||
in vec3 lightDir )
|
|
||||||
{
|
|
||||||
float nDotL = dot( normal , lightDir ) ,
|
|
||||||
nDotV = dot( normal , camDir );
|
|
||||||
if ( nDotL < 0 || nDotV < 0 ) {
|
|
||||||
return vec3( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 tangent = cross( vec3( 0 , 1 , 0 ) , normal );
|
|
||||||
if ( length( tangent ) == 0 ) {
|
|
||||||
tangent = cross( vec3( 1 , 0 , 0 ) , normal );
|
|
||||||
}
|
|
||||||
tangent = normalize( tangent );
|
|
||||||
vec3 bitangent = normalize( cross( normal , tangent ) );
|
|
||||||
|
|
||||||
vec3 halfVec = normalize( lightDir + camDir ) ,
|
|
||||||
tint = NormalizeColor( material.cAlbedo ) ,
|
|
||||||
cSpecular = mix( material.specular * .08 * mix(
|
|
||||||
vec3( 1 ) , tint , material.specularTint ) ,
|
|
||||||
material.cAlbedo , material.metallic );
|
|
||||||
//vec3 Csheen = mix(vec3(1), Ctint, sheenTint);
|
|
||||||
|
|
||||||
float nDotH = dot( normal , halfVec ) ,
|
|
||||||
lDotH = dot( lightDir , halfVec ) ,
|
|
||||||
|
|
||||||
// Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
|
|
||||||
// and mix in diffuse retro-reflection based on roughness
|
|
||||||
FL = PBR_SchlickFresnel( nDotL ) ,
|
|
||||||
FV = PBR_SchlickFresnel( nDotV ) ,
|
|
||||||
Fd90 = 0.5 + 2 * lDotH * lDotH * material.roughness ,
|
|
||||||
Fd = mix( 1 , Fd90 , FL ) * mix( 1 , Fd90 , FV ) ,
|
|
||||||
|
|
||||||
// Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
|
|
||||||
// 1.25 scale is used to (roughly) preserve albedo
|
|
||||||
// Fss90 used to "flatten" retroreflection based on roughness
|
|
||||||
Fss90 = lDotH * lDotH * material.roughness ,
|
|
||||||
Fss = mix( 1 , Fss90 , FL ) * mix( 1 , Fss90 , FV ) ,
|
|
||||||
ss = 1.25 * ( Fss * ( 1 / ( nDotL + nDotV ) - .5 ) + .5 ) ,
|
|
||||||
|
|
||||||
// Specular
|
|
||||||
aspect = sqrt( 1 - material.anisotropy * .9 ) ,
|
|
||||||
rsqr = material.roughness * material.roughness ,
|
|
||||||
ax = max( .001, rsqr / aspect ) ,
|
|
||||||
ay = max( .001, rsqr * aspect ) ,
|
|
||||||
Ds = PBR_GTR2Aniso( nDotH , dot( halfVec , tangent ) ,
|
|
||||||
dot( halfVec , bitangent ) , ax , ay ) ,
|
|
||||||
FH = PBR_SchlickFresnel( lDotH ) ,
|
|
||||||
Gs = PBR_SmithGGXAniso( nDotL , dot( lightDir , tangent ) ,
|
|
||||||
dot( lightDir , bitangent ) , ax , ay )
|
|
||||||
* PBR_SmithGGXAniso( nDotV , dot( camDir , tangent ) ,
|
|
||||||
dot( camDir , bitangent ) , ax , ay );
|
|
||||||
|
|
||||||
// sheen
|
|
||||||
//vec3 Fsheen = FH * sheen * Csheen;
|
|
||||||
|
|
||||||
// clearcoat (ior = 1.5 -> F0 = 0.04)
|
|
||||||
/*
|
|
||||||
float Dr = PBR_GTR1( nDotH , mix( .1 , .001 , clearcoatGloss));
|
|
||||||
float Fr = mix(.04, 1.0, FH);
|
|
||||||
float Gr = smithG_GGX(NdotL, .25) * smithG_GGX(NdotV, .25);
|
|
||||||
*/
|
|
||||||
|
|
||||||
vec3 Fs = mix( cSpecular , vec3(1) , FH );
|
|
||||||
return nDotL * ( ( ( 1 / PI )
|
|
||||||
* mix( Fd , ss , material.subsurface )
|
|
||||||
* material.cAlbedo /* + Fsheen */)
|
|
||||||
* pow( 1 - material.metallic , 3 )
|
|
||||||
+ clamp( Gs , 0 , 1 ) * Fs * Ds );
|
|
||||||
//+ .25*clearcoat*Gr*Fr*Dr;
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
vec3 getNormal( vec3 pos )
|
|
||||||
{
|
|
||||||
vec2 v = vec2( .0005 , 0 );
|
|
||||||
return normalize( vec3(
|
|
||||||
map( pos + v.xyy ).x - map( pos - v.xyy ).x ,
|
|
||||||
map( pos + v.yxy ).x - map( pos - v.yxy ).x ,
|
|
||||||
map( pos + v.yyx ).x - map( pos - v.yyx ).x ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
vec3 RM_Basic( vec3 o , vec3 d , int steps , float factor )
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
float dist = .01 , mat = -1;
|
|
||||||
|
|
||||||
for ( ; i < steps ; ++ i ) {
|
|
||||||
vec2 res = map( o + d * dist );
|
|
||||||
if ( abs( res.x ) < u_Render.z || dist > u_Render.w ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dist += res.x * factor;
|
|
||||||
mat = res.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return vec3( dist , dist >= u_Render.w ? -1 : mat , i );
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 RM_Advanced( vec3 o , vec3 d , int steps , float factor )
|
|
||||||
{
|
|
||||||
const float dMin = .1 , dMax = u_Render.w , pixel = u_Render.z;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
float dist = dMin , mat = -1;
|
|
||||||
float omega = factor;
|
|
||||||
float cError = 1 / 0. , cDist = dMin;
|
|
||||||
float pRad = 0 , sLen = 0;
|
|
||||||
|
|
||||||
for ( ; i < steps ; ++ i ) {
|
|
||||||
vec2 res = map( o + d * dist );
|
|
||||||
float rad = abs( res.x );
|
|
||||||
|
|
||||||
bool sorFail = omega > 1 && ( rad + pRad ) < sLen;
|
|
||||||
if ( sorFail ) {
|
|
||||||
sLen -= omega * sLen;
|
|
||||||
omega = 1;
|
|
||||||
} else {
|
|
||||||
sLen = res.x * omega;
|
|
||||||
}
|
|
||||||
pRad = rad;
|
|
||||||
|
|
||||||
float error = rad / dist;
|
|
||||||
if ( !sorFail && error < cError ) {
|
|
||||||
cError = error;
|
|
||||||
cDist = dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !sorFail && error < pixel || dist > dMax ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dist += sLen;
|
|
||||||
}
|
|
||||||
if ( dist <= dMax && cError <= pixel ) {
|
|
||||||
return vec3( cDist , map( o + d * cDist ).y , i );
|
|
||||||
}
|
|
||||||
return vec3( cDist , -1 , steps );
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void main( )
|
|
||||||
{
|
|
||||||
setCamFromUniforms( );
|
|
||||||
|
|
||||||
vec2 uv = ( gl_FragCoord.xy / u_Resolution ) * 2 - 1;
|
|
||||||
vec3 camDir = normalize( lookAt - camPos );
|
|
||||||
vec3 side = normalize( cross( camUp , camDir ) );
|
|
||||||
vec3 up = normalize( cross( camDir , side ) );
|
|
||||||
vec3 rayDir = normalize( camDir * nearPlane
|
|
||||||
+ uv.x * side * u_Resolution.x / u_Resolution.y
|
|
||||||
+ uv.y * up );
|
|
||||||
|
|
||||||
vec3 r = RM_Advanced( camPos , rayDir , int( u_Render.x ) , u_Render.y );
|
|
||||||
vec3 hitPos = camPos + rayDir * r.x;
|
|
||||||
|
|
||||||
vec3 bc = vec3( 0 );
|
|
||||||
if ( r.y >= 0. ) {
|
|
||||||
const int midx = int( r.y );
|
|
||||||
const vec3 normal = getNormal( hitPos );
|
|
||||||
const vec3 lightDir = normalize( -u_LightDir );
|
|
||||||
|
|
||||||
#if defined( USE_BP )
|
|
||||||
// Blinn-Phong only
|
|
||||||
bc = BP_Shade( BPMaterials[ midx ] ,
|
|
||||||
rayDir , normal , lightDir );
|
|
||||||
|
|
||||||
#else
|
|
||||||
#if defined( USE_PBR )
|
|
||||||
// PBR only
|
|
||||||
T_PBRMaterialOld material = PBRMaterialsOld[ midx ];
|
|
||||||
T_PBRPrecomputedOld precomputed = PBR_PrecomputeOld(
|
|
||||||
material , rayDir , normal );
|
|
||||||
bc = PBR_ShadeOld( material , precomputed ,
|
|
||||||
-rayDir , normal , lightDir );
|
|
||||||
|
|
||||||
#else
|
|
||||||
#if defined( USE_MAP_MATERIAL )
|
|
||||||
// Remap materials through mapMaterials
|
|
||||||
int mtype , mtidx , glowidx;
|
|
||||||
mapMaterial( midx , mtype , mtidx , glowidx );
|
|
||||||
if ( mtype == 0 ) {
|
|
||||||
bc = BP_Shade( BPMaterials[ mtidx ] ,
|
|
||||||
-rayDir , normal , lightDir );
|
|
||||||
} else {
|
|
||||||
#if 0
|
|
||||||
T_PBRMaterialOld material = PBRMaterialsOld[ mtidx ];
|
|
||||||
T_PBRPrecomputedOld precomputed = PBR_PrecomputeOld(
|
|
||||||
material , rayDir , normal );
|
|
||||||
bc = PBR_ShadeOld( material , precomputed ,
|
|
||||||
rayDir , normal , lightDir );
|
|
||||||
#else
|
|
||||||
bc = PBR_Shade( PBRMaterials[ mtidx ] ,
|
|
||||||
-rayDir , normal , lightDir );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if defined( USE_GLOW )
|
|
||||||
if ( glowidx >= 0 ) {
|
|
||||||
bc += Glow[ glowidx ];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW
|
|
||||||
#ifndef USE_MAP_MATERIAL
|
|
||||||
bc += Glow[ midx ];
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
o_Color = bc;
|
|
||||||
o_Z = r.x;
|
|
||||||
}
|
|
|
@ -1,7 +1,92 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
//! type fragment
|
//! type fragment
|
||||||
//! include raymarch-header.glsl
|
|
||||||
//! include pbr.glsl
|
//! include chunks/raymarcher.glsl
|
||||||
//! include blinn-phong.glsl
|
//! include lib/shading-pbr.glsl
|
||||||
//! include map.glsl
|
//! include lib/shading-blinnphong.glsl
|
||||||
//! include raymarcher.glsl
|
|
||||||
|
|
||||||
|
T_BPMaterial BPMaterials[1] = {
|
||||||
|
{ vec3( 1 , 1 , .4 ) * .1 , vec3( 1 , 1 , .4 ) , 40 , .1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
T_PBRMaterial PBRMaterials[1] = {
|
||||||
|
{
|
||||||
|
// Albedo color
|
||||||
|
vec3( 1 , 1 , .4 ) ,
|
||||||
|
// Roughness , metallic , subsurface , anisotropy
|
||||||
|
.4 , .7 , 1 , .1 ,
|
||||||
|
// Specular strength / tint%
|
||||||
|
.5 , .5
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vec3 Glow[1] = {
|
||||||
|
vec3( 2 , .4 , 5 ) * 4
|
||||||
|
};
|
||||||
|
|
||||||
|
void mapMaterial(
|
||||||
|
in int matIndex ,
|
||||||
|
out int type ,
|
||||||
|
out int tIndex ,
|
||||||
|
out int glowIndex )
|
||||||
|
{
|
||||||
|
if ( matIndex == 0 ) {
|
||||||
|
glowIndex = -1;
|
||||||
|
} else {
|
||||||
|
//type = 1;
|
||||||
|
glowIndex = 0;
|
||||||
|
}
|
||||||
|
type = 1;
|
||||||
|
tIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 RM_Map( vec3 pos )
|
||||||
|
{
|
||||||
|
pos = pos - vec3( 0 , 0 , 0 );
|
||||||
|
vec3 q = pos;
|
||||||
|
q.xy = mod( q.xy + 4. , 8. ) - 4.;
|
||||||
|
return vec2( length( q ) - 1.8 , step( 0. , 1.9 - length( pos.xy ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main( )
|
||||||
|
{
|
||||||
|
vec2 uv = ( gl_FragCoord.xy / u_Resolution ) * 2 - 1;
|
||||||
|
vec3 camDir = normalize( u_LookAt - u_CamPos );
|
||||||
|
vec3 side = normalize( cross( u_CamUp , camDir ) );
|
||||||
|
vec3 up = normalize( cross( camDir , side ) );
|
||||||
|
vec3 rayDir = normalize( camDir * u_NearPlane
|
||||||
|
+ uv.x * side * u_Resolution.x / u_Resolution.y
|
||||||
|
+ uv.y * up );
|
||||||
|
|
||||||
|
vec3 r = RM_Advanced( u_CamPos , rayDir ,
|
||||||
|
int( u_Render.x ) , u_Render.y ,
|
||||||
|
u_Render.z , .001 , u_Render.w );
|
||||||
|
vec3 hitPos = u_CamPos + rayDir * r.x;
|
||||||
|
|
||||||
|
vec3 bc = vec3( 0 );
|
||||||
|
if ( r.y >= 0. ) {
|
||||||
|
const int midx = int( r.y );
|
||||||
|
const vec3 normal = RM_GetNormal( hitPos );
|
||||||
|
const vec3 lightDir = normalize( -u_LightDir );
|
||||||
|
|
||||||
|
// Remap materials through mapMaterials
|
||||||
|
int mtype , mtidx , glowidx;
|
||||||
|
mapMaterial( midx , mtype , mtidx , glowidx );
|
||||||
|
if ( mtype == 0 ) {
|
||||||
|
bc = BP_Shade( BPMaterials[ mtidx ] ,
|
||||||
|
-rayDir , normal , lightDir );
|
||||||
|
} else {
|
||||||
|
bc = PBR_Shade( PBRMaterials[ mtidx ] ,
|
||||||
|
-rayDir , normal , lightDir );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( glowidx >= 0 ) {
|
||||||
|
bc += Glow[ glowidx ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o_Color = bc;
|
||||||
|
o_Z = r.x;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue