Overlays.
This commit is contained in:
parent
08ebff641e
commit
e90c151cd4
|
@ -1431,9 +1431,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
self.ExportParticleSystemRef(node.particle_systems[i], i, o)
|
||||
|
||||
o['dimensions'] = [node.dimensions[0], node.dimensions[1], node.dimensions[2]]
|
||||
|
||||
if node.model_overlay: # X-Ray enabled
|
||||
o['type'] = 'overlay_node'
|
||||
|
||||
#shapeKeys = ArmoryExporter.GetShapeKeys(object)
|
||||
#if (shapeKeys):
|
||||
|
@ -2301,6 +2298,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
ArmoryExporter.geometry_context = bpy.data.cameras[0].geometry_context
|
||||
ArmoryExporter.shadows_context = bpy.data.cameras[0].shadows_context
|
||||
ArmoryExporter.translucent_context = bpy.data.cameras[0].translucent_context
|
||||
ArmoryExporter.overlay_context = bpy.data.cameras[0].overlay_context
|
||||
|
||||
def cb_preprocess_node(self, node): # Returns false if node should not be exported
|
||||
#return True
|
||||
|
@ -2496,6 +2494,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
self.finalize_shader(o2, defs2, [decal_context])
|
||||
self.output['material_resources'].append(o2)
|
||||
|
||||
# X-Ray enabled
|
||||
if material.overlay:
|
||||
# Change to overlay context
|
||||
c['id'] = ArmoryExporter.overlay_context
|
||||
|
||||
# If material has transparency change to translucent context
|
||||
if '_Translucent' in defs:
|
||||
defs.remove('_Translucent')
|
||||
|
|
|
@ -330,8 +330,9 @@ class BeginNode(Node, CGPipelineTreeNode):
|
|||
self.inputs.new('NodeSocketString', "Geometry")
|
||||
self.inputs.new('NodeSocketString', "Shadows")
|
||||
self.inputs.new('NodeSocketString', "Translucent")
|
||||
self.inputs.new('NodeSocketString', "Overlay")
|
||||
self.inputs.new('NodeSocketBool', "HDR Space")
|
||||
self.inputs[4].default_value = True
|
||||
self.inputs[5].default_value = True
|
||||
self.outputs.new('NodeSocketShader', "Stage")
|
||||
|
||||
def copy(self, node):
|
||||
|
@ -608,7 +609,7 @@ class DrawWorldNode(Node, CGPipelineTreeNode):
|
|||
|
||||
def init(self, context):
|
||||
self.inputs.new('NodeSocketShader', "Stage")
|
||||
self.inputs.new('NodeSocketShader', "Depth")
|
||||
# self.inputs.new('NodeSocketShader', "Depth")
|
||||
|
||||
self.outputs.new('NodeSocketShader', "Stage")
|
||||
|
||||
|
@ -1323,7 +1324,8 @@ def getRootNode(node_group):
|
|||
bpy.data.cameras[0].geometry_context = n.inputs[1].default_value
|
||||
bpy.data.cameras[0].shadows_context = n.inputs[2].default_value
|
||||
bpy.data.cameras[0].translucent_context = n.inputs[3].default_value
|
||||
if n.inputs[4].default_value == False: # No HDR space lighting, append def
|
||||
bpy.data.cameras[0].overlay_context = n.inputs[4].default_value
|
||||
if n.inputs[5].default_value == False: # No HDR space lighting, append def
|
||||
bpy.data.worlds[0].world_defs += '_LDR'
|
||||
return findNodeByLinkFrom(node_group, n, n.outputs[0])
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ def initProperties():
|
|||
bpy.types.Object.custom_material = bpy.props.BoolProperty(name="Custom Material", default=False)
|
||||
bpy.types.Object.custom_material_name = bpy.props.StringProperty(name="Name", default="")
|
||||
bpy.types.Object.game_export = bpy.props.BoolProperty(name="Game Export", default=True)
|
||||
bpy.types.Object.model_overlay = bpy.props.BoolProperty(name="X-Ray", default=False)
|
||||
# For geometry
|
||||
bpy.types.Mesh.static_usage = bpy.props.BoolProperty(name="Static Usage", default=True)
|
||||
# For camera
|
||||
|
@ -61,6 +60,7 @@ def initProperties():
|
|||
bpy.types.Camera.geometry_context = bpy.props.StringProperty(name="Geometry", default="deferred")
|
||||
bpy.types.Camera.shadows_context = bpy.props.StringProperty(name="Shadows", default="shadowmap")
|
||||
bpy.types.Camera.translucent_context = bpy.props.StringProperty(name="Translucent", default="translucent")
|
||||
bpy.types.Camera.overlay_context = bpy.props.StringProperty(name="Overlay", default="overlay")
|
||||
bpy.types.Camera.is_probe = bpy.props.BoolProperty(name="Probe", default=False)
|
||||
bpy.types.Camera.probe_generate_radiance = bpy.props.BoolProperty(name="Generate Radiance", default=False)
|
||||
bpy.types.Camera.probe_texture = bpy.props.StringProperty(name="Texture", default="")
|
||||
|
@ -122,6 +122,7 @@ def initProperties():
|
|||
bpy.types.Material.stencil_mask = bpy.props.IntProperty(name="Stencil Mask", default=0)
|
||||
bpy.types.Material.export_tangents = bpy.props.BoolProperty(name="Export Tangents", default=False)
|
||||
bpy.types.Material.skip_context = bpy.props.StringProperty(name="Skip Context", default='')
|
||||
bpy.types.Material.overlay = bpy.props.BoolProperty(name="X-Ray", default=False)
|
||||
# For scene
|
||||
bpy.types.Scene.game_export = bpy.props.BoolProperty(name="Game Export", default=True)
|
||||
# For light
|
||||
|
@ -140,7 +141,6 @@ class ObjectPropsPanel(bpy.types.Panel):
|
|||
obj = bpy.context.object
|
||||
layout.prop(obj, 'game_export')
|
||||
if obj.type == 'MESH':
|
||||
layout.prop(obj, 'model_overlay')
|
||||
layout.prop(obj, 'instanced_children')
|
||||
layout.prop(obj, 'custom_material')
|
||||
if obj.custom_material:
|
||||
|
@ -234,6 +234,7 @@ class MatsPropsPanel(bpy.types.Panel):
|
|||
layout.prop(mat, 'custom_shader_name')
|
||||
layout.prop(mat, 'stencil_mask')
|
||||
layout.prop(mat, 'skip_context')
|
||||
layout.prop(mat, 'overlay')
|
||||
|
||||
# Menu in world region
|
||||
class WorldPropsPanel(bpy.types.Panel):
|
||||
|
|
|
@ -30,7 +30,7 @@ project.addAssets('Assets/**');
|
|||
f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/iron')[2:] + '");\n')
|
||||
f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/zui')[2:] + '");\n')
|
||||
|
||||
if bpy.data.worlds[0].CGPhysics != 0:
|
||||
if bpy.data.worlds[0].CGPhysics != 'Disabled':
|
||||
f.write("\nproject.addDefine('WITH_PHYSICS')\n")
|
||||
f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/haxebullet')[2:] + '");\n')
|
||||
|
||||
|
|
|
@ -72,6 +72,101 @@
|
|||
"vertex_shader": "deferred.vert.glsl",
|
||||
"fragment_shader": "deferred.frag.glsl"
|
||||
},
|
||||
{
|
||||
"id": "overlay",
|
||||
"params": [
|
||||
{
|
||||
"id": "depth_write",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"id": "compare_mode",
|
||||
"value": "less"
|
||||
},
|
||||
{
|
||||
"id": "cull_mode",
|
||||
"value": "counter_clockwise"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"id": "M",
|
||||
"link": "_modelMatrix"
|
||||
},
|
||||
{
|
||||
"id": "NM",
|
||||
"link": "_normalMatrix"
|
||||
},
|
||||
{
|
||||
"id": "V",
|
||||
"link": "_viewMatrix"
|
||||
},
|
||||
{
|
||||
"id": "P",
|
||||
"link": "_projectionMatrix"
|
||||
},
|
||||
{
|
||||
"id": "LMVP",
|
||||
"link": "_lightModelViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"id": "lightDir",
|
||||
"link": "_lightDirection"
|
||||
},
|
||||
{
|
||||
"id": "lightColor",
|
||||
"link": "_lightColor"
|
||||
},
|
||||
{
|
||||
"id": "lightStrength",
|
||||
"link": "_lightStrength"
|
||||
},
|
||||
{
|
||||
"id": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"id": "skinBones",
|
||||
"link": "_skinBones",
|
||||
"ifdef": ["_Skinning"]
|
||||
},
|
||||
{
|
||||
"id": "shirr",
|
||||
"link": "_envmapIrradiance"
|
||||
},
|
||||
{
|
||||
"id": "senvmapRadiance",
|
||||
"link": "_envmapRadiance",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"id": "envmapNumMipmaps",
|
||||
"link": "_envmapNumMipmaps",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"id": "senvmapBrdf",
|
||||
"link": "_envmapBrdf",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"id": "envmapStrength",
|
||||
"link": "_envmapStrength"
|
||||
},
|
||||
{
|
||||
"id": "sltcMat",
|
||||
"link": "_ltcMat",
|
||||
"ifdef": ["_PolyLight"]
|
||||
},
|
||||
{
|
||||
"id": "sltcMag",
|
||||
"link": "_ltcMag",
|
||||
"ifdef": ["_PolyLight"]
|
||||
}
|
||||
],
|
||||
"vertex_shader": "overlay.vert.glsl",
|
||||
"fragment_shader": "overlay.frag.glsl"
|
||||
},
|
||||
{
|
||||
"id": "shadowmap",
|
||||
"params": [
|
||||
|
|
699
raw/deferred/overlay.frag.glsl
Normal file
699
raw/deferred/overlay.frag.glsl
Normal file
|
@ -0,0 +1,699 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
|
||||
// #ifdef _NMTex
|
||||
// #define _Tex
|
||||
// #endif
|
||||
|
||||
#ifdef _AMTex
|
||||
uniform sampler2D salbedo;
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
uniform sampler2D shadowMap;
|
||||
#endif
|
||||
uniform float shirr[27];
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
// uniform sampler2D sltcMat;
|
||||
// uniform sampler2D sltcMag;
|
||||
#ifdef _NMTex
|
||||
uniform sampler2D snormal;
|
||||
#endif
|
||||
#ifdef _OMTex
|
||||
uniform sampler2D som;
|
||||
#else
|
||||
uniform float occlusion;
|
||||
#endif
|
||||
#ifdef _RMTex
|
||||
uniform sampler2D srm;
|
||||
#else
|
||||
uniform float roughness;
|
||||
#endif
|
||||
#ifdef _MMTex
|
||||
uniform sampler2D smm;
|
||||
#else
|
||||
uniform float metalness;
|
||||
#endif
|
||||
#ifdef _HMTex
|
||||
uniform sampler2D shm;
|
||||
uniform float heightStrength;
|
||||
#endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
uniform bool receiveShadow;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 lightColor;
|
||||
uniform float lightStrength;
|
||||
|
||||
// LTC
|
||||
/*uniform vec3 light;
|
||||
// const float roughness = 0.25;
|
||||
const vec3 dcolor = vec3(1.0, 1.0, 1.0);
|
||||
const vec3 scolor = vec3(1.0, 1.0, 1.0);
|
||||
const float intensity = 4.0; // 0-10
|
||||
const float width = 4.0;
|
||||
const float height = 4.0;
|
||||
const vec2 resolution = vec2(800.0, 600.0);
|
||||
const int sampleCount = 0;
|
||||
const int NUM_SAMPLES = 8;
|
||||
const float LUT_SIZE = 64.0;
|
||||
const float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;
|
||||
const float LUT_BIAS = 0.5/LUT_SIZE;
|
||||
// vec2 mys[NUM_SAMPLES];
|
||||
vec3 L0 = vec3(0.0);
|
||||
vec3 L1 = vec3(0.0);
|
||||
vec3 L2 = vec3(0.0);
|
||||
vec3 L3 = vec3(0.0);
|
||||
vec3 L4 = vec3(0.0);*/
|
||||
|
||||
|
||||
in vec3 position;
|
||||
#ifdef _Tex
|
||||
in vec2 texCoord;
|
||||
#endif
|
||||
in vec4 lPos;
|
||||
in vec4 matColor;
|
||||
in vec3 eyeDir;
|
||||
#ifdef _NMTex
|
||||
in mat3 TBN;
|
||||
#else
|
||||
in vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifndef _NoShadows
|
||||
// float linstep(float low, float high, float v) {
|
||||
// return clamp((v - low) / (high - low), 0.0, 1.0);
|
||||
// }
|
||||
// float VSM(vec2 uv, float compare) {
|
||||
// vec2 moments = texture(shadowMap, uv).xy;
|
||||
// float p = smoothstep(compare - 0.02, compare, moments.x);
|
||||
// float variance = max(moments.y - moments.x * moments.x, -0.001);
|
||||
// float d = compare - moments.x;
|
||||
// float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
|
||||
// return clamp(max(p, p_max), 0.0, 1.0);
|
||||
// }
|
||||
float texture2DCompare(vec2 uv, float compare){
|
||||
float depth = texture(shadowMap, uv).r * 2.0 - 1.0;
|
||||
return step(compare, depth);
|
||||
}
|
||||
float texture2DShadowLerp(vec2 size, vec2 uv, float compare){
|
||||
vec2 texelSize = vec2(1.0) / size;
|
||||
vec2 f = fract(uv * size + 0.5);
|
||||
vec2 centroidUV = floor(uv * size + 0.5) / size;
|
||||
|
||||
float lb = texture2DCompare(centroidUV + texelSize * vec2(0.0, 0.0), compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize * vec2(1.0, 1.0), compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
float PCF(vec2 uv, float compare) {
|
||||
float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
|
||||
vec2 off = vec2(-1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
float shadowTest(vec4 lPos) {
|
||||
vec4 lPosH = lPos / lPos.w;
|
||||
lPosH.x = (lPosH.x + 1.0) / 2.0;
|
||||
lPosH.y = (lPosH.y + 1.0) / 2.0;
|
||||
|
||||
return PCF(lPosH.xy, lPosH.z - shadowsBias);
|
||||
// return VSM(lPosH.xy, lPosH.z);
|
||||
// Basic
|
||||
// float distanceFromLight = texture(shadowMap, lPosH.xy).r * 2.0 - 1.0;
|
||||
// return float(distanceFromLight > lPosH.z - bias);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.x * nor.x - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.y * nor.y +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.x * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.x * nor.y +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.y +
|
||||
2.0 * c2 * cl11 * nor.x +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.y
|
||||
) * scale;
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
|
||||
vec2 LightingFuncGGX_FV(float dotLH, float roughness) {
|
||||
float alpha = roughness*roughness;
|
||||
|
||||
// F
|
||||
float F_a, F_b;
|
||||
float dotLH5 = pow(1.0 - dotLH, 5.0);
|
||||
F_a = 1.0;
|
||||
F_b = dotLH5;
|
||||
|
||||
// V
|
||||
float vis;
|
||||
float k = alpha / 2.0;
|
||||
float k2 = k * k;
|
||||
float invK2 = 1.0 - k2;
|
||||
//vis = rcp(dotLH * dotLH * invK2 + k2);
|
||||
vis = inversesqrt(dotLH * dotLH * invK2 + k2);
|
||||
|
||||
return vec2(F_a * vis, F_b * vis);
|
||||
}
|
||||
|
||||
float LightingFuncGGX_D(float dotNH, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSqr = alpha * alpha;
|
||||
float pi = 3.14159;
|
||||
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
float D = alphaSqr / (pi * denom * denom);
|
||||
return D;
|
||||
}
|
||||
|
||||
// John Hable - Optimizing GGX Shaders
|
||||
// http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
|
||||
float LightingFuncGGX_OPT3(float dotNL, float dotLH, float dotNH, float roughness, float F0) {
|
||||
// vec3 H = normalize(V + L);
|
||||
// float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
// float dotLH = clamp(dot(L, H), 0.0, 1.0);
|
||||
// float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
float D = LightingFuncGGX_D(dotNH, roughness);
|
||||
vec2 FV_helper = LightingFuncGGX_FV(dotLH, roughness);
|
||||
float FV = F0 * FV_helper.x + (1.0 - F0) * FV_helper.y;
|
||||
float specular = dotNL * D * FV;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh, float lh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
|
||||
vec3 lambert(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
|
||||
vec3 burley(vec3 albedo, float roughness, float NoV, float NoL, float VoH) {
|
||||
float FD90 = 0.5 + 2 * VoH * VoH * roughness;
|
||||
float FdV = 1 + (FD90 - 1) * pow( 1 - NoV, 5 );
|
||||
float FdL = 1 + (FD90 - 1) * pow( 1 - NoL, 5 );
|
||||
return albedo * ( (1.0 / 3.1415926535) * FdV * FdL );
|
||||
}
|
||||
|
||||
vec3 orenNayar(vec3 albedo, float roughness, float NoV, float NoL, float VoH ) {
|
||||
float pi = 3.1415926535;
|
||||
float a = roughness * roughness;
|
||||
float s = a;// / ( 1.29 + 0.5 * a );
|
||||
float s2 = s * s;
|
||||
float VoL = 2.0 * VoH * VoH - 1.0; // double angle identity
|
||||
float Cosri = VoL - NoV * NoL;
|
||||
float C1 = 1.0 - 0.5 * s2 / (s2 + 0.33);
|
||||
float test = 1.0;
|
||||
if (Cosri >= 0.0) test = (1.0 / ( max( NoL, NoV ) ));
|
||||
float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * test;
|
||||
return albedo / pi * ( C1 + C2 ) * ( 1.0 + roughness * 0.5 );
|
||||
}
|
||||
|
||||
vec3 diffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh, float lv) {
|
||||
return lambert(albedo, nl);
|
||||
//return burley(albedo, roughness, nv, nl, vh);
|
||||
//return orenNayar(albedo, roughness, lv, nl, nv);
|
||||
}
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * envmapNumMipmaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Linearly Transformed Cosines
|
||||
/*
|
||||
vec3 mul(mat3 m, vec3 v) {
|
||||
return m * v;
|
||||
}
|
||||
mat3 mul(mat3 m1, mat3 m2) {
|
||||
return m1 * m2;
|
||||
}
|
||||
mat3 transpose2(mat3 v) {
|
||||
mat3 tmp;
|
||||
tmp[0] = vec3(v[0].x, v[1].x, v[2].x);
|
||||
tmp[1] = vec3(v[0].y, v[1].y, v[2].y);
|
||||
tmp[2] = vec3(v[0].z, v[1].z, v[2].z);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
float IntegrateEdge(vec3 v1, vec3 v2) {
|
||||
float cosTheta = dot(v1, v2);
|
||||
cosTheta = clamp(cosTheta, -0.9999, 0.9999);
|
||||
float theta = acos(cosTheta);
|
||||
float res = cross(v1, v2).z * theta / sin(theta);
|
||||
return res;
|
||||
}
|
||||
int ClipQuadToHorizon() { //inout vec3 L[5], out int n) {
|
||||
// detect clipping config
|
||||
int config = 0;
|
||||
if (L0.z > 0.0) config += 1;
|
||||
if (L1.z > 0.0) config += 2;
|
||||
if (L2.z > 0.0) config += 4;
|
||||
if (L3.z > 0.0) config += 8;
|
||||
|
||||
// clip
|
||||
int n = 0;
|
||||
if (config == 0) {
|
||||
// clip all
|
||||
}
|
||||
else if (config == 1) { // V1 clip V2 V3 V4
|
||||
n = 3;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 2) { // V2 clip V1 V3 V4
|
||||
n = 3;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 3) { // V1 V2 clip V3 V4
|
||||
n = 4;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
L3 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 4) { // V3 clip V1 V2 V4
|
||||
n = 3;
|
||||
L0 = -L3.z * L2 + L2.z * L3;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
}
|
||||
else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 6) { // V2 V3 clip V1 V4
|
||||
n = 4;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 7) { // V1 V2 V3 clip V4
|
||||
n = 5;
|
||||
L4 = -L3.z * L0 + L0.z * L3;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 8) { // V4 clip V1 V2 V3
|
||||
n = 3;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
L1 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = L3;
|
||||
}
|
||||
else if (config == 9) { // V1 V4 clip V2 V3
|
||||
n = 4;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L2.z * L3 + L3.z * L2;
|
||||
}
|
||||
else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 11) { // V1 V2 V4 clip V3
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 12) { // V3 V4 clip V1 V2
|
||||
n = 4;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
}
|
||||
else if (config == 13) { // V1 V3 V4 clip V2
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = L2;
|
||||
L2 = -L1.z * L2 + L2.z * L1;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
}
|
||||
else if (config == 14) { // V2 V3 V4 clip V1
|
||||
n = 5;
|
||||
L4 = -L0.z * L3 + L3.z * L0;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
}
|
||||
else if (config == 15) { // V1 V2 V3 V4
|
||||
n = 4;
|
||||
}
|
||||
|
||||
if (n == 3)
|
||||
L3 = L0;
|
||||
if (n == 4)
|
||||
L4 = L0;
|
||||
return n;
|
||||
}
|
||||
vec3 LTC_Evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3, bool twoSided) {
|
||||
// construct orthonormal basis around N
|
||||
vec3 T1, T2;
|
||||
T1 = normalize(V - N*dot(V, N));
|
||||
T2 = cross(N, T1);
|
||||
|
||||
// rotate area light in (T1, T2, R) basis
|
||||
Minv = mul(Minv, transpose2(mat3(T1, T2, N)));
|
||||
|
||||
// polygon (allocate 5 vertices for clipping)
|
||||
// vec3 L[5];
|
||||
L0 = mul(Minv, points0 - P);
|
||||
L1 = mul(Minv, points1 - P);
|
||||
L2 = mul(Minv, points2 - P);
|
||||
L3 = mul(Minv, points3 - P);
|
||||
|
||||
int n = ClipQuadToHorizon(); //L, n);
|
||||
|
||||
if (n == 0) {
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
// project onto sphere
|
||||
L0 = normalize(L0);
|
||||
L1 = normalize(L1);
|
||||
L2 = normalize(L2);
|
||||
L3 = normalize(L3);
|
||||
L4 = normalize(L4);
|
||||
|
||||
// integrate
|
||||
float sum = 0.0;
|
||||
|
||||
sum += IntegrateEdge(L0, L1);
|
||||
sum += IntegrateEdge(L1, L2);
|
||||
sum += IntegrateEdge(L2, L3);
|
||||
|
||||
if (n >= 4) {
|
||||
sum += IntegrateEdge(L3, L4);
|
||||
}
|
||||
if (n == 5) {
|
||||
sum += IntegrateEdge(L4, L0);
|
||||
}
|
||||
|
||||
sum = twoSided ? abs(sum) : max(0.0, -sum);
|
||||
|
||||
vec3 Lo_i = vec3(sum, sum, sum);
|
||||
|
||||
return Lo_i;
|
||||
}*/
|
||||
|
||||
#ifdef _Toon
|
||||
float stepmix(float edge0, float edge1, float E, float x) {
|
||||
float T = clamp(0.5 * (x - edge0 + E) / E, 0.0, 1.0);
|
||||
return mix(edge0, edge1, T);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _NMTex
|
||||
vec3 n = (texture(snormal, texCoord).rgb * 2.0 - 1.0);
|
||||
n = normalize(TBN * normalize(n));
|
||||
|
||||
// vec3 nn = normalize(normal);
|
||||
// vec3 dp1 = dFdx( position );
|
||||
// vec3 dp2 = dFdy( position );
|
||||
// vec2 duv1 = dFdx( texCoord );
|
||||
// vec2 duv2 = dFdy( texCoord );
|
||||
// vec3 dp2perp = cross( dp2, nn );
|
||||
// vec3 dp1perp = cross( nn, dp1 );
|
||||
// vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
// vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
// float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
|
||||
// mat3 TBN = mat3(T * invmax, B * invmax, nn);
|
||||
// vec3 n = normalize(TBN * nn);
|
||||
#else
|
||||
vec3 n = normalize(normal);
|
||||
#endif
|
||||
|
||||
vec3 l = normalize(lightDir);
|
||||
float dotNL = max(dot(n, l), 0.0);
|
||||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
if (receiveShadow) {
|
||||
if (lPos.w > 0.0) {
|
||||
visibility = shadowTest(lPos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 baseColor = matColor.rgb;
|
||||
#ifdef _AMTex
|
||||
vec4 texel = texture(salbedo, texCoord);
|
||||
#ifdef _AlphaTest
|
||||
if (texel.a < 0.4)
|
||||
discard;
|
||||
#endif
|
||||
texel.rgb = pow(texel.rgb, vec3(2.2));
|
||||
baseColor *= texel.rgb;
|
||||
#endif
|
||||
|
||||
vec4 outColor;
|
||||
|
||||
vec3 v = normalize(eyeDir);
|
||||
vec3 h = normalize(v + l);
|
||||
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
float dotNH = max(dot(n, h), 0.0);
|
||||
float dotVH = max(dot(v, h), 0.0);
|
||||
float dotLV = max(dot(l, v), 0.0);
|
||||
float dotLH = max(dot(l, h), 0.0);
|
||||
|
||||
#ifdef _MMTex
|
||||
float metalness = texture(smm, texCoord).r;
|
||||
#endif
|
||||
vec3 albedo = surfaceAlbedo(baseColor, metalness);
|
||||
vec3 f0 = surfaceF0(baseColor, metalness);
|
||||
|
||||
#ifdef _RMTex
|
||||
float roughness = texture(srm, texCoord).r;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _Toon
|
||||
vec3 v = normalize(eyeDir);
|
||||
vec3 h = normalize(v + l);
|
||||
|
||||
const vec3 ambientMaterial = baseColor * vec3(0.35, 0.35, 0.35) + vec3(0.15);
|
||||
const vec3 diffuseMaterial = baseColor;
|
||||
const vec3 specularMaterial = vec3(0.45, 0.35, 0.35);
|
||||
const float shininess = 0.5;
|
||||
|
||||
float df = max(0.0, dotNL);
|
||||
float sf = max(0.0, dot(n, h));
|
||||
sf = pow(sf, shininess);
|
||||
|
||||
const float A = 0.1;
|
||||
const float B = 0.3;
|
||||
const float C = 0.6;
|
||||
const float D = 1.0;
|
||||
float E = fwidth(df);
|
||||
bool f = false;
|
||||
if (df > A - E) if (df < A + E) {
|
||||
f = true;
|
||||
df = stepmix(A, B, E, df);
|
||||
}
|
||||
|
||||
/*else*/if (!f) if (df > B - E) if(df < B + E) {
|
||||
f = true;
|
||||
df = stepmix(B, C, E, df);
|
||||
}
|
||||
|
||||
/*else*/if (!f) if (df > C - E) if (df < C + E) {
|
||||
f = true;
|
||||
df = stepmix(C, D, E, df);
|
||||
}
|
||||
/*else*/if (!f) if (df < A) {
|
||||
df = 0.0;
|
||||
}
|
||||
else if (df < B) {
|
||||
df = B;
|
||||
}
|
||||
else if (df < C) {
|
||||
df = C;
|
||||
}
|
||||
else df = D;
|
||||
|
||||
E = fwidth(sf);
|
||||
if (sf > 0.5 - E && sf < 0.5 + E) {
|
||||
sf = smoothstep(0.5 - E, 0.5 + E, sf);
|
||||
}
|
||||
else {
|
||||
sf = step(0.5, sf);
|
||||
}
|
||||
|
||||
outColor.rgb = ambientMaterial + (df * diffuseMaterial + sf * specularMaterial) * visibility;
|
||||
float edgeDetection = (dot(v, n) < 0.1) ? 0.0 : 1.0;
|
||||
outColor.rgb *= edgeDetection;
|
||||
|
||||
// const int levels = 4;
|
||||
// const float scaleFactor = 1.0 / levels;
|
||||
|
||||
// float diffuse = max(0, dotNL);
|
||||
// const float material_kd = 0.8;
|
||||
// const float material_ks = 0.3;
|
||||
// vec3 diffuseColor = vec3(0.40, 0.60, 0.70);
|
||||
// diffuseColor = diffuseColor * material_kd * floor(diffuse * levels) * scaleFactor;
|
||||
// float specular = 0.0;
|
||||
// if(dotNL > 0.0) {
|
||||
// specular = material_ks * pow( max(0, dot( h, n)), shininess);
|
||||
// }
|
||||
// // Limit specular
|
||||
// float specMask = (pow(dot(h, n), shininess) > 0.4) ? 1.0 : 0.0;
|
||||
|
||||
// float edgeDetection = (dot(v, n) > 0.3) ? 1.0 : 0.0;
|
||||
// outColor.rgb = edgeDetection * ((diffuseColor + specular * specMask) * visibility + ambientMaterial);
|
||||
#endif
|
||||
|
||||
|
||||
// LTC
|
||||
// const float rectSizeX = 2.5;
|
||||
// const float rectSizeY = 1.2;
|
||||
// vec3 ex = vec3(1, 0, 0)*rectSizeX;
|
||||
// vec3 ey = vec3(0, 0, 1)*rectSizeY;
|
||||
// vec3 p1 = light - ex + ey;
|
||||
// vec3 p2 = light + ex + ey;
|
||||
// vec3 p3 = light + ex - ey;
|
||||
// vec3 p4 = light - ex - ey;
|
||||
// float theta = acos(dotNV);
|
||||
// vec2 tuv = vec2(roughness, theta/(0.5*PI));
|
||||
// tuv = tuv*LUT_SCALE + LUT_BIAS;
|
||||
|
||||
// vec4 t = texture(sltcMat, tuv);
|
||||
// mat3 Minv = mat3(
|
||||
// vec3( 1, t.y, 0),
|
||||
// vec3( 0, 0, t.z),
|
||||
// vec3(t.w, 0, t.x)
|
||||
// );
|
||||
|
||||
// vec3 ltcspec = LTC_Evaluate(n, v, position, Minv, p1, p2, p3, p4, true);
|
||||
// ltcspec *= texture(sltcMag, tuv).a;
|
||||
// vec3 ltcdiff = LTC_Evaluate(n, v, position, mat3(1), p1, p2, p3, p4, true);
|
||||
// vec3 ltccol = ltcspec + ltcdiff * albedo;
|
||||
// ltccol /= 2.0*PI;
|
||||
|
||||
|
||||
|
||||
// Direct
|
||||
vec3 direct = diffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH, dotLV) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH, dotLH);
|
||||
direct = direct * lightColor * lightStrength;
|
||||
|
||||
// Indirect
|
||||
vec3 indirectDiffuse = shIrradiance(n, 2.2) / PI;
|
||||
#ifdef _EnvLDR
|
||||
indirectDiffuse = pow(indirectDiffuse, vec3(2.2));
|
||||
#endif
|
||||
indirectDiffuse *= albedo;
|
||||
vec3 indirect = indirectDiffuse;
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);// + 1.0;
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _EnvLDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;
|
||||
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
|
||||
indirect += indirectSpecular;
|
||||
#endif
|
||||
indirect = indirect * lightColor * lightStrength * envmapStrength;
|
||||
outColor = vec4(vec3(direct * visibility + indirect), 1.0);
|
||||
|
||||
#ifdef _OMTex
|
||||
vec3 occ = texture(som, texCoord).rgb;
|
||||
outColor.rgb *= occ;
|
||||
#else
|
||||
outColor.rgb *= occlusion;
|
||||
#endif
|
||||
// LTC
|
||||
// outColor.rgb = ltccol * 10.0 * visibility + indirect / 14.0;
|
||||
|
||||
#ifdef _LDR
|
||||
gl_FragColor = vec4(pow(outColor.rgb, vec3(1.0 / 2.2)), outColor.a);
|
||||
#else
|
||||
gl_FragColor = vec4(outColor.rgb, outColor.a);
|
||||
#endif
|
||||
}
|
141
raw/deferred/overlay.vert.glsl
Normal file
141
raw/deferred/overlay.vert.glsl
Normal file
|
@ -0,0 +1,141 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef _NMTex
|
||||
#define _Tex
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
#ifdef _AMTex
|
||||
in vec2 tex;
|
||||
#endif
|
||||
#ifdef _VCols
|
||||
in vec3 col;
|
||||
#endif
|
||||
#ifdef _NMTex
|
||||
in vec3 tan;
|
||||
#endif
|
||||
#ifdef _Skinning
|
||||
in vec4 bone;
|
||||
in vec4 weight;
|
||||
#endif
|
||||
#ifdef _Instancing
|
||||
in vec3 off;
|
||||
#endif
|
||||
|
||||
uniform mat4 M;
|
||||
uniform mat4 NM;
|
||||
uniform mat4 V;
|
||||
uniform mat4 P;
|
||||
uniform mat4 LMVP;
|
||||
uniform vec4 albedo_color;
|
||||
uniform vec3 eye;
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[50 * 12];
|
||||
#endif
|
||||
|
||||
out vec3 position;
|
||||
#ifdef _Tex
|
||||
out vec2 texCoord;
|
||||
#endif
|
||||
out vec4 lPos;
|
||||
out vec4 matColor;
|
||||
out vec3 eyeDir;
|
||||
#ifdef _NMTex
|
||||
out mat3 TBN;
|
||||
#else
|
||||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
mat4 getBoneMat(const int boneIndex) {
|
||||
vec4 v0 = vec4(skinBones[boneIndex * 12 + 0],
|
||||
skinBones[boneIndex * 12 + 1],
|
||||
skinBones[boneIndex * 12 + 2],
|
||||
skinBones[boneIndex * 12 + 3]);
|
||||
vec4 v1 = vec4(skinBones[boneIndex * 12 + 4],
|
||||
skinBones[boneIndex * 12 + 5],
|
||||
skinBones[boneIndex * 12 + 6],
|
||||
skinBones[boneIndex * 12 + 7]);
|
||||
vec4 v2 = vec4(skinBones[boneIndex * 12 + 8],
|
||||
skinBones[boneIndex * 12 + 9],
|
||||
skinBones[boneIndex * 12 + 10],
|
||||
skinBones[boneIndex * 12 + 11]);
|
||||
return mat4(v0.x, v0.y, v0.z, v0.w,
|
||||
v1.x, v1.y, v1.z, v1.w,
|
||||
v2.x, v2.y, v2.z, v2.w,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
mat4 getSkinningMat() {
|
||||
return weight.x * getBoneMat(int(bone.x)) +
|
||||
weight.y * getBoneMat(int(bone.y)) +
|
||||
weight.z * getBoneMat(int(bone.z)) +
|
||||
weight.w * getBoneMat(int(bone.w));
|
||||
}
|
||||
|
||||
mat3 getSkinningMatVec(const mat4 skinningMat) {
|
||||
return mat3(skinningMat[0].xyz, skinningMat[1].xyz, skinningMat[2].xyz);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _Instancing
|
||||
vec4 sPos = (vec4(pos + off, 1.0));
|
||||
#else
|
||||
vec4 sPos = (vec4(pos, 1.0));
|
||||
#endif
|
||||
#ifdef _Skinning
|
||||
mat4 skinningMat = getSkinningMat();
|
||||
mat3 skinningMatVec = getSkinningMatVec(skinningMat);
|
||||
sPos = sPos * skinningMat;
|
||||
#endif
|
||||
lPos = LMVP * sPos;
|
||||
|
||||
mat4 VM = V * M;
|
||||
|
||||
#ifdef _Billboard
|
||||
// Spherical
|
||||
VM[0][0] = 1.0; VM[0][1] = 0.0; VM[0][2] = 0.0;
|
||||
VM[1][0] = 0.0; VM[1][1] = 1.0; VM[1][2] = 0.0;
|
||||
VM[2][0] = 0.0; VM[2][1] = 0.0; VM[2][2] = 1.0;
|
||||
// Cylindrical
|
||||
//VM[0][0] = 1.0; VM[0][1] = 0.0; VM[0][2] = 0.0;
|
||||
//VM[2][0] = 0.0; VM[2][1] = 0.0; VM[2][2] = 1.0;
|
||||
#endif
|
||||
|
||||
gl_Position = P * VM * sPos;
|
||||
|
||||
#ifdef _Tex
|
||||
texCoord = tex;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
vec3 _normal = normalize(mat3(NM) * (nor * skinningMatVec));
|
||||
#else
|
||||
vec3 _normal = normalize(mat3(NM) * nor);
|
||||
#endif
|
||||
|
||||
matColor = albedo_color;
|
||||
|
||||
#ifdef _VCols
|
||||
matColor.rgb *= col;
|
||||
#endif
|
||||
|
||||
vec3 mPos = vec4(M * sPos).xyz;
|
||||
position = mPos;
|
||||
eyeDir = eye - mPos;
|
||||
|
||||
#ifdef _NMTex
|
||||
vec3 tangent = (mat3(NM) * (tan));
|
||||
vec3 bitangent = normalize(cross(_normal, tangent));
|
||||
TBN = mat3(tangent, bitangent, _normal);
|
||||
#else
|
||||
normal = _normal;
|
||||
#endif
|
||||
}
|
|
@ -707,9 +707,7 @@ vec3 shIrradiance(vec3 nor, float scale) {
|
|||
|
||||
void main() {
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
// float depth = 1.0 - g0.a;
|
||||
// if (depth == 0.0) discard;
|
||||
if (depth == 1.0) discard;
|
||||
// if (depth == 1.0) discard;
|
||||
|
||||
vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, occlusion, mask
|
||||
vec4 g1 = texture(gbuffer1, texCoord); // Base color.rgb, roughn/met
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"params": [
|
||||
{
|
||||
"id": "depth_write",
|
||||
"value": "false"
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"id": "compare_mode",
|
||||
|
|
|
@ -95,6 +95,101 @@
|
|||
"vertex_shader": "forward.vert.glsl",
|
||||
"fragment_shader": "forward.frag.glsl"
|
||||
},
|
||||
{
|
||||
"id": "overlay",
|
||||
"params": [
|
||||
{
|
||||
"id": "depth_write",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"id": "compare_mode",
|
||||
"value": "less"
|
||||
},
|
||||
{
|
||||
"id": "cull_mode",
|
||||
"value": "counter_clockwise"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"id": "M",
|
||||
"link": "_modelMatrix"
|
||||
},
|
||||
{
|
||||
"id": "NM",
|
||||
"link": "_normalMatrix"
|
||||
},
|
||||
{
|
||||
"id": "V",
|
||||
"link": "_viewMatrix"
|
||||
},
|
||||
{
|
||||
"id": "P",
|
||||
"link": "_projectionMatrix"
|
||||
},
|
||||
{
|
||||
"id": "LMVP",
|
||||
"link": "_lightModelViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"id": "lightDir",
|
||||
"link": "_lightDirection"
|
||||
},
|
||||
{
|
||||
"id": "lightColor",
|
||||
"link": "_lightColor"
|
||||
},
|
||||
{
|
||||
"id": "lightStrength",
|
||||
"link": "_lightStrength"
|
||||
},
|
||||
{
|
||||
"id": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"id": "skinBones",
|
||||
"link": "_skinBones",
|
||||
"ifdef": ["_Skinning"]
|
||||
},
|
||||
{
|
||||
"id": "shirr",
|
||||
"link": "_envmapIrradiance"
|
||||
},
|
||||
{
|
||||
"id": "senvmapRadiance",
|
||||
"link": "_envmapRadiance",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"id": "envmapNumMipmaps",
|
||||
"link": "_envmapNumMipmaps",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"id": "senvmapBrdf",
|
||||
"link": "_envmapBrdf",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"id": "envmapStrength",
|
||||
"link": "_envmapStrength"
|
||||
},
|
||||
{
|
||||
"id": "sltcMat",
|
||||
"link": "_ltcMat",
|
||||
"ifdef": ["_PolyLight"]
|
||||
},
|
||||
{
|
||||
"id": "sltcMag",
|
||||
"link": "_ltcMag",
|
||||
"ifdef": ["_PolyLight"]
|
||||
}
|
||||
],
|
||||
"vertex_shader": "overlay.vert.glsl",
|
||||
"fragment_shader": "overlay.frag.glsl"
|
||||
},
|
||||
{
|
||||
"id": "shadowmap",
|
||||
"params": [
|
||||
|
|
699
raw/forward/overlay.frag.glsl
Normal file
699
raw/forward/overlay.frag.glsl
Normal file
|
@ -0,0 +1,699 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
|
||||
// #ifdef _NMTex
|
||||
// #define _Tex
|
||||
// #endif
|
||||
|
||||
#ifdef _AMTex
|
||||
uniform sampler2D salbedo;
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
uniform sampler2D shadowMap;
|
||||
#endif
|
||||
uniform float shirr[27];
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
// uniform sampler2D sltcMat;
|
||||
// uniform sampler2D sltcMag;
|
||||
#ifdef _NMTex
|
||||
uniform sampler2D snormal;
|
||||
#endif
|
||||
#ifdef _OMTex
|
||||
uniform sampler2D som;
|
||||
#else
|
||||
uniform float occlusion;
|
||||
#endif
|
||||
#ifdef _RMTex
|
||||
uniform sampler2D srm;
|
||||
#else
|
||||
uniform float roughness;
|
||||
#endif
|
||||
#ifdef _MMTex
|
||||
uniform sampler2D smm;
|
||||
#else
|
||||
uniform float metalness;
|
||||
#endif
|
||||
#ifdef _HMTex
|
||||
uniform sampler2D shm;
|
||||
uniform float heightStrength;
|
||||
#endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
uniform bool receiveShadow;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 lightColor;
|
||||
uniform float lightStrength;
|
||||
|
||||
// LTC
|
||||
/*uniform vec3 light;
|
||||
// const float roughness = 0.25;
|
||||
const vec3 dcolor = vec3(1.0, 1.0, 1.0);
|
||||
const vec3 scolor = vec3(1.0, 1.0, 1.0);
|
||||
const float intensity = 4.0; // 0-10
|
||||
const float width = 4.0;
|
||||
const float height = 4.0;
|
||||
const vec2 resolution = vec2(800.0, 600.0);
|
||||
const int sampleCount = 0;
|
||||
const int NUM_SAMPLES = 8;
|
||||
const float LUT_SIZE = 64.0;
|
||||
const float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;
|
||||
const float LUT_BIAS = 0.5/LUT_SIZE;
|
||||
// vec2 mys[NUM_SAMPLES];
|
||||
vec3 L0 = vec3(0.0);
|
||||
vec3 L1 = vec3(0.0);
|
||||
vec3 L2 = vec3(0.0);
|
||||
vec3 L3 = vec3(0.0);
|
||||
vec3 L4 = vec3(0.0);*/
|
||||
|
||||
|
||||
in vec3 position;
|
||||
#ifdef _Tex
|
||||
in vec2 texCoord;
|
||||
#endif
|
||||
in vec4 lPos;
|
||||
in vec4 matColor;
|
||||
in vec3 eyeDir;
|
||||
#ifdef _NMTex
|
||||
in mat3 TBN;
|
||||
#else
|
||||
in vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifndef _NoShadows
|
||||
// float linstep(float low, float high, float v) {
|
||||
// return clamp((v - low) / (high - low), 0.0, 1.0);
|
||||
// }
|
||||
// float VSM(vec2 uv, float compare) {
|
||||
// vec2 moments = texture(shadowMap, uv).xy;
|
||||
// float p = smoothstep(compare - 0.02, compare, moments.x);
|
||||
// float variance = max(moments.y - moments.x * moments.x, -0.001);
|
||||
// float d = compare - moments.x;
|
||||
// float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
|
||||
// return clamp(max(p, p_max), 0.0, 1.0);
|
||||
// }
|
||||
float texture2DCompare(vec2 uv, float compare){
|
||||
float depth = texture(shadowMap, uv).r * 2.0 - 1.0;
|
||||
return step(compare, depth);
|
||||
}
|
||||
float texture2DShadowLerp(vec2 size, vec2 uv, float compare){
|
||||
vec2 texelSize = vec2(1.0) / size;
|
||||
vec2 f = fract(uv * size + 0.5);
|
||||
vec2 centroidUV = floor(uv * size + 0.5) / size;
|
||||
|
||||
float lb = texture2DCompare(centroidUV + texelSize * vec2(0.0, 0.0), compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize * vec2(1.0, 1.0), compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
float PCF(vec2 uv, float compare) {
|
||||
float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
|
||||
vec2 off = vec2(-1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
float shadowTest(vec4 lPos) {
|
||||
vec4 lPosH = lPos / lPos.w;
|
||||
lPosH.x = (lPosH.x + 1.0) / 2.0;
|
||||
lPosH.y = (lPosH.y + 1.0) / 2.0;
|
||||
|
||||
return PCF(lPosH.xy, lPosH.z - shadowsBias);
|
||||
// return VSM(lPosH.xy, lPosH.z);
|
||||
// Basic
|
||||
// float distanceFromLight = texture(shadowMap, lPosH.xy).r * 2.0 - 1.0;
|
||||
// return float(distanceFromLight > lPosH.z - bias);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.x * nor.x - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.y * nor.y +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.x * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.x * nor.y +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.y +
|
||||
2.0 * c2 * cl11 * nor.x +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.y
|
||||
) * scale;
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
|
||||
vec2 LightingFuncGGX_FV(float dotLH, float roughness) {
|
||||
float alpha = roughness*roughness;
|
||||
|
||||
// F
|
||||
float F_a, F_b;
|
||||
float dotLH5 = pow(1.0 - dotLH, 5.0);
|
||||
F_a = 1.0;
|
||||
F_b = dotLH5;
|
||||
|
||||
// V
|
||||
float vis;
|
||||
float k = alpha / 2.0;
|
||||
float k2 = k * k;
|
||||
float invK2 = 1.0 - k2;
|
||||
//vis = rcp(dotLH * dotLH * invK2 + k2);
|
||||
vis = inversesqrt(dotLH * dotLH * invK2 + k2);
|
||||
|
||||
return vec2(F_a * vis, F_b * vis);
|
||||
}
|
||||
|
||||
float LightingFuncGGX_D(float dotNH, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSqr = alpha * alpha;
|
||||
float pi = 3.14159;
|
||||
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
float D = alphaSqr / (pi * denom * denom);
|
||||
return D;
|
||||
}
|
||||
|
||||
// John Hable - Optimizing GGX Shaders
|
||||
// http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
|
||||
float LightingFuncGGX_OPT3(float dotNL, float dotLH, float dotNH, float roughness, float F0) {
|
||||
// vec3 H = normalize(V + L);
|
||||
// float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
// float dotLH = clamp(dot(L, H), 0.0, 1.0);
|
||||
// float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
float D = LightingFuncGGX_D(dotNH, roughness);
|
||||
vec2 FV_helper = LightingFuncGGX_FV(dotLH, roughness);
|
||||
float FV = F0 * FV_helper.x + (1.0 - F0) * FV_helper.y;
|
||||
float specular = dotNL * D * FV;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh, float lh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
|
||||
vec3 lambert(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
|
||||
vec3 burley(vec3 albedo, float roughness, float NoV, float NoL, float VoH) {
|
||||
float FD90 = 0.5 + 2 * VoH * VoH * roughness;
|
||||
float FdV = 1 + (FD90 - 1) * pow( 1 - NoV, 5 );
|
||||
float FdL = 1 + (FD90 - 1) * pow( 1 - NoL, 5 );
|
||||
return albedo * ( (1.0 / 3.1415926535) * FdV * FdL );
|
||||
}
|
||||
|
||||
vec3 orenNayar(vec3 albedo, float roughness, float NoV, float NoL, float VoH ) {
|
||||
float pi = 3.1415926535;
|
||||
float a = roughness * roughness;
|
||||
float s = a;// / ( 1.29 + 0.5 * a );
|
||||
float s2 = s * s;
|
||||
float VoL = 2.0 * VoH * VoH - 1.0; // double angle identity
|
||||
float Cosri = VoL - NoV * NoL;
|
||||
float C1 = 1.0 - 0.5 * s2 / (s2 + 0.33);
|
||||
float test = 1.0;
|
||||
if (Cosri >= 0.0) test = (1.0 / ( max( NoL, NoV ) ));
|
||||
float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * test;
|
||||
return albedo / pi * ( C1 + C2 ) * ( 1.0 + roughness * 0.5 );
|
||||
}
|
||||
|
||||
vec3 diffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh, float lv) {
|
||||
return lambert(albedo, nl);
|
||||
//return burley(albedo, roughness, nv, nl, vh);
|
||||
//return orenNayar(albedo, roughness, lv, nl, nv);
|
||||
}
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * envmapNumMipmaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Linearly Transformed Cosines
|
||||
/*
|
||||
vec3 mul(mat3 m, vec3 v) {
|
||||
return m * v;
|
||||
}
|
||||
mat3 mul(mat3 m1, mat3 m2) {
|
||||
return m1 * m2;
|
||||
}
|
||||
mat3 transpose2(mat3 v) {
|
||||
mat3 tmp;
|
||||
tmp[0] = vec3(v[0].x, v[1].x, v[2].x);
|
||||
tmp[1] = vec3(v[0].y, v[1].y, v[2].y);
|
||||
tmp[2] = vec3(v[0].z, v[1].z, v[2].z);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
float IntegrateEdge(vec3 v1, vec3 v2) {
|
||||
float cosTheta = dot(v1, v2);
|
||||
cosTheta = clamp(cosTheta, -0.9999, 0.9999);
|
||||
float theta = acos(cosTheta);
|
||||
float res = cross(v1, v2).z * theta / sin(theta);
|
||||
return res;
|
||||
}
|
||||
int ClipQuadToHorizon() { //inout vec3 L[5], out int n) {
|
||||
// detect clipping config
|
||||
int config = 0;
|
||||
if (L0.z > 0.0) config += 1;
|
||||
if (L1.z > 0.0) config += 2;
|
||||
if (L2.z > 0.0) config += 4;
|
||||
if (L3.z > 0.0) config += 8;
|
||||
|
||||
// clip
|
||||
int n = 0;
|
||||
if (config == 0) {
|
||||
// clip all
|
||||
}
|
||||
else if (config == 1) { // V1 clip V2 V3 V4
|
||||
n = 3;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 2) { // V2 clip V1 V3 V4
|
||||
n = 3;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 3) { // V1 V2 clip V3 V4
|
||||
n = 4;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
L3 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 4) { // V3 clip V1 V2 V4
|
||||
n = 3;
|
||||
L0 = -L3.z * L2 + L2.z * L3;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
}
|
||||
else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 6) { // V2 V3 clip V1 V4
|
||||
n = 4;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 7) { // V1 V2 V3 clip V4
|
||||
n = 5;
|
||||
L4 = -L3.z * L0 + L0.z * L3;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 8) { // V4 clip V1 V2 V3
|
||||
n = 3;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
L1 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = L3;
|
||||
}
|
||||
else if (config == 9) { // V1 V4 clip V2 V3
|
||||
n = 4;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L2.z * L3 + L3.z * L2;
|
||||
}
|
||||
else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 11) { // V1 V2 V4 clip V3
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 12) { // V3 V4 clip V1 V2
|
||||
n = 4;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
}
|
||||
else if (config == 13) { // V1 V3 V4 clip V2
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = L2;
|
||||
L2 = -L1.z * L2 + L2.z * L1;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
}
|
||||
else if (config == 14) { // V2 V3 V4 clip V1
|
||||
n = 5;
|
||||
L4 = -L0.z * L3 + L3.z * L0;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
}
|
||||
else if (config == 15) { // V1 V2 V3 V4
|
||||
n = 4;
|
||||
}
|
||||
|
||||
if (n == 3)
|
||||
L3 = L0;
|
||||
if (n == 4)
|
||||
L4 = L0;
|
||||
return n;
|
||||
}
|
||||
vec3 LTC_Evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3, bool twoSided) {
|
||||
// construct orthonormal basis around N
|
||||
vec3 T1, T2;
|
||||
T1 = normalize(V - N*dot(V, N));
|
||||
T2 = cross(N, T1);
|
||||
|
||||
// rotate area light in (T1, T2, R) basis
|
||||
Minv = mul(Minv, transpose2(mat3(T1, T2, N)));
|
||||
|
||||
// polygon (allocate 5 vertices for clipping)
|
||||
// vec3 L[5];
|
||||
L0 = mul(Minv, points0 - P);
|
||||
L1 = mul(Minv, points1 - P);
|
||||
L2 = mul(Minv, points2 - P);
|
||||
L3 = mul(Minv, points3 - P);
|
||||
|
||||
int n = ClipQuadToHorizon(); //L, n);
|
||||
|
||||
if (n == 0) {
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
// project onto sphere
|
||||
L0 = normalize(L0);
|
||||
L1 = normalize(L1);
|
||||
L2 = normalize(L2);
|
||||
L3 = normalize(L3);
|
||||
L4 = normalize(L4);
|
||||
|
||||
// integrate
|
||||
float sum = 0.0;
|
||||
|
||||
sum += IntegrateEdge(L0, L1);
|
||||
sum += IntegrateEdge(L1, L2);
|
||||
sum += IntegrateEdge(L2, L3);
|
||||
|
||||
if (n >= 4) {
|
||||
sum += IntegrateEdge(L3, L4);
|
||||
}
|
||||
if (n == 5) {
|
||||
sum += IntegrateEdge(L4, L0);
|
||||
}
|
||||
|
||||
sum = twoSided ? abs(sum) : max(0.0, -sum);
|
||||
|
||||
vec3 Lo_i = vec3(sum, sum, sum);
|
||||
|
||||
return Lo_i;
|
||||
}*/
|
||||
|
||||
#ifdef _Toon
|
||||
float stepmix(float edge0, float edge1, float E, float x) {
|
||||
float T = clamp(0.5 * (x - edge0 + E) / E, 0.0, 1.0);
|
||||
return mix(edge0, edge1, T);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _NMTex
|
||||
vec3 n = (texture(snormal, texCoord).rgb * 2.0 - 1.0);
|
||||
n = normalize(TBN * normalize(n));
|
||||
|
||||
// vec3 nn = normalize(normal);
|
||||
// vec3 dp1 = dFdx( position );
|
||||
// vec3 dp2 = dFdy( position );
|
||||
// vec2 duv1 = dFdx( texCoord );
|
||||
// vec2 duv2 = dFdy( texCoord );
|
||||
// vec3 dp2perp = cross( dp2, nn );
|
||||
// vec3 dp1perp = cross( nn, dp1 );
|
||||
// vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
// vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
// float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
|
||||
// mat3 TBN = mat3(T * invmax, B * invmax, nn);
|
||||
// vec3 n = normalize(TBN * nn);
|
||||
#else
|
||||
vec3 n = normalize(normal);
|
||||
#endif
|
||||
|
||||
vec3 l = normalize(lightDir);
|
||||
float dotNL = max(dot(n, l), 0.0);
|
||||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
if (receiveShadow) {
|
||||
if (lPos.w > 0.0) {
|
||||
visibility = shadowTest(lPos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 baseColor = matColor.rgb;
|
||||
#ifdef _AMTex
|
||||
vec4 texel = texture(salbedo, texCoord);
|
||||
#ifdef _AlphaTest
|
||||
if (texel.a < 0.4)
|
||||
discard;
|
||||
#endif
|
||||
texel.rgb = pow(texel.rgb, vec3(2.2));
|
||||
baseColor *= texel.rgb;
|
||||
#endif
|
||||
|
||||
vec4 outColor;
|
||||
|
||||
vec3 v = normalize(eyeDir);
|
||||
vec3 h = normalize(v + l);
|
||||
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
float dotNH = max(dot(n, h), 0.0);
|
||||
float dotVH = max(dot(v, h), 0.0);
|
||||
float dotLV = max(dot(l, v), 0.0);
|
||||
float dotLH = max(dot(l, h), 0.0);
|
||||
|
||||
#ifdef _MMTex
|
||||
float metalness = texture(smm, texCoord).r;
|
||||
#endif
|
||||
vec3 albedo = surfaceAlbedo(baseColor, metalness);
|
||||
vec3 f0 = surfaceF0(baseColor, metalness);
|
||||
|
||||
#ifdef _RMTex
|
||||
float roughness = texture(srm, texCoord).r;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _Toon
|
||||
vec3 v = normalize(eyeDir);
|
||||
vec3 h = normalize(v + l);
|
||||
|
||||
const vec3 ambientMaterial = baseColor * vec3(0.35, 0.35, 0.35) + vec3(0.15);
|
||||
const vec3 diffuseMaterial = baseColor;
|
||||
const vec3 specularMaterial = vec3(0.45, 0.35, 0.35);
|
||||
const float shininess = 0.5;
|
||||
|
||||
float df = max(0.0, dotNL);
|
||||
float sf = max(0.0, dot(n, h));
|
||||
sf = pow(sf, shininess);
|
||||
|
||||
const float A = 0.1;
|
||||
const float B = 0.3;
|
||||
const float C = 0.6;
|
||||
const float D = 1.0;
|
||||
float E = fwidth(df);
|
||||
bool f = false;
|
||||
if (df > A - E) if (df < A + E) {
|
||||
f = true;
|
||||
df = stepmix(A, B, E, df);
|
||||
}
|
||||
|
||||
/*else*/if (!f) if (df > B - E) if(df < B + E) {
|
||||
f = true;
|
||||
df = stepmix(B, C, E, df);
|
||||
}
|
||||
|
||||
/*else*/if (!f) if (df > C - E) if (df < C + E) {
|
||||
f = true;
|
||||
df = stepmix(C, D, E, df);
|
||||
}
|
||||
/*else*/if (!f) if (df < A) {
|
||||
df = 0.0;
|
||||
}
|
||||
else if (df < B) {
|
||||
df = B;
|
||||
}
|
||||
else if (df < C) {
|
||||
df = C;
|
||||
}
|
||||
else df = D;
|
||||
|
||||
E = fwidth(sf);
|
||||
if (sf > 0.5 - E && sf < 0.5 + E) {
|
||||
sf = smoothstep(0.5 - E, 0.5 + E, sf);
|
||||
}
|
||||
else {
|
||||
sf = step(0.5, sf);
|
||||
}
|
||||
|
||||
outColor.rgb = ambientMaterial + (df * diffuseMaterial + sf * specularMaterial) * visibility;
|
||||
float edgeDetection = (dot(v, n) < 0.1) ? 0.0 : 1.0;
|
||||
outColor.rgb *= edgeDetection;
|
||||
|
||||
// const int levels = 4;
|
||||
// const float scaleFactor = 1.0 / levels;
|
||||
|
||||
// float diffuse = max(0, dotNL);
|
||||
// const float material_kd = 0.8;
|
||||
// const float material_ks = 0.3;
|
||||
// vec3 diffuseColor = vec3(0.40, 0.60, 0.70);
|
||||
// diffuseColor = diffuseColor * material_kd * floor(diffuse * levels) * scaleFactor;
|
||||
// float specular = 0.0;
|
||||
// if(dotNL > 0.0) {
|
||||
// specular = material_ks * pow( max(0, dot( h, n)), shininess);
|
||||
// }
|
||||
// // Limit specular
|
||||
// float specMask = (pow(dot(h, n), shininess) > 0.4) ? 1.0 : 0.0;
|
||||
|
||||
// float edgeDetection = (dot(v, n) > 0.3) ? 1.0 : 0.0;
|
||||
// outColor.rgb = edgeDetection * ((diffuseColor + specular * specMask) * visibility + ambientMaterial);
|
||||
#endif
|
||||
|
||||
|
||||
// LTC
|
||||
// const float rectSizeX = 2.5;
|
||||
// const float rectSizeY = 1.2;
|
||||
// vec3 ex = vec3(1, 0, 0)*rectSizeX;
|
||||
// vec3 ey = vec3(0, 0, 1)*rectSizeY;
|
||||
// vec3 p1 = light - ex + ey;
|
||||
// vec3 p2 = light + ex + ey;
|
||||
// vec3 p3 = light + ex - ey;
|
||||
// vec3 p4 = light - ex - ey;
|
||||
// float theta = acos(dotNV);
|
||||
// vec2 tuv = vec2(roughness, theta/(0.5*PI));
|
||||
// tuv = tuv*LUT_SCALE + LUT_BIAS;
|
||||
|
||||
// vec4 t = texture(sltcMat, tuv);
|
||||
// mat3 Minv = mat3(
|
||||
// vec3( 1, t.y, 0),
|
||||
// vec3( 0, 0, t.z),
|
||||
// vec3(t.w, 0, t.x)
|
||||
// );
|
||||
|
||||
// vec3 ltcspec = LTC_Evaluate(n, v, position, Minv, p1, p2, p3, p4, true);
|
||||
// ltcspec *= texture(sltcMag, tuv).a;
|
||||
// vec3 ltcdiff = LTC_Evaluate(n, v, position, mat3(1), p1, p2, p3, p4, true);
|
||||
// vec3 ltccol = ltcspec + ltcdiff * albedo;
|
||||
// ltccol /= 2.0*PI;
|
||||
|
||||
|
||||
|
||||
// Direct
|
||||
vec3 direct = diffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH, dotLV) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH, dotLH);
|
||||
direct = direct * lightColor * lightStrength;
|
||||
|
||||
// Indirect
|
||||
vec3 indirectDiffuse = shIrradiance(n, 2.2) / PI;
|
||||
#ifdef _EnvLDR
|
||||
indirectDiffuse = pow(indirectDiffuse, vec3(2.2));
|
||||
#endif
|
||||
indirectDiffuse *= albedo;
|
||||
vec3 indirect = indirectDiffuse;
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);// + 1.0;
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _EnvLDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;
|
||||
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
|
||||
indirect += indirectSpecular;
|
||||
#endif
|
||||
indirect = indirect * lightColor * lightStrength * envmapStrength;
|
||||
outColor = vec4(vec3(direct * visibility + indirect), 1.0);
|
||||
|
||||
#ifdef _OMTex
|
||||
vec3 occ = texture(som, texCoord).rgb;
|
||||
outColor.rgb *= occ;
|
||||
#else
|
||||
outColor.rgb *= occlusion;
|
||||
#endif
|
||||
// LTC
|
||||
// outColor.rgb = ltccol * 10.0 * visibility + indirect / 14.0;
|
||||
|
||||
#ifdef _LDR
|
||||
gl_FragColor = vec4(pow(outColor.rgb, vec3(1.0 / 2.2)), outColor.a);
|
||||
#else
|
||||
gl_FragColor = vec4(outColor.rgb, outColor.a);
|
||||
#endif
|
||||
}
|
141
raw/forward/overlay.vert.glsl
Normal file
141
raw/forward/overlay.vert.glsl
Normal file
|
@ -0,0 +1,141 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef _NMTex
|
||||
#define _Tex
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
#ifdef _AMTex
|
||||
in vec2 tex;
|
||||
#endif
|
||||
#ifdef _VCols
|
||||
in vec3 col;
|
||||
#endif
|
||||
#ifdef _NMTex
|
||||
in vec3 tan;
|
||||
#endif
|
||||
#ifdef _Skinning
|
||||
in vec4 bone;
|
||||
in vec4 weight;
|
||||
#endif
|
||||
#ifdef _Instancing
|
||||
in vec3 off;
|
||||
#endif
|
||||
|
||||
uniform mat4 M;
|
||||
uniform mat4 NM;
|
||||
uniform mat4 V;
|
||||
uniform mat4 P;
|
||||
uniform mat4 LMVP;
|
||||
uniform vec4 albedo_color;
|
||||
uniform vec3 eye;
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[50 * 12];
|
||||
#endif
|
||||
|
||||
out vec3 position;
|
||||
#ifdef _Tex
|
||||
out vec2 texCoord;
|
||||
#endif
|
||||
out vec4 lPos;
|
||||
out vec4 matColor;
|
||||
out vec3 eyeDir;
|
||||
#ifdef _NMTex
|
||||
out mat3 TBN;
|
||||
#else
|
||||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
mat4 getBoneMat(const int boneIndex) {
|
||||
vec4 v0 = vec4(skinBones[boneIndex * 12 + 0],
|
||||
skinBones[boneIndex * 12 + 1],
|
||||
skinBones[boneIndex * 12 + 2],
|
||||
skinBones[boneIndex * 12 + 3]);
|
||||
vec4 v1 = vec4(skinBones[boneIndex * 12 + 4],
|
||||
skinBones[boneIndex * 12 + 5],
|
||||
skinBones[boneIndex * 12 + 6],
|
||||
skinBones[boneIndex * 12 + 7]);
|
||||
vec4 v2 = vec4(skinBones[boneIndex * 12 + 8],
|
||||
skinBones[boneIndex * 12 + 9],
|
||||
skinBones[boneIndex * 12 + 10],
|
||||
skinBones[boneIndex * 12 + 11]);
|
||||
return mat4(v0.x, v0.y, v0.z, v0.w,
|
||||
v1.x, v1.y, v1.z, v1.w,
|
||||
v2.x, v2.y, v2.z, v2.w,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
mat4 getSkinningMat() {
|
||||
return weight.x * getBoneMat(int(bone.x)) +
|
||||
weight.y * getBoneMat(int(bone.y)) +
|
||||
weight.z * getBoneMat(int(bone.z)) +
|
||||
weight.w * getBoneMat(int(bone.w));
|
||||
}
|
||||
|
||||
mat3 getSkinningMatVec(const mat4 skinningMat) {
|
||||
return mat3(skinningMat[0].xyz, skinningMat[1].xyz, skinningMat[2].xyz);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _Instancing
|
||||
vec4 sPos = (vec4(pos + off, 1.0));
|
||||
#else
|
||||
vec4 sPos = (vec4(pos, 1.0));
|
||||
#endif
|
||||
#ifdef _Skinning
|
||||
mat4 skinningMat = getSkinningMat();
|
||||
mat3 skinningMatVec = getSkinningMatVec(skinningMat);
|
||||
sPos = sPos * skinningMat;
|
||||
#endif
|
||||
lPos = LMVP * sPos;
|
||||
|
||||
mat4 VM = V * M;
|
||||
|
||||
#ifdef _Billboard
|
||||
// Spherical
|
||||
VM[0][0] = 1.0; VM[0][1] = 0.0; VM[0][2] = 0.0;
|
||||
VM[1][0] = 0.0; VM[1][1] = 1.0; VM[1][2] = 0.0;
|
||||
VM[2][0] = 0.0; VM[2][1] = 0.0; VM[2][2] = 1.0;
|
||||
// Cylindrical
|
||||
//VM[0][0] = 1.0; VM[0][1] = 0.0; VM[0][2] = 0.0;
|
||||
//VM[2][0] = 0.0; VM[2][1] = 0.0; VM[2][2] = 1.0;
|
||||
#endif
|
||||
|
||||
gl_Position = P * VM * sPos;
|
||||
|
||||
#ifdef _Tex
|
||||
texCoord = tex;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
vec3 _normal = normalize(mat3(NM) * (nor * skinningMatVec));
|
||||
#else
|
||||
vec3 _normal = normalize(mat3(NM) * nor);
|
||||
#endif
|
||||
|
||||
matColor = albedo_color;
|
||||
|
||||
#ifdef _VCols
|
||||
matColor.rgb *= col;
|
||||
#endif
|
||||
|
||||
vec3 mPos = vec4(M * sPos).xyz;
|
||||
position = mPos;
|
||||
eyeDir = eye - mPos;
|
||||
|
||||
#ifdef _NMTex
|
||||
vec3 tangent = (mat3(NM) * (tan));
|
||||
vec3 bitangent = normalize(cross(_normal, tangent));
|
||||
TBN = mat3(tangent, bitangent, _normal);
|
||||
#else
|
||||
normal = _normal;
|
||||
#endif
|
||||
}
|
Loading…
Reference in a new issue