Initial commit

This commit is contained in:
2025-12-17 16:47:48 +00:00
commit 13813f3363
4964 changed files with 1079753 additions and 0 deletions

View File

@@ -0,0 +1,193 @@
$input a_position, a_texcoord0, a_normal
$output v_texcoord0, v_color0, v_texcoord1, v_worldPos, v_position, v_start, v_end, v_centerRadius
#include "common.sh"
uniform vec4 u_color;
uniform vec4 u_pixelInfo; // x -> Fov * 0.5f / screenSize.y; y -> ScreenWidth; z -> ScreenWidth / ScreenHeight; w -> Line thickness
SAMPLER2D(s_diffuseMap, 0);
// Vertex Shaders
void AdornSelfLitVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
vec3 light = normalize(u_cameraPosition - worldPos.xyz);
float ndotl = saturate(dot(worldNormal, light));
float lighting = 0.5 + (1.0 - 0.5) * ndotl;
float specular = pow(ndotl, 64.0);
gl_Position = mul(u_viewProjection, worldPos);
v_texcoord0 = a_texcoord0;
v_color0 = vec4(u_color.rgb * lighting + vec3(specular), u_color.a);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
}
void AdornSelfLitHighlightVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
vec3 light = normalize(u_cameraPosition - worldPos.xyz);
float ndotl = saturate(dot(worldNormal, light));
float lighting = 0.75 + (1.0 - 0.75) * ndotl;
float specular = pow(ndotl, 64.0);
gl_Position = mul(u_viewProjection, worldPos);
v_texcoord0 = a_texcoord0;
v_color0 = vec4(u_color.rgb * lighting + vec3(specular), u_color.a);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
}
void AdornVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
#ifdef PIN_LIGHTING
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
float ndotl = dot(worldNormal, -u_lamp0Dir);
vec3 lighting = u_ambientColor + saturate(ndotl) * u_lamp0Color + saturate(-ndotl) * u_lamp1Color;
#else
vec3 lighting = vec3(1.0);
#endif
gl_Position = mul(u_viewProjection, worldPos);
v_texcoord0 = a_texcoord0;
v_color0 = vec4(u_color.rgb * lighting, u_color.a);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
}
void AdornAALineVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
// line start and end position in world space
vec4 startPosW = mul(u_worldMatrix, vec4(1.0, 0.0, 0.0, 1.0));
vec4 endPosW = mul(u_worldMatrix, vec4(-1.0, 0.0, 0.0, 1.0));
// Compute view-space w
float w = dot(u_viewProjection[3], vec4(worldPos.xyz, 1.0));
// radius in pixels + constant because line has to be little bit bigger to perform anti aliasing
float radius = u_pixelInfo.w + 2.0;
// scale the way that line has same size on screen
if (length(worldPos.xyz - startPosW.xyz) < length(worldPos.xyz - endPosW.xyz))
{
float w = dot(u_viewProjection[3], vec4(startPosW.xyz, 1.0));
float pixel_radius = radius * w * u_pixelInfo.x;
worldPos.xyz = startPosW.xyz + worldNormal * pixel_radius;
}
else
{
float w = dot(u_viewProjection[3], vec4(endPosW.xyz, 1.0));
float pixel_radius = radius * w * u_pixelInfo.x;
worldPos.xyz = endPosW.xyz + worldNormal * pixel_radius;
}
// output for PS
gl_Position = mul(u_viewProjection, worldPos);
v_position = gl_Position.xyw;
v_start = mul(u_viewProjection, startPosW);
v_end = mul(u_viewProjection, endPosW);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
// screen ratio
v_position.y *= u_pixelInfo.z;
v_start.y *= u_pixelInfo.z;
v_end.y *= u_pixelInfo.z;
}
void AdornOutlineVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
gl_Position = mul(u_viewProjection, worldPos);
v_color0 = u_color;
v_worldPos = worldPos.xyz;
v_centerRadius = vec4(mul(u_worldMatrix, vec4(0.0, 0.0, 0.0, 1.0)).xyz,
length(mul(u_worldMatrix, vec4(1.0, 0.0, 0.0, 0.0)).xyz));
}
// Pixel/Fragment Shaders
void AdornPS()
{
vec4 result = texture2D(s_diffuseMap, v_texcoord0) * v_color0;
result.rgb = mix(u_fogColor, result.rgb, saturate(v_texcoord1.x));
gl_FragColor = result;
}
void AdornAALinePS()
{
vec3 position = v_position / v_position.z;
vec4 start = v_start / v_start.w;
vec4 end = v_end / v_end.w;
vec2 lineDir = normalize(end.xy - start.xy);
vec2 fragToPoint = position.xy - start.xy;
// tips of the line are not Anti-Aliased, they are just cut
// discard as soon as we can
float startDist = dot(lineDir, fragToPoint);
float endDist = dot(lineDir, -position.xy + end.xy);
if (startDist < 0.0)
discard;
if (endDist < 0.0)
discard;
vec2 perpLineDir = vec2(lineDir.y, -lineDir.x);
float dist = abs(dot(perpLineDir, fragToPoint));
// high point serves to compute the function which is described below
float highPoint = 1.0 + (u_pixelInfo.w - 1.0) * 0.5;
// this is function that has this shape /¯¯¯\, it is symmetric, centered around 0 on X axis
// slope parts are +- 45 degree and are 1px thick. Area of the shape sums to line thickness in pixels
// function for 1px would be /\, func for 2px is /¯\ and so on...
vec4 result = vec4(1.0);
result.a = saturate(highPoint - (dist * 0.5 * u_pixelInfo.y));
result *= u_color;
// convert to sRGB, its not perfect for non-black backgrounds, but its the best we can get
result.a = pow(saturate(1.0 - result.a), 1.0/2.2);
result.a = 1.0 - result.a;
result.rgb = mix(u_fogColor, result.rgb, saturate(v_texcoord1.x));
gl_FragColor = result;
}
void AdornOutlinePS()
{
vec3 rayO = v_worldPos - v_centerRadius.xyz;
vec3 rayD = normalize(v_worldPos - u_cameraPosition);
// magnitude(rayO + t * rayD) = radius
// t^2 + bt + c = radius
float thickness = 1.0;
float r0 = v_centerRadius.w;
float r1 = max(0.0, v_centerRadius.w - thickness);
float b = 2.0 * dot(rayO, rayD);
float c0 = dot(rayO, rayO) - r0 * r0;
float c1 = dot(rayO, rayO) - r1 * r1;
if (b * b < 4.0 * c0)
discard;
if (b * b > 4.0 * c1)
discard;
gl_FragColor = v_color0;
}

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.4
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 128.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,731 @@
/*
* Copyright 2011-2025 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
*/
#ifndef BGFX_SHADER_H_HEADER_GUARD
#define BGFX_SHADER_H_HEADER_GUARD
#if !defined(BGFX_CONFIG_MAX_BONES)
# define BGFX_CONFIG_MAX_BONES 32
#endif // !defined(BGFX_CONFIG_MAX_BONES)
#ifndef __cplusplus
#if BGFX_SHADER_LANGUAGE_HLSL > 300
# define BRANCH [branch]
# define LOOP [loop]
# define UNROLL [unroll]
#else
# define BRANCH
# define LOOP
# define UNROLL
#endif // BGFX_SHADER_LANGUAGE_HLSL > 300
#if (BGFX_SHADER_LANGUAGE_HLSL > 300 || BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV) && BGFX_SHADER_TYPE_FRAGMENT
# define EARLY_DEPTH_STENCIL [earlydepthstencil]
#else
# define EARLY_DEPTH_STENCIL
#endif // BGFX_SHADER_LANGUAGE_HLSL > 300 && BGFX_SHADER_TYPE_FRAGMENT
#if BGFX_SHADER_LANGUAGE_GLSL
# define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = _type[](
# define ARRAY_END() )
#else
# define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = {
# define ARRAY_END() }
#endif // BGFX_SHADER_LANGUAGE_GLSL
#if BGFX_SHADER_LANGUAGE_HLSL \
|| BGFX_SHADER_LANGUAGE_PSSL \
|| BGFX_SHADER_LANGUAGE_SPIRV \
|| BGFX_SHADER_LANGUAGE_METAL
# define CONST(_x) static const _x
# define dFdx(_x) ddx(_x)
# define dFdy(_y) ddy(-(_y))
# define inversesqrt(_x) rsqrt(_x)
# define fract(_x) frac(_x)
# define bvec2 bool2
# define bvec3 bool3
# define bvec4 bool4
// To be able to patch the uav registers on the DXBC SPDB Chunk (D3D11 renderer) the whitespaces around
// '_type[_reg]' are necessary. This only affects shaders with debug info (i.e., those that have the SPDB Chunk).
# if BGFX_SHADER_LANGUAGE_HLSL > 400 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
# define REGISTER(_type, _reg) register( _type[_reg] )
# else
# define REGISTER(_type, _reg) register(_type ## _reg)
# endif // BGFX_SHADER_LANGUAGE_HLSL
# if BGFX_SHADER_LANGUAGE_HLSL > 300 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
# if BGFX_SHADER_LANGUAGE_HLSL > 400 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
# define dFdxCoarse(_x) ddx_coarse(_x)
# define dFdxFine(_x) ddx_fine(_x)
# define dFdyCoarse(_y) ddy_coarse(-(_y))
# define dFdyFine(_y) ddy_fine(-(_y))
# endif // BGFX_SHADER_LANGUAGE_HLSL > 400
# if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
float intBitsToFloat(int _x) { return asfloat(_x); }
vec2 intBitsToFloat(uint2 _x) { return asfloat(_x); }
vec3 intBitsToFloat(uint3 _x) { return asfloat(_x); }
vec4 intBitsToFloat(uint4 _x) { return asfloat(_x); }
# endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
float uintBitsToFloat(uint _x) { return asfloat(_x); }
vec2 uintBitsToFloat(uint2 _x) { return asfloat(_x); }
vec3 uintBitsToFloat(uint3 _x) { return asfloat(_x); }
vec4 uintBitsToFloat(uint4 _x) { return asfloat(_x); }
uint floatBitsToUint(float _x) { return asuint(_x); }
uvec2 floatBitsToUint(vec2 _x) { return asuint(_x); }
uvec3 floatBitsToUint(vec3 _x) { return asuint(_x); }
uvec4 floatBitsToUint(vec4 _x) { return asuint(_x); }
int floatBitsToInt(float _x) { return asint(_x); }
ivec2 floatBitsToInt(vec2 _x) { return asint(_x); }
ivec3 floatBitsToInt(vec3 _x) { return asint(_x); }
ivec4 floatBitsToInt(vec4 _x) { return asint(_x); }
uint bitfieldReverse(uint _x) { return reversebits(_x); }
uint2 bitfieldReverse(uint2 _x) { return reversebits(_x); }
uint3 bitfieldReverse(uint3 _x) { return reversebits(_x); }
uint4 bitfieldReverse(uint4 _x) { return reversebits(_x); }
# if !BGFX_SHADER_LANGUAGE_SPIRV
uint packHalf2x16(vec2 _x)
{
return (f32tof16(_x.y)<<16) | f32tof16(_x.x);
}
vec2 unpackHalf2x16(uint _x)
{
return vec2(f16tof32(_x & 0xffff), f16tof32(_x >> 16) );
}
# endif // !BGFX_SHADER_LANGUAGE_SPIRV
struct BgfxSampler2D
{
SamplerState m_sampler;
Texture2D m_texture;
};
struct BgfxISampler2D
{
Texture2D<ivec4> m_texture;
};
struct BgfxUSampler2D
{
Texture2D<uvec4> m_texture;
};
struct BgfxSampler2DArray
{
SamplerState m_sampler;
Texture2DArray m_texture;
};
struct BgfxSampler2DShadow
{
SamplerComparisonState m_sampler;
Texture2D m_texture;
};
struct BgfxSampler2DArrayShadow
{
SamplerComparisonState m_sampler;
Texture2DArray m_texture;
};
struct BgfxSampler3D
{
SamplerState m_sampler;
Texture3D m_texture;
};
struct BgfxISampler3D
{
Texture3D<ivec4> m_texture;
};
struct BgfxUSampler3D
{
Texture3D<uvec4> m_texture;
};
struct BgfxSamplerCube
{
SamplerState m_sampler;
TextureCube m_texture;
};
struct BgfxSamplerCubeShadow
{
SamplerComparisonState m_sampler;
TextureCube m_texture;
};
struct BgfxSampler2DMS
{
Texture2DMS<vec4> m_texture;
};
vec4 bgfxTexture2D(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture2DBias(BgfxSampler2D _sampler, vec2 _coord, float _bias)
{
return _sampler.m_texture.SampleBias(_sampler.m_sampler, _coord, _bias);
}
vec4 bgfxTexture2DLod(BgfxSampler2D _sampler, vec2 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
vec4 bgfxTexture2DLodOffset(BgfxSampler2D _sampler, vec2 _coord, float _level, ivec2 _offset)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level, _offset);
}
vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec3 _coord)
{
vec2 coord = _coord.xy * rcp(_coord.z);
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord)
{
vec2 coord = _coord.xy * rcp(_coord.w);
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
vec4 bgfxTexture2DGrad(BgfxSampler2D _sampler, vec2 _coord, vec2 _dPdx, vec2 _dPdy)
{
return _sampler.m_texture.SampleGrad(_sampler.m_sampler, _coord, _dPdx, _dPdy);
}
vec4 bgfxTexture2DArray(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture2DArrayLod(BgfxSampler2DArray _sampler, vec3 _coord, float _lod)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _lod);
}
vec4 bgfxTexture2DArrayLodOffset(BgfxSampler2DArray _sampler, vec3 _coord, float _level, ivec2 _offset)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level, _offset);
}
float bgfxShadow2D(BgfxSampler2DShadow _sampler, vec3 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xy, _coord.z);
}
float bgfxShadow2DProj(BgfxSampler2DShadow _sampler, vec4 _coord)
{
vec3 coord = _coord.xyz * rcp(_coord.w);
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, coord.xy, coord.z);
}
vec2 bgfxTextureSize(BgfxSampler2DShadow _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec4 bgfxShadow2DArray(BgfxSampler2DArrayShadow _sampler, vec4 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xyz, _coord.w);
}
vec2 bgfxTextureSize(BgfxSampler2DArrayShadow _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
float numberOfElements;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfElements, numberOfMipMapLevels);
return result;
}
vec4 bgfxTexture3D(BgfxSampler3D _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture3DLod(BgfxSampler3D _sampler, vec3 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
ivec4 bgfxTexture3D(BgfxISampler3D _sampler, vec3 _coord)
{
uvec3 size;
_sampler.m_texture.GetDimensions(size.x, size.y, size.z);
return _sampler.m_texture.Load(ivec4(_coord * size, 0) );
}
uvec4 bgfxTexture3D(BgfxUSampler3D _sampler, vec3 _coord)
{
uvec3 size;
_sampler.m_texture.GetDimensions(size.x, size.y, size.z);
return _sampler.m_texture.Load(ivec4(_coord * size, 0) );
}
vec4 bgfxTextureCube(BgfxSamplerCube _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureCubeBias(BgfxSamplerCube _sampler, vec3 _coord, float _bias)
{
return _sampler.m_texture.SampleBias(_sampler.m_sampler, _coord, _bias);
}
vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
float bgfxShadowCube(BgfxSamplerCubeShadow _sampler, vec4 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xyz, _coord.w);
}
vec4 bgfxTexelFetch(BgfxSampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
vec4 bgfxTexelFetchOffset(BgfxSampler2D _sampler, ivec2 _coord, int _lod, ivec2 _offset)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod), _offset );
}
vec2 bgfxTextureSize(BgfxSampler2D _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec2 bgfxTextureSize(BgfxISampler2D _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec2 bgfxTextureSize(BgfxUSampler2D _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec4 bgfxTextureGather0(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather1(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather2(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather3(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGatherOffset0(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGatherOffset1(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGatherOffset2(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGatherOffset3(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGather0(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather1(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather2(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather3(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord);
}
ivec4 bgfxTexelFetch(BgfxISampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
uvec4 bgfxTexelFetch(BgfxUSampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
vec4 bgfxTexelFetch(BgfxSampler2DMS _sampler, ivec2 _coord, int _sampleIdx)
{
return _sampler.m_texture.Load(_coord, _sampleIdx);
}
vec4 bgfxTexelFetch(BgfxSampler2DArray _sampler, ivec3 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec4(_coord, _lod) );
}
vec4 bgfxTexelFetch(BgfxSampler3D _sampler, ivec3 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec4(_coord, _lod) );
}
vec3 bgfxTextureSize(BgfxSampler3D _sampler, int _lod)
{
vec3 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, result.z, numberOfMipMapLevels);
return result;
}
# define SAMPLER2D(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform Texture2D _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2D _name = { _name ## Sampler, _name ## Texture }
# define ISAMPLER2D(_name, _reg) \
uniform Texture2D<ivec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxISampler2D _name = { _name ## Texture }
# define USAMPLER2D(_name, _reg) \
uniform Texture2D<uvec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxUSampler2D _name = { _name ## Texture }
# define sampler2D BgfxSampler2D
# define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord)
# define texture2DBias(_sampler, _coord, _bias) bgfxTexture2DBias(_sampler, _coord, _bias)
# define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level)
# define texture2DLodOffset(_sampler, _coord, _level, _offset) bgfxTexture2DLodOffset(_sampler, _coord, _level, _offset)
# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) bgfxTexture2DGrad(_sampler, _coord, _dPdx, _dPdy)
# define SAMPLER2DARRAY(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform Texture2DArray _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DArray _name = { _name ## Sampler, _name ## Texture }
# define sampler2DArray BgfxSampler2DArray
# define texture2DArray(_sampler, _coord) bgfxTexture2DArray(_sampler, _coord)
# define texture2DArrayLod(_sampler, _coord, _lod) bgfxTexture2DArrayLod(_sampler, _coord, _lod)
# define texture2DArrayLodOffset(_sampler, _coord, _level, _offset) bgfxTexture2DArrayLodOffset(_sampler, _coord, _level, _offset)
# define SAMPLER2DMS(_name, _reg) \
uniform Texture2DMS<vec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DMS _name = { _name ## Texture }
# define sampler2DMS BgfxSampler2DMS
# define SAMPLER2DSHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \
uniform Texture2D _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DShadow _name = { _name ## SamplerComparison, _name ## Texture }
# define sampler2DShadow BgfxSampler2DShadow
# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
# define SAMPLER2DARRAYSHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \
uniform Texture2DArray _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DArrayShadow _name = { _name ## SamplerComparison, _name ## Texture }
# define sampler2DArrayShadow BgfxSampler2DArrayShadow
# define shadow2DArray(_sampler, _coord) bgfxShadow2DArray(_sampler, _coord)
# define SAMPLER3D(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform Texture3D _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler3D _name = { _name ## Sampler, _name ## Texture }
# define ISAMPLER3D(_name, _reg) \
uniform Texture3D<ivec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxISampler3D _name = { _name ## Texture }
# define USAMPLER3D(_name, _reg) \
uniform Texture3D<uvec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxUSampler3D _name = { _name ## Texture }
# define sampler3D BgfxSampler3D
# define texture3D(_sampler, _coord) bgfxTexture3D(_sampler, _coord)
# define texture3DLod(_sampler, _coord, _level) bgfxTexture3DLod(_sampler, _coord, _level)
# define SAMPLERCUBE(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform TextureCube _name ## Texture : REGISTER(t, _reg); \
static BgfxSamplerCube _name = { _name ## Sampler, _name ## Texture }
# define samplerCube BgfxSamplerCube
# define textureCube(_sampler, _coord) bgfxTextureCube(_sampler, _coord)
# define textureCubeBias(_sampler, _coord, _bias) bgfxTextureCubeBias(_sampler, _coord, _bias)
# define textureCubeLod(_sampler, _coord, _level) bgfxTextureCubeLod(_sampler, _coord, _level)
# define SAMPLERCUBESHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \
uniform TextureCube _name ## Texture : REGISTER(t, _reg); \
static BgfxSamplerCubeShadow _name = { _name ## SamplerComparison, _name ## Texture }
# define samplerCubeShadow BgfxSamplerCubeShadow
# define shadowCube(_sampler, _coord) bgfxShadowCube(_sampler, _coord)
# define texelFetch(_sampler, _coord, _lod) bgfxTexelFetch(_sampler, _coord, _lod)
# define texelFetchOffset(_sampler, _coord, _lod, _offset) bgfxTexelFetchOffset(_sampler, _coord, _lod, _offset)
# define textureSize(_sampler, _lod) bgfxTextureSize(_sampler, _lod)
# define textureGather(_sampler, _coord, _comp) bgfxTextureGather ## _comp(_sampler, _coord)
# define textureGatherOffset(_sampler, _coord, _offset, _comp) bgfxTextureGatherOffset ## _comp(_sampler, _coord, _offset)
# else
# define sampler2DShadow sampler2D
vec4 bgfxTexture2DProj(sampler2D _sampler, vec3 _coord)
{
return tex2Dproj(_sampler, vec4(_coord.xy, 0.0, _coord.z) );
}
vec4 bgfxTexture2DProj(sampler2D _sampler, vec4 _coord)
{
return tex2Dproj(_sampler, _coord);
}
float bgfxShadow2D(sampler2DShadow _sampler, vec3 _coord)
{
#if 0
float occluder = tex2D(_sampler, _coord.xy).x;
return step(_coord.z, occluder);
#else
return tex2Dproj(_sampler, vec4(_coord.xy, _coord.z, 1.0) ).x;
#endif // 0
}
float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord)
{
#if 0
vec3 coord = _coord.xyz * rcp(_coord.w);
float occluder = tex2D(_sampler, coord.xy).x;
return step(coord.z, occluder);
#else
return tex2Dproj(_sampler, _coord).x;
#endif // 0
}
# define SAMPLER2D(_name, _reg) uniform sampler2D _name : REGISTER(s, _reg)
# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name : REGISTER(s, _reg)
# define texture2D(_sampler, _coord) tex2D(_sampler, _coord)
# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
# define SAMPLER2DARRAY(_name, _reg) SAMPLER2D(_name, _reg)
# define texture2DArray(_sampler, _coord) texture2D(_sampler, (_coord).xy)
# define texture2DArrayLod(_sampler, _coord, _lod) texture2DLod(_sampler, _coord, _lod)
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name : REGISTER(s, _reg)
# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
# define SAMPLER3D(_name, _reg) uniform sampler3D _name : REGISTER(s, _reg)
# define texture3D(_sampler, _coord) tex3D(_sampler, _coord)
# define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : REGISTER(s, _reg)
# define textureCube(_sampler, _coord) texCUBE(_sampler, _coord)
# define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) )
# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2Dgrad(_sampler, _coord, _dPdx, _dPdy)
# define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) )
# define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) )
# endif // BGFX_SHADER_LANGUAGE_HLSL > 300
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_mtx, _vec); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_vec, _mtx); }
bvec2 lessThan(vec2 _a, vec2 _b) { return _a < _b; }
bvec3 lessThan(vec3 _a, vec3 _b) { return _a < _b; }
bvec4 lessThan(vec4 _a, vec4 _b) { return _a < _b; }
bvec2 lessThanEqual(vec2 _a, vec2 _b) { return _a <= _b; }
bvec3 lessThanEqual(vec3 _a, vec3 _b) { return _a <= _b; }
bvec4 lessThanEqual(vec4 _a, vec4 _b) { return _a <= _b; }
bvec2 greaterThan(vec2 _a, vec2 _b) { return _a > _b; }
bvec3 greaterThan(vec3 _a, vec3 _b) { return _a > _b; }
bvec4 greaterThan(vec4 _a, vec4 _b) { return _a > _b; }
bvec2 greaterThanEqual(vec2 _a, vec2 _b) { return _a >= _b; }
bvec3 greaterThanEqual(vec3 _a, vec3 _b) { return _a >= _b; }
bvec4 greaterThanEqual(vec4 _a, vec4 _b) { return _a >= _b; }
bvec2 notEqual(vec2 _a, vec2 _b) { return _a != _b; }
bvec3 notEqual(vec3 _a, vec3 _b) { return _a != _b; }
bvec4 notEqual(vec4 _a, vec4 _b) { return _a != _b; }
bvec2 equal(vec2 _a, vec2 _b) { return _a == _b; }
bvec3 equal(vec3 _a, vec3 _b) { return _a == _b; }
bvec4 equal(vec4 _a, vec4 _b) { return _a == _b; }
float mix(float _a, float _b, float _t) { return lerp(_a, _b, _t); }
vec2 mix(vec2 _a, vec2 _b, vec2 _t) { return lerp(_a, _b, _t); }
vec3 mix(vec3 _a, vec3 _b, vec3 _t) { return lerp(_a, _b, _t); }
vec4 mix(vec4 _a, vec4 _b, vec4 _t) { return lerp(_a, _b, _t); }
float mod(float _a, float _b) { return _a - _b * floor(_a / _b); }
vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); }
vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); }
vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
#else
# define CONST(_x) const _x
# define atan2(_x, _y) atan(_x, _y)
# define mul(_a, _b) ( (_a) * (_b) )
# define saturate(_x) clamp(_x, 0.0, 1.0)
# define SAMPLER2D(_name, _reg) uniform sampler2D _name
# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name
# define SAMPLER3D(_name, _reg) uniform sampler3D _name
# define SAMPLERCUBE(_name, _reg) uniform samplerCube _name
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name
# define SAMPLER2DARRAY(_name, _reg) uniform sampler2DArray _name
# define SAMPLER2DMSARRAY(_name, _reg) uniform sampler2DMSArray _name
# define SAMPLERCUBEARRAY(_name, _reg) uniform samplerCubeArray _name
# define SAMPLER2DARRAYSHADOW(_name, _reg) uniform sampler2DArrayShadow _name
# define ISAMPLER2D(_name, _reg) uniform isampler2D _name
# define USAMPLER2D(_name, _reg) uniform usampler2D _name
# define ISAMPLER3D(_name, _reg) uniform isampler3D _name
# define USAMPLER3D(_name, _reg) uniform usampler3D _name
# if BGFX_SHADER_LANGUAGE_GLSL >= 130
# define texture2D(_sampler, _coord) texture(_sampler, _coord)
# define texture2DArray(_sampler, _coord) texture(_sampler, _coord)
# define texture3D(_sampler, _coord) texture(_sampler, _coord)
# define textureCube(_sampler, _coord) texture(_sampler, _coord)
# define texture2DLod(_sampler, _coord, _lod) textureLod(_sampler, _coord, _lod)
# define texture2DLodOffset(_sampler, _coord, _lod, _offset) textureLodOffset(_sampler, _coord, _lod, _offset)
# define texture2DBias(_sampler, _coord, _bias) texture(_sampler, _coord, _bias)
# define textureCubeBias(_sampler, _coord, _bias) texture(_sampler, _coord, _bias)
# else
# define texture2DBias(_sampler, _coord, _bias) texture2D(_sampler, _coord, _bias)
# define textureCubeBias(_sampler, _coord, _bias) textureCube(_sampler, _coord, _bias)
# endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_mtx, _vec); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_vec, _mtx); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_mtx, _vec); }
float rcp(float _a) { return 1.0/_a; }
vec2 rcp(vec2 _a) { return vec2(1.0)/_a; }
vec3 rcp(vec3 _a) { return vec3(1.0)/_a; }
vec4 rcp(vec4 _a) { return vec4(1.0)/_a; }
#endif // BGFX_SHADER_LANGUAGE_*
vec2 vec2_splat(float _x) { return vec2(_x, _x); }
vec3 vec3_splat(float _x) { return vec3(_x, _x, _x); }
vec4 vec4_splat(float _x) { return vec4(_x, _x, _x, _x); }
#if BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
uvec2 uvec2_splat(uint _x) { return uvec2(_x, _x); }
uvec3 uvec3_splat(uint _x) { return uvec3(_x, _x, _x); }
uvec4 uvec4_splat(uint _x) { return uvec4(_x, _x, _x, _x); }
#endif // BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
mat4 mtxFromRows(vec4 _0, vec4 _1, vec4 _2, vec4 _3)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return transpose(mat4(_0, _1, _2, _3) );
#else
return mat4(_0, _1, _2, _3);
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
mat4 mtxFromCols(vec4 _0, vec4 _1, vec4 _2, vec4 _3)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return mat4(_0, _1, _2, _3);
#else
return transpose(mat4(_0, _1, _2, _3) );
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
mat3 mtxFromRows(vec3 _0, vec3 _1, vec3 _2)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return transpose(mat3(_0, _1, _2) );
#else
return mat3(_0, _1, _2);
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
mat3 mtxFromCols(vec3 _0, vec3 _1, vec3 _2)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return mat3(_0, _1, _2);
#else
return transpose(mat3(_0, _1, _2) );
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
#if BGFX_SHADER_LANGUAGE_GLSL
#define mtxFromRows3(_0, _1, _2) transpose(mat3(_0, _1, _2) )
#define mtxFromRows4(_0, _1, _2, _3) transpose(mat4(_0, _1, _2, _3) )
#define mtxFromCols3(_0, _1, _2) mat3(_0, _1, _2)
#define mtxFromCols4(_0, _1, _2, _3) mat4(_0, _1, _2, _3)
#else
#define mtxFromRows3(_0, _1, _2) mat3(_0, _1, _2)
#define mtxFromRows4(_0, _1, _2, _3) mat4(_0, _1, _2, _3)
#define mtxFromCols3(_0, _1, _2) transpose(mat3(_0, _1, _2) )
#define mtxFromCols4(_0, _1, _2, _3) transpose(mat4(_0, _1, _2, _3) )
#endif // BGFX_SHADER_LANGUAGE_GLSL
uniform vec4 u_viewRect;
uniform vec4 u_viewTexel;
uniform mat4 u_view;
uniform mat4 u_invView;
uniform mat4 u_proj;
uniform mat4 u_invProj;
uniform mat4 u_viewProj;
uniform mat4 u_invViewProj;
uniform mat4 u_model[BGFX_CONFIG_MAX_BONES];
uniform mat4 u_modelView;
uniform mat4 u_invModelView;
uniform mat4 u_modelViewProj;
uniform vec4 u_alphaRef4;
#define u_alphaRef u_alphaRef4.x
#endif // __cplusplus
#endif // BGFX_SHADER_H_HEADER_GUARD

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 96.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 48.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,15 @@
#define CFG_WANG_TILES
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 64.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 32.0
#include "material.sc"

View File

@@ -0,0 +1,223 @@
#ifndef COMMON_SH_HEADER_GUARD
#define COMMON_SH_HEADER_GUARD
#include "globals.sh"
#include <bgfx_shader.sh>
// GLSLES has limited number of vertex shader registers so we have to use less bones
#if defined(GLSLES) && !defined(GL3)
#define MAX_BONE_COUNT 32
#else
#define MAX_BONE_COUNT 72
#endif
// PowerVR saturate() is compiled to min/max pair
// These are cross-platform specialized saturates that are free on PC and only cost 1 cycle on PowerVR
float saturate0(float v)
{
return max(v, 0.0);
}
float saturate1(float v)
{
return min(v, 1.0);
}
#if defined(GLSLES) && !defined(GL3)
#define WANG_SUBSET_SCALE 2.0
#else
#define WANG_SUBSET_SCALE 1.0
#endif
#define GBUFFER_MAX_DEPTH 500.0
// Texture samplers - bgfx style
#define TEX_DECLARE2D(name, reg) SAMPLER2D(name, reg)
#define TEX_DECLARE3D(name, reg) SAMPLER3D(name, reg)
#define TEX_DECLARECUBE(name, reg) SAMPLERCUBE(name, reg)
// Unified matrix uniforms
uniform mat4 u_worldMatrix;
uniform vec4 u_worldMatrixArray[MAX_BONE_COUNT * 3];
#if defined(GLSLES) || defined(PIN_WANG_FALLBACK)
#define TEXTURE_WANG(name) 0
void getWang(sampler2D unused, vec2 uv, float tiling, out vec2 wangUv, out vec4 wangUVDerivatives)
{
wangUv = uv * WANG_SUBSET_SCALE;
wangUVDerivatives = vec4(0.0, 0.0, 0.0, 0.0); // not used in this mode
}
vec4 sampleWang(sampler2D s, vec2 uv, vec4 wangUVDerivatives)
{
return texture2D(s, uv);
}
#else
#define TEXTURE_WANG(name) name
void getWang(sampler2D s, vec2 uv, float tiling, out vec2 wangUv, out vec4 wangUVDerivatives)
{
#ifndef WIN_MOBILE
float idxTexSize = 128.0;
#else
float idxTexSize = 32.0;
#endif
vec2 wangBase = uv * tiling * 4.0;
#if defined(DX11) && !defined(WIN_MOBILE)
// compensate the precision problem of Point Sampling on some cards
vec2 wangUV = (floor(wangBase) + 0.5) / idxTexSize;
#else
vec2 wangUV = wangBase / idxTexSize;
#endif
#if defined(DX11) || defined(GL3)
vec2 wang = texture2D(s, wangUV).rg;
#else
vec2 wang = texture2D(s, wangUV).ba;
#endif
wangUVDerivatives = vec4(dFdx(wangBase * 0.25), dFdy(wangBase * 0.25));
wang *= 255.0 / 256.0;
wangUv = wang + fract(wangBase) * 0.25;
}
vec4 sampleWang(sampler2D s, vec2 uv, vec4 derivates)
{
return texture2DGrad(s, uv, derivates.xy, derivates.zw);
}
#endif
vec4 gbufferPack(float depth, vec3 diffuse, vec3 specular, float fog)
{
depth = saturate(depth / GBUFFER_MAX_DEPTH);
const vec3 lumVec = vec3(0.299, 0.587, 0.114);
vec2 comp;
comp = depth * vec2(255.0, 255.0 * 256.0);
comp = fract(comp);
comp = vec2(depth, comp.x * 256.0 / 255.0) - vec2(comp.x, comp.y) / 255.0;
vec4 result;
result.r = mix(1.0, dot(specular, lumVec), saturate(3.0 * fog));
result.g = mix(0.0, dot(diffuse, lumVec), saturate(3.0 * fog));
result.ba = comp.yx;
return result;
}
vec3 lgridOffset(vec3 v, vec3 n)
{
// cells are 4 studs in size
// offset in normal direction to prevent self-occlusion
// the offset has to be 1.5 cells in order to fully eliminate the influence of the source cell with trilinear filtering
// (i.e. 1 cell is enough for point filtering, but is not enough for trilinear filtering)
return v + n * (1.5 * 4.0);
}
vec3 lgridPrepareSample(vec3 c)
{
// yxz swizzle is necessary for GLSLES sampling to work efficiently
// (having .y as the first component allows to do the LUT lookup as a non-dependent texture fetch)
return c.yxz * u_lightConfig0.xyz + u_lightConfig1.xyz;
}
#if defined(GLSLES) && !defined(GL3)
#define LGRID_SAMPLER(name, register) TEX_DECLARE2D(name, register)
vec4 lgridSample(sampler2D t, sampler2D lut, vec3 data)
{
vec4 offsets = texture2D(lut, data.xy);
// texture is 64 pixels high
// let's compute slice lerp coeff
float slicef = fract(data.x * 64.0);
// texture has 64 slices with 8x8 atlas setup
vec2 base = clamp(data.yz, vec2(0.0), vec2(1.0)) * 0.125;
vec4 s0 = texture2D(t, base + offsets.xy);
vec4 s1 = texture2D(t, base + offsets.zw);
return mix(s0, s1, slicef);
}
#else
#define LGRID_SAMPLER(name, register) TEX_DECLARE3D(name, register)
vec4 lgridSample(sampler3D t, sampler2D lut, vec3 data)
{
vec3 edge = step(u_lightConfig3.xyz, abs(data - u_lightConfig2.xyz));
float edgef = saturate1(dot(edge, vec3(1.0)));
// replace data with 0 on edges to minimize texture cache misses
vec4 light = texture3D(t, data.yzx - data.yzx * edgef);
return mix(light, u_lightBorder, vec4(edgef));
}
#endif
vec3 nmapUnpack(vec4 value)
{
#ifdef GLSLES
return value.rgb * 2.0 - 1.0;
#else
vec2 xy = value.ag * 2.0 - 1.0;
return vec3(xy, sqrt(saturate(1.0 + dot(-xy, xy))));
#endif
}
vec3 terrainNormal(vec4 tnp0, vec4 tnp1, vec4 tnp2, vec3 w, vec3 normal, vec3 tsel)
{
// Inspired by "Voxel-Based Terrain for Real-Time Virtual Simulations" [Lengyel2010] 5.5.2
vec3 tangentTop = vec3(normal.y, -normal.x, 0.0);
vec3 tangentSide = vec3(normal.z, 0.0, -normal.x);
vec3 bitangentTop = vec3(0.0, -normal.z, normal.y);
vec3 bitangentSide = vec3(0.0, -1.0, 0.0);
// Blend pre-unpack to save cycles
vec3 tn = nmapUnpack(tnp0 * w.x + tnp1 * w.y + tnp2 * w.z);
// We blend all tangent frames together as a faster approximation to the correct world normal blend
float tselw = dot(tsel, w);
vec3 tangent = mix(tangentSide, tangentTop, tselw);
vec3 bitangent = mix(bitangentSide, bitangentTop, tselw);
return normalize(tangent * tn.x + bitangent * tn.y + normal * tn.z);
}
vec3 shadowPrepareSample(vec3 p)
{
vec4 c = vec4(p, 1.0);
return vec3(dot(u_shadowMatrix0, c), dot(u_shadowMatrix1, c), dot(u_shadowMatrix2, c));
}
float shadowDepth(vec3 lpos)
{
return lpos.z;
}
float shadowStep(float d, float z)
{
// saturate returns 1 for z in [0.1..0.9]; it fades to 0 as z approaches 0 or 1
return step(d, z) * saturate(9.0 - 20.0 * abs(z - 0.5));
}
float shadowSample(sampler2D map, vec3 lpos, float lightShadow)
{
#ifdef CLASSIC
return lightShadow;
#else
vec2 smDepth = texture2D(map, lpos.xy).rg;
float smShadow = shadowStep(smDepth.x, shadowDepth(lpos));
return (1.0 - smShadow * smDepth.y * u_outlineBrightness_ShadowInfo.w) * lightShadow;
#endif
}
#endif // COMMON_SH_HEADER_GUARD

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 32.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,425 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#define LQMAT_FADE_FACTOR (1.0/300.0)
#define BEVEL_WIDTH 0.06
#define PI 3.14159265359
#define BEVEL_FADE_DIST 120.0
#define BEVEL_FADE_DIST_START 0.0
#define SPEC_EXPON 81.0
#define KS 0.75
#define FADE_DIST 500.0
#define FADE_DIST_START 0.0
uniform vec4 u_worldMatrixArray[MAX_BONE_COUNT * 3];
uniform vec4 u_debugColor;
SAMPLER2D(s_studsMap, 0);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLER2D(s_shadowMap, 3);
SAMPLERCUBE(s_environmentMap, 4);
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
SAMPLER2D(s_specularMap, 7);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
uniform vec4 u_lqmatFarTilingFactor;
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular)
{
vec3 ln = normalize(-u_lamp0Dir);
vec3 hn = normalize(ln + vn);
float ndl = dot(nn, ln);
float ndh = dot(nn, hn);
vec2 lit0 = vec2(max(0.0, ndl), pow(max(0.0, ndh), specExpon) * step(0.0, ndl));
vec3 lampColor = u_lamp0Color;
diffuse = (light.a * (lampColor * lit0.x) + u_ambientColor + light.xyz);
diffuse *= albedo;
specular = (lampColor * lit0.y) * ks * light.a;
}
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth)
{
vec4 bevelMultiplier = clamp((BEVEL_WIDTH - edgeDistances) / BEVEL_WIDTH, 0.0, 1.0);
float fade = clamp(1.0 - (viewDepth - BEVEL_FADE_DIST_START) / BEVEL_FADE_DIST, 0.0, 1.0);
bevelMultiplier *= fade;
normal += bevelMultiplier.x * vec3(0.5, 0.0, 0.0);
normal += bevelMultiplier.y * vec3(-0.5, 0.0, 0.0);
normal += bevelMultiplier.z * vec3(0.0, 0.5, 0.0);
normal += bevelMultiplier.w * vec3(0.0, -0.5, 0.0);
return normalize(normal);
}
vec3 DisplaceCoord(vec3 pos)
{
float cfactor = 0.980066578;
float sfactor = 0.198669331;
float cfactor2 = 0.955336489;
float sfactor2 = 0.295520207;
float cfactor3 = 0.921060994;
float sfactor3 = 0.389418342;
vec3 p = pos.xyz;
vec3 shiftPos = p;
shiftPos.x += p.x * cfactor + p.z * sfactor;
shiftPos.z += p.x * -sfactor + p.z * cfactor;
shiftPos.x += p.x * cfactor2 - p.y * sfactor2;
shiftPos.y += p.x * sfactor2 + p.y * cfactor2;
shiftPos.y += p.y * cfactor3 - p.z * sfactor3;
shiftPos.z += p.y * sfactor3 + p.z * cfactor3;
return shiftPos;
}
#ifdef CLASSIC
void DefaultVS()
{
// Transform position and normal to world space
#ifdef PIN_SKINNED
int boneIndex = int(a_color1.r);
vec4 worldRow0 = u_worldMatrixArray[boneIndex * 3];
vec4 worldRow1 = u_worldMatrixArray[boneIndex * 3 + 1];
vec4 worldRow2 = u_worldMatrixArray[boneIndex * 3 + 2];
vec3 posWorld = vec3(dot(worldRow0, vec4(a_position, 1.0)),
dot(worldRow1, vec4(a_position, 1.0)),
dot(worldRow2, vec4(a_position, 1.0)));
vec3 normalWorld = vec3(dot(worldRow0.xyz, a_normal),
dot(worldRow1.xyz, a_normal),
dot(worldRow2.xyz, a_normal));
v_tangent = vec3(dot(worldRow0.xyz, a_texcoord2),
dot(worldRow1.xyz, a_texcoord2),
dot(worldRow2.xyz, a_texcoord2));
#else
vec3 posWorld = a_position;
vec3 normalWorld = a_normal;
v_tangent = a_texcoord2;
#endif
v_pos = a_position;
v_worldPos = posWorld;
vec4 color = a_color0;
gl_Position = mul(u_viewProjection, vec4(posWorld, 1.0));
v_normal = normalWorld;
v_texcoord0 = a_texcoord0;
v_texcoord1 = a_texcoord1;
v_color0 = color;
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)),
(u_fogParams.z - gl_Position.w) * u_fogParams.w);
v_view_depth = vec4(u_cameraPosition - posWorld, gl_Position.w);
#ifdef CLASSIC_GOURAUD
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffuse, specular;
Shade(vec3(1.0), normalize(v_normal), normalize(v_view_depth.xyz), 0.71, 81.0, light, diffuse, specular);
// Store in unused varyings
#endif
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
v_reflection = a_color1.a / 255.0;
v_edgedist = a_texcoord3;
#endif
v_poslightspace = shadowPrepareSample(posWorld);
}
void DefaultPS()
{
float normalStrength = 0.4;
float fade = clamp(normalStrength - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec3 nn = normalize(v_normal);
vec4 edgeDistances = v_edgedist;
vec4 albedo = v_color0;
vec2 uv;
#ifndef PIN_MESH
uv = v_texcoord0;
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec3 tn = vec3(0.0, 0.0, 0.5);
tn = mix(vec3(0.0, 0.0, 0.5), tn, fade);
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
vec4 colorTex = texture2D(s_diffuseMap, uv);
albedo *= colorTex;
#else
uv = v_texcoord0;
vec4 colorTex = texture2D(s_diffuseMap, uv);
albedo *= colorTex;
#endif
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffusePhong, specularPhong;
vec3 diffuse, specular;
#ifdef CLASSIC_GOURAUD
// Use pre-computed lighting from vertex shader
diffuse = albedo.rgb; // Should use stored diffuse from VS
specular = vec3(0.0); // Should use stored specular from VS
#else
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffusePhong, specularPhong);
diffuse = diffusePhong;
specular = specularPhong;
#endif
vec3 result = diffuse + specular;
#ifdef PIN_REFLECTION
vec3 reflection = textureCube(s_environmentMap, reflect(-vn, nn)).rgb;
result = mix(result, reflection, v_reflection);
#endif
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
result = mix(u_fogColor, result, fogAlpha);
gl_FragColor = vec4(result, albedo.a);
#ifdef PIN_GBUFFER
// Output to second render target
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else // !CLASSIC - Modern rendering path
void DefaultVS()
{
// Transform position and normal to world space
#ifdef PIN_SKINNED
int boneIndex = int(a_color1.r);
vec4 worldRow0 = u_worldMatrixArray[boneIndex * 3 + 0];
vec4 worldRow1 = u_worldMatrixArray[boneIndex * 3 + 1];
vec4 worldRow2 = u_worldMatrixArray[boneIndex * 3 + 2];
vec3 posWorld = vec3(dot(worldRow0, vec4(a_position, 1.0)),
dot(worldRow1, vec4(a_position, 1.0)),
dot(worldRow2, vec4(a_position, 1.0)));
vec3 normalWorld = vec3(dot(worldRow0.xyz, a_normal),
dot(worldRow1.xyz, a_normal),
dot(worldRow2.xyz, a_normal));
#else
vec3 posWorld = a_position;
vec3 normalWorld = a_normal;
#endif
// Decode diffuse/specular parameters
#ifdef PIN_DEBUG
vec4 color = u_debugColor;
#else
vec4 color = a_color0;
#endif
float specularIntensity = a_color1.g / 255.0;
float specularPower = float(int(a_color1.b));
float ndotl = dot(normalWorld, -u_lamp0Dir);
#ifdef PIN_HQ
// We'll calculate specular in pixel shader
vec2 lt = vec2(clamp(ndotl, 0.0, 1.0), step(0.0, ndotl));
#else
// Using lit here improves performance on software vertex shader implementations
vec2 lt = vec2(max(0.0, ndotl),
pow(max(0.0, dot(normalize(-u_lamp0Dir + normalize(u_cameraPosition - posWorld)), normalWorld)), specularPower) * step(0.0, ndotl));
#endif
gl_Position = mul(u_viewProjection, vec4(posWorld, 1.0));
v_texcoord0 = a_texcoord0;
v_texcoord1 = a_texcoord1;
v_color0 = color;
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)),
(u_fogParams.z - gl_Position.w) * u_fogParams.w);
v_view_depth = vec4(u_cameraPosition - posWorld, gl_Position.w);
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
vec4 edgeDistances = a_texcoord3 * u_fadeDistance_GlowFactor.z + 0.5 * v_view_depth.w * u_fadeDistance_GlowFactor.y;
v_edgedist = edgeDistances;
v_normal = normalWorld;
// Store specular power in normal.w if needed
v_reflection = a_color1.a / 255.0;
#endif
#ifdef PIN_SURFACE
#ifdef PIN_SKINNED
vec3 tangent = vec3(dot(worldRow0.xyz, a_texcoord2),
dot(worldRow1.xyz, a_texcoord2),
dot(worldRow2.xyz, a_texcoord2));
#else
vec3 tangent = a_texcoord2;
#endif
v_tangent = tangent;
#else
vec3 diffuse = lt.x * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
// Store diffuse and specular in color channels (pack into v_color0.w and other varyings)
#endif
v_poslightspace = shadowPrepareSample(posWorld);
}
vec4 sampleFar1(sampler2D s, vec2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return texture2D(s, uv);
#else
if (cutoff == 0.0)
return texture2D(s, uv);
else
{
float cscale = 1.0 / (1.0 - cutoff);
return mix(texture2D(s, uv * u_lqmatFarTilingFactor.xy),
texture2D(s, uv),
saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
vec4 sampleWangSimple(sampler2D s, vec2 uv)
{
vec2 wangUv;
vec4 wangUVDerivatives;
getWang(s_normalDetailMap, uv, 1.0, wangUv, wangUVDerivatives);
return sampleWang(s, wangUv, wangUVDerivatives);
}
#endif
void DefaultPS()
{
// Compute albedo term
#ifdef PIN_SURFACE
// Surface shader path - would need surface shader implementation
vec4 albedo = v_color0;
vec3 normal = normalize(v_normal);
#elif defined(PIN_LOWQMAT)
#ifndef CFG_FAR_DIFFUSE_CUTOFF
#define CFG_FAR_DIFFUSE_CUTOFF 0.6
#endif
#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
vec4 albedo = sampleWangSimple(s_diffuseMap, v_texcoord0);
#else
float fade = saturate0(1.0 - v_view_depth.w * LQMAT_FADE_FACTOR);
vec4 albedo = sampleFar1(s_diffuseMap, v_texcoord0, fade, CFG_FAR_DIFFUSE_CUTOFF);
#endif
albedo.rgb = mix(vec3(1.0), v_color0.rgb, albedo.a) * albedo.rgb;
albedo.a = v_color0.a;
// Diffuse and specular from vertex shader (stored in varyings)
vec3 diffuseIntensity = vec3(1.0); // Should unpack from varyings
float specularIntensity = 0.0; // Should unpack from varyings
float reflectance = 0.0;
#else
#ifdef PIN_PLASTIC
vec4 studs = texture2D(s_studsMap, v_texcoord1);
vec4 albedo = vec4(v_color0.rgb * (studs.r * 2.0), v_color0.a);
#else
vec4 albedo = texture2D(s_diffuseMap, v_texcoord0) * v_color0;
#endif
#ifdef PIN_HQ
vec3 normal = normalize(v_normal);
float specularPower = 81.0; // Should come from varying
#elif defined(PIN_REFLECTION)
vec3 normal = v_normal;
#endif
vec3 diffuseIntensity = vec3(1.0); // Should unpack from varyings
float specularIntensity = 0.0; // Should unpack from varyings
#ifdef PIN_REFLECTION
float reflectance = v_reflection;
#endif
#endif
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = shadowSample(s_shadowMap, v_poslightspace, light.a);
// Compute reflection term
#if defined(PIN_SURFACE) || defined(PIN_REFLECTION)
vec3 reflection = textureCube(s_environmentMap, reflect(-v_view_depth.xyz, normal)).rgb;
albedo.rgb = mix(albedo.rgb, reflection.rgb, reflectance);
#endif
// Compute diffuse term
vec3 diffuse = (u_ambientColor + diffuseIntensity * shadow + light.rgb) * albedo.rgb;
// Compute specular term
#ifdef PIN_HQ
vec3 normal = normalize(v_normal);
float specularPower = 81.0;
vec3 specular = u_lamp0Color * (specularIntensity * shadow *
pow(clamp(dot(normal, normalize(-u_lamp0Dir + normalize(v_view_depth.xyz))), 0.0, 1.0), specularPower));
#else
vec3 specular = u_lamp0Color * (specularIntensity * shadow);
#endif
// Combine
vec3 resultColor = diffuse.rgb + specular.rgb;
float resultAlpha = albedo.a;
#ifdef PIN_HQ
float ViewDepthMul = v_view_depth.w * u_fadeDistance_GlowFactor.y;
float outlineFade = saturate1(ViewDepthMul * u_outlineBrightness_ShadowInfo.x + u_outlineBrightness_ShadowInfo.y);
vec2 minIntermediate = min(v_edgedist.xy, v_edgedist.zw);
float minEdgesPlus = min(minIntermediate.x, minIntermediate.y) / ViewDepthMul;
resultColor *= saturate1(outlineFade * (1.5 - minEdgesPlus) + minEdgesPlus);
#endif
float fogAlpha = clamp(v_lightpos_fog.w, 0.0, 1.0);
#ifdef PIN_NEON
resultColor = v_color0.rgb * u_fadeDistance_GlowFactor.w;
resultAlpha = 1.0 - fogAlpha * v_color0.a;
diffuse.rgb = vec3(0.0);
specular.rgb = vec3(0.0);
#endif
resultColor = mix(u_fogColor, resultColor, fogAlpha);
gl_FragColor = vec4(resultColor, resultAlpha);
#ifdef PIN_GBUFFER
// Output to second render target
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#endif // CLASSIC

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.3
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 64.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 64.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.5
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,37 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include "common.sh"
uniform vec4 u_textureSize;
SAMPLER2D(s_tex, 0);
vec4 convertPosition(vec4 p)
{
#if defined(GLSL) || defined(DX11)
return p;
#else
return p + vec4(-u_textureSize.z, u_textureSize.w, 0.0, 0.0);
#endif
}
vec2 convertUv(vec4 p)
{
#if defined(GLSL)
return p.xy * 0.5 + 0.5;
#else
return p.xy * vec2(0.5, -0.5) + 0.5;
#endif
}
void gbufferVS()
{
gl_Position = convertPosition(vec4(a_position, 1.0));
v_texcoord0 = convertUv(vec4(a_position, 1.0));
}
void gbufferPS()
{
gl_FragColor = texture2D(s_tex, v_texcoord0);
}

View File

@@ -0,0 +1,33 @@
#ifndef GLOBALS_SH_HEADER_GUARD
#define GLOBALS_SH_HEADER_GUARD
// Uniform declarations for bgfx
uniform mat4 u_viewProjection;
uniform vec4 u_viewRight;
uniform vec4 u_viewUp;
uniform vec4 u_viewDir;
uniform vec3 u_cameraPosition;
uniform vec3 u_ambientColor;
uniform vec3 u_lamp0Color;
uniform vec3 u_lamp0Dir;
uniform vec3 u_lamp1Color;
uniform vec3 u_fogColor;
uniform vec4 u_fogParams;
uniform vec4 u_lightBorder;
uniform vec4 u_lightConfig0;
uniform vec4 u_lightConfig1;
uniform vec4 u_lightConfig2;
uniform vec4 u_lightConfig3;
uniform vec4 u_fadeDistance_GlowFactor;
uniform vec4 u_outlineBrightness_ShadowInfo;
uniform vec4 u_shadowMatrix0;
uniform vec4 u_shadowMatrix1;
uniform vec4 u_shadowMatrix2;
#endif // GLOBALS_SH_HEADER_GUARD

View File

@@ -0,0 +1,23 @@
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 0.8
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.2
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.7
#define CFG_GLOSS_LOD 54.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.0
#define CFG_FAR_DIFFUSE_CUTOFF 0.0
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#define CFG_OPT_NORMAL_CONST
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 32.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.4
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 128.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "slate.sc"
#else
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.2
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.7
#define CFG_GLOSS_LOD 54.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.0
#define CFG_FAR_DIFFUSE_CUTOFF 0.0
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#define CFG_OPT_NORMAL_CONST
#include "material.sc"
#endif

View File

@@ -0,0 +1,130 @@
#define PIN_SURFACE
#include "default.sc"
#ifndef CFG_WANG_TILES
vec4 sampleFar(sampler2D s, vec2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return texture2D(s, uv);
#else
if (cutoff == 0.0)
return texture2D(s, uv);
else
{
float cscale = 1.0 / (1.0 - cutoff);
return mix(texture2D(s, uv * (CFG_FAR_TILING)),
texture2D(s, uv),
saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
#endif
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
SAMPLER2D(s_specularMap, 7);
SAMPLER2D(s_studsMap, 0);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
struct SurfaceInput
{
vec4 Color;
vec2 Uv;
vec2 UvStuds;
#ifdef PIN_REFLECTION
float Reflectance;
#endif
};
struct Surface
{
vec3 albedo;
vec3 normal;
float specular;
float gloss;
float reflectance;
};
vec3 nmapUnpack(vec4 value);
Surface surfaceShader(SurfaceInput IN, vec2 fade2)
{
#ifdef CFG_WANG_TILES
vec2 wangUv;
vec4 wangUVDerivatives;
getWang(s_normalDetailMap, IN.Uv, CFG_TEXTURE_TILING, wangUv, wangUVDerivatives);
#endif
vec2 uv = IN.Uv * (CFG_TEXTURE_TILING);
float fadeDiffuse = fade2.x;
float fade = fade2.y;
#ifdef CFG_OPT_DIFFUSE_CONST
vec4 diffuse = vec4(1.0);
#else
#ifdef CFG_WANG_TILES
vec4 diffuse = sampleWang(s_diffuseMap, wangUv, wangUVDerivatives);
#else
vec4 diffuse = sampleFar(s_diffuseMap, uv, fadeDiffuse, CFG_FAR_DIFFUSE_CUTOFF);
#endif
diffuse.rgba = diffuse.rgba * (CFG_DIFFUSE_SCALE);
#endif
#ifdef CFG_OPT_NORMAL_CONST
vec3 normal = vec3(0.0, 0.0, 1.0);
#else
#ifdef CFG_WANG_TILES
vec3 normal = nmapUnpack(sampleWang(s_normalMap, wangUv, wangUVDerivatives));
#else
vec3 normal = nmapUnpack(sampleFar(s_normalMap, uv, fade, CFG_FAR_NORMAL_CUTOFF));
#endif
#endif
#ifndef GLSLES
#ifndef CFG_WANG_TILES // normal detail unavailable when running wang tiles
vec3 normalDetail = nmapUnpack(texture2D(s_normalDetailMap, uv * (CFG_NORMAL_DETAIL_TILING)));
normal.xy += normalDetail.xy * (CFG_NORMAL_DETAIL_SCALE);
#endif
#endif
normal.xy *= fade;
float shadowFactor = 1.0 + normal.x * (CFG_NORMAL_SHADOW_SCALE);
#ifdef CFG_OPT_BLEND_COLOR
vec3 albedo = mix(vec3(1.0), IN.Color.rgb, diffuse.a) * diffuse.rgb * shadowFactor;
#else
vec3 albedo = IN.Color.rgb * diffuse.rgb * shadowFactor;
#endif
#ifndef GLSLES
vec4 studs = texture2D(s_studsMap, IN.UvStuds);
albedo *= studs.r * 2.0;
#endif
#ifdef CFG_WANG_TILES
vec2 specular = sampleWang(s_specularMap, wangUv, wangUVDerivatives).rg;
#else
vec2 specular = sampleFar(s_specularMap, uv, fade, CFG_FAR_SPECULAR_CUTOFF).rg;
#endif
// make sure glossiness is never 0 to avoid fp specials
vec2 specbase = specular * vec2(CFG_SPECULAR_SCALE, CFG_GLOSS_SCALE) + vec2(0.0, 0.01);
vec2 specfade = mix(vec2(CFG_SPECULAR_LOD, CFG_GLOSS_LOD), specbase, fade);
Surface surface;
surface.albedo = albedo;
surface.normal = normal;
surface.specular = specfade.r;
surface.gloss = specfade.g;
surface.reflectance = specular.g * fade * (CFG_REFLECTION_SCALE);
return surface;
}

View File

@@ -0,0 +1,121 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_tangent
$output v_pos, v_texcoord0, v_texcoord1, v_lightpos_fog, v_view_depth, v_normal, v_tangent, v_color0, v_poslightspace
#include "common.sh"
#include "globals.sh"
SAMPLER2D(s_diffuseHighMap, 0);
SAMPLER2D(s_diffuseLowMap, 1);
SAMPLER2D(s_normalMap, 2);
SAMPLER2D(s_specularMap, 3);
SAMPLER2D(s_lightMap, 4);
SAMPLER2D(s_lightMapLookup, 5);
SAMPLER2D(s_shadowMap, 6);
void MegaClusterVS()
{
// Decode vertex data
vec3 Normal = (a_normal.xyz - 127.0) / 127.0;
vec4 UV = a_texcoord0 / 2048.0;
// Transform position and normal to world space
// Note: world matrix does not contain rotation/scale for static geometry so we can avoid transforming normal
vec3 posWorld = mul(u_worldMatrix, vec4(a_position.xyz, 1.0)).xyz;
vec3 normalWorld = Normal;
v_pos = mul(u_viewProjection, vec4(posWorld, 1.0));
float blend = v_pos.w / 200.0;
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (u_fogParams.z - v_pos.w) * u_fogParams.w);
v_texcoord0.xy = UV.xy;
v_texcoord1.xy = UV.zw;
#ifdef PIN_HQ
v_view_depth = vec4(posWorld, v_pos.w * u_fadeDistance_GlowFactor.y);
vec4 edgeDistances = a_texcoord1 * u_fadeDistance_GlowFactor.z + 0.5 * v_view_depth.w;
v_texcoord0.zw = edgeDistances.xy;
v_texcoord1.zw = edgeDistances.zw;
v_view_depth.xyz = u_cameraPosition.xyz - posWorld;
v_normal = vec4(Normal, blend);
// decode tangent
v_tangent = (a_tangent.xyz - 127.0) / 127.0;
#else
// IF LQ shading is performed in VS
float ndotl = dot(normalWorld, -u_lamp0Dir);
vec3 diffuse = saturate0(ndotl) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
v_color0 = vec4(diffuse, blend);
#endif
v_poslightspace = shadowPrepareSample(posWorld);
gl_Position = v_pos;
}
void MegaClusterPS()
{
vec4 high = texture2D(s_diffuseHighMap, v_texcoord0.xy);
vec4 low = texture2D(s_diffuseLowMap, v_texcoord1.xy);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = shadowSample(s_shadowMap, v_poslightspace, light.a);
#ifdef PIN_HQ
vec3 albedo = mix(high.rgb, low.rgb, saturate1(v_normal.a));
// sample normal map and specular map
vec4 normalMapSample = texture2D(s_normalMap, v_texcoord0.xy);
vec4 specularMapSample = texture2D(s_specularMap, v_texcoord0.xy);
// compute bitangent and world space normal
vec3 bitangent = cross(v_normal.xyz, v_tangent.xyz);
#ifdef CLASSIC
vec3 nmap = vec3(0.0, 0.0, 0.5);
#else
vec3 nmap = nmapUnpack(normalMapSample);
#endif
vec3 normal = normalize(nmap.x * v_tangent.xyz + nmap.y * bitangent + nmap.z * v_normal.xyz);
float ndotl = dot(normal, -u_lamp0Dir);
vec3 diffuseIntensity = saturate0(ndotl) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
float specularIntensity = step(0.0, ndotl) * specularMapSample.r;
float specularPower = specularMapSample.g * 255.0 + 0.01;
// Compute diffuse and specular and combine them
vec3 diffuse = (u_ambientColor + diffuseIntensity * shadow + light.rgb) * albedo.rgb;
vec3 specular = u_lamp0Color * (specularIntensity * shadow * pow(saturate0(dot(normal, normalize(-u_lamp0Dir + normalize(v_view_depth.xyz)))), specularPower));
gl_FragColor.rgb = diffuse + specular;
// apply outlines
float outlineFade = saturate1(v_view_depth.w * u_outlineBrightness_ShadowInfo.x + u_outlineBrightness_ShadowInfo.y);
vec2 minIntermediate = min(v_texcoord0.wz, v_texcoord1.wz);
float minEdgesPlus = min(minIntermediate.x, minIntermediate.y) / v_view_depth.w;
gl_FragColor.rgb *= saturate1(outlineFade * (1.5 - minEdgesPlus) + minEdgesPlus);
gl_FragColor.a = 1.0;
#else
vec3 albedo = mix(high.rgb, low.rgb, saturate1(v_color0.a));
// Compute diffuse term
vec3 diffuse = (u_ambientColor + v_color0.rgb * shadow + light.rgb) * albedo.rgb;
// Combine
gl_FragColor.rgb = diffuse;
gl_FragColor.a = 1.0;
#endif
float fogAlpha = saturate0(v_lightpos_fog.w);
gl_FragColor.rgb = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef CLASSIC
gl_FragColor.rgb = v_texcoord0.xyy;
gl_FragColor.rgb = u_outlineBrightness_ShadowInfo.xxx;
#endif
}

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.5
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 128.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,3 @@
#define PIN_PLASTIC
#define PIN_NEON
#include "default.sc"

View File

@@ -0,0 +1,198 @@
$input a_position, a_texcoord0, a_texcoord1, a_texcoord2, a_texcoord3
$output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_cstrip, 1);
SAMPLER2D(s_astrip, 2);
uniform vec4 u_throttleFactor; // .x = alpha cutoff, .y = alpha boost (clamp), .w - additive/alpha ratio for Crazy shaders
uniform vec4 u_modulateColor;
uniform vec4 u_zOffset;
vec4 rotScale(vec4 scaleRotLife)
{
float cr = cos(scaleRotLife.z);
float sr = sin(scaleRotLife.z);
vec4 r;
r.x = cr * scaleRotLife.x;
r.y = -sr * scaleRotLife.x;
r.z = sr * scaleRotLife.y;
r.w = cr * scaleRotLife.y;
return r;
}
vec4 mulq(vec4 a, vec4 b)
{
vec3 i = cross(a.xyz, b.xyz) + a.w * b.xyz + b.w * a.xyz;
float r = a.w * b.w - dot(a.xyz, b.xyz);
return vec4(i, r);
}
vec4 conj(vec4 a)
{
return vec4(-a.xyz, a.w);
}
vec4 rotate(vec4 v, vec4 q)
{
return mulq(mulq(q, v), conj(q));
}
vec4 axis_angle(vec3 axis, float angle)
{
return vec4(sin(angle/2.0) * axis, cos(angle/2.0));
}
void vs()
{
vec4 pos = vec4(a_position, 1.0);
vec2 disp = a_texcoord1.xy * 2.0 - 1.0; // -1..1
vec4 scaleRotLifeFlt = a_texcoord0 * vec4(1.0/256.0, 1.0/256.0, 2.0 * 3.1415926 / 32767.0, 1.0 / 32767.0);
scaleRotLifeFlt.xy += 127.0;
vec4 rs = rotScale(scaleRotLifeFlt);
pos += u_viewRight * dot(disp, rs.xy);
pos += u_viewUp * dot(disp, rs.zw);
vec4 pos2 = pos + u_viewDir * u_zOffset.x; // Z-offset position in world space
gl_Position = mul(u_viewProjection, pos);
v_texcoord0.xy = a_texcoord1.xy;
v_texcoord0.y = 1.0 - v_texcoord0.y;
v_texcoord0.z = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
v_texcoord1.x = 1.0 - max(0.0, min(1.0, scaleRotLifeFlt.w));
v_texcoord1.y = a_texcoord2.x * (1.0 / 32767.0);
pos2 = mul(u_viewProjection, pos2); // Z-offset position in clip space
gl_Position.z = pos2.z * gl_Position.w / pos2.w; // Only need z
}
void psAdd()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy);
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
vec4 result;
result.rgb = (texcolor.rgb + vcolor.rgb) * u_modulateColor.rgb;
result.a = texcolor.a * vcolor.a;
result.rgb *= result.a;
result.rgb = mix(vec3(0.0), result.rgb, saturate(v_texcoord0.zzz));
gl_FragColor = result;
}
void psModulate()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy) * u_modulateColor;
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r * u_modulateColor.a;
vec4 result;
result.rgb = texcolor.rgb * vcolor.rgb;
result.a = texcolor.a * vcolor.a;
result.rgb = mix(u_fogColor.rgb, result.rgb, saturate(v_texcoord0.zzz));
gl_FragColor = result;
}
// - this shader is crazy
// - used instead of additive particles to help see bright particles (e.g. fire) on top of extremely bright backgrounds
// - requires ONE | INVSRCALPHA blend mode, useless otherwise
// - does not use color strip texture
// - outputs a blend between additive blend and alpha blend in fragment alpha
// - ratio multiplier is in throttleFactor.w
void psCrazy()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = vec4(1.0, 0.0, 0.0, 0.0);
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
float blendRatio = u_throttleFactor.w;
vec4 result;
result.rgb = (texcolor.rgb) * u_modulateColor.rgb * vcolor.a * texcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
gl_FragColor = result;
}
void psCrazySparkles()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy);
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
float blendRatio = u_throttleFactor.w;
vec4 result;
if (texcolor.a < 0.5)
{
result.rgb = vcolor.rgb * u_modulateColor.rgb * (2.0 * texcolor.a);
}
else
{
result.rgb = mix(vcolor.rgb * u_modulateColor.rgb, texcolor.rgb, 2.0 * texcolor.a - 1.0);
}
result.rgb *= vcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
gl_FragColor = result;
}
// Custom particle shader
void vsCustom()
{
vec4 pos = vec4(a_position, 1.0);
vec2 disp = a_texcoord1.xy * 2.0 - 1.0; // -1..1
vec4 scaleRotLifeFlt = a_texcoord0 * vec4(1.0/256.0, 1.0/256.0, 2.0 * 3.1415926 / 32767.0, 1.0 / 32767.0);
scaleRotLifeFlt.xy += 127.0;
vec4 rs = rotScale(scaleRotLifeFlt);
pos += u_viewRight * dot(disp, rs.xy);
pos += u_viewUp * dot(disp, rs.zw);
vec4 pos2 = pos + u_viewDir * u_zOffset.x; // Z-offset position in world space
gl_Position = mul(u_viewProjection, pos);
v_texcoord0.xy = a_texcoord1.xy;
v_texcoord0.y = 1.0 - v_texcoord0.y;
v_texcoord0.z = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
v_color0 = a_texcoord3 * (1.0/255.0);
pos2 = mul(u_viewProjection, pos2); // Z-offset position in clip space
gl_Position.z = pos2.z * gl_Position.w / pos2.w; // Only need z
}
void psCustom()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = v_color0;
float blendRatio = u_throttleFactor.w;
vec4 result;
result.rgb = texcolor.rgb * vcolor.rgb * vcolor.a * texcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
gl_FragColor = result;
}

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 32.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.15
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.5
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,208 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#ifdef PIN_HQ
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 81.0
#define KS 0.75
#define FADE_DIST 500.0
#define FADE_DIST_START 0.0
#define BEVEL_WIDTH 0.06
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLERCUBE(s_environmentMap, 4);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
uniform vec4 u_waveParams; // .x = frequency .y = phase .z = height .w = lerp
vec3 CalcBevelDir(vec4 edgeDistances)
{
vec3 dir = vec3(0.0);
vec4 bevelMultiplier = step(edgeDistances, vec4(BEVEL_WIDTH));
dir += bevelMultiplier.x * vec3(1.0, 0.0, 0.0);
dir += bevelMultiplier.y * vec3(-1.0, 0.0, 0.0);
dir += bevelMultiplier.z * vec3(0.0, 1.0, 0.0);
dir += bevelMultiplier.w * vec3(0.0, -1.0, 0.0);
return dir;
}
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
void DefaultPS()
{
float normalStrength = 0.4;
float fade = clamp(normalStrength - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec3 nn = normalize(v_normal);
vec4 edgeDistances = v_edgedist;
vec4 albedo = v_color0;
vec2 uv;
float wt = 1.0;
#ifndef PIN_MESH
uv = v_texcoord1; // UvStuds
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec3 tn = vec3(0.0, 0.0, 0.5);
tn = mix(vec3(0.0, 0.0, 0.5), tn, fade);
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
wt = 1.0 - abs(length(tn.xy));
vec4 colorTex = texture2D(s_diffuseMap, uv);
#else
uv = v_texcoord0;
vec4 colorTex = texture2D(s_diffuseMap, uv);
albedo *= colorTex;
#endif
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffuse;
vec3 specular;
#ifdef CLASSIC_GOURAUD
vec3 diffusePhong;
vec3 specularPhong;
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffusePhong, specularPhong);
diffuse = mix(diffusePhong, albedo.rgb, wt); // Simplified - should use stored diffuse
specular = mix(specularPhong, vec3(0.0), wt); // Simplified - should use stored specular
#else
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
#endif
#ifndef PIN_MESH
diffuse = mix(diffuse, colorTex.xyz, colorTex.w);
#endif
vec3 result = diffuse + specular;
#ifdef PIN_REFLECTION
vec3 reflection = textureCube(s_environmentMap, reflect(-vn, nn)).rgb;
result = mix(result, reflection, v_reflection);
#endif
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
result = mix(u_fogColor, result, fogAlpha);
gl_FragColor = vec4(result, albedo.a);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define PIN_PLASTIC
#include "default.sc"
#endif
#else // !CLASSIC
#if defined(PIN_HQ)
#define PIN_SURFACE
#define CFG_TEXTURE_TILING 1.0
#define CFG_BUMP_INTENSITY 0.5
#define CFG_SPECULAR 0.4
#define CFG_GLOSS 9.0
#define CFG_NORMAL_SHADOW_SCALE 0.1
struct SurfaceInput
{
vec4 Color;
vec2 Uv;
vec2 UvStuds;
#ifdef PIN_REFLECTION
float Reflectance;
#endif
};
struct Surface
{
vec3 albedo;
vec3 normal;
float specular;
float gloss;
float reflectance;
};
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
vec3 nmapUnpack(vec4 value);
Surface surfaceShader(SurfaceInput IN, vec2 fade2)
{
float fade = fade2.y;
vec4 studs = texture2D(s_diffuseMap, IN.UvStuds);
vec3 normal = nmapUnpack(texture2D(s_normalMap, IN.UvStuds));
#ifdef GLSLES
vec3 noise = vec3(0.0, 0.0, 1.0);
#else
vec3 noise = nmapUnpack(texture2D(s_normalDetailMap, IN.Uv * CFG_TEXTURE_TILING));
#endif
float noiseScale = saturate0(IN.Color.a * 2.0 * CFG_BUMP_INTENSITY - 1.0 * CFG_BUMP_INTENSITY);
#ifdef PIN_REFLECTION
noiseScale *= clamp(1.0 - 2.0 * IN.Reflectance, 0.0, 1.0);
#endif
normal.xy += noise.xy * noiseScale;
normal.xy *= fade;
Surface surface;
surface.albedo = IN.Color.rgb * (studs.r * 2.0);
surface.normal = normal;
surface.specular = CFG_SPECULAR;
surface.gloss = CFG_GLOSS;
#ifdef PIN_REFLECTION
surface.reflectance = IN.Reflectance;
#endif
return surface;
}
#include "default.sc"
#else
#define PIN_PLASTIC
#include "default.sc"
#endif
#endif // CLASSIC

View File

@@ -0,0 +1,31 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0
#include "common.sh"
SAMPLER2D(s_diffuseMap, 0);
void ProfilerVS()
{
gl_Position = mul(u_viewProjection, vec4(a_position, 1.0));
gl_Position.y = -gl_Position.y;
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
void ProfilerPS()
{
vec4 c0 = texture2D(s_diffuseMap, v_texcoord0);
vec4 c1 = texture2D(s_diffuseMap, v_texcoord0 + vec2(0.0, 1.0 / 9.0));
gl_FragColor = c0.a < 0.5 ? vec4(0.0, 0.0, 0.0, c1.a) : c0 * v_color0;
}
void ImGuiPS()
{
vec4 texColor = texture2D(s_diffuseMap, v_texcoord0);
vec4 finalColor = texColor * v_color0;
gl_FragColor = finalColor;
}

View File

@@ -0,0 +1,15 @@
#define CFG_WANG_TILES
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 64.0
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 96.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.15
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 48.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.5
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,343 @@
$input a_position
$output v_pos, v_texcoord0, v_texcoord1, v_texcoord2
#include "common.sh"
#include "globals.sh"
SAMPLER2D(s_texture, 0);
SAMPLER2D(s_mask, 1);
// .xy = gbuffer width/height, .zw = inverse gbuffer width/height
uniform vec4 u_textureSize;
uniform vec4 u_params1;
uniform vec4 u_params2;
vec4 convertPosition(vec4 p, float scale)
{
#if defined(GLSL) || defined(DX11)
return p;
#else
// half-pixel offset
return p + vec4(-u_textureSize.z, u_textureSize.w, 0.0, 0.0) * scale;
#endif
}
vec2 convertUv(vec4 p)
{
#ifndef GLSL
return p.xy * vec2(0.5, -0.5) + 0.5;
#else
return p.xy * 0.5 + 0.5;
#endif
}
// ===== Pass Through =====
void passThrough_vs()
{
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = convertUv(vec4(a_position.xyz, 1.0));
gl_Position = v_pos;
}
void passThrough_ps()
{
gl_FragColor = texture2D(s_texture, v_texcoord0.xy);
}
// ===== Image Processing =====
void imageProcess_ps()
{
vec3 color = texture2D(s_texture, v_texcoord0.xy).rgb;
vec4 tintColor = vec4(u_params2.xyz, 1.0);
float contrast = u_params1.y;
float brightness = u_params1.x;
float grayscaleLvl = u_params1.z;
color = contrast * (color - 0.5) + 0.5 + brightness;
float grayscale = (color.r + color.g + color.g) / 3.0;
gl_FragColor = mix(vec4(color.rgb, 1.0), vec4(grayscale, grayscale, grayscale, 1.0), grayscaleLvl) * tintColor;
}
// ===== Gaussian Blur =====
vec4 gauss(float samples, vec2 uv)
{
vec2 step = u_params1.xy;
float sigma = u_params1.z;
float sigmaN1 = 1.0 / sqrt(2.0 * 3.1415926 * sigma * sigma);
float sigmaN2 = 1.0 / (2.0 * sigma * sigma);
// First sample is in the center and accounts for our pixel
vec4 result = texture2D(s_texture, uv) * sigmaN1;
float weight = sigmaN1;
// Every loop iteration computes impact of 4 pixels
// Each sample computes impact of 2 neighbor pixels, starting with the next one to the right
// Note that we sample exactly in between pixels to leverage bilinear filtering
for (int i = 0; i < int(samples); ++i)
{
float ix = 2.0 * float(i) + 1.5;
float iw = 2.0 * exp(-ix * ix * sigmaN2) * sigmaN1;
result += (texture2D(s_texture, uv + step * ix) + texture2D(s_texture, uv - step * ix)) * iw;
weight += 2.0 * iw;
}
// Since the above is an approximation of the integral with step functions, normalization compensates for the error
return (result / weight);
}
void blur3_ps()
{
gl_FragColor = gauss(3.0, v_texcoord0.xy);
}
void blur5_ps()
{
gl_FragColor = gauss(5.0, v_texcoord0.xy);
}
void blur7_ps()
{
gl_FragColor = gauss(7.0, v_texcoord0.xy);
}
// ===== FXAA =====
void fxaa_ps()
{
vec2 uv = v_texcoord0.xy;
vec2 rcpFrame = u_textureSize.zw;
// Luma conversion weights
const vec3 luma = vec3(0.299, 0.587, 0.114);
// Sample 3x3 neighborhood
vec3 rgbM = texture2D(s_texture, uv).rgb;
vec3 rgbN = texture2D(s_texture, uv + vec2(0.0, -rcpFrame.y)).rgb;
vec3 rgbS = texture2D(s_texture, uv + vec2(0.0, rcpFrame.y)).rgb;
vec3 rgbE = texture2D(s_texture, uv + vec2(rcpFrame.x, 0.0)).rgb;
vec3 rgbW = texture2D(s_texture, uv + vec2(-rcpFrame.x, 0.0)).rgb;
vec3 rgbNW = texture2D(s_texture, uv + vec2(-rcpFrame.x, -rcpFrame.y)).rgb;
vec3 rgbNE = texture2D(s_texture, uv + vec2(rcpFrame.x, -rcpFrame.y)).rgb;
vec3 rgbSW = texture2D(s_texture, uv + vec2(-rcpFrame.x, rcpFrame.y)).rgb;
vec3 rgbSE = texture2D(s_texture, uv + vec2(rcpFrame.x, rcpFrame.y)).rgb;
float lumaM = dot(rgbM, luma);
float lumaN = dot(rgbN, luma);
float lumaS = dot(rgbS, luma);
float lumaE = dot(rgbE, luma);
float lumaW = dot(rgbW, luma);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
// Find local contrast including corners
float lumaMin = min(lumaM, min(min(min(lumaN, lumaS), min(lumaE, lumaW)),
min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))));
float lumaMax = max(lumaM, max(max(max(lumaN, lumaS), max(lumaE, lumaW)),
max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))));
float range = lumaMax - lumaMin;
// Very low threshold - catch almost all edges
if (range < max(0.0156, lumaMax * 0.0625))
{
gl_FragColor = vec4(rgbM, 1.0);
return;
}
// Determine edge orientation
float edgeVert = abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
abs((0.50 * lumaW) + (-1.0 * lumaM) + (0.50 * lumaE)) +
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
float edgeHorz = abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
abs((0.50 * lumaN) + (-1.0 * lumaM) + (0.50 * lumaS)) +
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
bool isHorizontal = (edgeHorz >= edgeVert);
// Select samples along edge
float luma1 = isHorizontal ? lumaS : lumaE;
float luma2 = isHorizontal ? lumaN : lumaW;
float gradient1 = luma1 - lumaM;
float gradient2 = luma2 - lumaM;
// Pick steepest gradient
bool is1Steepest = abs(gradient1) >= abs(gradient2);
float gradientScaled = 0.25 * max(abs(gradient1), abs(gradient2));
float lengthSign = is1Steepest ? -1.0 : 1.0;
if (!isHorizontal)
lengthSign *= -1.0;
// Setup for edge search
vec2 posB = uv;
vec2 offNP;
offNP.x = (!isHorizontal) ? rcpFrame.x : 0.0;
offNP.y = (isHorizontal) ? rcpFrame.y : 0.0;
if (!isHorizontal)
posB.x += lengthSign * 0.5 * rcpFrame.x;
else
posB.y += lengthSign * 0.5 * rcpFrame.y;
// Extended edge search
vec2 posN = posB - offNP;
vec2 posP = posB + offNP;
float lumaEndN = dot(texture2D(s_texture, posN).rgb, luma) - lumaM * 0.5;
float lumaEndP = dot(texture2D(s_texture, posP).rgb, luma) - lumaM * 0.5;
bool doneN = abs(lumaEndN) >= gradientScaled;
bool doneP = abs(lumaEndP) >= gradientScaled;
float stepSizes[12];
stepSizes[0] = 1.0; stepSizes[1] = 1.0; stepSizes[2] = 1.5; stepSizes[3] = 1.5;
stepSizes[4] = 2.0; stepSizes[5] = 2.0; stepSizes[6] = 4.0; stepSizes[7] = 4.0;
stepSizes[8] = 8.0; stepSizes[9] = 8.0; stepSizes[10] = 16.0; stepSizes[11] = 16.0;
for (int i = 0; i < 12; ++i)
{
if (doneN && doneP) break;
if (!doneN)
{
posN -= offNP * stepSizes[i];
lumaEndN = dot(texture2D(s_texture, posN).rgb, luma) - lumaM * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
}
if (!doneP)
{
posP += offNP * stepSizes[i];
lumaEndP = dot(texture2D(s_texture, posP).rgb, luma) - lumaM * 0.5;
doneP = abs(lumaEndP) >= gradientScaled;
}
}
// Calculate span and offset
float dstN = isHorizontal ? (uv.x - posN.x) : (uv.y - posN.y);
float dstP = isHorizontal ? (posP.x - uv.x) : (posP.y - uv.y);
bool directionN = dstN < dstP;
float dst = min(dstN, dstP);
float spanLength = (dstP + dstN);
float spanLengthRcp = 1.0 / spanLength;
float pixelOffset = dst * (-spanLengthRcp) + 0.5;
// Check if we're at a good span
bool goodSpanN = (lumaEndN < 0.0) != (lumaM < lumaMin);
bool goodSpanP = (lumaEndP < 0.0) != (lumaM < lumaMin);
bool goodSpan = directionN ? goodSpanN : goodSpanP;
if (!goodSpan)
pixelOffset = 0.0;
// sub-pixel antialiasing
float lumaAverage = (1.0 / 12.0) * (2.0 * (lumaN + lumaS + lumaE + lumaW) +
lumaNW + lumaNE + lumaSW + lumaSE);
float subPixelOffset1 = saturate0(abs(lumaAverage - lumaM) / range);
subPixelOffset1 = (-2.0 * subPixelOffset1 + 3.0) * subPixelOffset1 * subPixelOffset1;
subPixelOffset1 = subPixelOffset1 * subPixelOffset1 * 0.85;
float pixelOffsetFinal = max(pixelOffset, subPixelOffset1);
// Apply offset
vec2 finalUv = uv;
if (!isHorizontal)
finalUv.x += pixelOffsetFinal * lengthSign * rcpFrame.x;
else
finalUv.y += pixelOffsetFinal * lengthSign * rcpFrame.y;
// Additional edge blending for remaining jaggies
vec3 rgbFinal = texture2D(s_texture, finalUv).rgb;
// If we're on a strong edge, do additional smart blending
if (range > 0.1)
{
float edgeBlend = saturate0(range * 2.0 - 0.2);
vec3 rgbBlur = (rgbN + rgbS + rgbE + rgbW) * 0.25;
rgbFinal = mix(rgbFinal, rgbBlur, edgeBlend * 0.15);
}
gl_FragColor = vec4(rgbFinal, 1.0);
}
// ===== Glow Apply =====
void glowApply_ps()
{
vec4 color = texture2D(s_texture, v_texcoord0.xy);
gl_FragColor = vec4(color.rgb * u_params1.x, color.a);
}
// ===== Downsample 4x4 =====
void downsample4x4_vs()
{
vec2 uv = convertUv(vec4(a_position.xyz, 1.0));
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = uv;
vec2 uvOffset = u_textureSize.zw * 0.25;
v_texcoord0.zw = uv + uvOffset * vec2(-1.0, -1.0);
v_texcoord1.xy = uv + uvOffset * vec2(+1.0, -1.0);
v_texcoord1.zw = uv + uvOffset * vec2(-1.0, +1.0);
v_texcoord2.xy = uv + uvOffset * vec2(+1.0, +1.0);
gl_Position = v_pos;
}
void downSample4x4Glow_ps()
{
vec4 avgColor = texture2D(s_texture, v_texcoord0.zw);
avgColor += texture2D(s_texture, v_texcoord1.xy);
avgColor += texture2D(s_texture, v_texcoord1.zw);
avgColor += texture2D(s_texture, v_texcoord2.xy);
avgColor *= 0.25;
gl_FragColor = vec4(avgColor.rgb, 1.0) * (1.0 - avgColor.a);
}
// ===== Shadow Blur =====
void ShadowBlurPS()
{
#ifdef GLSLES
int N = 1;
float sigma = 0.5;
#else
int N = 3;
float sigma = 1.5;
#endif
vec2 step = u_params1.xy;
float sigmaN1 = 1.0 / sqrt(2.0 * 3.1415926 * sigma * sigma);
float sigmaN2 = 1.0 / (2.0 * sigma * sigma);
float depth = 1.0;
float color = 0.0;
float weight = 0.0;
for (int i = -N; i <= N; ++i)
{
float ix = float(i);
float iw = exp(-ix * ix * sigmaN2) * sigmaN1;
vec4 data = texture2D(s_texture, v_texcoord0.xy + step * ix);
depth = min(depth, data.x);
color += data.y * iw;
weight += iw;
}
float mask = texture2D(s_mask, v_texcoord0.xy).r;
// Since the above is an approximation of the integral with step functions, normalization compensates for the error
gl_FragColor = vec4(depth, color * mask * (1.0 / weight), 0.0, 0.0);
}

View File

@@ -0,0 +1,33 @@
$input a_position, a_color1
$output v_texcoord0
#include "common.sh"
void ShadowVS()
{
// Transform position to world space
#ifdef PIN_SKINNED
int boneIndex = int(a_color1.r);
vec4 worldRow0 = u_worldMatrixArray[boneIndex * 3 + 0];
vec4 worldRow1 = u_worldMatrixArray[boneIndex * 3 + 1];
vec4 worldRow2 = u_worldMatrixArray[boneIndex * 3 + 2];
vec3 posWorld = vec3(dot(worldRow0, vec4(a_position, 1.0)),
dot(worldRow1, vec4(a_position, 1.0)),
dot(worldRow2, vec4(a_position, 1.0)));
#else
vec3 posWorld = a_position;
#endif
gl_Position = mul(u_viewProjection, vec4(posWorld, 1.0));
v_texcoord0 = shadowPrepareSample(posWorld);
}
void ShadowPS()
{
float depth = shadowDepth(v_texcoord0);
gl_FragColor = vec4(depth, 1.0, 0.0, 0.0);
}

View File

@@ -0,0 +1,35 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0
#include "common.sh"
uniform vec4 u_color;
uniform vec4 u_color2;
SAMPLER2D(s_diffuseMap, 0);
void SkyVS()
{
vec4 wpos = mul(u_worldMatrix, vec4(a_position, 1.0));
gl_Position = mul(u_viewProjection, wpos);
#ifndef GLSLES
// snap to far plane to prevent scene-sky intersections
// small offset is needed to prevent 0/0 division in case w=0, which causes rasterization issues
// some mobile chips (hello, Vivante!) don't like it
gl_Position.z = gl_Position.w - 1.0 / 16.0;
#endif
#if BGFX_SHADER_LANGUAGE_GLSL
gl_PointSize = 2.0; // star size
#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0 * mix(u_color2, u_color, wpos.y / 1700.0);
}
void SkyPS()
{
gl_FragColor = texture2D(s_diffuseMap, v_texcoord0) * v_color0;
}

View File

@@ -0,0 +1,98 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 40.0
#define KS 0.1
#define NOISE_SCALE 7.0
#define SPREAD 0.3
#define GRASS_THRESHOLD 0.95
#define FADE_DIST 290.0
#define FADE_DIST_START 0.0
SAMPLER2D(s_normalMap, 6);
SAMPLER3D(s_specularMap, 7);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLER2D(s_shadowMap, 3);
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
void DefaultPS()
{
vec3 normal = normalize(v_normal);
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(normal, v_tangent.xyz),
normal
);
float fade = clamp(1.0 - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec2 uv = v_texcoord0;
vec3 shiftPos = v_pos;
float noiseval = texture3D(s_specularMap, shiftPos.xyz / NOISE_SCALE * 0.04).x;
float noiseval2 = texture3D(s_specularMap, shiftPos.xyz / NOISE_SCALE * 0.3).x + 0.2;
noiseval *= noiseval2;
vec3 albedo = v_color0.xyz + 0.8 * fade * (noiseval * 0.5 - 0.1);
vec3 tn = texture2D(s_normalMap, uv).xyz - 0.5;
float tNormSum = 0.9 + 0.4 * (tn.x + tn.y + tn.z);
tn = mix(tn, vec3(0.0, 0.0, 0.5), 0.9);
albedo *= ((1.0 - fade) + (fade * tNormSum));
tn = CalcBevel(v_edgedist, tn, v_view_depth.w);
vec3 nn = mul(tn, normalMatrix);
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
light.a = shadowSample(s_shadowMap, v_poslightspace, light.a);
vec3 diffuse;
vec3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
gl_FragColor = vec4(diffuse + specular, v_color0.w);
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
gl_FragColor.xyz = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 0.9
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.5
#define CFG_SPECULAR_LOD 0.14
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 5.0
#define CFG_NORMAL_DETAIL_SCALE 1.0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0.75
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#include "material.sc"
#endif

View File

@@ -0,0 +1,149 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1
$output v_pos, v_color0, v_color1, v_texcoord0, v_texcoord1, v_texcoord2, v_lightpos_fog, v_poslightspace, v_normal, v_view_depth
#include "common.sh"
#include "globals.sh"
uniform vec4 u_layerScale;
SAMPLER2D(s_albedoMap, 0);
SAMPLER2D(s_normalMap, 1);
SAMPLER2D(s_specularMap, 2);
SAMPLERCUBE(s_envMap, 3);
SAMPLER2D(s_lightMap, 4);
SAMPLER2D(s_lightMapLookup, 5);
SAMPLER2D(s_shadowMap, 6);
vec4 getUV(vec3 position, int material, int projection, float seed)
{
vec3 u = u_worldMatrixArray[1 + projection].xyz;
vec3 v = u_worldMatrixArray[19 + projection].xyz;
vec4 m = u_worldMatrixArray[37 + material];
vec2 uv = vec2(dot(position, u), dot(position, v)) * m.x + m.y * vec2(seed, floor(seed * 2.6651441));
return vec4(uv, m.zw);
}
void TerrainVS()
{
vec3 posWorld = a_position.xyz * u_worldMatrixArray[0].w + u_worldMatrixArray[0].xyz;
vec3 normalWorld = a_normal.xyz * (1.0 / 127.0) - 1.0;
v_pos = mul(u_viewProjection, vec4(posWorld, 1.0));
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (u_fogParams.z - v_pos.w) * u_fogParams.w);
v_poslightspace = shadowPrepareSample(posWorld);
v_texcoord0 = getUV(posWorld, int(a_texcoord0.x), int(a_texcoord1.x), a_normal.w / 255.0);
v_texcoord1 = getUV(posWorld, int(a_texcoord0.y), int(a_texcoord1.y), a_texcoord0.w / 255.0);
v_texcoord2 = getUV(posWorld, int(a_texcoord0.z), int(a_texcoord1.z), a_texcoord1.w / 255.0);
#if defined(GLSLES) && !defined(GL3) // iPad2 workaround
v_color0.xyz = vec3(
abs(a_position.w - 0.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 1.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 2.0) < 0.1 ? 1.0 : 0.0
);
#else
v_color0.xyz = vec3(
a_position.w == 0.0 ? 1.0 : 0.0,
a_position.w == 1.0 ? 1.0 : 0.0,
a_position.w == 2.0 ? 1.0 : 0.0
);
#endif
#ifdef PIN_HQ
v_normal = normalWorld;
v_view_depth = vec4(u_cameraPosition - posWorld, v_pos.w);
v_color1.xyz = vec3(
a_texcoord1.x > 7.5 ? 1.0 : 0.0,
a_texcoord1.y > 7.5 ? 1.0 : 0.0,
a_texcoord1.z > 7.5 ? 1.0 : 0.0
); // side vs top
#else
float ndotl = dot(normalWorld, -u_lamp0Dir);
vec3 diffuse = max(ndotl, 0.0) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
v_color1.xyz = diffuse;
#endif
gl_Position = v_pos;
}
vec4 sampleMap(sampler2D s, vec4 uv)
{
#ifdef PIN_HQ
vec2 uvs = uv.xy * u_layerScale.xy;
return texture2DGrad(s, fract(uv.xy) * u_layerScale.xy + uv.zw, dFdx(uvs), dFdy(uvs));
#else
return texture2D(s, fract(uv.xy) * u_layerScale.xy + uv.zw);
#endif
}
vec4 sampleBlend(sampler2D s, vec4 uv0, vec4 uv1, vec4 uv2, vec3 w)
{
return
sampleMap(s, uv0) * w.x +
sampleMap(s, uv1) * w.y +
sampleMap(s, uv2) * w.z;
}
vec3 sampleNormal(sampler2D s, vec4 uv0, vec4 uv1, vec4 uv2, vec3 w, vec3 normal, vec3 tsel)
{
return terrainNormal(sampleMap(s, uv0), sampleMap(s, uv1), sampleMap(s, uv2), w, normal, tsel);
}
void TerrainPS()
{
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = shadowSample(s_shadowMap, v_poslightspace, light.a);
vec3 w = v_color0.xyz;
vec4 albedo = sampleBlend(s_albedoMap, v_texcoord0, v_texcoord1, v_texcoord2, w);
#ifdef PIN_HQ
float fade = saturate0(1.0 - v_view_depth.w * u_fadeDistance_GlowFactor.y);
#ifndef PIN_GBUFFER
vec3 normal = v_normal;
#else
vec3 normal = sampleNormal(s_normalMap, v_texcoord0, v_texcoord1, v_texcoord2, w, v_normal, v_color1.xyz);
#endif
vec4 params = sampleBlend(s_specularMap, v_texcoord0, v_texcoord1, v_texcoord2, w);
float ndotl = dot(normal, -u_lamp0Dir);
// Compute diffuse term
vec3 diffuse = (u_ambientColor + (saturate0(ndotl) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color) * shadow + light.rgb + params.b * 2.0) * albedo.rgb;
// Compute specular term
float specularIntensity = step(0.0, ndotl) * params.r * fade;
float specularPower = params.g * 128.0 + 0.01;
vec3 specular = u_lamp0Color * (specularIntensity * shadow * pow(saturate0(dot(normal, normalize(-u_lamp0Dir + normalize(v_view_depth.xyz)))), specularPower));
#else
// Compute diffuse term
vec3 diffuse = (u_ambientColor + v_color1.xyz * shadow + light.rgb) * albedo.rgb;
// Compute specular term
vec3 specular = vec3(0.0, 0.0, 0.0);
#endif
// Combine
gl_FragColor.rgb = diffuse + specular;
gl_FragColor.a = 1.0;
float fogAlpha = saturate0(v_lightpos_fog.w);
gl_FragColor.rgb = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef PIN_GBUFFER
gl_FragColor = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}

View File

@@ -0,0 +1,86 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 81.0
#define KS 0.75
#define FADE_DIST 500.0
#define FADE_DIST_START 0.0
#define BEVEL_WIDTH 0.06
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLERCUBE(s_environmentMap, 4);
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
vec3 CalcBevelDir(vec4 edgeDistances)
{
vec3 dir = vec3(0.0);
vec4 bevelMultiplier = step(edgeDistances, vec4(BEVEL_WIDTH));
dir += bevelMultiplier.x * vec3(1.0, 0.0, 0.0);
dir += bevelMultiplier.y * vec3(-1.0, 0.0, 0.0);
dir += bevelMultiplier.z * vec3(0.0, 1.0, 0.0);
dir += bevelMultiplier.w * vec3(0.0, -1.0, 0.0);
return dir;
}
void DefaultPS()
{
float normalStrength = 0.4;
float fade = clamp(normalStrength - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec3 nn = normalize(v_normal);
vec4 edgeDistances = v_edgedist;
vec4 albedo = v_color0;
// lets generate this matrix in the vertex shader and pass it in later
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec2 uv = v_texcoord0;
vec3 tn = vec3(0.0, 0.0, 0.5);
tn = mix(vec3(0.0, 0.0, 0.5), tn, fade);
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffuse;
vec3 specular;
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
vec3 result = diffuse + specular;
#ifdef PIN_REFLECTION
vec3 reflection = textureCube(s_environmentMap, reflect(-vn, nn)).rgb;
result = mix(result, reflection, v_reflection);
#endif
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
result = mix(u_fogColor, result, fogAlpha);
gl_FragColor = vec4(result, albedo.a);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define PIN_PLASTIC
#include "default.sc"
#endif

View File

@@ -0,0 +1,286 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1
$output v_pos, v_color0, v_color1, v_texcoord0, v_texcoord1, v_texcoord2, v_lightpos_fog, v_normal, v_view_depth, v_poslightspace
#include "common.sh"
#include "globals.sh"
// Tunables
#define CFG_TEXTURE_TILING 0.2
#define CFG_TEXTURE_DETILING 0.1
#define CFG_SPECULAR 2.0
#define CFG_GLOSS 900.0
#define CFG_NORMAL_STRENGTH 0.25
#define CFG_REFRACTION_STRENGTH 0.05
#define CFG_FRESNEL_OFFSET 0.3
#define CFG_SSR_STEPS 8
#define CFG_SSR_START_DISTANCE 1.0
#define CFG_SSR_STEP_CLAMP 0.2
#define CFG_SSR_DEPTH_CUTOFF 10.0
uniform vec4 u_waveParams; // .x = frequency .y = phase .z = height .w = lerp
uniform vec4 u_waterColor; // deep water color
uniform vec4 u_waterParams; // .x = refraction depth scale, .y = refraction depth offset
SAMPLER2D(s_normalMap1, 0);
SAMPLER2D(s_normalMap2, 1);
SAMPLERCUBE(s_envMap, 2);
SAMPLER2D(s_lightMap, 3);
SAMPLER2D(s_lightMapLookup, 4);
SAMPLER2D(s_gbufferColor, 5);
SAMPLER2D(s_gbufferDepth, 6);
vec3 displacePosition(vec3 position, float waveFactor)
{
float x = sin((position.z - position.x) * u_waveParams.x - u_waveParams.y);
float z = sin((position.z + position.x) * u_waveParams.x + u_waveParams.y);
float p = (x + z) * u_waveParams.z;
vec3 result = position;
result.y += p * waveFactor;
return result;
}
vec4 clipToScreen(vec4 pos)
{
#ifdef GLSL
pos.xy = pos.xy * 0.5 + 0.5 * pos.w;
#else
pos.xy = pos.xy * vec2(0.5, -0.5) + 0.5 * pos.w;
#endif
return pos;
}
vec2 getUV(vec3 position, int projection, float seed)
{
vec3 u = u_worldMatrixArray[1 + projection].xyz;
vec3 v = u_worldMatrixArray[19 + projection].xyz;
vec2 uv = vec2(dot(position, u), dot(position, v)) * (0.25 * CFG_TEXTURE_TILING) + CFG_TEXTURE_DETILING * vec2(seed, floor(seed * 2.6651441));
return uv;
}
void WaterVS()
{
vec3 posWorld = a_position.xyz * u_worldMatrixArray[0].w + u_worldMatrixArray[0].xyz;
vec3 normalWorld = a_normal.xyz * (1.0 / 127.0) - 1.0;
#if defined(GLSLES) && !defined(GL3) // iPad2 workaround
vec3 weights = vec3(
abs(a_position.w - 0.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 1.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 2.0) < 0.1 ? 1.0 : 0.0
);
#else
vec3 weights = vec3(
a_position.w == 0.0 ? 1.0 : 0.0,
a_position.w == 1.0 ? 1.0 : 0.0,
a_position.w == 2.0 ? 1.0 : 0.0
);
#endif
float waveFactor = dot(weights, a_texcoord0.xyz) * (1.0 / 255.0);
#ifdef PIN_HQ
float fade = saturate0(1.0 - dot(posWorld - u_cameraPosition, -u_viewDir.xyz) * u_fadeDistance_GlowFactor.y);
posWorld = displacePosition(posWorld, waveFactor * fade);
#endif
v_pos = mul(u_viewProjection, vec4(posWorld, 1.0));
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (u_fogParams.z - v_pos.w) * u_fogParams.w);
v_texcoord0.xy = getUV(posWorld, int(a_texcoord1.x), a_normal.w / 255.0);
v_texcoord1.xy = getUV(posWorld, int(a_texcoord1.y), a_texcoord0.w / 255.0);
v_texcoord2.xy = getUV(posWorld, int(a_texcoord1.z), a_texcoord1.w / 255.0);
v_color0.xyz = weights;
v_color0.w = waveFactor;
v_normal = normalWorld;
v_view_depth = vec4(u_cameraPosition - posWorld, v_pos.w);
v_color1.xyz = vec3(
a_texcoord1.x > 7.5 ? 1.0 : 0.0,
a_texcoord1.y > 7.5 ? 1.0 : 0.0,
a_texcoord1.z > 7.5 ? 1.0 : 0.0
); // side vs top
#ifdef PIN_HQ
v_poslightspace = clipToScreen(v_pos).xyz;
#endif
gl_Position = v_pos;
}
float fresnel(float ndotv)
{
return saturate0(0.78 - 2.5 * abs(ndotv)) + CFG_FRESNEL_OFFSET;
}
vec4 sampleMix(vec2 uv)
{
#ifdef PIN_HQ
return mix(texture2D(s_normalMap1, uv), texture2D(s_normalMap2, uv), u_waveParams.w);
#else
return texture2D(s_normalMap1, uv);
#endif
}
vec3 sampleNormal(vec2 uv0, vec2 uv1, vec2 uv2, vec3 w, vec3 normal, vec3 tsel)
{
return terrainNormal(sampleMix(uv0), sampleMix(uv1), sampleMix(uv2), w, normal, tsel);
}
vec3 sampleNormalSimple(vec2 uv0, vec2 uv1, vec2 uv2, vec3 w)
{
vec4 data = sampleMix(uv0) * w.x + sampleMix(uv1) * w.y + sampleMix(uv2) * w.z;
return nmapUnpack(data).xzy;
}
float unpackDepth(vec2 uv)
{
vec4 geomTex = texture2D(s_gbufferDepth, uv);
float d = geomTex.z * (1.0 / 256.0) + geomTex.w;
return d * GBUFFER_MAX_DEPTH;
}
vec3 getRefractedColor(vec4 cpos, vec3 N, vec3 waterColor)
{
vec2 refruv0 = cpos.xy / cpos.w;
vec2 refruv1 = refruv0 + N.xz * CFG_REFRACTION_STRENGTH;
vec4 refr0 = texture2D(s_gbufferColor, refruv0);
refr0.w = unpackDepth(refruv0);
vec4 refr1 = texture2D(s_gbufferColor, refruv1);
refr1.w = unpackDepth(refruv1);
vec4 result = mix(refr0, refr1, saturate0(refr1.w - cpos.w));
// Estimate water absorption by a scaled depth difference
float depthfade = saturate0((result.w - cpos.w) * u_waterParams.x + u_waterParams.y);
// Since GBuffer depth is clamped we tone the refraction down after half of the range for a smooth fadeout
float gbuffade = saturate0(cpos.w * (2.0 / GBUFFER_MAX_DEPTH) - 1.0);
float fade = saturate0(depthfade + gbuffade);
return mix(result.rgb, waterColor, fade);
}
vec3 getReflectedColor(vec4 cpos, vec3 wpos, vec3 R)
{
vec3 result = vec3(0.0, 0.0, 0.0);
float inside = 0.0;
float distance = CFG_SSR_START_DISTANCE;
float diff = 0.0;
float diffclamp = cpos.w * CFG_SSR_STEP_CLAMP;
vec4 Pproj = cpos;
vec4 Rproj = clipToScreen(mul(u_viewProjection, vec4(R, 0.0)));
for (int i = 0; i < CFG_SSR_STEPS; ++i)
{
distance += clamp(diff, -diffclamp, diffclamp);
vec4 cposi = Pproj + Rproj * distance;
vec2 uv = cposi.xy / cposi.w;
float depth = unpackDepth(uv);
diff = depth - cposi.w;
}
vec4 cposi = Pproj + Rproj * distance;
vec2 uv = cposi.xy / cposi.w;
// Ray hit has to be inside the screen bounds
float ufade = abs(uv.x - 0.5) < 0.5 ? 1.0 : 0.0;
float vfade = abs(uv.y - 0.5) < 0.5 ? 1.0 : 0.0;
// Fade reflections out with distance
float wfade = saturate0((4.0 - 0.1) - max(cpos.w, cposi.w) * (4.0 / GBUFFER_MAX_DEPTH));
// Ray hit has to be reasonably close to where we started
float dfade = abs(diff) < CFG_SSR_DEPTH_CUTOFF ? 1.0 : 0.0;
// Avoid back-projection
float Vfade = Rproj.w > 0.0 ? 1.0 : 0.0;
float fade = ufade * vfade * wfade * dfade * Vfade;
return mix(textureCube(s_envMap, R).rgb, texture2D(s_gbufferColor, uv).rgb, fade);
}
void WaterPS()
{
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = light.a;
vec3 w = v_color0.xyz;
// Use simplified normal reconstruction for LQ mobile (assumes flat water surface)
#if defined(GLSLES) && !defined(PIN_HQ)
vec3 normal = sampleNormalSimple(v_texcoord0.xy, v_texcoord1.xy, v_texcoord2.xy, w);
#else
vec3 normal = sampleNormal(v_texcoord0.xy, v_texcoord1.xy, v_texcoord2.xy, w, v_normal, v_color1.xyz);
#endif
// Flatten the normal for Fresnel and for reflections to make them less chaotic
vec3 flatNormal = mix(v_normal, normal, CFG_NORMAL_STRENGTH);
vec3 waterColor = u_waterColor.rgb;
#ifdef PIN_HQ
float fade = saturate0(1.0 - v_view_depth.w * u_fadeDistance_GlowFactor.y);
vec3 view = normalize(v_view_depth.xyz);
float fre = fresnel(dot(flatNormal, view)) * v_color0.w;
vec3 position = u_cameraPosition - v_view_depth.xyz;
#ifdef PIN_GBUFFER
vec3 refr = getRefractedColor(vec4(v_poslightspace, v_view_depth.w), normal, waterColor);
vec3 refl = getReflectedColor(vec4(v_poslightspace, v_view_depth.w), position, reflect(-view, flatNormal));
#else
vec3 refr = waterColor;
vec3 refl = textureCube(s_envMap, reflect(-view, flatNormal)).rgb;
#endif
float specularIntensity = CFG_SPECULAR * fade;
float specularPower = CFG_GLOSS;
vec3 specular = u_lamp0Color * (specularIntensity * shadow * pow(saturate0(dot(normal, normalize(-u_lamp0Dir + view))), specularPower));
#else
vec3 view = normalize(v_view_depth.xyz);
float fre = fresnel(dot(flatNormal, view));
vec3 refr = waterColor;
vec3 refl = textureCube(s_envMap, reflect(-v_view_depth.xyz, flatNormal)).rgb;
vec3 specular = vec3(0.0, 0.0, 0.0);
#endif
// Combine
vec4 result;
result.rgb = mix(refr, refl, fre) * (u_ambientColor.rgb + u_lamp0Color.rgb * shadow + light.rgb) + specular;
result.a = 1.0;
float fogAlpha = saturate0(v_lightpos_fog.w);
result.rgb = mix(u_fogColor, result.rgb, fogAlpha);
gl_FragColor = result;
}

View File

@@ -0,0 +1,238 @@
$input a_position
$output v_pos, v_texcoord0, v_texcoord1, v_texcoord2
#include "common.sh"
#include "globals.sh"
// ao sampling
#define SSAO_NUM_PAIRS 8
#define SSAO_RADIUS 2.0
#define SSAO_MIN_PIXELS 10.0
#define SSAO_MAX_PIXELS 100.0
#define SSAO_MIP_OFFSET 2.0
// ao tuning
#define SSAO_OVERSHADOW 0.75
#define SSAO_ANGLELIMIT 0.1
#define SSAO_BOOST 1.0
// blur tuning
#define SSAO_BLUR_SAMPLES 3
#define SSAO_BLUR_STRENGTH 1.5
#define SSAO_BLUR_DEPTH_THRESHOLD 0.4
// composite tuning
#define SSAO_DEPTH_THRESHOLD_CENTER 0.02
#define SSAO_DEPTH_THRESHOLD_ESTIMATE 0.4
SAMPLER2D(s_depthBuffer, 0);
SAMPLER2D(s_randMap, 1);
SAMPLER2D(s_map, 2);
SAMPLER2D(s_geomMap, 3);
uniform vec4 u_textureSize;
uniform vec4 u_params;
vec4 convertPosition(vec4 p, float scale)
{
#if defined(GLSL) || defined(DX11)
return p;
#else
// half-pixel offset
return p + vec4(-u_textureSize.z, u_textureSize.w, 0.0, 0.0) * scale;
#endif
}
vec2 convertUv(vec4 p)
{
#ifndef GLSL
return p.xy * vec2(0.5, -0.5) + 0.5;
#else
return p.xy * 0.5 + 0.5;
#endif
}
// ===== Pass Through =====
void passThrough_vs()
{
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = convertUv(vec4(a_position.xyz, 1.0));
gl_Position = v_pos;
}
// ===== SSAO Depth Downsample =====
void SSAODepthDownPS()
{
float d0 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(-0.25, -0.25)).r;
float d1 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(+0.25, -0.25)).r;
float d2 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(-0.25, +0.25)).r;
float d3 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(+0.25, +0.25)).r;
gl_FragColor = vec4(min(min(d0, d3), min(d1, d2)));
}
// ===== SSAO Calculation =====
float getSampleLength(float i)
{
return (i + 1.0) / (float(SSAO_NUM_PAIRS) + 2.0);
}
vec2 getSampleRotation(float i)
{
float pi = 3.1415926;
return vec2(cos(i / float(SSAO_NUM_PAIRS) * 2.0 * pi), sin(i / float(SSAO_NUM_PAIRS) * 2.0 * pi));
}
void SSAOPS()
{
float baseDepth = texture2DLod(s_depthBuffer, vec4(v_texcoord0.xy, 0.0, 0.0)).r;
vec4 noiseTex = texture2D(s_randMap, fract(v_texcoord0.xy * u_textureSize.xy / 4.0)) * 2.0 - 1.0;
mat2 rotation = mat2(
noiseTex.y, noiseTex.x,
-noiseTex.x, noiseTex.y
);
const float sphereRadiusZB = SSAO_RADIUS / GBUFFER_MAX_DEPTH;
vec2 radiusTex = clamp(sphereRadiusZB / baseDepth * u_params.xy, SSAO_MIN_PIXELS * u_textureSize.zw, SSAO_MAX_PIXELS * u_textureSize.zw);
float lod = log2(getSampleLength(0.0) * length(radiusTex * u_textureSize.xy)) - SSAO_MIP_OFFSET;
float result = 1.0; // center pixel
float weight = 2.0;
for (int i = 0; i < SSAO_NUM_PAIRS; i++)
{
const float offsetLength = getSampleLength(float(i));
const vec2 offsetVector = getSampleRotation(float(i)) * offsetLength;
const float segmentDiff = sphereRadiusZB * sqrt(1.0 - offsetLength * offsetLength);
const float angleLimit = offsetLength * SSAO_ANGLELIMIT;
vec2 offset = mul(rotation, offsetVector) * radiusTex;
vec2 offsetDepth;
offsetDepth.x = texture2DLod(s_depthBuffer, vec4(v_texcoord0.xy + offset, 0.0, lod)).r;
offsetDepth.y = texture2DLod(s_depthBuffer, vec4(v_texcoord0.xy - offset, 0.0, lod)).r;
vec2 diff = offsetDepth - vec2(baseDepth, baseDepth);
// 0 is the near surface of the sphere, 1 is the far surface, 0.5 is the middle
vec2 normalizedDiff = diff * (1.0 / segmentDiff * 0.5) + 0.5;
// only add sample contribution if both samples are visible - if one is invisible we estimate the twin as 1-s so sum is 1
float sampleadd = saturate0(min(normalizedDiff.x, normalizedDiff.y) + SSAO_OVERSHADOW);
result += (saturate0(normalizedDiff.x + angleLimit) + saturate0(normalizedDiff.y + angleLimit)) * sampleadd;
weight += 2.0 * sampleadd;
}
// rescale result from 0..0.5 to 0..1 and apply a power function
float finalocc = (baseDepth > 0.99) ? 1.0 : pow(saturate0(result / weight * 2.0), SSAO_BOOST);
gl_FragColor = vec4(finalocc, baseDepth, 0.0, 1.0);
}
// ===== SSAO Blur =====
vec2 ssaoBlur(vec2 uv, vec2 offset, sampler2D map)
{
float sigmaN = 1.0 / (2.0 * SSAO_BLUR_STRENGTH * SSAO_BLUR_STRENGTH);
float baseDepth = texture2D(map, uv).g;
const float sphereRadiusZB = SSAO_BLUR_DEPTH_THRESHOLD / GBUFFER_MAX_DEPTH;
float depthTolerance = clamp((baseDepth * 80.0) * sphereRadiusZB, 0.1 * sphereRadiusZB, 10.0 * sphereRadiusZB);
float result = 0.0;
float weight = 0.0;
for (int i = -SSAO_BLUR_SAMPLES; i <= SSAO_BLUR_SAMPLES; ++i)
{
const float ix = float(i);
const float iw = exp(-ix * ix * sigmaN);
vec4 data = texture2D(map, uv + offset * ix);
float w = iw * (abs(data.g - baseDepth) < depthTolerance ? 1.0 : 0.0);
result += data.r * w;
weight += w;
}
return vec2(result / weight, baseDepth);
}
void SSAOBlurXPS()
{
vec2 o = vec2(u_textureSize.z, 0.0);
vec2 ssaoTerm = ssaoBlur(v_texcoord0.xy, o, s_map);
gl_FragColor = vec4(ssaoTerm, 0.0, 1.0);
}
void SSAOBlurYPS()
{
vec2 o = vec2(0.0, u_textureSize.w);
vec2 ssaoTerm = ssaoBlur(v_texcoord0.xy, o, s_map);
gl_FragColor = vec4(ssaoTerm, 0.0, 1.0);
}
// ===== SSAO Composite =====
void SSAOCompositVS()
{
vec2 uv = convertUv(vec4(a_position.xyz, 1.0));
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = uv;
vec2 uvOffset = u_textureSize.zw * 2.0;
v_texcoord0.zw = uv + vec2(uvOffset.x, 0.0);
v_texcoord1.xy = uv - vec2(uvOffset.x, 0.0);
v_texcoord1.zw = uv + vec2(0.0, uvOffset.y);
v_texcoord2.xy = uv - vec2(0.0, uvOffset.y);
gl_Position = v_pos;
}
void SSAOCompositPS()
{
vec4 geom = texture2D(s_geomMap, v_texcoord0.xy);
vec4 mapC = texture2D(s_map, v_texcoord0.xy);
vec4 map0 = texture2D(s_map, v_texcoord0.zw);
vec4 map1 = texture2D(s_map, v_texcoord1.xy);
vec4 map2 = texture2D(s_map, v_texcoord1.zw);
vec4 map3 = texture2D(s_map, v_texcoord2.xy);
float baseDepth = geom.r;
float ssaoC = mapC.r;
float depthC = mapC.g;
vec4 ssaoEst = vec4(map0.r, map1.r, map2.r, map3.r);
vec4 depthEst = vec4(map0.g, map1.g, map2.g, map3.g);
// can we trust the neighbors? 1 - yes, 0 - no
vec4 checkEst = vec4(
abs(depthEst.x - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0,
abs(depthEst.y - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0,
abs(depthEst.z - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0,
abs(depthEst.w - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0
);
float checkEstSum = dot(checkEst, vec4(1.0, 1.0, 1.0, 1.0));
float ssaoTermEst = dot(ssaoEst, checkEst) / checkEstSum;
// the final decision: pick the estimate sample if there are good neighbors and base depth is not trustworthy
float ssaoTerm = abs(depthC - baseDepth) * checkEstSum > SSAO_DEPTH_THRESHOLD_CENTER / GBUFFER_MAX_DEPTH ? ssaoTermEst : ssaoC;
// AO reduction for high specular and diffuse values. Computed in gbufferPack in common.h
float slope = geom.g;
gl_FragColor = vec4((1.0 - slope) * vec3(ssaoTerm, ssaoTerm, ssaoTerm) + slope, 1.0);
}

View File

@@ -0,0 +1,26 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include "common.sh"
SAMPLER2D(s_diffuseMap, 0);
uniform vec4 u_color;
void TexCompVS()
{
gl_Position = mul(u_viewProjection, vec4(a_position, 1.0));
v_texcoord0 = a_texcoord0;
}
void TexCompPS()
{
gl_FragColor = texture2DLod(s_diffuseMap, v_texcoord0, -10.0) * u_color;
}
void TexCompPMAPS()
{
vec4 tex = texture2DLod(s_diffuseMap, v_texcoord0, -10.0);
gl_FragColor = vec4(tex.rgb * tex.a * u_color.rgb, tex.a * u_color.a);
}

View File

@@ -0,0 +1,38 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0, v_texcoord1
#include "common.sh"
uniform vec4 u_uiParams; // x = luminance sampling on/off, w = z offset
SAMPLER2D(s_diffuseMap, 0);
void UIVS()
{
gl_Position = mul(u_viewProjection, vec4(a_position, 1.0));
gl_Position.z -= u_uiParams.w; // against z-fighting
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
#if defined(PIN_FOG)
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
#endif
}
void UIPS()
{
vec4 base;
if (u_uiParams.x > 0.5)
base = vec4(1.0, 1.0, 1.0, texture2D(s_diffuseMap, v_texcoord0).r);
else
base = texture2D(s_diffuseMap, v_texcoord0);
vec4 result = v_color0 * base;
#if defined(PIN_FOG)
result.rgb = mix(u_fogColor, result.rgb, saturate(v_texcoord1.x));
#endif
gl_FragColor = result;
}

View File

@@ -0,0 +1,28 @@
vec3 v_pos : TEXCOORD0;
vec3 v_worldPos : TEXCOORD1;
vec4 v_texcoord0 : TEXCOORD2;
vec4 v_texcoord1 : TEXCOORD3;
vec4 v_color0 : COLOR0;
vec3 v_normal : NORMAL;
vec3 v_tangent : TANGENT;
vec4 v_lightpos_fog : TEXCOORD4;
vec4 v_view_depth : TEXCOORD5;
vec3 v_poslightspace : TEXCOORD6;
vec4 v_edgedist : TEXCOORD7;
float v_reflection : TEXCOORD8;
vec3 v_position : TEXCOORD9;
vec4 v_start : TEXCOORD10;
vec4 v_end : TEXCOORD11;
vec4 v_centerRadius : TEXCOORD12;
vec4 v_color1 : COLOR1;
vec2 v_texcoord2 : TEXCOORD13;
vec3 a_position : POSITION;
vec3 a_normal : NORMAL;
vec4 a_color0 : COLOR0;
vec4 a_color1 : COLOR1;
vec4 a_texcoord0 : TEXCOORD0;
vec4 a_texcoord1 : TEXCOORD1;
vec3 a_tangent : TEXCOORD2;
vec4 a_texcoord2 : TEXCOORD3;
vec4 a_texcoord3 : TEXCOORD4;

View File

@@ -0,0 +1,181 @@
$input a_position, a_normal
$output v_pos, v_texcoord0, v_worldPos, v_normal, v_lightpos_fog, v_color0
#include "common.sh"
#include "globals.sh"
//
// Water shader.
// Big, fat and ugly.
//
// All (most) things considered, I have converged to this particular way of rendering water:
//
// Vertex waves
// No transparency. Solid color for deep water.
// Fresnel law, reflects environment.
// Phong speculars.
// Ripples via animated normal map. Adjustable intensity, speed and scale. Affect reflection and speculars.
uniform vec4 u_nmAnimLerp; // ratio between normal map frames
uniform vec4 u_waveParams; // .x = frequency .y = phase .z = height
uniform vec4 u_waterColor; // deep water color
SAMPLER2D(s_normalMap1, 0);
SAMPLER2D(s_normalMap2, 1);
SAMPLERCUBE(s_envMap, 2);
SAMPLER2D(s_lightMap, 3);
SAMPLER2D(s_lightMapLookup, 4);
#ifdef PIN_HQ
# define WATER_LOD 1
#else
# define WATER_LOD 2
#endif
#define LODBIAS (-1.0)
float fadeFactor(vec3 wspos)
{
return saturate0(-0.4 + 1.4 * length(u_cameraPosition - wspos.xyz) * u_fadeDistance_GlowFactor.y);
}
float wave(vec4 wspos)
{
float x = sin((wspos.z - wspos.x - u_waveParams.y) * u_waveParams.x);
float z = sin((wspos.z + wspos.x + u_waveParams.y) * u_waveParams.x);
float p = (x + z) * u_waveParams.z;
return p - p * fadeFactor(wspos.xyz);
}
// perturbs the water mesh and vertex normals
void makeWaves(inout vec4 wspos, inout vec3 wsnrm)
{
#if WATER_LOD == 0
float gridSize = 4.0;
vec4 wspos1 = wspos;
vec4 wspos2 = wspos;
wspos1.x += gridSize;
wspos2.z += gridSize;
wspos.y += wave(wspos);
wspos1.y += wave(wspos1);
wspos2.y += wave(wspos2);
wsnrm = normalize(cross(wspos2.xyz - wspos.xyz, wspos1.xyz - wspos.xyz));
#elif WATER_LOD == 1
wspos.y += wave(wspos);
#else /* do nothing */
#endif
}
void water_vs()
{
// Decode vertex data
vec3 normal = (a_normal.xyz - 127.0) / 127.0;
normal = normalize(normal);
vec4 wspos = mul(u_worldMatrix, vec4(a_position.xyz, 1.0));
vec3 wsnrm = normal;
wspos.y -= 2.0 * u_waveParams.z;
makeWaves(wspos, wsnrm);
v_worldPos = wspos;
v_normal = wsnrm;
if (normal.y < 0.01) v_normal = normal;
// box mapping
vec2 tcselect;
vec3 wspostc = vec3(wspos.x, -wspos.y, wspos.z);
tcselect.x = dot(abs(normal.yxz), wspostc.xzx);
tcselect.y = dot(abs(normal.yxz), wspostc.zyy);
v_pos = mul(u_viewProjection, wspos);
v_texcoord0.xy = tcselect * 0.05;
v_texcoord0.z = saturate0((u_fogParams.z - v_pos.w) * u_fogParams.w);
v_texcoord0.w = LODBIAS;
v_lightpos_fog.xyz = lgridPrepareSample(lgridOffset(wspos.xyz, wsnrm.xyz));
v_color0.x = fadeFactor(wspos.xyz);
v_color0.y = (1.0 - v_color0.x) * saturate0(dot(wsnrm, -u_lamp0Dir)) * 100.0;
v_color0.z = 1.0 - 0.9 * saturate1(exp(-0.005 * length(u_cameraPosition - wspos.xyz)));
gl_Position = v_pos;
}
vec3 pixelNormal(vec4 tc0)
{
vec4 nm1 = texture2DLod(s_normalMap1, tc0.xy, tc0.w);
#if WATER_LOD <= 1
vec4 nm2 = texture2DLod(s_normalMap2, tc0.xy, tc0.w);
vec4 nm3 = mix(nm1, nm2, u_nmAnimLerp.xxxx);
#else
vec4 nm3 = nm1;
#endif
return nmapUnpack(nm3);
}
// Fresnel approximation. N1 and N2 are refractive indices.
// for above water, use n1 = 1, n2 = 1.3, for underwater use n1 = 1.3, n2 = 1
float fresnel(vec3 N, vec3 V, float n1, float n2, float p, float fade)
{
#if WATER_LOD == 0
float r0 = (n1 - n2) / (n1 + n2);
r0 *= r0;
return r0 + (1.0 - r0) * pow(1.0 - abs(dot(normalize(N), V)), p);
#else
return 0.1 + saturate0(-1.9 * abs(dot(N, V)) + 0.8); // HAXX!
#endif
}
vec4 envColor(vec3 N, vec3 V, float fade)
{
vec3 dir = reflect(V, N);
return textureCube(s_envMap, dir) * 0.91;
}
vec4 deepWaterColor(vec4 light)
{
vec4 tint = 0.8 * vec4(118.0, 143.0, 153.0, 255.0) / 255.0;
return (light + textureCubeLod(s_envMap, vec3(0.0, 1.0, 0.0), 10.0)) * tint;
}
void water_ps()
{
vec3 N2 = v_normal;
vec3 N1 = pixelNormal(v_texcoord0).xzy;
vec3 N3 = 0.5 * (N2 + N1);
N3 = mix(N3, N2, v_color0.z);
vec3 L = -u_lamp0Dir.xyz;
vec3 E = normalize(u_cameraPosition - v_worldPos.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float fre = fresnel(N3, E, 1.0, 1.3, 5.0, v_color0.x);
vec3 diffuse = deepWaterColor(light).rgb;
vec3 env = envColor(N3, -E, v_color0.x).rgb;
vec3 R = reflect(-L, N1);
#if WATER_LOD <= 1
float specular = pow(saturate0(dot(R, E)), 1600.0) * L.y * 100.0; // baseline
# ifndef GLSLES
specular = 0.65 * saturate1(specular * saturate0(light.a - 0.4));
# endif
#else
float specular = 0.0;
#endif
vec3 result = mix(diffuse, env, fre) + vec3(specular, specular, specular);
result = mix(u_fogColor.rgb, result, v_texcoord0.z);
gl_FragColor = vec4(result, 1.0);
}

View File

@@ -0,0 +1,110 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 4.0
#define KS 0.1
#define WoodContrast vec3(0.1, 0.1, 0.1)
#define Ks1 0.32
#define Ks2 0.16
#define RingScale 4.0
#define AmpScale 1.0
#define LightRingEnd 0.4
#define DarkRingStart 0.8
#define DarkRingEnd 0.83
#define NormMapScale 0.6
#define NoiseScale 64.0
#define MixedColorRatio 0.315
#define AAFreqMultiplier 12.0
SAMPLER2D(s_normalMap, 6);
SAMPLER3D(s_specularMap, 7);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLER2D(s_shadowMap, 3);
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
void DefaultPS()
{
vec3 nn = normalize(v_normal);
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec4 WoodPos = vec4(v_pos.xyz, mix(0.0, 0.92, abs(dot(vec3(1.0, 0.0, 0.0), nn))));
vec2 NormalUV = v_texcoord0.xy * NormMapScale * 3.0;
float singularityAttenuation = WoodPos.w;
float noiseval = texture3D(s_specularMap, WoodPos.xyz / NoiseScale).x;
vec3 tn = texture2D(s_normalMap, NormalUV).xyz - 0.5;
tn = mix(tn, vec3(0.0, 0.0, 0.5), singularityAttenuation);
vec4 edgeDistances = v_edgedist;
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
float signalfreq = length(vec4(dFdx(WoodPos.y), dFdx(WoodPos.z), dFdy(WoodPos.y), dFdy(WoodPos.z)));
float aa_attn = clamp(signalfreq * AAFreqMultiplier - 1.0, 0.0, 1.0);
vec3 Pwood = WoodPos.xyz + (AmpScale * noiseval);
float r = RingScale * length(Pwood.yz);
r = r + texture3D(s_specularMap, vec3(r) / 32.0).x;
r = r - floor(r);
r = smoothstep(LightRingEnd, DarkRingStart, r) - smoothstep(DarkRingEnd, 1.0, r);
r = mix(r, MixedColorRatio, aa_attn);
vec3 albedo = v_color0.xyz + WoodContrast * (MixedColorRatio - r);
float Ks = mix(Ks1, Ks2, r);
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
light.a = shadowSample(s_shadowMap, v_poslightspace, light.a);
vec3 diffuse;
vec3 specular;
Shade(albedo, nn, vn, Ks, SPEC_EXPON, light, diffuse, specular);
gl_FragColor = vec4(diffuse + specular, v_color0.w);
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
gl_FragColor.xyz = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 2.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.3
#define CFG_SPECULAR_LOD 0.25
#define CFG_GLOSS_LOD 32.0
#define CFG_NORMAL_DETAIL_TILING 7.0
#define CFG_NORMAL_DETAIL_SCALE 0.6
#define CFG_FAR_TILING 0.0
#define CFG_FAR_DIFFUSE_CUTOFF 0.0
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#include "material.sc"
#endif

View File

@@ -0,0 +1,15 @@
#define CFG_WANG_TILES
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 96.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 48.0
#include "material.sc"