@galacean/engine-shader 2.0.0-alpha.30 → 2.0.0-alpha.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +350 -110
- package/dist/browser.js.map +1 -1
- package/dist/browser.min.js +1 -1
- package/dist/browser.min.js.map +1 -1
- package/dist/main.js +345 -107
- package/dist/main.js.map +1 -1
- package/dist/module.js +324 -106
- package/dist/module.js.map +1 -1
- package/dist/sources.main.js +497 -0
- package/dist/sources.main.js.map +1 -0
- package/dist/sources.module.js +492 -0
- package/dist/sources.module.js.map +1 -0
- package/package.json +19 -12
- package/types/compiledShaders/index.d.ts +23 -0
- package/types/src/ShaderLibrary/index.d.ts +2 -0
- package/types/src/Shaders/index.d.ts +5 -0
- package/types/src/index.d.ts +2 -0
- package/types/src/sources.d.ts +11 -0
- package/types/index.d.ts +0 -3
- package/types/shaders/index.d.ts +0 -7
- package/types/shaders/shadingPBR/index.d.ts +0 -5
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var BlinnPhong_ForwardPassBlinnPhong = "#ifndef FORWARD_PASS_BLINNPHONG_INCLUDED\n#define FORWARD_PASS_BLINNPHONG_INCLUDED\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n#include \"ShaderLibrary/Common/Fog.glsl\"\n#include \"ShaderLibrary/Common/Transform.glsl\"\n#include \"ShaderLibrary/Common/Attributes.glsl\"\n#include \"ShaderLibrary/Skin/Skin.glsl\"\n#include \"ShaderLibrary/Skin/BlendShape.glsl\"\n#include \"ShaderLibrary/Shadow/Shadow.glsl\"\n#include \"ShaderLibrary/BlinnPhong/MobileBlinnPhong.glsl\"\n\n// Vertex stage carries mesh tangent through to fragment only when BlinnPhong\n// samples a normal map AND the mesh provides a tangent attribute. Otherwise\n// fragment derives the tangent frame from dFdx/dFdy.\n#if defined(RENDERER_HAS_NORMAL) && defined(RENDERER_HAS_TANGENT) && defined(MATERIAL_HAS_NORMALTEXTURE)\n #define NEED_VERTEX_TANGENT\n#endif\n\nvec4 material_TilingOffset;\n\nstruct Varyings {\n vec2 v_uv;\n\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n vec4 v_color;\n #endif\n\n vec3 v_pos;\n\n #if SCENE_FOG_MODE != 0\n vec3 v_positionVS;\n #endif\n\n #ifdef RENDERER_HAS_NORMAL\n vec3 v_normalWS;\n #ifdef NEED_VERTEX_TANGENT\n vec3 v_tangentWS;\n vec3 v_bitangentWS;\n #endif\n #endif\n\n #if defined(NEED_CALCULATE_SHADOWS) && (SCENE_SHADOW_CASCADED_COUNT == 1)\n vec3 v_shadowCoord;\n #endif\n};\n\n\nVaryings BlinnPhongVertex(Attributes attr) {\n Varyings v;\n\n vec4 position = vec4(attr.POSITION, 1.0);\n\n #ifdef RENDERER_HAS_NORMAL\n vec3 normal = attr.NORMAL;\n #ifdef RENDERER_HAS_TANGENT\n vec4 tangent = attr.TANGENT;\n #endif\n #endif\n\n // Blend shape\n #ifdef RENDERER_HAS_BLENDSHAPE\n calculateBlendShape(attr, position\n #ifdef RENDERER_HAS_NORMAL\n , normal\n #ifdef RENDERER_HAS_TANGENT\n , tangent\n #endif\n #endif\n );\n #endif\n\n // Skinning\n #ifdef RENDERER_HAS_SKIN\n mat4 skinMatrix = getSkinMatrix(attr);\n position = skinMatrix * position;\n #if defined(RENDERER_HAS_NORMAL) && !defined(MATERIAL_OMIT_NORMAL)\n mat3 skinNormalMatrix = INVERSE_MAT(mat3(skinMatrix));\n normal = normal * skinNormalMatrix;\n #ifdef NEED_VERTEX_TANGENT\n tangent.xyz = tangent.xyz * skinNormalMatrix;\n #endif\n #endif\n #endif\n\n // UV\n #ifdef RENDERER_HAS_UV\n v.v_uv = attr.TEXCOORD_0;\n #else\n v.v_uv = vec2(0.0);\n #endif\n #ifdef MATERIAL_NEED_TILING_OFFSET\n v.v_uv = v.v_uv * material_TilingOffset.xy + material_TilingOffset.zw;\n #endif\n\n // Vertex color\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n v.v_color = attr.COLOR_0;\n #endif\n\n // Normal\n #if defined(RENDERER_HAS_NORMAL) && !defined(MATERIAL_OMIT_NORMAL)\n v.v_normalWS = normalize( mat3(renderer_NormalMat) * normal );\n #ifdef NEED_VERTEX_TANGENT\n vec3 tangentWS = normalize( mat3(renderer_NormalMat) * tangent.xyz );\n v.v_tangentWS = tangentWS;\n v.v_bitangentWS = cross(v.v_normalWS, tangentWS) * tangent.w;\n #endif\n #endif\n\n // World position\n vec4 worldPos = renderer_ModelMat * position;\n v.v_pos = worldPos.xyz / worldPos.w;\n\n // Clip position\n gl_Position = renderer_MVPMat * position;\n\n // Shadow\n #if defined(NEED_CALCULATE_SHADOWS) && (SCENE_SHADOW_CASCADED_COUNT == 1)\n v.v_shadowCoord = getShadowCoord(v.v_pos);\n #endif\n\n // Fog\n #if SCENE_FOG_MODE != 0\n v.v_positionVS = (renderer_MVMat * position).xyz;\n #endif\n\n return v;\n}\n\n\nvoid BlinnPhongFragment(Varyings v) {\n vec4 ambient, emission, diffuse, specular;\n initBlinnPhongMaterial(v.v_uv, ambient, emission, diffuse, specular);\n\n // Apply vertex color\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n diffuse *= v.v_color;\n #endif\n\n // Normal\n vec3 N;\n #ifdef RENDERER_HAS_NORMAL\n N = normalize(v.v_normalWS);\n #ifdef MATERIAL_HAS_NORMALTEXTURE\n #ifdef NEED_VERTEX_TANGENT\n mat3 tbn = mat3(v.v_tangentWS, v.v_bitangentWS, v.v_normalWS);\n #else\n mat3 tbn = getTBNByDerivatives(v.v_uv, N, v.v_pos, gl_FrontFacing);\n #endif\n N = getNormalByNormalTexture(tbn, material_NormalTexture, material_NormalIntensity, v.v_uv, gl_FrontFacing);\n #else\n N *= float(gl_FrontFacing) * 2.0 - 1.0;\n #endif\n #else\n N = vec3(0.0, 0.0, 1.0);\n #endif\n\n // View direction\n vec3 V = getViewDirection(camera_Position, camera_Forward, v.v_pos);\n\n // Shadow\n float shadowAttenuation = 1.0;\n #if defined(SCENE_DIRECT_LIGHT_COUNT) && defined(NEED_CALCULATE_SHADOWS)\n #if SCENE_SHADOW_CASCADED_COUNT == 1\n vec3 shadowCoord = v.v_shadowCoord;\n #else\n vec3 shadowCoord = getShadowCoord(v.v_pos);\n #endif\n shadowAttenuation *= sampleShadowMap(v.v_pos, shadowCoord);\n #endif\n\n // Lighting\n calculateBlinnPhongLighting(N, V, v.v_pos, shadowAttenuation, diffuse, specular);\n\n // Alpha cutoff\n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if (diffuse.a < material_AlphaCutoff) {\n discard;\n }\n #endif\n\n vec4 color = emission + ambient + diffuse + specular;\n\n #ifdef MATERIAL_IS_TRANSPARENT\n color.a = diffuse.a;\n #else\n color.a = 1.0;\n #endif\n\n // Fog\n #if SCENE_FOG_MODE != 0\n color = fog(color, v.v_positionVS);\n #endif\n\n gl_FragColor = color;\n}\n\n\n#endif\n";
|
|
6
|
+
|
|
7
|
+
var BlinnPhong_MobileBlinnPhong = "#ifndef MOBILE_BLINNPHONG_INCLUDED\n#define MOBILE_BLINNPHONG_INCLUDED\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n#include \"ShaderLibrary/Lighting/Light.glsl\"\n#include \"ShaderLibrary/Common/Normal.glsl\"\n\n// Material uniforms\nvec4 material_EmissiveColor;\nvec4 material_BaseColor;\nvec4 material_SpecularColor;\nfloat material_Shininess;\nfloat material_NormalIntensity;\nfloat material_AlphaCutoff;\n\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n sampler2D material_EmissiveTexture;\n#endif\n\n#ifdef MATERIAL_HAS_BASETEXTURE\n sampler2D material_BaseTexture;\n#endif\n\n#ifdef MATERIAL_HAS_SPECULAR_TEXTURE\n sampler2D material_SpecularTexture;\n#endif\n\n#ifdef MATERIAL_HAS_NORMALTEXTURE\n sampler2D material_NormalTexture;\n#endif\n\n// Initialize material colors from textures\n// Note: vertex color should be applied by the caller after this function\nvoid initBlinnPhongMaterial(vec2 uv, out vec4 ambient, out vec4 emission, out vec4 diffuse, out vec4 specular) {\n ambient = vec4(0.0);\n emission = material_EmissiveColor;\n diffuse = material_BaseColor;\n specular = material_SpecularColor;\n\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emission *= texture2DSRGB(material_EmissiveTexture, uv);\n #endif\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n diffuse *= texture2DSRGB(material_BaseTexture, uv);\n #endif\n\n #ifdef MATERIAL_HAS_SPECULAR_TEXTURE\n specular *= texture2DSRGB(material_SpecularTexture, uv);\n #endif\n\n ambient = vec4(scene_EnvMapLight.diffuse * scene_EnvMapLight.diffuseIntensity, 1.0) * diffuse;\n}\n\n// Calculate Blinn-Phong lighting\n// shadowAttenuation: pre-computed shadow factor (1.0 = no shadow)\nvoid calculateBlinnPhongLighting(\n vec3 N, vec3 V, vec3 worldPos,\n float shadowAttenuation,\n inout vec4 diffuse, inout vec4 specular\n) {\n vec3 lightDiffuse = vec3(0.0);\n vec3 lightSpecular = vec3(0.0);\n\n #ifdef SCENE_DIRECT_LIGHT_COUNT\n DirectLight directionalLight;\n for (int i = 0; i < SCENE_DIRECT_LIGHT_COUNT; i++) {\n if (!isRendererCulledByLight(renderer_Layer.xy, scene_DirectLightCullingMask[i])) {\n directionalLight.color = scene_DirectLightColor[i];\n #ifdef NEED_CALCULATE_SHADOWS\n if (i == 0) {\n directionalLight.color *= shadowAttenuation;\n }\n #endif\n directionalLight.direction = scene_DirectLightDirection[i];\n\n float d = max(dot(N, -directionalLight.direction), 0.0);\n lightDiffuse += directionalLight.color * d;\n\n vec3 halfDir = normalize(V - directionalLight.direction);\n float s = pow(clamp(dot(N, halfDir), 0.0, 1.0), material_Shininess);\n lightSpecular += directionalLight.color * s;\n }\n }\n #endif\n\n #ifdef SCENE_POINT_LIGHT_COUNT\n PointLight pointLight;\n for (int i = 0; i < SCENE_POINT_LIGHT_COUNT; i++) {\n if (!isRendererCulledByLight(renderer_Layer.xy, scene_PointLightCullingMask[i])) {\n pointLight.color = scene_PointLightColor[i];\n pointLight.position = scene_PointLightPosition[i];\n pointLight.distance = scene_PointLightDistance[i];\n\n vec3 direction = worldPos - pointLight.position;\n float dist = length(direction);\n direction /= dist;\n float decay = clamp(1.0 - pow(dist / pointLight.distance, 4.0), 0.0, 1.0);\n\n float d = max(dot(N, -direction), 0.0) * decay;\n lightDiffuse += pointLight.color * d;\n\n vec3 halfDir = normalize(V - direction);\n float s = pow(clamp(dot(N, halfDir), 0.0, 1.0), material_Shininess) * decay;\n lightSpecular += pointLight.color * s;\n }\n }\n #endif\n\n #ifdef SCENE_SPOT_LIGHT_COUNT\n SpotLight spotLight;\n for (int i = 0; i < SCENE_SPOT_LIGHT_COUNT; i++) {\n if (!isRendererCulledByLight(renderer_Layer.xy, scene_SpotLightCullingMask[i])) {\n spotLight.color = scene_SpotLightColor[i];\n spotLight.position = scene_SpotLightPosition[i];\n spotLight.direction = scene_SpotLightDirection[i];\n spotLight.distance = scene_SpotLightDistance[i];\n spotLight.angleCos = scene_SpotLightAngleCos[i];\n spotLight.penumbraCos = scene_SpotLightPenumbraCos[i];\n\n vec3 direction = spotLight.position - worldPos;\n float lightDistance = length(direction);\n direction /= lightDistance;\n float angleCos = dot(direction, -spotLight.direction);\n float decay = clamp(1.0 - pow(lightDistance / spotLight.distance, 4.0), 0.0, 1.0);\n float spotEffect = smoothstep(spotLight.penumbraCos, spotLight.angleCos, angleCos);\n float decayTotal = decay * spotEffect;\n float d = max(dot(N, direction), 0.0) * decayTotal;\n lightDiffuse += spotLight.color * d;\n\n vec3 halfDir = normalize(V + direction);\n float s = pow(clamp(dot(N, halfDir), 0.0, 1.0), material_Shininess) * decayTotal;\n lightSpecular += spotLight.color * s;\n }\n }\n #endif\n\n diffuse *= vec4(lightDiffuse, 1.0);\n specular *= vec4(lightSpecular, 1.0);\n}\n\n#endif\n";
|
|
8
|
+
|
|
9
|
+
var Blit_BlitVertex = "#ifndef BLIT_VERTEX_INCLUDED\n#define BLIT_VERTEX_INCLUDED\n\nstruct Attributes {\n vec4 POSITION_UV;\n};\n\nstruct Varyings {\n vec2 v_uv;\n};\n\nVaryings vert(Attributes attr) {\n Varyings v;\n gl_Position = vec4(attr.POSITION_UV.xy, 0.0, 1.0);\n v.v_uv = attr.POSITION_UV.zw;\n return v;\n}\n\n#endif\n";
|
|
10
|
+
|
|
11
|
+
var Common_Attributes = "#ifndef ATTRIBUTES_INCLUDED\n#define ATTRIBUTES_INCLUDED\n\n\nstruct Attributes{\n \tvec3 POSITION;\n\n\t#ifdef RENDERER_HAS_BLENDSHAPE\n \t#ifndef RENDERER_BLENDSHAPE_USE_TEXTURE\n \t\tvec3 POSITION_BS0;\n \t \tvec3 POSITION_BS1;\n \t \t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) && defined( RENDERER_BLENDSHAPE_HAS_TANGENT )\n \t \tvec3 NORMAL_BS0;\n \t \tvec3 NORMAL_BS1;\n \t \tvec3 TANGENT_BS0;\n \t \tvec3 TANGENT_BS1;\n \t \t#else\n \t \t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) || defined( RENDERER_BLENDSHAPE_HAS_TANGENT )\n \t \t vec3 POSITION_BS2;\n \t \t vec3 POSITION_BS3;\n\n \t \t #ifdef RENDERER_BLENDSHAPE_HAS_NORMAL\n \t \t vec3 NORMAL_BS0;\n \t \t vec3 NORMAL_BS1;\n \t \t vec3 NORMAL_BS2;\n \t \t vec3 NORMAL_BS3;\n \t \t #endif\n\n \t \t #ifdef RENDERER_BLENDSHAPE_HAS_TANGENT\n \t \t vec3 TANGENT_BS0;\n \t \t vec3 TANGENT_BS1;\n \t \t vec3 TANGENT_BS2;\n \t \t vec3 TANGENT_BS3;\n \t \t #endif\n\n \t \t#else\n \t \t vec3 POSITION_BS2;\n \t \t vec3 POSITION_BS3;\n \t \t vec3 POSITION_BS4;\n \t \t vec3 POSITION_BS5;\n \t \t vec3 POSITION_BS6;\n \t \t vec3 POSITION_BS7;\n \t #endif\n \t#endif\n #endif\n #endif\n\n\n \t#ifdef RENDERER_HAS_UV\n \t vec2 TEXCOORD_0;\n \t#endif\n\n \t#ifdef RENDERER_HAS_UV1\n \t vec2 TEXCOORD_1;\n \t#endif\n\n \t#ifdef RENDERER_HAS_SKIN\n \t vec4 JOINTS_0;\n \t vec4 WEIGHTS_0;\n \t#endif\n\n \t#ifdef RENDERER_ENABLE_VERTEXCOLOR\n \t vec4 COLOR_0;\n \t#endif\n\n\t#ifdef RENDERER_HAS_NORMAL\n\t vec3 NORMAL;\n\t#endif\n\n #ifdef RENDERER_HAS_TANGENT\n vec4 TANGENT;\n #endif\n};\n\n\n#endif";
|
|
12
|
+
|
|
13
|
+
var Common_Common = "#ifndef COMMON_INCLUDED\n#define COMMON_INCLUDED\n\n#define PI 3.14159265359\n#define RECIPROCAL_PI 0.31830988618\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats\n#define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n\nfloat pow2(float x ) {\n return x * x;\n}\n\nvec4 gammaToLinear(vec4 value){\n return vec4( pow(value.rgb, vec3(2.2)), value.a);\n}\n\nvec4 linearToGamma(vec4 value){\n\tvalue = max(value, 0.0);\n return vec4( pow(value.rgb, vec3(1.0 / 2.2)), value.a);\n}\n\n// https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_framebuffer_sRGB.txt\n// https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_sRGB_decode.txt\nfloat sRGBToLinear(float value){\n float linearRGBLo = value / 12.92;\n float linearRGBHi = pow((value + 0.055) / 1.055, 2.4);\n float linearRGB = (value <= 0.04045) ? linearRGBLo : linearRGBHi;\n return linearRGB;\n}\n\nvec4 sRGBToLinear(vec4 value){\n return vec4(sRGBToLinear(value.r), sRGBToLinear(value.g), sRGBToLinear(value.b), value.a);\n}\n\nfloat linearToSRGB(float value){\n\tvalue = max(value, 0.0);\n return (value <= 0.0031308) ? (value * 12.9232102) : 1.055 * pow(value, 1.0 / 2.4) - 0.055;\n}\n\nvec4 linearToSRGB(vec4 value){\n return vec4(linearToSRGB(value.r), linearToSRGB(value.g), linearToSRGB(value.b), value.a);\n}\n\n// Compatible with devices that do not even support EXT_sRGB in WebGL1.0.\nvec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n\tvec4 color = texture2D(tex, uv);\n\t#ifdef ENGINE_NO_SRGB\n\t\tcolor = sRGBToLinear(color);\n\t#endif\n\treturn color;\n}\n\nvec4 outputSRGBCorrection(vec4 linearIn){\n #ifdef ENGINE_OUTPUT_SRGB_CORRECT\n \treturn linearToSRGB(linearIn);\n #else \n \treturn linearIn;\n #endif\n}\n\n\nvec4 camera_DepthBufferParams;\nvec4 camera_ProjectionParams;\n\nfloat remapDepthBufferLinear01(float depth){\n\treturn 1.0 / (camera_DepthBufferParams.x * depth + camera_DepthBufferParams.y);\n}\n\nfloat remapDepthBufferEyeDepth(float depth){\n\t#ifdef CAMERA_ORTHOGRAPHIC\n\t\treturn camera_ProjectionParams.y + (camera_ProjectionParams.z - camera_ProjectionParams.y) * depth;\n\t#else\n\t\treturn 1.0 / (camera_DepthBufferParams.z * depth + camera_DepthBufferParams.w);\n\t#endif\n}\n\n// From Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]\n// http://advances.realtimerendering.com/s2014/index.html\n// sampleCoord must not be normalized (e.g. window coordinates)\nfloat interleavedGradientNoise(vec2 sampleCoord)\n{\n\tconst vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);\n\treturn fract(magic.z * fract(dot(sampleCoord, magic.xy)));\n}\n\n#ifdef GRAPHICS_API_WEBGL2\n\t#define INVERSE_MAT(mat) inverse(mat)\n#else\n\tmat2 inverseMat(mat2 m) {\n\t\treturn mat2(m[1][1],-m[0][1],\n\t\t\t\t-m[1][0], m[0][0]) / (m[0][0]*m[1][1] - m[0][1]*m[1][0]);\n\t}\n\tmat3 inverseMat(mat3 m) {\n\t\tfloat a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];\n\t\tfloat a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];\n\t\tfloat a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];\n\n\t\tfloat b01 = a22 * a11 - a12 * a21;\n\t\tfloat b11 = -a22 * a10 + a12 * a20;\n\t\tfloat b21 = a21 * a10 - a11 * a20;\n\n\t\tfloat det = a00 * b01 + a01 * b11 + a02 * b21;\n\n\t\treturn mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),\n\t\t\t\t\tb11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),\n\t\t\t\t\tb21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;\n\t}\n\tmat4 inverseMat(mat4 m) {\n\t\tfloat a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],\n\t\t\ta10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],\n\t\t\ta20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],\n\t\t\ta30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],\n\n\t\t\tb00 = a00 * a11 - a01 * a10,\n\t\t\tb01 = a00 * a12 - a02 * a10,\n\t\t\tb02 = a00 * a13 - a03 * a10,\n\t\t\tb03 = a01 * a12 - a02 * a11,\n\t\t\tb04 = a01 * a13 - a03 * a11,\n\t\t\tb05 = a02 * a13 - a03 * a12,\n\t\t\tb06 = a20 * a31 - a21 * a30,\n\t\t\tb07 = a20 * a32 - a22 * a30,\n\t\t\tb08 = a20 * a33 - a23 * a30,\n\t\t\tb09 = a21 * a32 - a22 * a31,\n\t\t\tb10 = a21 * a33 - a23 * a31,\n\t\t\tb11 = a22 * a33 - a23 * a32,\n\n\t\t\tdet = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n\t\treturn mat4(\n\t\t\ta11 * b11 - a12 * b10 + a13 * b09,\n\t\t\ta02 * b10 - a01 * b11 - a03 * b09,\n\t\t\ta31 * b05 - a32 * b04 + a33 * b03,\n\t\t\ta22 * b04 - a21 * b05 - a23 * b03,\n\t\t\ta12 * b08 - a10 * b11 - a13 * b07,\n\t\t\ta00 * b11 - a02 * b08 + a03 * b07,\n\t\t\ta32 * b02 - a30 * b05 - a33 * b01,\n\t\t\ta20 * b05 - a22 * b02 + a23 * b01,\n\t\t\ta10 * b10 - a11 * b08 + a13 * b06,\n\t\t\ta01 * b08 - a00 * b10 - a03 * b06,\n\t\t\ta30 * b04 - a31 * b02 + a33 * b00,\n\t\t\ta21 * b02 - a20 * b04 - a23 * b00,\n\t\t\ta11 * b07 - a10 * b09 - a12 * b06,\n\t\t\ta00 * b09 - a01 * b07 + a02 * b06,\n\t\t\ta31 * b01 - a30 * b03 - a32 * b00,\n\t\t\ta20 * b03 - a21 * b01 + a22 * b00) / det;\n\t}\n\n\t#define INVERSE_MAT(mat) inverseMat(mat)\n#endif\n\nvec3 safeNormalize(vec3 inVec)\n{\n float dp3 = max(float(HALF_MIN), dot(inVec, inVec));\n return inVec * inversesqrt(dp3);\n}\n\nvec3 getViewDirection(vec3 cameraPosition, vec3 cameraForward, vec3 worldPosition) {\n #ifdef CAMERA_ORTHOGRAPHIC\n return -cameraForward;\n #else\n return normalize(cameraPosition - worldPosition);\n #endif\n}\n\n#endif";
|
|
14
|
+
|
|
15
|
+
var Common_Fog = "#ifndef FOG_INCLUDED\n#define FOG_INCLUDED\n\n#if SCENE_FOG_MODE != 0\n vec4 scene_FogColor;\n vec4 scene_FogParams; // (-1/(end-start), end/(end-start), density/ln(2),density/sprt(ln(2)));\n\n vec4 fog(vec4 color, vec3 positionVS){\n float fogDepth = length(positionVS);\n\n #if SCENE_FOG_MODE == 1\n // (end-z) / (end-start) = z * (-1/(end-start)) + (end/(end-start))\n float fogIntensity = clamp(fogDepth * scene_FogParams.x + scene_FogParams.y, 0.0, 1.0);\n #elif SCENE_FOG_MODE == 2\n // exp(-z * density) = exp2((-z * density)/ln(2)) = exp2(-z * density/ln(2))\n float fogIntensity = clamp(exp2(-fogDepth * scene_FogParams.z), 0.0, 1.0);\n #elif SCENE_FOG_MODE == 3\n // exp(-(z * density)^2) = exp2(-(z * density)^2/ln(2)) = exp2(-(z * density/sprt(ln(2)))^2)\n float factor = fogDepth * scene_FogParams.w;\n float fogIntensity = clamp(exp2(-factor * factor), 0.0, 1.0);\n #endif\n\n color.rgb = mix(scene_FogColor.rgb, color.rgb, fogIntensity);\n\n return color;\n }\n#endif\n\n\n#endif";
|
|
16
|
+
|
|
17
|
+
var Common_Normal = "#ifndef NORMAL_INCLUDED\n#define NORMAL_INCLUDED\n\n\nvec3 getNormalByNormalTexture(mat3 tbn, sampler2D normalTexture, float normalIntensity, vec2 uv, bool isFrontFacing){\n vec3 normal = (texture2D(normalTexture, uv)).rgb;\n normal = normalize(tbn * ((2.0 * normal - 1.0) * vec3(normalIntensity, normalIntensity, 1.0)));\n normal *= float( isFrontFacing ) * 2.0 - 1.0;\n\n return normal;\n}\n\nmat3 getTBNByDerivatives(vec2 uv, vec3 normal, vec3 position, bool isFrontFacing){\n #ifdef HAS_DERIVATIVES\n uv = isFrontFacing? uv: -uv;\n // ref: http://www.thetenthplanet.de/archives/1180\n // get edge vectors of the pixel triangle\n\t vec3 dp1 = dFdx(position);\n\t vec3 dp2 = dFdy(position);\n\t vec2 duv1 = dFdx(uv);\n\t vec2 duv2 = dFdy(uv);\n\t // solve the linear system\n\t vec3 dp2perp = cross(dp2, normal);\n\t vec3 dp1perp = cross(normal, dp1);\n\t vec3 tangent = dp2perp * duv1.x + dp1perp * duv2.x;\n\t vec3 bitangent = dp2perp * duv1.y + dp1perp * duv2.y;\n\t // construct a scale-invariant frame \n float denom = max( dot(tangent, tangent), dot(bitangent, bitangent) );\n float invmax = (denom == 0.0) ? 0.0 : camera_ProjectionParams.x / sqrt( denom );\n\t return mat3(tangent * invmax, bitangent * invmax, normal);\n #else\n return mat3(vec3(0.0), vec3(0.0), normal);\n #endif\n}\n\n\n#endif";
|
|
18
|
+
|
|
19
|
+
var Common_Transform = "#ifndef TRANSFORM_INCLUDED\n#define TRANSFORM_INCLUDED\n\nmat4 renderer_LocalMat;\nmat4 renderer_ModelMat;\nmat4 camera_ViewMat;\nmat4 camera_ProjMat;\nmat4 camera_VPMat;\nmat4 renderer_MVMat;\nmat4 renderer_MVPMat;\nmat4 renderer_NormalMat;\n\nvec3 camera_Position;\nvec3 camera_Forward;\n\n#endif";
|
|
20
|
+
|
|
21
|
+
var Lighting_AmbientOcclusion_BilateralBlur = "#ifndef BILATERAL_BLUR_INCLUDED\n#define BILATERAL_BLUR_INCLUDED\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n\nsampler2D renderer_BlitTexture;\nvec4 renderer_SourceScaleOffset;\nfloat material_farPlaneOverEdgeDistance;\n\n#if SSAO_QUALITY == 0\n #define BLUR_SAMPLE_COUNT 3\n#elif SSAO_QUALITY == 1\n #define BLUR_SAMPLE_COUNT 6\n#elif SSAO_QUALITY == 2\n #define BLUR_SAMPLE_COUNT 12\n#endif\n\nfloat material_kernel[12];\n\nfloat bilateralWeight(float depth, float sampleDepth) {\n float diff = (sampleDepth - depth) * material_farPlaneOverEdgeDistance;\n return max(0.0, 1.0 - diff * diff);\n}\n\nhighp float unpack(highp vec2 depth) {\n return (depth.x * (256.0 / 257.0) + depth.y * (1.0 / 257.0));\n}\n\nvoid tap(const sampler2D saoTexture,\n inout float sum, inout float totalWeight, float weight, float depth, vec2 position) {\n vec4 data = texture2D(saoTexture, position);\n float bilateral = weight * bilateralWeight(depth, unpack(data.gb));\n sum += data.r * bilateral;\n totalWeight += bilateral;\n}\n\nvoid frag(Varyings v) {\n mediump vec4 data = texture2D(renderer_BlitTexture, v.v_uv);\n float depth = unpack(data.gb);\n\n float totalWeight = material_kernel[0];\n float sum = data.r * totalWeight;\n\n vec2 offset = renderer_SourceScaleOffset.zw;\n for (int i = 1; i < BLUR_SAMPLE_COUNT; i++) {\n float weight = material_kernel[i];\n tap(renderer_BlitTexture, sum, totalWeight, weight, depth, v.v_uv + offset);\n tap(renderer_BlitTexture, sum, totalWeight, weight, depth, v.v_uv - offset);\n offset += renderer_SourceScaleOffset.zw;\n }\n\n float ao = sum * (1.0 / totalWeight);\n\n ao += ((interleavedGradientNoise(gl_FragCoord.xy) - 0.5) / 255.0);\n gl_FragColor = vec4(ao, data.gb, 1.0);\n}\n\n#endif\n";
|
|
22
|
+
|
|
23
|
+
var Lighting_AmbientOcclusion_ScalableAmbientOcclusion = "#ifndef SCALABLE_AMBIENT_OCCLUSION_INCLUDED\n#define SCALABLE_AMBIENT_OCCLUSION_INCLUDED\n\n// Ambient Occlusion, largely inspired from:\n// \"The Alchemy Screen-Space Ambient Obscurance Algorithm\" by Morgan McGuire\n// \"Scalable Ambient Obscurance\" by Morgan McGuire, Michael Mara and David Luebke\n// https://research.nvidia.com/sites/default/files/pubs/2012-06_Scalable-Ambient-Obscurance/McGuire12SAO.pdf\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n\nvec4 renderer_texelSize; // x: 1/width, y: 1/height, z: width, w: height\nhighp sampler2D renderer_BlitTexture; // Camera_DepthTexture\n\n// float inc = (1.0f / (SAMPLE_COUNT - 0.5f)) * SPIRAL_TURNS * 2.0 * PI\n// const vec2 angleIncCosSin = vec2(cos(inc), sin(inc))\n#if SSAO_QUALITY == 0\n #define SAMPLE_COUNT 7.0\n #define SPIRAL_TURNS 3.0\n const vec2 angleIncCosSin = vec2(-0.971148, 0.238227);\n#elif SSAO_QUALITY == 1\n #define SAMPLE_COUNT 11.0\n #define SPIRAL_TURNS 6.0\n const vec2 angleIncCosSin = vec2(-0.896127, -0.443780);\n#elif SSAO_QUALITY == 2\n #define SAMPLE_COUNT 16.0\n #define SPIRAL_TURNS 7.0\n const vec2 angleIncCosSin = vec2(-0.966846, 0.255311);\n#endif\n\nfloat material_invRadiusSquared; // Inverse of the squared radius\nfloat material_minHorizonAngleSineSquared; // Minimum horizon angle sine squared\nfloat material_intensity; // Intensity of the ambient occlusion\nfloat material_projectionScaleRadius;\nfloat material_bias; // Bias to avoid self-occlusion\nfloat material_peak2; // Peak value to avoid singularities\nfloat material_power; // Exponent to convert occlusion to visibility\nvec2 material_invProjScaleXY; //invProjection[0][0] * 2, invProjection[1][1] * 2\n\n\nvec3 computeViewSpacePosition(vec2 uv, float linearDepth, vec2 invProjScaleXY) {\n #ifdef CAMERA_ORTHOGRAPHIC\n return vec3((vec2(0.5) - uv) * invProjScaleXY , linearDepth);\n #else\n return vec3((vec2(0.5) - uv) * invProjScaleXY * linearDepth, linearDepth);\n #endif\n}\n\nfloat depthToViewZ(float depth) {\n return -remapDepthBufferEyeDepth(depth);\n}\n\n// reconstructing normal from depth buffer\n// https://atyuwen.github.io/posts/normal-reconstruction\n// https://wickedengine.net/2019/09/22/improved-normal-reconstruction-from-depth/\nvec3 computeViewSpaceNormal(vec2 uv, highp sampler2D depthTexture, float depth, vec3 viewPos, vec2 texel, vec2 invProjScaleXY) {\n vec3 normal = vec3(0.0);\n#if SSAO_QUALITY == 0 || SSAO_QUALITY == 1\n vec2 uvdx = uv + vec2(texel.x, 0.0);\n vec2 uvdy = uv + vec2(0.0, texel.y);\n\n float depthX = texture2D(depthTexture, uvdx).r;\n float depthY = texture2D(depthTexture, uvdy).r;\n\n vec3 px = computeViewSpacePosition(uvdx, depthToViewZ(depthX), invProjScaleXY);\n vec3 py = computeViewSpacePosition(uvdy, depthToViewZ(depthY), invProjScaleXY);\n\n vec3 dpdx = px - viewPos;\n vec3 dpdy = py - viewPos;\n\n normal = normalize(cross(dpdx, dpdy));\n\n#elif SSAO_QUALITY == 2\n vec2 dx = vec2(texel.x, 0.0);\n vec2 dy = vec2(0.0, texel.y);\n\n vec4 H;\n H.x = texture2D(depthTexture, uv - dx).r; // left\n H.y = texture2D(depthTexture, uv + dx).r; // right\n H.z = texture2D(depthTexture, uv - dx * 2.0).r; // left2\n H.w = texture2D(depthTexture, uv + dx * 2.0).r; // right2\n\n // Calculate horizontal edge weights\n vec2 horizontalEdgeWeights = abs((2.0 * H.xy - H.zw) - depth);\n\n vec3 pos_l = computeViewSpacePosition(uv - dx, depthToViewZ(H.x), invProjScaleXY);\n vec3 pos_r = computeViewSpacePosition(uv + dx, depthToViewZ(H.y), invProjScaleXY);\n vec3 dpdx = (horizontalEdgeWeights.x < horizontalEdgeWeights.y) ? (viewPos - pos_l) : (pos_r - viewPos);\n\n // Sample depths for vertical edge detection\n vec4 V;\n V.x = texture2D(depthTexture, uv - dy).r; // down\n V.y = texture2D(depthTexture, uv + dy).r; // up\n V.z = texture2D(depthTexture, uv - dy * 2.0).r; // down2\n V.w = texture2D(depthTexture, uv + dy * 2.0).r; // up2\n\n // Calculate vertical edge weights\n vec2 verticalEdgeWeights = abs((2.0 * V.xy - V.zw) - depth);\n vec3 pos_d = computeViewSpacePosition(uv - dy, depthToViewZ(V.x), invProjScaleXY);\n vec3 pos_u = computeViewSpacePosition(uv + dy, depthToViewZ(V.y), invProjScaleXY);\n vec3 dpdy = (verticalEdgeWeights.x < verticalEdgeWeights.y) ? (viewPos - pos_d) : (pos_u - viewPos);\n normal = normalize(cross(dpdx, dpdy));\n #endif\n return normal;\n}\n\nvec3 tapLocation(float i, const float noise) {\n float offset = ((2.0 * PI) * 2.4) * noise;\n float angle = ((i / SAMPLE_COUNT) * SPIRAL_TURNS) * (2.0 * PI) + offset;\n float radius = (i + noise + 0.5) / SAMPLE_COUNT;\n return vec3(cos(angle), sin(angle), radius * radius);\n}\n\nvec2 startPosition(const float noise) {\n float angle = ((2.0 * PI) * 2.4) * noise;\n return vec2(cos(angle), sin(angle));\n}\n\nmat2 tapAngleStep() {\n vec2 t = angleIncCosSin;\n return mat2(t.x, t.y, -t.y, t.x);\n}\n\nvec3 tapLocationFast(float i, vec2 p, const float noise) {\n float radius = (i + noise + 0.5) / SAMPLE_COUNT;\n return vec3(p, radius * radius);\n}\n\nvoid computeAmbientOcclusionSAO(inout float occlusion, float i, float ssDiskRadius, vec2 uv, vec3 originPosition, vec3 normal,\n vec2 tapPosition, float noise) {\n\n vec3 tap = tapLocationFast(i, tapPosition, noise);\n\n float ssRadius = max(1.0, tap.z * ssDiskRadius); // at least 1 pixel screen-space radius\n\n vec2 uvSamplePos = uv + vec2(ssRadius * tap.xy) * renderer_texelSize.xy;\n\n float occlusionDepth = texture2D(renderer_BlitTexture, uvSamplePos).r;\n float linearOcclusionDepth = depthToViewZ(occlusionDepth);\n // “p” is the position after spiral sampling\n vec3 p = computeViewSpacePosition(uvSamplePos, linearOcclusionDepth, material_invProjScaleXY);\n\n // now we have the sample, compute AO\n vec3 v = p - originPosition; // sample vector\n float vv = dot(v, v); // squared distance\n float vn = dot(v, normal); // distance * cos(v, normal)\n\n // discard samples that are outside of the radius, preventing distant geometry to\n // cast shadows -- there are many functions that work and choosing one is an artistic\n // decision.\n float weight = pow(max(0.0, 1.0 - vv * material_invRadiusSquared), 2.0);\n\n // discard samples that are too close to the horizon to reduce shadows cast by geometry\n // not sufficently tessellated. The goal is to discard samples that form an angle 'beta'\n // smaller than 'epsilon' with the horizon. We already have dot(v,n) which is equal to the\n // sin(beta) * |v|. So the test simplifies to vn^2 < vv * sin(epsilon)^2.\n weight *= step(vv * material_minHorizonAngleSineSquared, vn * vn);\n\n // Calculate the contribution of a single sampling point to Ambient Occlusion\n float sampleOcclusion = max(0.0, vn + (originPosition.z * material_bias)) / (vv + material_peak2);\n occlusion += weight * sampleOcclusion;\n}\n\nvoid scalableAmbientObscurance(vec2 uv, vec3 origin, vec3 normal, out float obscurance) {\n float noise = interleavedGradientNoise(gl_FragCoord.xy);\n vec2 tapPosition = startPosition(noise);\n mat2 angleStep = tapAngleStep();\n\n // Choose the screen-space sample radius\n // proportional to the projected area of the sphere\n float ssDiskRadius = -(material_projectionScaleRadius / origin.z);\n\n // Accumulate the occlusion amount of all sampling points\n obscurance = 0.0;\n for (float i = 0.0; i < SAMPLE_COUNT; i += 1.0) {\n computeAmbientOcclusionSAO(obscurance, i, ssDiskRadius, uv, origin, normal, tapPosition, noise);\n tapPosition = angleStep * tapPosition;\n }\n obscurance = sqrt(obscurance * material_intensity);\n}\n\nvec2 pack(highp float normalizedDepth) {\n highp float z = clamp(normalizedDepth, 0.0, 1.0);\n highp float t = floor(256.0 * z);\n mediump float hi = t * (1.0 / 256.0);\n mediump float lo = (256.0 * z) - t;\n return vec2(hi, lo);\n}\n\n\nvoid frag(Varyings v) {\n float depth = texture2D(renderer_BlitTexture, v.v_uv).r;\n float z = depthToViewZ(depth);\n\n // Reconstruct view space position from depth\n vec3 positionVS = computeViewSpacePosition(v.v_uv, z, material_invProjScaleXY);\n\n // Compute normal\n vec3 normal = computeViewSpaceNormal(v.v_uv, renderer_BlitTexture, depth, positionVS, renderer_texelSize.xy, material_invProjScaleXY);\n\n float occlusion = 0.0;\n scalableAmbientObscurance(v.v_uv, positionVS, normal, occlusion);\n\n // Occlusion to visibility\n float aoVisibility = pow(clamp(1.0 - occlusion, 0.0, 1.0), material_power);\n\n gl_FragColor = vec4(aoVisibility, pack(-positionVS.z/camera_ProjectionParams.z), 1.0);\n}\n\n#endif\n";
|
|
24
|
+
|
|
25
|
+
var Lighting_Light = "#ifndef LIGHT_INCLUDED\n#define LIGHT_INCLUDED\n\n\nivec4 renderer_Layer;\n#ifndef GRAPHICS_API_WEBGL2\n bool isBitSet(float value, float mask, float bitIndex){\n return mod(floor(value / pow(2.0, bitIndex)), 2.0) == 1.0 && mod(floor(mask / pow(2.0, bitIndex)), 2.0) == 1.0;\n }\n#endif\n\nbool isRendererCulledByLight(ivec2 rendererLayer, ivec2 lightCullingMask){\n #ifdef GRAPHICS_API_WEBGL2\n return !((rendererLayer.x & lightCullingMask.x) != 0 || (rendererLayer.y & lightCullingMask.y) != 0);\n #else\n for (int i = 0; i < 16; i++) {\n if (isBitSet( float(rendererLayer.x), float(lightCullingMask.x), float(i)) || isBitSet( float(rendererLayer.y), float(lightCullingMask.y), float(i))) {\n return false;\n }\n }\n return true;\n #endif\n}\n\n// Directional light\n#ifdef SCENE_DIRECT_LIGHT_COUNT\n\n struct DirectLight {\n vec3 color;\n vec3 direction;\n };\n\n ivec2 scene_DirectLightCullingMask[SCENE_DIRECT_LIGHT_COUNT];\n vec3 scene_DirectLightColor[SCENE_DIRECT_LIGHT_COUNT];\n vec3 scene_DirectLightDirection[SCENE_DIRECT_LIGHT_COUNT];\n\n #ifdef GRAPHICS_API_WEBGL2\n DirectLight getDirectLight(int index){\n DirectLight light;\n light.color = scene_DirectLightColor[index];\n light.direction = scene_DirectLightDirection[index];\n \n return light;\n }\n #endif\n\n#endif\n\n\n// Point light\n#ifdef SCENE_POINT_LIGHT_COUNT\n\n struct PointLight {\n vec3 color;\n vec3 position;\n float distance;\n };\n\n ivec2 scene_PointLightCullingMask[ SCENE_POINT_LIGHT_COUNT ];\n vec3 scene_PointLightColor[ SCENE_POINT_LIGHT_COUNT ];\n vec3 scene_PointLightPosition[ SCENE_POINT_LIGHT_COUNT ];\n float scene_PointLightDistance[ SCENE_POINT_LIGHT_COUNT ];\n\n #ifdef GRAPHICS_API_WEBGL2\n PointLight getPointLight(int index){\n PointLight light;\n light.color = scene_PointLightColor[index];\n light.position = scene_PointLightPosition[index];\n light.distance = scene_PointLightDistance[index];\n\n return light;\n }\n #endif\n\n#endif\n\n\n// Spot light\n#ifdef SCENE_SPOT_LIGHT_COUNT\n\n struct SpotLight {\n vec3 color;\n vec3 position;\n vec3 direction;\n float distance;\n float angleCos;\n float penumbraCos;\n };\n\n ivec2 scene_SpotLightCullingMask[ SCENE_SPOT_LIGHT_COUNT ];\n vec3 scene_SpotLightColor[ SCENE_SPOT_LIGHT_COUNT ];\n vec3 scene_SpotLightPosition[ SCENE_SPOT_LIGHT_COUNT ];\n vec3 scene_SpotLightDirection[ SCENE_SPOT_LIGHT_COUNT ];\n float scene_SpotLightDistance[ SCENE_SPOT_LIGHT_COUNT ];\n float scene_SpotLightAngleCos[ SCENE_SPOT_LIGHT_COUNT ];\n float scene_SpotLightPenumbraCos[ SCENE_SPOT_LIGHT_COUNT ];\n\n #ifdef GRAPHICS_API_WEBGL2\n SpotLight getSpotLight(int index){\n SpotLight light;\n light.color = scene_SpotLightColor[index];\n light.position = scene_SpotLightPosition[index];\n light.direction = scene_SpotLightDirection[index];\n light.distance = scene_SpotLightDistance[index];\n light.angleCos = scene_SpotLightAngleCos[index];\n light.penumbraCos = scene_SpotLightPenumbraCos[index];\n\n return light;\n }\n #endif\n\n\n#endif\n\n// Ambient light\nstruct EnvMapLight {\n vec3 diffuse;\n float mipMapLevel;\n float diffuseIntensity;\n float specularIntensity;\n};\n\n\nEnvMapLight scene_EnvMapLight;\n\n#ifdef SCENE_USE_SH\n vec3 scene_EnvSH[9];\n#endif\n\n#ifdef SCENE_USE_SPECULAR_ENV\n samplerCube scene_EnvSpecularSampler;\n#endif\n\n\n\n\n#endif\n";
|
|
26
|
+
|
|
27
|
+
var Noise_NoiseCommon = "#ifndef NOISE_COMMON_INCLUDED\n#define NOISE_COMMON_INCLUDED\n\n// Common helper functions for simplex noise.\n// Algorithm: Ken Perlin, \"Noise hardware\" (2001) — simplex lattice improvement over classic Perlin noise (1985).\n// GLSL implementation: Ian McEwan, Ashima Arts (MIT License) — https://github.com/ashima/webgl-noise\n\n// Modulo 289 without a division (only multiplications)\nvec4 mod289( vec4 x ) {\n\n return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0;\n\n}\n\nvec3 mod289( vec3 x ) {\n\n return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0;\n\n}\n\nvec2 mod289( vec2 x ) {\n\n return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0;\n\n}\n\nfloat mod289( float x ) {\n\n return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0;\n\n}\n\n// Modulo 7 without a division\nvec4 mod7( vec4 x ) {\n\n return x - floor( x * ( 1.0 / 7.0 ) ) * 7.0;\n\n}\n\nvec3 mod7( vec3 x ) {\n\n return x - floor( x * ( 1.0 / 7.0 ) ) * 7.0;\n\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nvec4 permute( vec4 x ) {\n\n return mod289( ( 34.0 * x + 1.0 ) * x);\n\n}\n\nvec3 permute( vec3 x ) {\n\n return mod289( ( 34.0 * x + 1.0 ) * x );\n\n}\n\nfloat permute( float x ) {\n\n return mod289( ( ( x * 34.0 ) + 1.0 ) * x );\n\n}\n\nvec4 taylorInvSqrt( vec4 r ) {\n\n return 1.79284291400159 - 0.85373472095314 * r;\n\n}\n\nfloat taylorInvSqrt( float r ) {\n\n return 1.79284291400159 - 0.85373472095314 * r;\n\n}\n\nvec4 fade( vec4 t ) {\n\n return t * t * t * ( t * ( t * 6.0 - 15.0 ) + 10.0 );\n\n}\n\nvec3 fade( vec3 t ) {\n\n return t * t * t * ( t * ( t * 6.0 - 15.0 ) + 10.0 );\n\n}\n\nvec2 fade( vec2 t ) {\n\n return t * t * t * ( t * ( t * 6.0 - 15.0 ) + 10.0 );\n\n}\n\n#define K 0.142857142857 // 1/7\n#define Ko 0.428571428571 // 1/2-K/2\n#define K2 0.020408163265306 // 1/(7*7)\n#define Kd2 0.0714285714285 // K/2\n#define Kz 0.166666666667 // 1/6\n#define Kzo 0.416666666667 // 1/2-1/6*2\n#define jitter 1.0 // smaller jitter gives more regular pattern\n#define jitter1 0.8 // smaller jitter gives less errors in F1 F2\n\n#endif // NOISE_COMMON_INCLUDED\n";
|
|
28
|
+
|
|
29
|
+
var Noise_NoiseSimplexGrad = "#ifndef NOISE_SIMPLEX_GRAD_INCLUDED\n#define NOISE_SIMPLEX_GRAD_INCLUDED\n\n// 3D simplex noise analytical gradient.\n// Algorithm: Ken Perlin, \"Noise hardware\" (2001) — simplex lattice improvement over classic Perlin noise (1985).\n// Curl noise: Robert Bridson et al., \"Curl-noise for procedural fluid flow\" (2007).\n// GLSL implementation: Ian McEwan, Ashima Arts (MIT License) — https://github.com/ashima/webgl-noise\n\n#include \"ShaderLibrary/Noise/NoiseCommon.glsl\"\n\nvec3 simplexGrad( vec3 v ) {\n\n const vec2 C = vec2( 1.0 / 6.0, 1.0 / 3.0 );\n const vec4 D = vec4( 0.0, 0.5, 1.0, 2.0 );\n\n // First corner\n vec3 i = floor( v + dot( v, C.yyy ) );\n vec3 x0 = v - i + dot( i, C.xxx ) ;\n\n // Other corners\n vec3 g = step( x0.yzx, x0.xyz );\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n // Permutations\n i = mod289( i );\n vec4 p = permute( permute( permute(\n i.z + vec4( 0.0, i1.z, i2.z, 1.0 ) )\n + i.y + vec4( 0.0, i1.y, i2.y, 1.0 ) )\n + i.x + vec4( 0.0, i1.x, i2.x, 1.0 ) );\n\n // Gradients: 7x7 points over a square, mapped onto an octahedron.\n // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ * ns.x + ns.yyyy;\n vec4 y = y_ * ns.x + ns.yyyy;\n vec4 h = 1.0 - abs( x ) - abs( y );\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n vec4 s0 = floor( b0 ) * 2.0 + 1.0;\n vec4 s1 = floor( b1 ) * 2.0 + 1.0;\n vec4 sh = - step( h, vec4( 0.0 ) );\n\n vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww ;\n\n vec3 p0 = vec3( a0.xy, h.x );\n vec3 p1 = vec3( a0.zw, h.y );\n vec3 p2 = vec3( a1.xy, h.z );\n vec3 p3 = vec3( a1.zw, h.w );\n\n //Normalise gradients\n vec4 norm = taylorInvSqrt( vec4( dot( p0, p0 ), dot( p1, p1 ), dot( p2, p2 ), dot( p3, p3 ) ) );\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n // Mix final noise value\n vec4 m = max( 0.6 - vec4( dot( x0, x0 ), dot( x1, x1 ), dot( x2, x2 ), dot( x3, x3 ) ), 0.0 );\n vec4 m2 = m * m;\n vec4 m4 = m2 * m2;\n vec4 pdotx = vec4( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ), dot( p3, x3 ) );\n\n // Compute and return noise gradient\n vec4 temp = m2 * m * pdotx;\n vec3 grad = - 8.0 * ( temp.x * x0 + temp.y * x1 + temp.z * x2 + temp.w * x3 );\n grad += m4.x * p0 + m4.y * p1 + m4.z * p2 + m4.w * p3;\n return grad * 42.0;\n\n}\n\n#endif // NOISE_SIMPLEX_GRAD_INCLUDED\n";
|
|
30
|
+
|
|
31
|
+
var PBR_BSDF = "#ifndef BSDF_INCLUDED\n#define BSDF_INCLUDED\n\n#include \"ShaderLibrary/PBR/Refraction.glsl\"\n\n#define MIN_PERCEPTUAL_ROUGHNESS 0.045\n#define MIN_ROUGHNESS 0.002025\n\n#ifdef MATERIAL_ENABLE_SHEEN\n sampler2D scene_PrefilteredDFG;\n#endif\n\nstruct SurfaceData{\n // common\n\tvec3 albedoColor;\n\tvec3 emissiveColor;\n float metallic;\n float roughness;\n float ambientOcclusion;\n float opacity;\n float IOR;\n\n // geometry\n vec3 position;\n vec4 positionCS;\n vec3 normal;\n\n #ifdef NEED_TANGENT_SPACE\n vec3 tangent;\n vec3 bitangent;\n #endif\n\n vec3 viewDir;\n float dotNV;\n\n // Specular\n float specularIntensity;\n vec3 specularColor;\n\n // Anisotropy\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n float anisotropy;\n vec3 anisotropicT;\n vec3 anisotropicB;\n vec3 anisotropicN;\n #endif\n\n // Clear coat\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n float clearCoat;\n float clearCoatRoughness;\n vec3 clearCoatNormal;\n float clearCoatDotNV;\n #endif\n\n // Iridescence\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n float iridescenceIOR;\n float iridescenceFactor;\n float iridescenceThickness;\n #endif\n\n // Sheen\n #ifdef MATERIAL_ENABLE_SHEEN\n float sheenRoughness;\n vec3 sheenColor;\n #endif\n\n // Transmission\n #ifdef MATERIAL_ENABLE_TRANSMISSION \n vec3 absorptionCoefficient;\n float transmission;\n float thickness;\n #endif\n};\n\n\nstruct BSDFData{\n vec3 diffuseColor;\n float roughness;\n vec3 envSpecularDFG;\n float diffuseAO;\n vec3 specularF0;\n vec3 resolvedSpecularF0;\n float specularF90;\n vec3 energyCompensation; // Multi-scattering energy compensation factor\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n vec3 clearCoatSpecularColor;\n float clearCoatRoughness;\n #endif\n\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n vec3 iridescenceSpecularColor;\n #endif\n\n #ifdef MATERIAL_ENABLE_SHEEN\n float sheenRoughness;\n float sheenScaling;\n float approxIBLSheenDG;\n #endif\n \n};\n\n\nfloat getAARoughnessFactor(vec3 normal) {\n // Kaplanyan 2016, \"Stable specular highlights\"\n // Tokuyoshi 2017, \"Error Reduction and Simplification for Shading Anti-Aliasing\"\n // Tokuyoshi and Kaplanyan 2019, \"Improved Geometric Specular Antialiasing\"\n #ifdef HAS_DERIVATIVES\n vec3 dxy = max( abs(dFdx(normal)), abs(dFdy(normal)) );\n return max( max(dxy.x, dxy.y), dxy.z );\n #else\n return 0.0;\n #endif\n}\n\n\nfloat F_Schlick(float f0, float f90, float dotLH) {\n\treturn f0 + (f90 - f0) * (pow(1.0 - dotLH, 5.0));\n}\n\nvec3 F_Schlick(vec3 f0, float f90, float dotLH ) {\n\n\t// Original approximation by Christophe Schlick '94\n\t// float fresnel = pow( 1.0 - dotLH, 5.0 );\n\n\t// Optimized variant (presented by Epic at SIGGRAPH '13)\n\t// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\n\treturn (f90 - f0 ) * fresnel + f0;\n\n}\n\n// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2\n// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf\nfloat G_GGX_SmithCorrelated(float alpha, float dotNL, float dotNV ) {\n\n\tfloat a2 = pow2( alpha );\n\n\t// dotNL and dotNV are explicitly swapped. This is not a mistake.\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\n\treturn 0.5 / max( gv + gl, EPSILON );\n\n}\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n // Heitz 2014, \"Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs\"\n // Heitz http://jcgt.org/published/0003/02/03/paper.pdf\n float G_GGX_SmithCorrelated_Anisotropic(float at, float ab, float ToV, float BoV, float ToL, float BoL, float NoV, float NoL) {\n float lambdaV = NoL * length(vec3(at * ToV, ab * BoV, NoV));\n float lambdaL = NoV * length(vec3(at * ToL, ab * BoL, NoL));\n return 0.5 / max(lambdaV + lambdaL, EPSILON);\n }\n#endif\n\n// Microfacet Models for Refraction through Rough Surfaces - equation (33)\n// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html\n// alpha is \"roughness squared\" in Disney’s reparameterization\nfloat D_GGX(float alpha, float dotNH ) {\n\n\tfloat a2 = pow2( alpha );\n\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1\n\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n\n}\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n // GGX Distribution Anisotropic\n // https://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf Addenda\n float D_GGX_Anisotropic(float at, float ab, float ToH, float BoH, float NoH) {\n float a2 = at * ab;\n highp vec3 d = vec3(ab * ToH, at * BoH, a2 * NoH);\n highp float d2 = dot(d, d);\n float b2 = a2 / d2;\n return a2 * b2 * b2 * RECIPROCAL_PI;\n }\n#endif\n\nfloat DG_GGX(float alpha, float dotNV, float dotNL, float dotNH) {\n\tfloat D = D_GGX( alpha, dotNH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n return G * D;\n}\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n float DG_GGX_anisotropic(vec3 h, vec3 l, SurfaceData surfaceData, float alpha, float dotNV, float dotNL, float dotNH) {\n vec3 t = surfaceData.anisotropicT;\n vec3 b = surfaceData.anisotropicB;\n vec3 v = surfaceData.viewDir;\n\n float dotTV = dot(t, v);\n float dotBV = dot(b, v);\n float dotTL = dot(t, l);\n float dotBL = dot(b, l);\n float dotTH = dot(t, h);\n float dotBH = dot(b, h);\n\n // Aniso parameter remapping\n // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf page 24\n float at = max(alpha * (1.0 + surfaceData.anisotropy), MIN_ROUGHNESS);\n float ab = max(alpha * (1.0 - surfaceData.anisotropy), MIN_ROUGHNESS);\n\n // specular anisotropic BRDF\n float D = D_GGX_Anisotropic(at, ab, dotTH, dotBH, dotNH);\n float G = G_GGX_SmithCorrelated_Anisotropic(at, ab, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL);\n\n return G * D;\n }\n#endif\n\n// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility\nvec3 BRDF_Specular_GGX(vec3 incidentDirection, SurfaceData surfaceData, BSDFData bsdfData, vec3 normal, vec3 specularColor, float roughness ) {\n\n\tfloat alpha = pow2( roughness ); // UE4's roughness\n\n\tvec3 halfDir = normalize( incidentDirection + surfaceData.viewDir );\n\n\tfloat dotNL = saturate( dot( normal, incidentDirection ) );\n float dotNV = saturate( dot( normal, surfaceData.viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentDirection, halfDir ) );\n\n vec3 F = F_Schlick(specularColor, bsdfData.specularF90 , dotLH );\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n F = mix(F, bsdfData.iridescenceSpecularColor, surfaceData.iridescenceFactor);\n #endif\n\t\n\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n float GD = DG_GGX_anisotropic(halfDir, incidentDirection, surfaceData, alpha, dotNV, dotNL, dotNH);\n #else\n float GD = DG_GGX(alpha, dotNV, dotNL, dotNH);\n #endif\n return F * GD;\n}\n\nvec3 BRDF_Diffuse_Lambert(vec3 diffuseColor) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\n\n#ifdef MATERIAL_ENABLE_IRIDESCENCE\n\n vec3 iorToFresnel0(vec3 transmittedIOR, float incidentIOR) {\n return pow((transmittedIOR - incidentIOR) / (transmittedIOR + incidentIOR),vec3(2.0));\n } \n\n float iorToFresnel0(float transmittedIOR, float incidentIOR) {\n return pow((transmittedIOR - incidentIOR) / (transmittedIOR + incidentIOR),2.0);\n } \n\n // Assume air interface for top\n // Note: We don't handle the case fresnel0 == 1\n vec3 fresnelToIOR(vec3 f0){\n vec3 sqrtF0 = sqrt(f0);\n return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0);\n }\n\n // Evaluation XYZ sensitivity curves in Fourier space\n vec3 evalSensitivity(float opd, vec3 shift){\n // Use Gaussian fits, given by 3 parameters: val, pos and var\n float phase = 2.0 * PI * opd * 1.0e-9;\n const vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13);\n const vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06);\n const vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09);\n vec3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * pow2(phase));\n xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift[0]) * exp(-4.5282e+09 * pow2(phase));\n xyz /= 1.0685e-7;\n // XYZ to RGB color space\n const mat3 XYZ_TO_RGB = mat3( 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252);\n vec3 rgb = XYZ_TO_RGB * xyz;\n return rgb;\n }\n\n // Fresnel equations for dielectric/dielectric interfaces.\n // Ref: https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html\n vec3 evalIridescenceSpecular(float outsideIOR, float dotNV, float thinIOR, vec3 baseF0, float baseF90, float iridescenceThickness){\n vec3 iridescence = vec3(1.0);\n // Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0\n float iridescenceIOR = mix( outsideIOR, thinIOR, smoothstep( 0.0, 0.03, iridescenceThickness ) );\n // Evaluate the cosTheta on the base layer (Snell law)\n float sinTheta2Sq = pow( outsideIOR / iridescenceIOR, 2.0) * (1.0 - pow( dotNV, 2.0));\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n // Handle total internal reflection\n if (cosTheta2Sq < 0.0) {\n return iridescence;\n }\n float cosTheta2 = sqrt(cosTheta2Sq);\n \n // First interface\n float f0 = iorToFresnel0(iridescenceIOR, outsideIOR);\n float reflectance = F_Schlick(f0, baseF90, dotNV);\n float t121 = 1.0 - reflectance;\n float phi12 = 0.0;\n // iridescenceIOR has limited greater than 1.0\n // if (iridescenceIOR < outsideIOR) {phi12 = PI;} \n float phi21 = PI - phi12;\n \n // Second interface\n vec3 baseIOR = fresnelToIOR(clamp(baseF0, 0.0, 0.9999)); // guard against 1.0\n vec3 r1 = iorToFresnel0(baseIOR, iridescenceIOR);\n vec3 r23 = F_Schlick(r1, baseF90, cosTheta2);\n vec3 phi23 =vec3(0.0);\n if (baseIOR[0] < iridescenceIOR) {phi23[0] = PI;}\n if (baseIOR[1] < iridescenceIOR) {phi23[1] = PI;}\n if (baseIOR[2] < iridescenceIOR) {phi23[2] = PI;}\n \n // Phase shift\n float opd = 2.0 * iridescenceIOR * iridescenceThickness * cosTheta2;\n vec3 phi = vec3(phi21) + phi23;\n \n // Compound terms\n vec3 r123 = clamp(reflectance * r23, 1e-5, 0.9999);\n vec3 sr123 = sqrt(r123);\n vec3 rs = pow2(t121) * r23 / (vec3(1.0) - r123);\n // Reflectance term for m = 0 (DC term amplitude)\n vec3 c0 = reflectance + rs;\n iridescence = c0;\n // Reflectance term for m > 0 (pairs of diracs)\n vec3 cm = rs - t121;\n for (int m = 1; m <= 2; ++m) {\n cm *= sr123;\n vec3 sm = 2.0 * evalSensitivity(float(m) * opd, float(m) * phi);\n iridescence += cm * sm;\n }\n return iridescence = max(iridescence, vec3(0.0)); \n }\n#endif\n\n#ifdef MATERIAL_ENABLE_SHEEN\n // http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf\n float D_Charlie(float roughness, float dotNH) {\n float invAlpha = 1.0 / roughness;\n float cos2h = dotNH * dotNH;\n float sin2h = max(1.0 - cos2h, 0.0078125); // 2^(-14/2), so sin2h^2 > 0 in fp16\n return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n }\n\n // Neubelt and Pettineo 2013, \"Crafting a Next-gen Material Pipeline for The Order: 1886\".\n float V_Neubelt(float NoV, float NoL) {\n return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n }\n\n vec3 sheenBRDF(vec3 incidentDirection, SurfaceData surfaceData, vec3 sheenColor, float sheenRoughness) {\n vec3 halfDir = normalize(incidentDirection + surfaceData.viewDir);\n float dotNL = saturate(dot(surfaceData.normal, incidentDirection));\n float dotNH = saturate(dot(surfaceData.normal, halfDir));\n float D = D_Charlie(sheenRoughness, dotNH);\n float V = V_Neubelt(surfaceData.dotNV, dotNL);\n vec3 F = sheenColor;\n return D * V * F;\n }\n\n float prefilteredSheenDFG(float dotNV, float sheenRoughness) {\n #ifdef HAS_TEX_LOD\n return texture2DLodEXT(scene_PrefilteredDFG, vec2(dotNV, sheenRoughness), 0.0).b;\n #else\n return texture2D(scene_PrefilteredDFG, vec2(dotNV, sheenRoughness),0.0).b;\n #endif \n }\n#endif\n\n// ------------------------Indirect Specular------------------------\n\n// Returns raw DFG approximation coefficients (split-sum LUT approximation)\nvec2 envDFGApprox(float roughness, float dotNV) {\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n return vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\n\n// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile\nvec3 envBRDFApprox(vec3 f0, float f90, float roughness, float dotNV ) {\n vec2 AB = envDFGApprox(roughness, dotNV);\n return f0 * AB.x + f90 * AB.y;\n}\n\n#ifdef MATERIAL_ENABLE_TRANSMISSION \n sampler2D camera_OpaqueTexture;\n vec3 evaluateTransmission(SurfaceData surfaceData, BSDFData bsdfData) {\n RefractionModelResult ray;\n #if REFRACTION_MODE == 0 \n // RefractionMode.Sphere\n refractionModelSphere(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray);\n #elif REFRACTION_MODE == 1\n // RefractionMode.Planar\n refractionModelPlanar(-surfaceData.viewDir, surfaceData.position, surfaceData.normal, surfaceData.IOR, surfaceData.thickness, ray);\n #endif\n\n vec3 refractedRayExit = ray.positionExit;\n\n // We calculate the screen space position of the refracted point\n vec4 samplingPositionNDC = camera_ProjMat * camera_ViewMat * vec4( refractedRayExit, 1.0 );\n vec2 refractionCoords = (samplingPositionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5;\n\n // Sample the opaque texture to get the transmitted light\n vec3 refractionTransmitted = texture2DSRGB(camera_OpaqueTexture, refractionCoords).rgb;\n \n refractionTransmitted *= bsdfData.diffuseColor;\n \n // Since we did not calculate the true Fresnel result in the diffuse reflection, \n // it will cause the lower edge of the transmission to be too bright,\n // Therefore, we use an approximate Fresnel attenuation.\n // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf\n refractionTransmitted *= (1.0 - max(max(bsdfData.envSpecularDFG.r,bsdfData.envSpecularDFG.g),bsdfData.envSpecularDFG.b));\n\n #ifdef MATERIAL_HAS_THICKNESS\n // Absorption coefficient from Disney: http://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf\n vec3 transmittance = min(vec3(1.0), exp(-surfaceData.absorptionCoefficient * ray.transmissionLength));\n refractionTransmitted *= transmittance;\n #endif\n \n return refractionTransmitted;\n }\n#endif\n\n#ifdef SCENE_ENABLE_AMBIENT_OCCLUSION\n sampler2D camera_AOTexture;\n float evaluateAmbientOcclusion(vec2 uv){\n #ifdef MATERIAL_IS_TRANSPARENT\n return 1.0;\n #else\n return texture2D(camera_AOTexture, uv).r;\n #endif\n }\n#endif\n\nvoid initBSDFData(SurfaceData surfaceData, out BSDFData bsdfData){\n vec3 albedoColor = surfaceData.albedoColor;\n float metallic = surfaceData.metallic;\n float roughness = surfaceData.roughness;\n\n vec3 dielectricBaseF0 = vec3(pow2( (surfaceData.IOR - 1.0) / (surfaceData.IOR + 1.0) ));\n vec3 dielectricF0 = min(dielectricBaseF0 * surfaceData.specularColor , vec3(1.0)) * surfaceData.specularIntensity;\n float dielectricF90 = surfaceData.specularIntensity; \n\n bsdfData.specularF0 = mix(dielectricF0, albedoColor, metallic);\n bsdfData.specularF90 = mix(dielectricF90, 1.0, metallic);\n\n // Simplify: albedoColor * mix((1.0 - max(max(dielectricF0.r,dielectricF0.g),dielectricF0.b)), 0.0, metallic);\n bsdfData.diffuseColor = albedoColor * (1.0-metallic) * (1.0 - max(max(dielectricF0.r,dielectricF0.g),dielectricF0.b));\n \n bsdfData.roughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(roughness + getAARoughnessFactor(surfaceData.normal), 1.0));\n\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n float topIOR = 1.0;\n bsdfData.iridescenceSpecularColor = evalIridescenceSpecular(topIOR, surfaceData.dotNV, surfaceData.iridescenceIOR, bsdfData.specularF0, bsdfData.specularF90 , surfaceData.iridescenceThickness);\n #endif\n\n // Use a single effective F0 basis to keep IBL, transmission and compensation consistent.\n bsdfData.resolvedSpecularF0 = bsdfData.specularF0;\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n bsdfData.resolvedSpecularF0 = mix(bsdfData.resolvedSpecularF0, bsdfData.iridescenceSpecularColor, surfaceData.iridescenceFactor);\n #endif\n\n // Environment BRDF and multi-scattering energy compensation\n // Ref: Kulla & Conty 2017, \"Revisiting Physically Based Shading at Imageworks\"\n // Ref: Lagarde & Golubev 2018, simplified multiplier approach\n vec2 dfg = envDFGApprox(bsdfData.roughness, surfaceData.dotNV);\n bsdfData.envSpecularDFG = bsdfData.resolvedSpecularF0 * dfg.x + bsdfData.specularF90 * dfg.y;\n bsdfData.energyCompensation = 1.0 + bsdfData.resolvedSpecularF0 * (1.0 / max(dfg.x + dfg.y, EPSILON) - 1.0);\n\n bsdfData.diffuseAO = surfaceData.ambientOcclusion;\n\n #ifdef SCENE_ENABLE_AMBIENT_OCCLUSION\n float ambientAO = evaluateAmbientOcclusion((surfaceData.positionCS.xy / surfaceData.positionCS.w) * 0.5 + 0.5);\n bsdfData.diffuseAO = min(bsdfData.diffuseAO, ambientAO);\n #endif\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n bsdfData.clearCoatRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.clearCoatRoughness + getAARoughnessFactor(surfaceData.clearCoatNormal), 1.0));\n bsdfData.clearCoatSpecularColor = vec3(0.04);\n #endif\n\n #ifdef MATERIAL_ENABLE_SHEEN\n bsdfData.sheenRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.sheenRoughness + getAARoughnessFactor(surfaceData.normal), 1.0));\n bsdfData.approxIBLSheenDG = prefilteredSheenDFG(surfaceData.dotNV, bsdfData.sheenRoughness);\n bsdfData.sheenScaling = 1.0 - bsdfData.approxIBLSheenDG * max(max(surfaceData.sheenColor.r, surfaceData.sheenColor.g), surfaceData.sheenColor.b);\n #endif\n}\n\n#endif\n";
|
|
32
|
+
|
|
33
|
+
var PBR_ForwardPassPBR = "#ifndef FORWARD_PASS_PBR_INCLUDED\n#define FORWARD_PASS_PBR_INCLUDED\n\n// Vertex stage carries mesh tangent through to fragment only when the surface\n// samples a normal-style map AND the mesh actually provides a tangent\n// attribute. Anisotropy alone falls back to dFdx/dFdy in fragment, so it does\n// not pull tangent through the vertex pipeline.\n#if defined(RENDERER_HAS_NORMAL) && defined(RENDERER_HAS_TANGENT) && (defined(MATERIAL_HAS_NORMALTEXTURE) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE))\n #define NEED_VERTEX_TANGENT\n#endif\n\n// Fragment needs a tangent space whenever any tangent-space material feature\n// is enabled. With NEED_VERTEX_TANGENT the basis comes from the interpolated\n// tangent varying; otherwise fragment derives it from dFdx/dFdy.\n#if defined(MATERIAL_HAS_NORMALTEXTURE) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE) || defined(MATERIAL_ENABLE_ANISOTROPY)\n #define NEED_TANGENT_SPACE\n#endif\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n#include \"ShaderLibrary/Common/Fog.glsl\"\n#include \"ShaderLibrary/Common/Transform.glsl\"\n#include \"ShaderLibrary/Common/Attributes.glsl\"\n#include \"ShaderLibrary/Skin/Skin.glsl\"\n#include \"ShaderLibrary/Skin/BlendShape.glsl\"\n#include \"ShaderLibrary/Shadow/Shadow.glsl\"\n#include \"ShaderLibrary/PBR/VaryingsPBR.glsl\"\n#include \"ShaderLibrary/PBR/LightDirectPBR.glsl\"\n#include \"ShaderLibrary/PBR/LightIndirectPBR.glsl\"\n#include \"ShaderLibrary/PBR/VertexPBR.glsl\"\n#include \"ShaderLibrary/PBR/FragmentPBR.glsl\"\n\n\nVaryings PBRVertex(Attributes attributes) {\n Varyings varyings;\n\n varyings.uv = getUV0(attributes);\n #ifdef RENDERER_HAS_UV1\n varyings.uv1 = attributes.TEXCOORD_1;\n #endif\n\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n varyings.vertexColor = attributes.COLOR_0;\n #endif\n\n\n VertexInputs vertexInputs = getVertexInputs(attributes);\n\n // positionWS\n varyings.positionWS = vertexInputs.positionWS;\n\n // positionVS\n #if SCENE_FOG_MODE != 0\n\t varyings.positionVS = vertexInputs.positionVS;\n\t#endif\n\n // normalWS、tangentWS、bitangentWS\n #ifdef RENDERER_HAS_NORMAL\n varyings.normalWS = vertexInputs.normalWS;\n #ifdef NEED_VERTEX_TANGENT\n varyings.tangentWS = vertexInputs.tangentWS;\n varyings.bitangentWS = vertexInputs.bitangentWS;\n #endif\n #endif\n\n // ShadowCoord\n #if defined(NEED_CALCULATE_SHADOWS) && (SCENE_SHADOW_CASCADED_COUNT == 1)\n varyings.shadowCoord = getShadowCoord(vertexInputs.positionWS);\n #endif\n\n gl_Position = renderer_MVPMat * vertexInputs.positionOS;\n\n varyings.positionCS = gl_Position;\n\n return varyings;\n}\n\n\nvoid PBRFragment(Varyings varyings) {\n BSDFData bsdfData;\n\n // Get aoUV\n vec2 aoUV = varyings.uv;\n #if defined(MATERIAL_HAS_OCCLUSION_TEXTURE) && defined(RENDERER_HAS_UV1)\n if(material_OcclusionTextureCoord == 1.0){\n aoUV = varyings.uv1;\n }\n #endif\n\n SurfaceData surfaceData = getSurfaceData(varyings, aoUV, gl_FrontFacing);\n\n // Can modify surfaceData here\n initBSDFData(surfaceData, bsdfData);\n\n\n vec3 totalDiffuseColor = vec3(0, 0, 0);\n vec3 totalSpecularColor = vec3(0, 0, 0);\n\n // Get shadow attenuation\n float shadowAttenuation = 1.0;\n #if defined(SCENE_DIRECT_LIGHT_COUNT) && defined(NEED_CALCULATE_SHADOWS)\n #if SCENE_SHADOW_CASCADED_COUNT == 1\n vec3 shadowCoord = varyings.shadowCoord;\n #else\n vec3 shadowCoord = getShadowCoord(varyings.positionWS);\n #endif\n shadowAttenuation *= sampleShadowMap(varyings.positionWS, shadowCoord);\n #endif\n\n // Evaluate direct lighting\n evaluateDirectRadiance(varyings, surfaceData, bsdfData, shadowAttenuation, totalDiffuseColor, totalSpecularColor);\n\n // IBL\n evaluateIBL(varyings, surfaceData, bsdfData, totalDiffuseColor, totalSpecularColor);\n\n #ifdef MATERIAL_ENABLE_TRANSMISSION \n vec3 refractionTransmitted = evaluateTransmission(surfaceData, bsdfData);\n totalDiffuseColor = mix(totalDiffuseColor, refractionTransmitted, surfaceData.transmission);\n #endif\n\n // Final color\n vec4 color = vec4((totalDiffuseColor + totalSpecularColor).rgb, surfaceData.opacity);\n\n // Emissive\n color.rgb += surfaceData.emissiveColor;\n\n\n #if SCENE_FOG_MODE != 0\n color = fog(color, varyings.positionVS);\n #endif\n\n gl_FragColor = color;\n}\n\n\n#endif";
|
|
34
|
+
|
|
35
|
+
var PBR_FragmentPBR = "#ifndef MATERIAL_INPUT_PBR_INCLUDED\n#define MATERIAL_INPUT_PBR_INCLUDED\n\n#include \"ShaderLibrary/Common/Normal.glsl\"\n\nfloat material_AlphaCutoff;\nvec4 material_BaseColor;\nfloat material_Metal;\nfloat material_Roughness;\nfloat material_IOR;\nvec3 material_EmissiveColor;\nfloat material_NormalIntensity;\nfloat material_OcclusionIntensity;\nfloat material_OcclusionTextureCoord;\n\nfloat material_SpecularIntensity;\nvec3 material_SpecularColor;\n#ifdef MATERIAL_HAS_SPECULAR_TEXTURE\n sampler2D material_SpecularIntensityTexture;\n#endif\n\n#ifdef MATERIAL_HAS_SPECULAR_COLOR_TEXTURE\n sampler2D material_SpecularColorTexture;\n#endif\n\n#ifdef MATERIAL_ENABLE_CLEAR_COAT\n float material_ClearCoat;\n float material_ClearCoatRoughness;\n\n #ifdef MATERIAL_HAS_CLEAR_COAT_TEXTURE\n sampler2D material_ClearCoatTexture;\n #endif\n\n #ifdef MATERIAL_HAS_CLEAR_COAT_ROUGHNESS_TEXTURE\n sampler2D material_ClearCoatRoughnessTexture;\n #endif\n\n #ifdef MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE\n sampler2D material_ClearCoatNormalTexture;\n #endif\n#endif\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n vec3 material_AnisotropyInfo;\n #ifdef MATERIAL_HAS_ANISOTROPY_TEXTURE\n sampler2D material_AnisotropyTexture;\n #endif\n#endif\n\n#ifdef MATERIAL_ENABLE_IRIDESCENCE\n vec4 material_IridescenceInfo;\n #ifdef MATERIAL_HAS_IRIDESCENCE_THICKNESS_TEXTURE\n sampler2D material_IridescenceThicknessTexture;\n #endif\n\n #ifdef MATERIAL_HAS_IRIDESCENCE_TEXTURE\n sampler2D material_IridescenceTexture;\n #endif\n#endif\n\n#ifdef MATERIAL_ENABLE_SHEEN\n float material_SheenRoughness;\n vec3 material_SheenColor;\n #ifdef MATERIAL_HAS_SHEEN_TEXTURE\n sampler2D material_SheenTexture;\n #endif\n\n #ifdef MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE\n sampler2D material_SheenRoughnessTexture;\n #endif\n#endif\n\n#ifdef MATERIAL_ENABLE_TRANSMISSION\n float material_Transmission;\n #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE\n sampler2D material_TransmissionTexture;\n #endif\n\n #ifdef MATERIAL_HAS_THICKNESS\n vec3 material_AttenuationColor;\n float material_AttenuationDistance;\n float material_Thickness;\n #ifdef MATERIAL_HAS_THICKNESS_TEXTURE\n sampler2D material_ThicknessTexture;\n #endif\n #endif\n#endif\n\n// Texture\n#ifdef MATERIAL_HAS_BASETEXTURE\n sampler2D material_BaseTexture;\n#endif\n\n#ifdef MATERIAL_HAS_NORMALTEXTURE\n sampler2D material_NormalTexture;\n#endif\n\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n sampler2D material_EmissiveTexture;\n#endif\n\n#ifdef MATERIAL_HAS_ROUGHNESS_METALLIC_TEXTURE\n sampler2D material_RoughnessMetallicTexture;\n#endif\n\n#ifdef MATERIAL_HAS_OCCLUSION_TEXTURE\n sampler2D material_OcclusionTexture;\n#endif\n\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n // Aniso Bent Normals\n // Mc Alley https://www.gdcvault.com/play/1022235/Rendering-the-World-of-Far \n vec3 getAnisotropicBentNormal(SurfaceData surfaceData) {\n vec3 anisotropyDirection = (surfaceData.anisotropy >= 0.0) ? surfaceData.anisotropicB : surfaceData.anisotropicT;\n vec3 anisotropicTangent = cross(anisotropyDirection, surfaceData.viewDir);\n vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection);\n // reduce stretching for (roughness < 0.2), refer to https://advances.realtimerendering.com/s2018/Siggraph%202018%20HDRP%20talk_with%20notes.pdf 80\n vec3 bentNormal = normalize( mix(surfaceData.normal, anisotropicNormal, abs(surfaceData.anisotropy) * saturate( 5.0 * surfaceData.roughness)) );\n\n return bentNormal;\n }\n#endif\n\n\nSurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){\n SurfaceData surfaceData;\n\n vec2 uv = v.uv;\n\n // common\n vec4 baseColor = material_BaseColor;\n float metallic = material_Metal;\n float roughness = material_Roughness;\n vec3 emissiveRadiance = material_EmissiveColor;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n baseColor *= texture2DSRGB(material_BaseTexture, uv);\n #endif\n\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n baseColor *= v.vertexColor;\n #endif\n\n\n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if( baseColor.a < material_AlphaCutoff ) {\n discard;\n }\n #endif\n\n #ifdef MATERIAL_HAS_ROUGHNESS_METALLIC_TEXTURE\n vec4 metalRoughMapColor = texture2D( material_RoughnessMetallicTexture, uv );\n roughness *= metalRoughMapColor.g;\n metallic *= metalRoughMapColor.b;\n #endif\n\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emissiveRadiance *= texture2DSRGB(material_EmissiveTexture, uv).rgb;\n #endif\n\n surfaceData.albedoColor = baseColor.rgb;\n surfaceData.emissiveColor = emissiveRadiance;\n surfaceData.metallic = metallic;\n surfaceData.roughness = roughness;\n surfaceData.IOR = material_IOR;\n\n #ifdef MATERIAL_IS_TRANSPARENT\n surfaceData.opacity = baseColor.a;\n #else\n surfaceData.opacity = 1.0;\n #endif\n\n\n // Geometry\n surfaceData.position = v.positionWS;\n surfaceData.positionCS = v.positionCS;\n \n #ifdef CAMERA_ORTHOGRAPHIC\n surfaceData.viewDir = -camera_Forward;\n #else\n surfaceData.viewDir = normalize(camera_Position - v.positionWS);\n #endif\n\n // Normal\n #ifdef RENDERER_HAS_NORMAL\n vec3 normal = normalize(v.normalWS);\n #elif defined(HAS_DERIVATIVES)\n vec3 pos_dx = dFdx(v.positionWS);\n vec3 pos_dy = dFdy(v.positionWS);\n vec3 normal = normalize( cross(pos_dx, pos_dy) );\n normal *= camera_ProjectionParams.x;\n #else\n vec3 normal = vec3(0, 0, 1);\n #endif\n \n normal *= float( isFrontFacing ) * 2.0 - 1.0;\n surfaceData.normal = normal;\n\n // Tangent\n #ifdef NEED_TANGENT_SPACE\n #ifdef NEED_VERTEX_TANGENT\n surfaceData.tangent = v.tangentWS;\n surfaceData.bitangent = v.bitangentWS;\n mat3 tbn = mat3(v.tangentWS, v.bitangentWS, v.normalWS);\n #else\n mat3 tbn = getTBNByDerivatives(uv, normal, v.positionWS, isFrontFacing);\n surfaceData.tangent = tbn[0];\n surfaceData.bitangent = tbn[1];\n #endif\n\n #ifdef MATERIAL_HAS_NORMALTEXTURE\n surfaceData.normal = getNormalByNormalTexture(tbn, material_NormalTexture, material_NormalIntensity, uv, isFrontFacing);\n #endif\n #endif\n\n surfaceData.dotNV = saturate( dot(surfaceData.normal, surfaceData.viewDir) );\n\n // Specular\n surfaceData.specularIntensity = material_SpecularIntensity;\n surfaceData.specularColor = material_SpecularColor;\n #ifdef MATERIAL_HAS_SPECULAR_TEXTURE\n surfaceData.specularIntensity *= texture2D( material_SpecularIntensityTexture, uv ).a;\n #endif\n\n #ifdef MATERIAL_HAS_SPECULAR_COLOR_TEXTURE\n surfaceData.specularColor *= texture2D( material_SpecularColorTexture, uv ).rgb;\n #endif\n\n // Clear Coat\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n #ifdef MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE\n surfaceData.clearCoatNormal = getNormalByNormalTexture(tbn, material_ClearCoatNormalTexture, material_NormalIntensity, uv, isFrontFacing);\n #else\n surfaceData.clearCoatNormal = normal;\n #endif\n surfaceData.clearCoatDotNV = saturate( dot(surfaceData.clearCoatNormal, surfaceData.viewDir) );\n\n surfaceData.clearCoat = material_ClearCoat;\n surfaceData.clearCoatRoughness = material_ClearCoatRoughness;\n\n #ifdef MATERIAL_HAS_CLEAR_COAT_TEXTURE\n surfaceData.clearCoat *= (texture2D( material_ClearCoatTexture, uv )).r;\n #endif\n\n #ifdef MATERIAL_HAS_CLEAR_COAT_ROUGHNESS_TEXTURE\n surfaceData.clearCoatRoughness *= (texture2D( material_ClearCoatRoughnessTexture, uv )).g;\n #endif\n\n surfaceData.clearCoat = saturate( surfaceData.clearCoat );\n #endif\n\n // Anisotropy\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n float anisotropy = material_AnisotropyInfo.z;\n vec3 anisotropicDirection = vec3(material_AnisotropyInfo.xy, 0.0);\n #ifdef MATERIAL_HAS_ANISOTROPY_TEXTURE\n vec3 anisotropyTextureInfo = (texture2D( material_AnisotropyTexture, uv )).rgb;\n anisotropy *= anisotropyTextureInfo.b;\n anisotropicDirection.xy *= anisotropyTextureInfo.rg * 2.0 - 1.0;\n #endif\n\n surfaceData.anisotropy = anisotropy;\n surfaceData.anisotropicT = normalize(mat3(surfaceData.tangent, surfaceData.bitangent, surfaceData.normal) * anisotropicDirection);\n surfaceData.anisotropicB = normalize(cross(surfaceData.normal, surfaceData.anisotropicT));\n surfaceData.anisotropicN = getAnisotropicBentNormal(surfaceData);\n #endif\n\n // Iridescence\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n surfaceData.iridescenceFactor = material_IridescenceInfo.x;\n surfaceData.iridescenceIOR = material_IridescenceInfo.y;\n\n #ifdef MATERIAL_HAS_IRIDESCENCE_THICKNESS_TEXTURE\n float iridescenceThicknessWeight = texture2D( material_IridescenceThicknessTexture, uv).g;\n surfaceData.iridescenceThickness = mix(material_IridescenceInfo.z, material_IridescenceInfo.w, iridescenceThicknessWeight);\n #else\n surfaceData.iridescenceThickness = material_IridescenceInfo.w;\n #endif\n \n #ifdef MATERIAL_HAS_IRIDESCENCE_TEXTURE\n surfaceData.iridescenceFactor *= texture2D( material_IridescenceTexture, uv).r;\n #endif\n #endif\n\n #ifdef MATERIAL_ENABLE_SHEEN\n vec3 sheenColor = material_SheenColor;\n #ifdef MATERIAL_HAS_SHEEN_TEXTURE\n sheenColor *= texture2DSRGB(material_SheenTexture, uv).rgb;\n #endif\n surfaceData.sheenColor = sheenColor;\n\n surfaceData.sheenRoughness = material_SheenRoughness;\n #ifdef MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE\n surfaceData.sheenRoughness *= texture2D(material_SheenRoughnessTexture, uv).a;\n #endif\n #endif\n\n #ifdef MATERIAL_ENABLE_TRANSMISSION \n surfaceData.transmission = material_Transmission;\n #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE\n surfaceData.transmission *= texture2D(material_TransmissionTexture, uv).r;\n #endif\n\n #ifdef MATERIAL_HAS_THICKNESS\n surfaceData.absorptionCoefficient = -log(material_AttenuationColor + HALF_EPS) / max(HALF_EPS, material_AttenuationDistance);\n surfaceData.thickness = max(material_Thickness, 0.0001);\n #ifdef MATERIAL_HAS_THICKNESS_TEXTURE\n surfaceData.thickness *= texture2D( material_ThicknessTexture, uv).g;\n #endif\n #endif \n #endif\n\n // Ambient Occlusion\n #ifdef MATERIAL_HAS_OCCLUSION_TEXTURE\n surfaceData.ambientOcclusion = ((texture2D(material_OcclusionTexture, aoUV)).r - 1.0) * material_OcclusionIntensity + 1.0;\n #else\n surfaceData.ambientOcclusion = 1.0;\n #endif\n\n return surfaceData;\n}\n\n\n\n#endif";
|
|
36
|
+
|
|
37
|
+
var PBR_LightDirectPBR = "\n#ifndef LIGHT_DIRECT_PBR_INCLUDED\n#define LIGHT_DIRECT_PBR_INCLUDED\n\n#ifndef FUNCTION_SURFACE_SHADING\n #define FUNCTION_SURFACE_SHADING surfaceShading\n#endif\n#ifndef FUNCTION_DIFFUSE_LOBE\n #define FUNCTION_DIFFUSE_LOBE diffuseLobe\n#endif\n#ifndef FUNCTION_SPECULAR_LOBE\n #define FUNCTION_SPECULAR_LOBE specularLobe\n#endif\n#ifndef FUNCTION_CLEAR_COAT_LOBE\n #define FUNCTION_CLEAR_COAT_LOBE clearCoatLobe\n#endif\n#ifndef FUNCTION_SHEEN_LOBE\n #define FUNCTION_SHEEN_LOBE sheenLobe\n#endif\n\n#include \"ShaderLibrary/PBR/BSDF.glsl\"\n#include \"ShaderLibrary/Lighting/Light.glsl\"\n#include \"ShaderLibrary/PBR/ReflectionLobe.glsl\"\n\nvoid surfaceShading(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 lightColor, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) {\n\n vec3 diffuseColor = vec3(0);\n vec3 specularColor = vec3(0);\n float dotNL = saturate( dot( surfaceData.normal, incidentDirection ) );\n vec3 irradiance = dotNL * lightColor * PI;\n\n // ClearCoat Lobe\n float attenuation = FUNCTION_CLEAR_COAT_LOBE(varyings, surfaceData, bsdfData, incidentDirection, lightColor, specularColor);\n\n vec3 attenuationIrradiance = attenuation * irradiance;\n // Diffuse Lobe\n FUNCTION_DIFFUSE_LOBE(varyings, surfaceData, bsdfData, attenuationIrradiance, diffuseColor);\n // Specular Lobe\n FUNCTION_SPECULAR_LOBE(varyings, surfaceData, bsdfData, incidentDirection, attenuationIrradiance, specularColor);\n // Sheen Lobe\n FUNCTION_SHEEN_LOBE(varyings, surfaceData, bsdfData, incidentDirection, attenuationIrradiance, diffuseColor, specularColor);\n \n totalDiffuseColor += diffuseColor;\n totalSpecularColor += specularColor;\n\n}\n\n#ifdef SCENE_DIRECT_LIGHT_COUNT\n\n void addDirectionalDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, DirectLight directionalLight, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) {\n vec3 lightColor = directionalLight.color;\n vec3 direction = -directionalLight.direction;\n\n FUNCTION_SURFACE_SHADING(varyings, surfaceData, bsdfData, direction, lightColor, totalDiffuseColor, totalSpecularColor);\n\n }\n\n#endif\n\n#ifdef SCENE_POINT_LIGHT_COUNT\n\n\tvoid addPointDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, PointLight pointLight, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) {\n\t\tvec3 lVector = pointLight.position - surfaceData.position;\n\t\tvec3 direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\n\t\tvec3 lightColor = pointLight.color;\n\t\tlightColor *= clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0);\n\n FUNCTION_SURFACE_SHADING(varyings, surfaceData, bsdfData, direction, lightColor, totalDiffuseColor, totalSpecularColor);\n\t}\n\n#endif\n\n#ifdef SCENE_SPOT_LIGHT_COUNT\n\n\tvoid addSpotDirectLightRadiance(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, SpotLight spotLight, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor) {\n\n\t\tvec3 lVector = spotLight.position - surfaceData.position;\n\t\tvec3 direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( direction, -spotLight.direction );\n\n\t\tfloat spotEffect = smoothstep( spotLight.penumbraCos, spotLight.angleCos, angleCos );\n\t\tfloat decayEffect = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0);\n\n\t\tvec3 lightColor = spotLight.color;\n\t\tlightColor *= spotEffect * decayEffect;\n\n FUNCTION_SURFACE_SHADING(varyings, surfaceData, bsdfData, direction, lightColor, totalDiffuseColor, totalSpecularColor);\n\n\t}\n\n\n#endif\n\nvoid evaluateDirectRadiance(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, float shadowAttenuation, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor){\n #ifdef SCENE_DIRECT_LIGHT_COUNT\n\n for ( int i = 0; i < SCENE_DIRECT_LIGHT_COUNT; i ++ ) {\n // warning: use `continue` syntax may trigger flickering bug in safri 16.1.\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_DirectLightCullingMask[i])){\n #ifdef GRAPHICS_API_WEBGL2\n DirectLight directionalLight = getDirectLight(i);\n #else\n DirectLight directionalLight;\n directionalLight.color = scene_DirectLightColor[i];\n directionalLight.direction = scene_DirectLightDirection[i];\n #endif\n \n #ifdef NEED_CALCULATE_SHADOWS\n if (i == 0) { // Sun light index is always 0\n directionalLight.color *= shadowAttenuation;\n }\n #endif\n addDirectionalDirectLightRadiance(varyings, surfaceData, bsdfData, directionalLight, totalDiffuseColor, totalSpecularColor );\n }\n }\n\n #endif\n\n #ifdef SCENE_POINT_LIGHT_COUNT\n\n for ( int i = 0; i < SCENE_POINT_LIGHT_COUNT; i ++ ) {\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_PointLightCullingMask[i])){\n #ifdef GRAPHICS_API_WEBGL2\n PointLight pointLight = getPointLight(i);\n #else\n PointLight pointLight;\n pointLight.color = scene_PointLightColor[i];\n pointLight.position = scene_PointLightPosition[i];\n pointLight.distance = scene_PointLightDistance[i];\n #endif\n addPointDirectLightRadiance(varyings, surfaceData, bsdfData, pointLight, totalDiffuseColor, totalSpecularColor);\n } \n }\n\n #endif\n\n #ifdef SCENE_SPOT_LIGHT_COUNT\n \n for ( int i = 0; i < SCENE_SPOT_LIGHT_COUNT; i ++ ) {\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_SpotLightCullingMask[i])){\n #ifdef GRAPHICS_API_WEBGL2\n SpotLight spotLight = getSpotLight(i);\n #else\n SpotLight spotLight;\n spotLight.color = scene_SpotLightColor[i];\n spotLight.position = scene_SpotLightPosition[i];\n spotLight.direction = scene_SpotLightDirection[i];\n spotLight.distance = scene_SpotLightDistance[i];\n spotLight.angleCos = scene_SpotLightAngleCos[i];\n spotLight.penumbraCos = scene_SpotLightPenumbraCos[i];\n #endif\n addSpotDirectLightRadiance( varyings, surfaceData, bsdfData, spotLight, totalDiffuseColor, totalSpecularColor);\n } \n }\n\n #endif\n}\n\n\n#endif";
|
|
38
|
+
|
|
39
|
+
var PBR_LightIndirectFunctions = "#ifndef LIGHT_INDIRECT_FUNCTIONS_INCLUDED\n#define LIGHT_INDIRECT_FUNCTIONS_INCLUDED\n\nvec3 getReflectedVector(SurfaceData surfaceData, vec3 n) {\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n vec3 r = reflect(-surfaceData.viewDir, surfaceData.anisotropicN);\n #else\n vec3 r = reflect(-surfaceData.viewDir, n);\n #endif\n\n return r;\n}\n\nfloat getSpecularMIPLevel(float roughness, int maxMIPLevel ) {\n return roughness * float(maxMIPLevel);\n}\n\n// sh need be pre-scaled in CPU.\nvec3 getLightProbeRadiance(SurfaceData surfaceData, vec3 normal, float roughness) {\n\n #ifndef SCENE_USE_SPECULAR_ENV\n return vec3(0);\n #else\n vec3 reflectVec = getReflectedVector(surfaceData, normal);\n\n float specularMIPLevel = getSpecularMIPLevel(roughness, int(scene_EnvMapLight.mipMapLevel) );\n\n #ifdef HAS_TEX_LOD\n vec4 envMapColor = textureCubeLodEXT( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #endif\n\n #ifdef ENGINE_NO_SRGB\n envMapColor = sRGBToLinear(envMapColor);\n #endif\n \n return envMapColor.rgb * scene_EnvMapLight.specularIntensity;\n\n #endif\n}\n\nfloat evaluateSpecularOcclusion(float dotNV, float diffuseAO, float roughness){\n float specularAOFactor = 1.0;\n #if (defined(MATERIAL_HAS_OCCLUSION_TEXTURE) || defined(SCENE_ENABLE_AMBIENT_OCCLUSION)) && defined(SCENE_USE_SPECULAR_ENV)\n specularAOFactor = saturate( pow(dotNV + diffuseAO, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + diffuseAO );\n #endif\n return specularAOFactor;\n}\n\n#endif";
|
|
40
|
+
|
|
41
|
+
var PBR_LightIndirectPBR = "\n#ifndef LIGHT_INDIRECT_PBR_INCLUDED\n#define LIGHT_INDIRECT_PBR_INCLUDED\n\n#ifndef FUNCTION_DIFFUSE_IBL\n #define FUNCTION_DIFFUSE_IBL evaluateDiffuseIBL\n#endif\n#ifndef FUNCTION_SPECULAR_IBL\n #define FUNCTION_SPECULAR_IBL evaluateSpecularIBL\n#endif\n#ifndef FUNCTION_CLEAR_COAT_IBL\n #define FUNCTION_CLEAR_COAT_IBL evaluateClearCoatIBL\n#endif\n#ifndef FUNCTION_SHEEN_IBL\n #define FUNCTION_SHEEN_IBL evaluateSheenIBL\n#endif\n\n#include \"ShaderLibrary/PBR/LightIndirectFunctions.glsl\"\n\n// ------------------------Diffuse------------------------\n\n// sh need be pre-scaled in CPU.\nvec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){\n vec3 result = sh[0] +\n\n sh[1] * (normal.y) +\n sh[2] * (normal.z) +\n sh[3] * (normal.x) +\n\n sh[4] * (normal.y * normal.x) +\n sh[5] * (normal.y * normal.z) +\n sh[6] * (3.0 * normal.z * normal.z - 1.0) +\n sh[7] * (normal.z * normal.x) +\n sh[8] * (normal.x * normal.x - normal.y * normal.y);\n \n return max(result, vec3(0.0));\n\n}\n\n\nvoid evaluateDiffuseIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, inout vec3 diffuseColor){\n #ifdef SCENE_USE_SH\n vec3 irradiance = getLightProbeIrradiance(scene_EnvSH, surfaceData.normal);\n irradiance *= scene_EnvMapLight.diffuseIntensity;\n #else\n vec3 irradiance = scene_EnvMapLight.diffuse * scene_EnvMapLight.diffuseIntensity;\n irradiance *= PI;\n #endif\n diffuseColor += bsdfData.diffuseAO * irradiance * BRDF_Diffuse_Lambert( bsdfData.diffuseColor );\n}\n\nfloat evaluateClearCoatIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, inout vec3 specularColor){\n float radianceAttenuation = 1.0;\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n vec3 clearCoatRadiance = getLightProbeRadiance(surfaceData, surfaceData.clearCoatNormal, bsdfData.clearCoatRoughness);\n float specularAO = evaluateSpecularOcclusion(surfaceData.dotNV, bsdfData.diffuseAO, bsdfData.clearCoatRoughness);\n specularColor += specularAO * clearCoatRadiance * surfaceData.clearCoat * envBRDFApprox(bsdfData.clearCoatSpecularColor, 1.0, bsdfData.clearCoatRoughness, surfaceData.clearCoatDotNV);\n radianceAttenuation -= surfaceData.clearCoat * F_Schlick( 0.04, 1.0, surfaceData.clearCoatDotNV);\n #endif\n\n return radianceAttenuation;\n}\n\nvoid evaluateSpecularIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, float radianceAttenuation, inout vec3 outSpecularColor){\n vec3 radiance = getLightProbeRadiance(surfaceData, surfaceData.normal, bsdfData.roughness);\n \n float specularAO = evaluateSpecularOcclusion(surfaceData.dotNV, bsdfData.diffuseAO, bsdfData.roughness);\n outSpecularColor += specularAO * radianceAttenuation * radiance * envBRDFApprox(bsdfData.resolvedSpecularF0, bsdfData.specularF90 , bsdfData.roughness, surfaceData.dotNV) * bsdfData.energyCompensation;\n}\n\nvoid evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= bsdfData.sheenScaling;\n specularColor *= bsdfData.sheenScaling;\n float specularAO = evaluateSpecularOcclusion(surfaceData.dotNV, bsdfData.diffuseAO, bsdfData.sheenRoughness) ;\n vec3 reflectance = specularAO * radianceAttenuation * bsdfData.approxIBLSheenDG * surfaceData.sheenColor;\n specularColor += reflectance;\n #endif\n}\n\nvoid evaluateIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor){\n vec3 diffuseColor = vec3(0);\n vec3 specularColor = vec3(0);\n\n // IBL diffuse\n FUNCTION_DIFFUSE_IBL(varyings, surfaceData, bsdfData, diffuseColor);\n\n // IBL ClearCoat\n float radianceAttenuation = FUNCTION_CLEAR_COAT_IBL(varyings, surfaceData, bsdfData, specularColor);\n\n // IBL specular\n FUNCTION_SPECULAR_IBL(varyings, surfaceData, bsdfData, radianceAttenuation, specularColor);\n \n // IBL sheen\n FUNCTION_SHEEN_IBL(varyings, surfaceData, bsdfData, radianceAttenuation, diffuseColor, specularColor);\n\n totalDiffuseColor += diffuseColor;\n totalSpecularColor += specularColor;\n\n}\n\n#endif\n";
|
|
42
|
+
|
|
43
|
+
var PBR_ReflectionLobe = "#ifndef REFLECTION_LOBE_INCLUDED\n#define REFLECTION_LOBE_INCLUDED\n\nvoid diffuseLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 attenuationIrradiance, inout vec3 diffuseColor){\n diffuseColor += attenuationIrradiance * BRDF_Diffuse_Lambert( bsdfData.diffuseColor );\n}\n\nvoid specularLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 specularColor){\n specularColor += attenuationIrradiance * BRDF_Specular_GGX( incidentDirection, surfaceData, bsdfData, surfaceData.normal, bsdfData.specularF0, bsdfData.roughness) * bsdfData.energyCompensation;\n}\n\nvoid sheenLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= bsdfData.sheenScaling;\n specularColor *= bsdfData.sheenScaling;\n\n specularColor += attenuationIrradiance * sheenBRDF(incidentDirection, surfaceData, surfaceData.sheenColor, bsdfData.sheenRoughness);\n #endif\n}\n\nfloat clearCoatLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 color, inout vec3 specularColor){\n float attenuation = 1.0;\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n float clearCoatDotNL = saturate( dot( surfaceData.clearCoatNormal, incidentDirection ) );\n vec3 clearCoatIrradiance = clearCoatDotNL * color;\n\n specularColor += surfaceData.clearCoat * clearCoatIrradiance * BRDF_Specular_GGX( incidentDirection, surfaceData, bsdfData, surfaceData.clearCoatNormal, bsdfData.clearCoatSpecularColor, bsdfData.clearCoatRoughness );\n attenuation -= surfaceData.clearCoat * F_Schlick(0.04, 1.0, surfaceData.clearCoatDotNV);\n #endif\n\n return attenuation;\n}\n\n#endif";
|
|
44
|
+
|
|
45
|
+
var PBR_Refraction = "#ifndef REFRACTION_INCLUDED\n#define REFRACTION_INCLUDED\n\n#ifdef MATERIAL_ENABLE_TRANSMISSION \n\nstruct RefractionModelResult{\n float transmissionLength; // length of the transmission during refraction through the shape\n vec3 positionExit; // out ray position\n // vec3 directionExit; // out ray direction\n};\n\n//https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html\n void refractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){\n // Refracted ray\n vec3 R1 = refract(V, normalWS, 1.0 / ior);\n // Center of the tangent sphere\n // vec3 C = positionWS - normalWS * thickness * 0.5;\n\n // Second refraction (tangent sphere out)\n float dist = dot(-normalWS, R1) * thickness;\n // Out hit point in the tangent sphere\n vec3 P1 = positionWS + R1 * dist;\n // Out normal\n // vec3 N1 = safeNormalize(C - P1);\n // Out refracted ray\n // vec3 R2 = refract(R1, N1, ior);\n\n ray.transmissionLength = dist;\n ray.positionExit = P1;\n // ray.directionExit = R2; \n}\n\nvoid refractionModelPlanar(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray){\n // Refracted ray\n vec3 R = refract(V, normalWS, 1.0 / ior);\n // Optical depth within the thin plane\n float dist = thickness / max(dot(-normalWS, R), 1e-5f);\n\n ray.transmissionLength = dist;\n ray.positionExit = vec3(positionWS + R * dist);\n // ray.directionExit = V;\n}\n#endif\n\n#endif";
|
|
46
|
+
|
|
47
|
+
var PBR_VaryingsPBR = "#ifndef VARYINGS_PBR_INCLUDED\n#define VARYINGS_PBR_INCLUDED\n\nstruct Varyings{\n\tvec2 uv;\n\t#ifdef RENDERER_HAS_UV1\n\t vec2 uv1;\n\t#endif\n\n\t#ifdef RENDERER_ENABLE_VERTEXCOLOR\n \t\tvec4 vertexColor;\n\t#endif\n\n\tvec3 positionWS;\n\n\t#if SCENE_FOG_MODE != 0\n\t vec3 positionVS;\n\t#endif\n\n\t#ifdef RENDERER_HAS_NORMAL\n\t vec3 normalWS;\n\t #ifdef NEED_VERTEX_TANGENT\n\t\t\tvec3 tangentWS;\n\t\t\tvec3 bitangentWS;\n\t #endif\n\t#endif\n\n\n\t#if defined(NEED_CALCULATE_SHADOWS) && (SCENE_SHADOW_CASCADED_COUNT == 1)\n\t vec3 shadowCoord;\n\t#endif\n\n vec4 positionCS;\n};\n\n\n#endif";
|
|
48
|
+
|
|
49
|
+
var PBR_VertexPBR = "#ifndef VERTEX_INCLUDE\n#define VERTEX_INCLUDE\n\nstruct VertexInputs{\n vec4 positionOS;\n vec3 positionWS;\n\n #if SCENE_FOG_MODE != 0\n vec3 positionVS;\n #endif\n\n #ifdef RENDERER_HAS_NORMAL\n vec3 normalWS;\n #ifdef NEED_VERTEX_TANGENT\n vec3 tangentWS;\n vec3 bitangentWS;\n #endif\n #endif\n};\n\nvec4 material_TilingOffset;\nvec2 getUV0(Attributes attributes){\n vec2 uv0 = vec2(0);\n\n #ifdef RENDERER_HAS_UV\n uv0 = attributes.TEXCOORD_0;\n #endif\n\n return uv0 * material_TilingOffset.xy + material_TilingOffset.zw;\n}\n\nVertexInputs getVertexInputs(Attributes attributes){\n VertexInputs inputs;\n vec4 position = vec4(attributes.POSITION, 1.0);\n\n // tangent must follow RENDERER_HAS_TANGENT here so the call site stays in\n // sync with calculateBlendShape's signature (which is gated on the same\n // mesh-attribute macro). Downstream worldspace projection + varying writes\n // are separately gated on NEED_VERTEX_TANGENT below.\n #ifdef RENDERER_HAS_NORMAL\n vec3 normal = vec3( attributes.NORMAL );\n #ifdef RENDERER_HAS_TANGENT\n vec4 tangent = vec4( attributes.TANGENT );\n #endif\n #endif\n\n\n // BlendShape\n #ifdef RENDERER_HAS_BLENDSHAPE\n calculateBlendShape(attributes, position\n #ifdef RENDERER_HAS_NORMAL\n ,normal\n #ifdef RENDERER_HAS_TANGENT\n ,tangent\n #endif\n #endif\n );\n #endif\n\n // Skin\n #ifdef RENDERER_HAS_SKIN\n mat4 skinMatrix = getSkinMatrix(attributes);\n position = skinMatrix * position;\n\n #if defined(RENDERER_HAS_NORMAL) && !defined(MATERIAL_OMIT_NORMAL)\n mat3 skinNormalMatrix = INVERSE_MAT(mat3(skinMatrix));\n normal = normal * skinNormalMatrix;\n #ifdef NEED_VERTEX_TANGENT\n tangent.xyz = tangent.xyz * skinNormalMatrix;\n #endif\n #endif\n #endif\n\n // TBN world space\n #if defined(RENDERER_HAS_NORMAL) && !defined(MATERIAL_OMIT_NORMAL)\n inputs.normalWS = normalize( mat3(renderer_NormalMat) * normal );\n\n #ifdef NEED_VERTEX_TANGENT\n vec3 tangentWS = normalize( mat3(renderer_NormalMat) * tangent.xyz );\n vec3 bitangentWS = cross( inputs.normalWS, tangentWS ) * tangent.w;\n\n inputs.tangentWS = tangentWS;\n inputs.bitangentWS = bitangentWS;\n #endif\n #endif\n\n\n inputs.positionOS = position;\n vec4 positionWS = renderer_ModelMat * position;\n inputs.positionWS = positionWS.xyz / positionWS.w;\n\n #if SCENE_FOG_MODE != 0\n vec4 positionVS = renderer_MVMat * position;\n inputs.positionVS = positionVS.xyz / positionVS.w;\n #endif\n\n return inputs;\n}\n\n#endif";
|
|
50
|
+
|
|
51
|
+
var Particle_Billboard_HorizontalBillboard = "#ifndef HORIZONTAL_BILLBOARD_INCLUDED\n#define HORIZONTAL_BILLBOARD_INCLUDED\n\n#ifdef RENDERER_MODE_HORIZONTAL_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tconst vec3 sideVector = vec3(1.0, 0.0, 0.0);\n\tconst vec3 upVector = vec3(0.0, 0.0, -1.0);\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\n\t// HorizontalBillboard rotates in XZ plane (around Y-axis normal).\n\t// Uses Z-axis rotation data to match Unity behavior.\n\tfloat rot;\n\tif (renderer_ThreeDStartRotation) {\n\t\trot = radians(computeParticleRotationFloat(a_StartRotation0.z, age, normalizedAge));\n\t} else {\n\t\trot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n\t}\n\n\tfloat c = cos(rot);\n\tfloat s = sin(rot);\n\tmat2 rotation = mat2(c, -s, s, c);\n\tcorner = rotation * corner;\n\tcenter += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n#endif\n\n#endif\n";
|
|
52
|
+
|
|
53
|
+
var Particle_Billboard_SphereBillboard = "#ifndef SPHERE_BILLBOARD_INCLUDED\n#define SPHERE_BILLBOARD_INCLUDED\n\n#ifdef RENDERER_MODE_SPHERE_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tvec3 sideVector = normalize(cross(camera_Forward, camera_Up));\n\tvec3 upVector = normalize(cross(sideVector, camera_Forward));\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n if (renderer_ThreeDStartRotation) {\n vec3 rotation = radians(vec3(a_StartRotation0.xy, computeParticleRotationFloat(a_StartRotation0.z, age, normalizedAge)));\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, rotation);\n } else {\n float rot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n float c = cos(rot);\n float s = sin(rot);\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #else\n if (renderer_ThreeDStartRotation) {\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, radians(a_StartRotation0));\n } else {\n float c = cos(radians(a_StartRotation0.x));\n float s = sin(radians(a_StartRotation0.x));\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #endif\n#endif\n\n#endif\n";
|
|
54
|
+
|
|
55
|
+
var Particle_Billboard_StretchedBillboard = "#ifndef STRETCHED_BILLBOARD_INCLUDED\n#define STRETCHED_BILLBOARD_INCLUDED\n\n#ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tvec3 velocity = rotationByQuaternions(renderer_SizeScale * localVelocity, worldRotation) + worldVelocity;\n\tvec3 cameraUpVector = normalize(velocity);\n\tvec3 direction = normalize(center - camera_Position);\n\tvec3 sideVector = normalize(cross(direction, normalize(velocity)));\n\n\tsideVector = renderer_SizeScale.xzy * sideVector;\n\tcameraUpVector = length(vec3(renderer_SizeScale.x, 0.0, 0.0)) * cameraUpVector;\n\n\tvec2 size = computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\n\tconst mat2 rotationZHalfPI = mat2(0.0, -1.0, 1.0, 0.0);\n\tcorner = rotationZHalfPI * corner;\n\tcorner.y = corner.y - abs(corner.y);\n\n\tfloat speed = length(velocity); // TODO:\n\tcenter += sign(renderer_SizeScale.x) * (sign(renderer_StretchedBillboardLengthScale) * size.x * corner.x * sideVector\n\t + (speed * renderer_StretchedBillboardSpeedScale + size.y * renderer_StretchedBillboardLengthScale) * corner.y * cameraUpVector);\n#endif\n\n#endif\n";
|
|
56
|
+
|
|
57
|
+
var Particle_Billboard_VerticalBillboard = "#ifndef VERTICAL_BILLBOARD_INCLUDED\n#define VERTICAL_BILLBOARD_INCLUDED\n\n#ifdef RENDERER_MODE_VERTICAL_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy; // Billboard模式z轴无效\n\tconst vec3 cameraUpVector = vec3(0.0, 1.0, 0.0);\n\tvec3 sideVector = normalize(cross(camera_Forward, cameraUpVector));\n\n\tfloat rot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n\tfloat c = cos(rot);\n\tfloat s = sin(rot);\n\tmat2 rotation = mat2(c, -s, s, c);\n\tcorner = rotation * corner * cos(0.78539816339744830961566084581988); // TODO:临时缩小cos45,不确定U3D原因\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\tcenter += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * cameraUpVector);\n#endif\n\n#endif\n";
|
|
58
|
+
|
|
59
|
+
var Particle_Module_ColorOverLifetime = "#ifndef COLOR_OVER_LIFETIME_INCLUDED\n#define COLOR_OVER_LIFETIME_INCLUDED\n\n#if defined(RENDERER_COL_GRADIENT) || defined(RENDERER_COL_RANDOM_GRADIENTS)\n vec4 renderer_COLMaxGradientColor[4]; // x:time y:r z:g w:b\n vec2 renderer_COLMaxGradientAlpha[4]; // x:time y:alpha\n\n #ifdef RENDERER_COL_RANDOM_GRADIENTS\n vec4 renderer_COLMinGradientColor[4]; // x:time y:r z:g w:b\n vec2 renderer_COLMinGradientAlpha[4]; // x:time y:alpha\n #endif\n\n vec4 renderer_COLGradientKeysMaxTime; // x: minColorKeysMaxTime, y: minAlphaKeysMaxTime, z: maxColorKeysMaxTime, w: maxAlphaKeysMaxTime\n#endif\n\n\nvec4 computeParticleColor(Attributes attributes, in vec4 color, in float normalizedAge) {\n #if defined(RENDERER_COL_GRADIENT) || defined(RENDERER_COL_RANDOM_GRADIENTS)\n vec4 gradientColor = evaluateParticleGradient(renderer_COLMaxGradientColor, renderer_COLGradientKeysMaxTime.z, renderer_COLMaxGradientAlpha, renderer_COLGradientKeysMaxTime.w, normalizedAge);\n #endif\n\n #ifdef RENDERER_COL_RANDOM_GRADIENTS\n gradientColor = mix(evaluateParticleGradient(renderer_COLMinGradientColor,renderer_COLGradientKeysMaxTime.x, renderer_COLMinGradientAlpha, renderer_COLGradientKeysMaxTime.y, normalizedAge), gradientColor, attributes.a_Random0.y);\n #endif\n\n #if defined(RENDERER_COL_GRADIENT) || defined(RENDERER_COL_RANDOM_GRADIENTS)\n color *= gradientColor;\n #endif\n\n return color;\n}\n\n#endif\n";
|
|
60
|
+
|
|
61
|
+
var Particle_Module_ForceOverLifetime = "#ifndef FORCE_OVER_LIFETIME_INCLUDED\n#define FORCE_OVER_LIFETIME_INCLUDED\n\n#if defined(RENDERER_FOL_CONSTANT_MODE) || defined(RENDERER_FOL_CURVE_MODE)\n #define _FOL_MODULE_ENABLED\n#endif\n\n#ifdef _FOL_MODULE_ENABLED\n int renderer_FOLSpace;\n\n #ifdef RENDERER_FOL_CONSTANT_MODE\n vec3 renderer_FOLMaxConst;\n\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 renderer_FOLMinConst;\n #endif\n\n #endif\n\n #ifdef RENDERER_FOL_CURVE_MODE\n vec2 renderer_FOLMaxGradientX[4];\n vec2 renderer_FOLMaxGradientY[4];\n vec2 renderer_FOLMaxGradientZ[4];\n\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec2 renderer_FOLMinGradientX[4];\n vec2 renderer_FOLMinGradientY[4];\n vec2 renderer_FOLMinGradientZ[4];\n #endif\n #endif\n\n // (tHat - t1) * (tHat - t1) * (tHat - t1) * (a2 - a1) / ((t2 - t1) * 6.0) + a1 * (tHat - t1) * (tHat - t1) * 0.5 + v1 * (tHat - t1);\n // to = tHat - t1; tr = t2 - t1\n float computeDisplacementIntegral(in float to, in float tr, in float a1, in float a2, in float v1) {\n return to * to * to * (a2 - a1) / (tr * 6.0) + a1 * to * to * 0.5 + v1 * to;\n }\n\n float evaluateForceParticleCurveCumulative(Attributes attributes, in vec2 keys[4], in float normalizedAge, out float velocityCumulative) {\n float cumulativeValue = 0.0;\n velocityCumulative = 0.0;\n\n for (int i = 1; i < 4; i++){\n vec2 key = keys[i];\n vec2 lastKey = keys[i - 1];\n float timeRange = (key.x - lastKey.x) * attributes.a_ShapePositionStartLifeTime.w;\n\n if (key.x >= normalizedAge){\n float timeOffset = (normalizedAge - lastKey.x) * attributes.a_ShapePositionStartLifeTime.w;\n cumulativeValue += computeDisplacementIntegral(timeOffset, timeRange, lastKey.y, key.y, velocityCumulative);\n\n float finalAcceleration = mix(lastKey.y, key.y, timeOffset / timeRange);\n velocityCumulative += 0.5 * timeOffset * (finalAcceleration + lastKey.y);\n break;\n } else {\n cumulativeValue += computeDisplacementIntegral(timeRange, timeRange, lastKey.y, key.y, velocityCumulative);\n velocityCumulative += 0.5 * timeRange * (lastKey.y + key.y);\n }\n }\n return cumulativeValue;\n }\n\n vec3 computeForcePositionOffset(Attributes attributes, in float normalizedAge, in float age, out vec3 velocityOffset) {\n vec3 forcePosition;\n\n #if defined(RENDERER_FOL_CONSTANT_MODE)\n vec3 forceAcceleration = renderer_FOLMaxConst;\n\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n forceAcceleration = mix(renderer_FOLMinConst, forceAcceleration, vec3(attributes.a_Random2.x, attributes.a_Random2.y, attributes.a_Random2.z));\n #endif\n\n velocityOffset = forceAcceleration * age;\n\n forcePosition = 0.5 * forceAcceleration * age * age;\n #elif defined(RENDERER_FOL_CURVE_MODE)\n forcePosition = vec3(\n evaluateForceParticleCurveCumulative(attributes, renderer_FOLMaxGradientX, normalizedAge, velocityOffset.x),\n evaluateForceParticleCurveCumulative(attributes, renderer_FOLMaxGradientY, normalizedAge, velocityOffset.y),\n evaluateForceParticleCurveCumulative(attributes, renderer_FOLMaxGradientZ, normalizedAge, velocityOffset.z)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minVelocityOffset;\n\n forcePosition = vec3(\n mix(evaluateForceParticleCurveCumulative(attributes, renderer_FOLMinGradientX, normalizedAge, minVelocityOffset.x), forcePosition.x, attributes.a_Random2.x),\n mix(evaluateForceParticleCurveCumulative(attributes, renderer_FOLMinGradientY, normalizedAge, minVelocityOffset.y), forcePosition.y, attributes.a_Random2.y),\n mix(evaluateForceParticleCurveCumulative(attributes, renderer_FOLMinGradientZ, normalizedAge, minVelocityOffset.z), forcePosition.z, attributes.a_Random2.z)\n );\n\n velocityOffset = mix(minVelocityOffset, velocityOffset, vec3(attributes.a_Random2.x, attributes.a_Random2.y, attributes.a_Random2.z));\n #endif\n #endif\n return forcePosition;\n }\n#endif\n\n#endif\n";
|
|
62
|
+
|
|
63
|
+
var Particle_Module_LimitVelocityOverLifetime = "#ifndef LIMIT_VELOCITY_OVER_LIFETIME_INCLUDED\n#define LIMIT_VELOCITY_OVER_LIFETIME_INCLUDED\n\n#ifdef RENDERER_LVL_MODULE_ENABLED\n int renderer_LVLSpace;\n float renderer_LVLDampen;\n\n // Scalar limit\n #ifndef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n float renderer_LVLSpeedMaxConst;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n float renderer_LVLSpeedMinConst;\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n vec2 renderer_LVLSpeedMaxCurve[4];\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n vec2 renderer_LVLSpeedMinCurve[4];\n #endif\n #endif\n #endif\n\n // Per-axis limit\n #ifdef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n vec3 renderer_LVLSpeedMaxConstVector;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n vec3 renderer_LVLSpeedMinConstVector;\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n vec2 renderer_LVLSpeedXMaxCurve[4];\n vec2 renderer_LVLSpeedYMaxCurve[4];\n vec2 renderer_LVLSpeedZMaxCurve[4];\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n vec2 renderer_LVLSpeedXMinCurve[4];\n vec2 renderer_LVLSpeedYMinCurve[4];\n vec2 renderer_LVLSpeedZMinCurve[4];\n #endif\n #endif\n #endif\n\n // Drag curve\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n vec2 renderer_LVLDragMaxCurve[4];\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n vec2 renderer_LVLDragMinCurve[4];\n #endif\n #endif\n\n float evaluateLVLDrag(float normalizedAge, float dragRand) {\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n float dragMax = evaluateParticleCurve(renderer_LVLDragMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n float dragMin = evaluateParticleCurve(renderer_LVLDragMinCurve, normalizedAge);\n return mix(dragMin, dragMax, dragRand);\n #else\n return dragMax;\n #endif\n #else\n return mix(renderer_LVLDragConstant.x, renderer_LVLDragConstant.y, dragRand);\n #endif\n }\n\n vec3 applyLVLSpeedLimitTF(vec3 velocity, float normalizedAge, float limitRand, float effectiveDampen) {\n #ifdef RENDERER_LVL_SEPARATE_AXES\n vec3 limitSpeed;\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n limitSpeed = renderer_LVLSpeedMaxConstVector;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n limitSpeed = mix(renderer_LVLSpeedMinConstVector, limitSpeed, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n limitSpeed = vec3(\n evaluateParticleCurve(renderer_LVLSpeedXMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedYMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedZMaxCurve, normalizedAge)\n );\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n vec3 minLimitSpeed = vec3(\n evaluateParticleCurve(renderer_LVLSpeedXMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedYMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedZMinCurve, normalizedAge)\n );\n limitSpeed = mix(minLimitSpeed, limitSpeed, limitRand);\n #endif\n #endif\n\n vec3 absVel = abs(velocity);\n vec3 excess = max(absVel - limitSpeed, vec3(0.0));\n velocity = sign(velocity) * (absVel - excess * effectiveDampen);\n #else\n float limitSpeed;\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n limitSpeed = renderer_LVLSpeedMaxConst;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n limitSpeed = mix(renderer_LVLSpeedMinConst, limitSpeed, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n limitSpeed = evaluateParticleCurve(renderer_LVLSpeedMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n float minLimitSpeed = evaluateParticleCurve(renderer_LVLSpeedMinCurve, normalizedAge);\n limitSpeed = mix(minLimitSpeed, limitSpeed, limitRand);\n #endif\n #endif\n\n float speed = length(velocity);\n if (speed > limitSpeed && speed > 0.0) {\n float excess = speed - limitSpeed;\n velocity = velocity * ((speed - excess * effectiveDampen) / speed);\n }\n #endif\n return velocity;\n }\n\n#endif\n\n#endif\n";
|
|
64
|
+
|
|
65
|
+
var Particle_Module_NoiseModule = "#ifndef NOISE_MODULE_INCLUDED\n#define NOISE_MODULE_INCLUDED\n\n#ifdef RENDERER_NOISE_MODULE_ENABLED\n\n#include \"ShaderLibrary/Noise/NoiseCommon.glsl\"\n#include \"ShaderLibrary/Noise/NoiseSimplexGrad.glsl\"\n\nvec4 renderer_NoiseParams; // xyz = strength (constant mode only), w = frequency\nvec4 renderer_NoiseOctaveParams; // x = scrollSpeed, y = octaveCount, z = octaveIntensityMultiplier, w = octaveFrequencyMultiplier\n\n#ifdef RENDERER_NOISE_STRENGTH_CURVE\n vec2 renderer_NoiseStrengthMaxCurveX[4];\n #ifdef RENDERER_NOISE_IS_SEPARATE\n vec2 renderer_NoiseStrengthMaxCurveY[4];\n vec2 renderer_NoiseStrengthMaxCurveZ[4];\n #endif\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n vec2 renderer_NoiseStrengthMinCurveX[4];\n #ifdef RENDERER_NOISE_IS_SEPARATE\n vec2 renderer_NoiseStrengthMinCurveY[4];\n vec2 renderer_NoiseStrengthMinCurveZ[4];\n #endif\n #endif\n#else\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n vec3 renderer_NoiseStrengthMinConst;\n #endif\n#endif\n\nvec3 sampleCurlNoise3D(vec3 coord) {\n float axisOffset = 100.0;\n vec3 gradX = simplexGrad(vec3(coord.z, coord.y, coord.x));\n vec3 gradY = simplexGrad(vec3(coord.x + axisOffset, coord.z, coord.y));\n vec3 gradZ = simplexGrad(vec3(coord.y, coord.x + axisOffset, coord.z));\n return vec3(\n gradZ.x - gradY.y,\n gradX.x - gradZ.y,\n gradY.x - gradX.y\n );\n}\n\nvec3 computeNoiseVelocity(Attributes attributes, vec3 currentPosition, float normalizedAge) {\n vec3 coord = currentPosition * renderer_NoiseParams.w\n + vec3(renderer_CurrentTime * renderer_NoiseOctaveParams.x);\n\n int octaveCount = int(renderer_NoiseOctaveParams.y);\n float octaveIntensityMultiplier = renderer_NoiseOctaveParams.z;\n float octaveFrequencyMultiplier = renderer_NoiseOctaveParams.w;\n\n vec3 noiseValue = sampleCurlNoise3D(coord);\n float totalAmplitude = 1.0;\n\n // Unrolled octave loop (GLSL ES 1.0 requires constant loop bounds)\n if (octaveCount >= 2) {\n float amplitude = octaveIntensityMultiplier;\n totalAmplitude += amplitude;\n noiseValue += amplitude * sampleCurlNoise3D(coord * octaveFrequencyMultiplier);\n\n if (octaveCount >= 3) {\n amplitude *= octaveIntensityMultiplier;\n totalAmplitude += amplitude;\n noiseValue += amplitude * sampleCurlNoise3D(coord * octaveFrequencyMultiplier * octaveFrequencyMultiplier);\n }\n }\n\n // Evaluate strength (supports Constant, TwoConstants, Curve, TwoCurves).\n vec3 strength;\n #ifdef RENDERER_NOISE_STRENGTH_CURVE\n float sx = evaluateParticleCurve(renderer_NoiseStrengthMaxCurveX, normalizedAge);\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n sx = mix(evaluateParticleCurve(renderer_NoiseStrengthMinCurveX, normalizedAge), sx, attributes.a_Random0.z);\n #endif\n #ifdef RENDERER_NOISE_IS_SEPARATE\n float sy = evaluateParticleCurve(renderer_NoiseStrengthMaxCurveY, normalizedAge);\n float sz = evaluateParticleCurve(renderer_NoiseStrengthMaxCurveZ, normalizedAge);\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n sy = mix(evaluateParticleCurve(renderer_NoiseStrengthMinCurveY, normalizedAge), sy, attributes.a_Random0.z);\n sz = mix(evaluateParticleCurve(renderer_NoiseStrengthMinCurveZ, normalizedAge), sz, attributes.a_Random0.z);\n #endif\n strength = vec3(sx, sy, sz);\n #else\n strength = vec3(sx);\n #endif\n #else\n strength = renderer_NoiseParams.xyz;\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n strength = mix(renderer_NoiseStrengthMinConst, strength, attributes.a_Random0.z);\n #endif\n #endif\n\n return (noiseValue / totalAmplitude) * strength;\n}\n\n#endif\n\n#endif // NOISE_MODULE_INCLUDED\n";
|
|
66
|
+
|
|
67
|
+
var Particle_Module_RotationOverLifetime = "#ifndef ROTATION_OVER_LIFETIME_INCLUDED\n#define ROTATION_OVER_LIFETIME_INCLUDED\n\n#if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #ifdef RENDERER_ROL_CURVE_MODE\n vec2 renderer_ROLMaxCurveZ[4];\n #ifdef RENDERER_ROL_IS_SEPARATE\n vec2 renderer_ROLMaxCurveX[4];\n vec2 renderer_ROLMaxCurveY[4];\n #endif\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n vec2 renderer_ROLMinCurveZ[4];\n #ifdef RENDERER_ROL_IS_SEPARATE\n vec2 renderer_ROLMinCurveX[4];\n vec2 renderer_ROLMinCurveY[4];\n #endif\n #endif\n #else\n vec3 renderer_ROLMaxConst;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n vec3 renderer_ROLMinConst;\n #endif\n #endif\n#endif\n\nfloat computeParticleRotationFloat(Attributes attributes, in float rotation, in float age, in float normalizedAge) {\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #ifdef RENDERER_ROL_CURVE_MODE\n float currentValue;\n float lifeRotation = evaluateParticleCurveCumulative(renderer_ROLMaxCurveZ, normalizedAge, currentValue);\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveZ, normalizedAge, currentValue), lifeRotation, attributes.a_Random0.w);\n #endif\n rotation += lifeRotation * attributes.a_ShapePositionStartLifeTime.w;\n #else\n float lifeRotation = renderer_ROLMaxConst.z;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(renderer_ROLMinConst.z, lifeRotation, attributes.a_Random0.w);\n #endif\n rotation += lifeRotation * age;\n #endif\n #endif\n return rotation;\n}\n\n\n#if defined(RENDERER_MODE_MESH) && (defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE))\nvec3 computeParticleRotationVec3(Attributes attributes, in vec3 rotation, in float age, in float normalizedAge) {\n #ifdef RENDERER_ROL_IS_SEPARATE\n #ifdef RENDERER_ROL_CONSTANT_MODE\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n vec3 ageRot = mix(renderer_ROLMinConst, renderer_ROLMaxConst, attributes.a_Random0.w) * age;\n #else\n vec3 ageRot = renderer_ROLMaxConst * age;\n #endif\n rotation += ageRot;\n #endif\n #ifdef RENDERER_ROL_CURVE_MODE\n float currentValue;\n float lifetime = attributes.a_ShapePositionStartLifeTime.w;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n rotation += vec3(\n mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveX, normalizedAge, currentValue),\n evaluateParticleCurveCumulative(renderer_ROLMaxCurveX, normalizedAge, currentValue), attributes.a_Random0.w),\n mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveY, normalizedAge, currentValue),\n evaluateParticleCurveCumulative(renderer_ROLMaxCurveY, normalizedAge, currentValue), attributes.a_Random0.w),\n mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveZ, normalizedAge, currentValue),\n evaluateParticleCurveCumulative(renderer_ROLMaxCurveZ, normalizedAge, currentValue), attributes.a_Random0.w)) * lifetime;\n #else\n rotation += vec3(\n evaluateParticleCurveCumulative(renderer_ROLMaxCurveX, normalizedAge, currentValue),\n evaluateParticleCurveCumulative(renderer_ROLMaxCurveY, normalizedAge, currentValue),\n evaluateParticleCurveCumulative(renderer_ROLMaxCurveZ, normalizedAge, currentValue)) * lifetime;\n #endif\n #endif\n #else\n #ifdef RENDERER_ROL_CONSTANT_MODE\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n float ageRot = mix(renderer_ROLMinConst.z, renderer_ROLMaxConst.z, attributes.a_Random0.w) * age;\n #else\n float ageRot = renderer_ROLMaxConst.z * age;\n #endif\n rotation += ageRot;\n #endif\n\n #ifdef RENDERER_ROL_CURVE_MODE\n float currentValue;\n float lifeRotation = evaluateParticleCurveCumulative(renderer_ROLMaxCurveZ, normalizedAge, currentValue);\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveZ, normalizedAge, currentValue), lifeRotation, attributes.a_Random0.w);\n #endif\n rotation += lifeRotation * attributes.a_ShapePositionStartLifeTime.w;\n #endif\n #endif\n return rotation;\n}\n#endif\n\n#endif\n";
|
|
68
|
+
|
|
69
|
+
var Particle_Module_SizeOverLifetime = "#ifndef SIZE_OVER_LIFETIME_INCLUDED\n#define SIZE_OVER_LIFETIME_INCLUDED\n\n#ifdef RENDERER_SOL_CURVE_MODE\n vec2 renderer_SOLMaxCurveX[4]; // x:time y:value\n #ifdef RENDERER_SOL_IS_SEPARATE\n vec2 renderer_SOLMaxCurveY[4]; // x:time y:value\n vec2 renderer_SOLMaxCurveZ[4]; // x:time y:value\n #endif\n\n #ifdef RENDERER_SOL_IS_RANDOM_TWO\n vec2 renderer_SOLMinCurveX[4]; // x:time y:value\n #ifdef RENDERER_SOL_IS_SEPARATE\n vec2 renderer_SOLMinCurveY[4]; // x:time y:value\n vec2 renderer_SOLMinCurveZ[4]; // x:time y:value\n #endif\n #endif\n#endif\n\nvec2 computeParticleSizeBillboard(Attributes attributes, in vec2 size, in float normalizedAge) {\n #ifdef RENDERER_SOL_CURVE_MODE\n float lifeSizeX = evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge);\n #ifdef RENDERER_SOL_IS_RANDOM_TWO\n lifeSizeX = mix(evaluateParticleCurve(renderer_SOLMinCurveX, normalizedAge), lifeSizeX, attributes.a_Random0.z);\n #endif\n\n #ifdef RENDERER_SOL_IS_SEPARATE\n float lifeSizeY = evaluateParticleCurve(renderer_SOLMaxCurveY, normalizedAge);\n #ifdef RENDERER_SOL_IS_RANDOM_TWO\n lifeSizeY = mix(evaluateParticleCurve(renderer_SOLMinCurveY, normalizedAge), lifeSizeY, attributes.a_Random0.z);\n #endif\n size *= vec2(lifeSizeX, lifeSizeY);\n #else\n size *= lifeSizeX;\n #endif\n #endif\n return size;\n}\n\n#ifdef RENDERER_MODE_MESH\n vec3 computeParticleSizeMesh(Attributes attributes, in vec3 size, in float normalizedAge) {\n #ifdef RENDERER_SOL_CURVE\n size *= evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge);\n #endif\n #ifdef RENDERER_SOL_RANDOM_CURVES\n size *= mix(evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge),\n evaluateParticleCurve(u_SOLSizeGradientMax, normalizedAge),\n attributes.a_Random0.z);\n #endif\n #ifdef RENDERER_SOL_CURVE_SEPARATE\n size *= vec3(evaluateParticleCurve(renderer_SOLMinCurveX, normalizedAge),\n evaluateParticleCurve(renderer_SOLMinCurveY, normalizedAge),\n evaluateParticleCurve(renderer_SOLMinCurveZ, normalizedAge));\n #endif\n #ifdef RENDERER_SOL_RANDOM_CURVES_SEPARATE\n size *= vec3(mix(evaluateParticleCurve(renderer_SOLMinCurveX, normalizedAge),\n evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge),\n attributes.a_Random0.z),\n mix(evaluateParticleCurve(renderer_SOLMinCurveY, normalizedAge),\n evaluateParticleCurve(renderer_SOLMaxCurveY, normalizedAge),\n attributes.a_Random0.z),\n mix(evaluateParticleCurve(renderer_SOLMinCurveZ, normalizedAge),\n evaluateParticleCurve(renderer_SOLMaxCurveZ, normalizedAge),\n attributes.a_Random0.z));\n #endif\n return size;\n }\n#endif\n\n#endif\n";
|
|
70
|
+
|
|
71
|
+
var Particle_Module_TextureSheetAnimation = "#ifndef TEXTURE_SHEET_ANIMATION_INCLUDED\n#define TEXTURE_SHEET_ANIMATION_INCLUDED\n\n#if defined(RENDERER_TSA_FRAME_CURVE) || defined(RENDERER_TSA_FRAME_RANDOM_CURVES)\n float renderer_TSACycles;\n vec3 renderer_TSATillingParams; // x:subU y:subV z:tileCount\n vec2 renderer_TSAFrameMaxCurve[4]; // x:time y:value\n\n #ifdef RENDERER_TSA_FRAME_RANDOM_CURVES\n vec2 renderer_TSAFrameMinCurve[4]; // x:time y:value\n #endif\n#endif\n\nvec2 computeParticleUV(Attributes attributes, in vec2 uv, in float normalizedAge) {\n #if defined(RENDERER_TSA_FRAME_CURVE) || defined(RENDERER_TSA_FRAME_RANDOM_CURVES)\n float scaledNormalizedAge = normalizedAge * renderer_TSACycles;\n float cycleNormalizedAge = scaledNormalizedAge - floor(scaledNormalizedAge);\n float normalizedFrame = evaluateParticleCurve(renderer_TSAFrameMaxCurve, cycleNormalizedAge);\n #ifdef RENDERER_TSA_FRAME_RANDOM_CURVES\n normalizedFrame = mix(evaluateParticleCurve(renderer_TSAFrameMinCurve, cycleNormalizedAge), normalizedFrame, attributes.a_Random1.x);\n #endif\n\n float frame = floor(normalizedFrame * renderer_TSATillingParams.z);\n\n float tileRow = frame * renderer_TSATillingParams.x;\n float tileRowIndex = floor(tileRow);\n uv.x += tileRow - tileRowIndex;\n uv.y += tileRowIndex * renderer_TSATillingParams.y;\n #endif\n\n return uv;\n}\n\n#endif\n";
|
|
72
|
+
|
|
73
|
+
var Particle_Module_VelocityOverLifetime = "#ifndef VELOCITY_OVER_LIFETIME_INCLUDED\n#define VELOCITY_OVER_LIFETIME_INCLUDED\n\n#if defined(RENDERER_VOL_CONSTANT_MODE) || defined(RENDERER_VOL_CURVE_MODE)\n #define _VOL_MODULE_ENABLED\n#endif\n\n#ifdef _VOL_MODULE_ENABLED\n int renderer_VOLSpace;\n\n #ifdef RENDERER_VOL_CONSTANT_MODE\n vec3 renderer_VOLMaxConst;\n\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 renderer_VOLMinConst;\n #endif\n #endif\n\n #ifdef RENDERER_VOL_CURVE_MODE\n vec2 renderer_VOLMaxGradientX[4]; // x:time y:value\n vec2 renderer_VOLMaxGradientY[4]; // x:time y:value\n vec2 renderer_VOLMaxGradientZ[4]; // x:time y:value\n\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec2 renderer_VOLMinGradientX[4]; // x:time y:value\n vec2 renderer_VOLMinGradientY[4]; // x:time y:value\n vec2 renderer_VOLMinGradientZ[4]; // x:time y:value\n #endif\n #endif\n\n\n vec3 computeVelocityPositionOffset(Attributes attributes, in float normalizedAge, in float age, out vec3 currentVelocity) {\n vec3 velocityPosition;\n\n #ifdef RENDERER_VOL_CONSTANT_MODE\n currentVelocity = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n currentVelocity = mix(renderer_VOLMinConst, currentVelocity, attributes.a_Random1.yzw);\n #endif\n\n velocityPosition = currentVelocity * age;\n #endif\n\n #ifdef RENDERER_VOL_CURVE_MODE\n velocityPosition = vec3(\n evaluateParticleCurveCumulative(renderer_VOLMaxGradientX, normalizedAge, currentVelocity.x),\n evaluateParticleCurveCumulative(renderer_VOLMaxGradientY, normalizedAge, currentVelocity.y),\n evaluateParticleCurveCumulative(renderer_VOLMaxGradientZ, normalizedAge, currentVelocity.z));\n\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minCurrentVelocity;\n vec3 minVelocityPosition = vec3(\n evaluateParticleCurveCumulative(renderer_VOLMinGradientX, normalizedAge, minCurrentVelocity.x),\n evaluateParticleCurveCumulative(renderer_VOLMinGradientY, normalizedAge, minCurrentVelocity.y),\n evaluateParticleCurveCumulative(renderer_VOLMinGradientZ, normalizedAge, minCurrentVelocity.z));\n\n currentVelocity = mix(minCurrentVelocity, currentVelocity, attributes.a_Random1.yzw);\n velocityPosition = mix(minVelocityPosition, velocityPosition, attributes.a_Random1.yzw);\n #endif\n\n velocityPosition *= vec3(attributes.a_ShapePositionStartLifeTime.w);\n #endif\n return velocityPosition;\n }\n#endif\n\n#endif\n";
|
|
74
|
+
|
|
75
|
+
var Particle_ParticleCommon = "#ifndef PARTICLE_COMMON_INCLUDED\n#define PARTICLE_COMMON_INCLUDED\n\nvec3 rotationByQuaternions(in vec3 v, in vec4 q) {\n return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n\nvec4 quaternionConjugate(in vec4 q) {\n return vec4(-q.xyz, q.w);\n}\n\nvec3 rotationByEuler(in vec3 vector, in vec3 rot) {\n float halfRoll = rot.z * 0.5;\n float halfPitch = rot.x * 0.5;\n float halfYaw = rot.y * 0.5;\n\n float sinRoll = sin(halfRoll);\n float cosRoll = cos(halfRoll);\n float sinPitch = sin(halfPitch);\n float cosPitch = cos(halfPitch);\n float sinYaw = sin(halfYaw);\n float cosYaw = cos(halfYaw);\n\n float cosYawPitch = cosYaw * cosPitch;\n float sinYawPitch = sinYaw * sinPitch;\n\n float quaX = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);\n float quaY = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);\n float quaZ = (cosYawPitch * sinRoll) - (sinYawPitch * cosRoll);\n float quaW = (cosYawPitch * cosRoll) + (sinYawPitch * sinRoll);\n\n return rotationByQuaternions(vector, vec4(quaX, quaY, quaZ, quaW));\n}\n\n// Assume axis is normalized\nvec3 rotationByAxis(in vec3 vector, in vec3 axis, in float angle) {\n float halfAngle = angle * 0.5;\n float s = sin(halfAngle);\n\n return rotationByQuaternions(vector, vec4(axis * s, cos(halfAngle)));\n}\n\n\nfloat evaluateParticleCurve(in vec2 keys[4], in float normalizedAge) {\n float value;\n for (int i = 1; i < 4; i++) {\n vec2 key = keys[i];\n float time = key.x;\n if (time >= normalizedAge) {\n vec2 lastKey = keys[i - 1];\n float lastTime = lastKey.x;\n float age = (normalizedAge - lastTime) / (time - lastTime);\n value = mix(lastKey.y, key.y, age);\n break;\n }\n }\n return value;\n}\n\nfloat evaluateParticleCurveCumulative(in vec2 keys[4], in float normalizedAge, out float currentValue){\n float cumulativeValue = 0.0;\n for (int i = 1; i < 4; i++){\n\t vec2 key = keys[i];\n\t float time = key.x;\n\t vec2 lastKey = keys[i - 1];\n\t float lastValue = lastKey.y;\n\n\t if (time >= normalizedAge){\n\t\t float lastTime = lastKey.x;\n float offsetTime = normalizedAge - lastTime;\n\t\t float age = offsetTime / (time - lastTime);\n currentValue = mix(lastValue, key.y, age);\n\t\t cumulativeValue += (lastValue + currentValue) * 0.5 * offsetTime;\n\t\t break;\n\t\t}\n\t else{\n\t\t cumulativeValue += (lastValue + key.y) * 0.5 * (time - lastKey.x);\n\t\t}\n\t}\n return cumulativeValue;\n}\n\nvec4 evaluateParticleGradient(in vec4 colorKeys[4], in float colorMaxTime, in vec2 alphaKeys[4], in float alphaMaxTime, in float t) {\n vec4 value;\n\n float alphaT = min(t, alphaMaxTime);\n for (int i = 0; i < 4; i++) {\n vec2 key = alphaKeys[i];\n if (alphaT <= key.x) {\n if (i == 0) {\n value.a = alphaKeys[0].y;\n } else {\n vec2 lastKey = alphaKeys[i - 1];\n float age = (alphaT - lastKey.x) / (key.x - lastKey.x);\n value.a = mix(lastKey.y, key.y, age);\n }\n break;\n }\n }\n\n float colorT = min(t, colorMaxTime);\n for (int i = 0; i < 4; i++) {\n vec4 key = colorKeys[i];\n if (colorT <= key.x) {\n if (i == 0) {\n value.rgb = colorKeys[0].yzw;\n } else {\n vec4 lastKey = colorKeys[i - 1];\n float age = (colorT - lastKey.x) / (key.x - lastKey.x);\n value.rgb = mix(lastKey.yzw, key.yzw, age);\n }\n break;\n }\n }\n\n return value;\n}\n\n#endif\n";
|
|
76
|
+
|
|
77
|
+
var Particle_ParticleFeedback = "#ifndef PARTICLE_FEEDBACK_INCLUDED\n#define PARTICLE_FEEDBACK_INCLUDED\n\n// Transform Feedback update shader for particle simulation.\n// Update order: VOL/FOL -> Dampen -> Drag -> Position.\n// Runs once per particle per frame (no rasterization).\n\n// Previous frame TF data\nvec3 a_FeedbackPosition;\nvec3 a_FeedbackVelocity;\n\n// Per-particle instance data\nvec4 a_ShapePositionStartLifeTime;\nvec4 a_DirectionTime;\nvec3 a_StartSize;\nfloat a_StartSpeed;\nvec4 a_Random0;\nvec4 a_Random1;\nvec3 a_SimulationWorldPosition;\nvec4 a_SimulationWorldRotation;\nvec4 a_Random2;\n\n// Uniforms\nfloat renderer_CurrentTime;\nfloat renderer_DeltaTime;\nvec3 renderer_Gravity;\nvec2 renderer_LVLDragConstant;\nvec3 renderer_WorldPosition;\nvec4 renderer_WorldRotation;\nint renderer_SimulationSpace;\n\n// TF outputs\nvec3 v_FeedbackPosition;\nvec3 v_FeedbackVelocity;\n\n#include \"ShaderLibrary/Particle/ParticleCommon.glsl\"\n#include \"ShaderLibrary/Particle/Module/VelocityOverLifetime.glsl\"\n#include \"ShaderLibrary/Particle/Module/ForceOverLifetime.glsl\"\n#include \"ShaderLibrary/Particle/Module/LimitVelocityOverLifetime.glsl\"\n#include \"ShaderLibrary/Particle/Module/NoiseModule.glsl\"\n\n// Get VOL instantaneous velocity at normalizedAge\nvec3 getVOLVelocity(float normalizedAge) {\n vec3 vel = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n #ifdef RENDERER_VOL_CONSTANT_MODE\n vel = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vel = mix(renderer_VOLMinConst, vel, a_Random1.yzw);\n #endif\n #endif\n #ifdef RENDERER_VOL_CURVE_MODE\n vel = vec3(\n evaluateParticleCurve(renderer_VOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minVel = vec3(\n evaluateParticleCurve(renderer_VOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientZ, normalizedAge)\n );\n vel = mix(minVel, vel, a_Random1.yzw);\n #endif\n #endif\n #endif\n return vel;\n}\n\n// Get FOL instantaneous acceleration at normalizedAge\nvec3 getFOLAcceleration(float normalizedAge) {\n vec3 acc = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n #ifdef RENDERER_FOL_CONSTANT_MODE\n acc = renderer_FOLMaxConst;\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n acc = mix(renderer_FOLMinConst, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #ifdef RENDERER_FOL_CURVE_MODE\n acc = vec3(\n evaluateParticleCurve(renderer_FOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minAcc = vec3(\n evaluateParticleCurve(renderer_FOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientZ, normalizedAge)\n );\n acc = mix(minAcc, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #endif\n return acc;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float lifetime = a_ShapePositionStartLifeTime.w;\n float normalizedAge = age / lifetime;\n // Clamp to age on the first TF pass: particles emitted mid-frame have age < dt,\n // so using the full dt would over-integrate. Subsequent passes are unaffected (age >= dt).\n float dt = min(renderer_DeltaTime, age);\n\n // normalizedAge < 0.0: stale TF slot whose startTime is from a previous playback (e.g. after StopEmittingAndClear).\n if (normalizedAge >= 1.0 || normalizedAge < 0.0) {\n v_FeedbackPosition = a_FeedbackPosition;\n v_FeedbackVelocity = a_FeedbackVelocity;\n gl_Position = vec4(0.0);\n return;\n }\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n vec4 invWorldRotation = quaternionConjugate(worldRotation);\n\n // Read previous frame state (initialized by CPU on particle birth)\n vec3 localVelocity = a_FeedbackVelocity;\n\n // =====================================================\n // Step 1: Apply velocity module deltas (VOL + FOL + Gravity)\n // =====================================================\n\n // Gravity (world space)\n vec3 gravityDelta = renderer_Gravity * a_Random0.x * dt;\n\n // VOL instantaneous velocity (animated velocity, not persisted)\n vec3 volLocal = vec3(0.0);\n vec3 volWorld = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n vec3 vol = getVOLVelocity(normalizedAge);\n if (renderer_VOLSpace == 0) {\n volLocal = vol;\n } else {\n volWorld = vol;\n }\n #endif\n\n // FOL acceleration -> velocity delta (always persisted, like gravity)\n vec3 folDeltaLocal = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n vec3 folAcc = getFOLAcceleration(normalizedAge);\n vec3 folVelDelta = folAcc * dt;\n if (renderer_FOLSpace == 0) {\n folDeltaLocal = folVelDelta;\n } else {\n // World FOL: convert to local and persist, same as gravity\n folDeltaLocal = rotationByQuaternions(folVelDelta, invWorldRotation);\n }\n #endif\n\n // Gravity and FOL contribute to base velocity (persisted, subject to dampen/drag).\n vec3 gravityLocal = rotationByQuaternions(gravityDelta, invWorldRotation);\n localVelocity += folDeltaLocal + gravityLocal;\n\n // =====================================================\n // Step 2 & 3: Dampen (Limit Velocity) + Drag\n // VOL must be projected into the LVL target space so that\n // limit/drag see the full velocity regardless of VOL.space vs LVL.space.\n // =====================================================\n #ifdef RENDERER_LVL_MODULE_ENABLED\n // Precompute VOL in both spaces\n vec3 volAsLocal = volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n vec3 volAsWorld = rotationByQuaternions(volLocal, worldRotation) + volWorld;\n\n float limitRand = a_Random2.w;\n float dampen = renderer_LVLDampen;\n // Frame-rate independent dampen (30fps as reference)\n float effectiveDampen = 1.0 - pow(1.0 - dampen, dt * 30.0);\n\n if (renderer_LVLSpace == 0) {\n // Local space: total = base + all VOL projected to local\n vec3 totalLocal = localVelocity + volAsLocal;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalLocal, normalizedAge, limitRand, effectiveDampen);\n localVelocity = dampenedTotal - volAsLocal;\n } else {\n // World space: total = rotated base + all VOL projected to world\n vec3 totalWorld = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalWorld, normalizedAge, limitRand, effectiveDampen);\n localVelocity = rotationByQuaternions(dampenedTotal - volAsWorld, invWorldRotation);\n }\n\n // Drag: same space as dampen\n {\n float dragCoeff = evaluateLVLDrag(normalizedAge, a_Random2.w);\n if (dragCoeff > 0.0) {\n vec3 totalVel;\n if (renderer_LVLSpace == 0) {\n totalVel = localVelocity + volAsLocal;\n } else {\n totalVel = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n }\n float velMagSqr = dot(totalVel, totalVel);\n float velMag = sqrt(velMagSqr);\n\n float drag = dragCoeff;\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_SIZE\n float maxDim = max(a_StartSize.x, max(a_StartSize.y, a_StartSize.z));\n float radius = maxDim * 0.5;\n drag *= 3.14159265 * radius * radius;\n #endif\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_VELOCITY\n drag *= velMagSqr;\n #endif\n\n if (velMag > 0.0) {\n float newVelMag = max(0.0, velMag - drag * dt);\n vec3 draggedTotal = totalVel * (newVelMag / velMag);\n if (renderer_LVLSpace == 0) {\n localVelocity = draggedTotal - volAsLocal;\n } else {\n localVelocity = rotationByQuaternions(draggedTotal - volAsWorld, invWorldRotation);\n }\n }\n }\n }\n #endif\n\n // =====================================================\n // Step 4: Integrate position in simulation space\n // Local mode: position in local space, velocity rotated to local\n // World mode: position in world space, velocity rotated to world\n // =====================================================\n // FOL is now fully in localVelocity (both local and world-space FOL).\n // VOL and Noise overlays are added here (not persisted).\n\n vec3 totalVelocity;\n if (renderer_SimulationSpace == 0) {\n totalVelocity = localVelocity + volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n } else {\n totalVelocity = rotationByQuaternions(localVelocity + volLocal, worldRotation) + volWorld;\n }\n #ifdef RENDERER_NOISE_MODULE_ENABLED\n // Use analytical base position (birth + initial velocity * age) instead of\n // a_FeedbackPosition to avoid feedback loop: position → noise → velocity → position\n vec3 noiseBasePos;\n if (renderer_SimulationSpace == 0) {\n noiseBasePos = a_ShapePositionStartLifeTime.xyz + a_DirectionTime.xyz * a_StartSpeed * age;\n } else {\n noiseBasePos = rotationByQuaternions(\n a_ShapePositionStartLifeTime.xyz + a_DirectionTime.xyz * a_StartSpeed * age,\n worldRotation) + a_SimulationWorldPosition;\n }\n totalVelocity += computeNoiseVelocity(noiseBasePos, normalizedAge);\n #endif\n vec3 position = a_FeedbackPosition + totalVelocity * dt;\n\n v_FeedbackPosition = position;\n v_FeedbackVelocity = localVelocity;\n gl_Position = vec4(0.0);\n}\n\n#endif\n";
|
|
78
|
+
|
|
79
|
+
var Particle_ParticleMesh = "#ifndef PARTICLE_MESH_INCLUDED\n#define PARTICLE_MESH_INCLUDED\n\n// Only support local alignment mode\n#ifdef RENDERER_MODE_MESH\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #define RENDERER_ROL_ENABLED\n #endif\n\n\tvec3 size = computeParticleSizeMesh(a_StartSize, normalizedAge);\n\n bool is3DRotation = renderer_ThreeDStartRotation;\n #if defined(RENDERER_ROL_ENABLED) && defined(RENDERER_ROL_IS_SEPARATE)\n is3DRotation = true;\n #endif\n\n if (is3DRotation) {\n #ifdef RENDERER_ROL_ENABLED\n vec3 startRotation = renderer_ThreeDStartRotation ? a_StartRotation0 : vec3(0.0, 0.0, a_StartRotation0.x);\n vec3 rotation = radians(computeParticleRotationVec3(startRotation, age, normalizedAge));\n #else\n vec3 rotation = radians(a_StartRotation0);\n #endif\n // 3D Start Rotation is same in local and world simulation space\n center += rotationByQuaternions(renderer_SizeScale * rotationByEuler(POSITION * size, rotation), worldRotation);\n } else {\n #ifdef RENDERER_ROL_ENABLED\n float angle = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n #else\n float angle = radians(a_StartRotation0.x);\n #endif\n #ifdef RENDERER_EMISSION_SHAPE\n // Axis is side vector of emit position look at zero\n vec3 axis = vec3(a_ShapePositionStartLifeTime.xy, 0.0);\n if (renderer_SimulationSpace == 1){\n axis = rotationByQuaternions(axis, worldRotation);\n }\n vec3 crossResult = cross(axis, vec3(0.0, 0.0, -1.0));\n float crossLen = length(crossResult);\n vec3 rotateAxis = crossLen > 0.0001 ? crossResult / crossLen : vec3(0.0, 1.0, 0.0);\n #else\n // Axis is negative z\n vec3 rotateAxis = vec3(0.0, 0.0, -1.0);\n #endif\n center += rotationByQuaternions(renderer_SizeScale *rotationByAxis(POSITION * size, rotateAxis, angle), worldRotation);\n }\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n\t\tv_MeshColor = COLOR_0;\n\t#endif\n#endif\n\n#endif\n";
|
|
80
|
+
|
|
81
|
+
var PostProcess_Bloom_BloomBlurH = "#ifndef BLOOM_BLUR_H\n#define BLOOM_BLUR_H\n\n#include \"ShaderLibrary/PostProcess/PostCommon.glsl\"\n\nmediump sampler2D renderer_BlitTexture;\nvec4 renderer_texelSize;\n\nvoid frag(Varyings v) {\n\tvec2 texelSize = renderer_texelSize.xy * 2.0;\n\n // 9-tap gaussian blur on the downsampled source\n mediump vec4 c0 = texture2DSRGB(renderer_BlitTexture, v.v_uv - vec2(texelSize.x * 4.0, 0.0));\n mediump vec4 c1 = texture2DSRGB(renderer_BlitTexture, v.v_uv - vec2(texelSize.x * 3.0, 0.0));\n mediump vec4 c2 = texture2DSRGB(renderer_BlitTexture, v.v_uv - vec2(texelSize.x * 2.0, 0.0));\n mediump vec4 c3 = texture2DSRGB(renderer_BlitTexture, v.v_uv - vec2(texelSize.x * 1.0, 0.0));\n mediump vec4 c4 = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n mediump vec4 c5 = texture2DSRGB(renderer_BlitTexture, v.v_uv + vec2(texelSize.x * 1.0, 0.0));\n mediump vec4 c6 = texture2DSRGB(renderer_BlitTexture, v.v_uv + vec2(texelSize.x * 2.0, 0.0));\n mediump vec4 c7 = texture2DSRGB(renderer_BlitTexture, v.v_uv + vec2(texelSize.x * 3.0, 0.0));\n mediump vec4 c8 = texture2DSRGB(renderer_BlitTexture, v.v_uv + vec2(texelSize.x * 4.0, 0.0));\n\n gl_FragColor = c0 * 0.01621622 + c1 * 0.05405405 + c2 * 0.12162162 + c3 * 0.19459459\n + c4 * 0.22702703\n + c5 * 0.19459459 + c6 * 0.12162162 + c7 * 0.05405405 + c8 * 0.01621622;\n}\n\n#endif\n";
|
|
82
|
+
|
|
83
|
+
var PostProcess_Bloom_BloomBlurV = "#ifndef BLOOM_BLUR_V\n#define BLOOM_BLUR_V\n\n#include \"ShaderLibrary/PostProcess/PostCommon.glsl\"\n\nmediump sampler2D renderer_BlitTexture;\nvec4 renderer_texelSize;\n\nvoid frag(Varyings v) {\n vec2 texelSize = renderer_texelSize.xy;\n\n // Optimized bilinear 5-tap gaussian on the same-sized source (9-tap equivalent)\n mediump vec4 c0 = texture2DSRGB(renderer_BlitTexture, v.v_uv - vec2(0.0, texelSize.y * 3.23076923));\n mediump vec4 c1 = texture2DSRGB(renderer_BlitTexture, v.v_uv - vec2(0.0, texelSize.y * 1.38461538));\n mediump vec4 c2 = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n mediump vec4 c3 = texture2DSRGB(renderer_BlitTexture, v.v_uv + vec2(0.0, texelSize.y * 1.38461538));\n mediump vec4 c4 = texture2DSRGB(renderer_BlitTexture, v.v_uv + vec2(0.0, texelSize.y * 3.23076923));\n\n gl_FragColor = c0 * 0.07027027 + c1 * 0.31621622\n + c2 * 0.22702703\n + c3 * 0.31621622 + c4 * 0.07027027;\n}\n\n#endif\n";
|
|
84
|
+
|
|
85
|
+
var PostProcess_Bloom_BloomPrefilter = "#ifndef BLOOM_PREFILTER\n#define BLOOM_PREFILTER\n\n#include \"ShaderLibrary/PostProcess/PostCommon.glsl\"\n\nmediump sampler2D renderer_BlitTexture;\nvec4 material_BloomParams;\nvec4 renderer_texelSize;\n\nvoid frag(Varyings v) {\n\t#ifdef BLOOM_HQ\n vec2 texelSize = renderer_texelSize.xy;\n mediump vec4 A = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(-1.0, -1.0));\n mediump vec4 B = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(0.0, -1.0));\n mediump vec4 C = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(1.0, -1.0));\n mediump vec4 D = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(-0.5, -0.5));\n mediump vec4 E = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(0.5, -0.5));\n mediump vec4 F = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(-1.0, 0.0));\n mediump vec4 G = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n mediump vec4 H = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(1.0, 0.0));\n mediump vec4 I = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(-0.5, 0.5));\n mediump vec4 J = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(0.5, 0.5));\n mediump vec4 K = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(-1.0, 1.0));\n mediump vec4 L = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(0.0, 1.0));\n mediump vec4 M = texture2DSRGB(renderer_BlitTexture, v.v_uv + texelSize * vec2(1.0, 1.0));\n\n mediump vec2 scale = vec2(0.5, 0.125);\n mediump vec2 div = (1.0 / 4.0) * scale;\n\n mediump vec4 samplerColor = (D + E + I + J) * div.x;\n samplerColor += (A + B + G + F) * div.y;\n samplerColor += (B + C + H + G) * div.y;\n samplerColor += (F + G + L + K) * div.y;\n samplerColor += (G + H + M + L) * div.y;\n #else\n mediump vec4 samplerColor = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n #endif\n\n mediump vec3 color = samplerColor.rgb;\n\n // User controlled clamp to limit crazy high broken spec\n color = min(color, HALF_MAX);\n\n // Thresholding\n mediump float brightness = max3(color);\n float threshold = material_BloomParams.x;\n float thresholdKnee = material_BloomParams.y;\n mediump float softness = clamp(brightness - threshold + thresholdKnee, 0.0, 2.0 * thresholdKnee);\n softness = (softness * softness) / (4.0 * thresholdKnee + 1e-4);\n mediump float multiplier = max(brightness - threshold, softness) / max(brightness, 1e-4);\n color *= multiplier;\n\n // Clamp colors to positive once in prefilter. Encode can have a sqrt, and sqrt(-x) == NaN. Up/Downsample passes would then spread the NaN.\n color = max(color, 0.0);\n\n // Bloom is addtive blend mode, we should set alpha 0 to avoid browser background color dark when canvas alpha and premultiplyAlpha is true\n gl_FragColor = vec4(color, 0.0);\n}\n\n#endif\n";
|
|
86
|
+
|
|
87
|
+
var PostProcess_Bloom_BloomUpsample = "#ifndef BLOOM_UPSAMPLE\n#define BLOOM_UPSAMPLE\n\n#include \"ShaderLibrary/PostProcess/PostCommon.glsl\"\n#include \"ShaderLibrary/PostProcess/Filtering.glsl\"\n\nmediump sampler2D renderer_BlitTexture;\nmediump sampler2D material_lowMipTexture;\nvec4 material_BloomParams;\nvec4 material_lowMipTexelSize;\n\nvoid frag(Varyings v) {\n mediump vec4 highMip = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n\n #ifdef BLOOM_HQ\n mediump vec4 lowMip = sampleTexture2DBicubic(material_lowMipTexture, v.v_uv, material_lowMipTexelSize);\n #else\n mediump vec4 lowMip = texture2DSRGB(material_lowMipTexture, v.v_uv);\n #endif\n\n gl_FragColor = mix(highMip, lowMip, material_BloomParams.z);\n}\n\n#endif\n";
|
|
88
|
+
|
|
89
|
+
var PostProcess_FXAA_FXAA3_11 = "//----------------------------------------------------------------------------------\n// This file was obatined from: https://github.com/hghdev/NVIDIAGameWorks-GraphicsSamples/blob/master/samples/es3-kepler/FXAA/FXAA3_11.h\n// NVIDIA paper: https://www.iryoku.com/aacourse/downloads/09-FXAA-3.11-in-15-Slides.pdf\n// Modifications to this file done by Galacean:\n// * Deleted HLSL-related macros\n// * Deleted the macros and function except for 'FXAA_PC == 1' \n// * Deleted the useless parameters in 'FxaaPixelShader' \n// * Webgl does not compile the double underline, so we remove the double underline for macros\n// * Changed the 'FXAA_GREEN_AS_LUMA == 0' code-path to compute luminance since we don't precompute luminance into the alpha channel\n// * Change the alpha value of the `ret` finally returned by the function from brightness to transparency when `FXAA_DISCARD == 1` code path\n//----------------------------------------------------------------------------------\n\n//----------------------------------------------------------------------------------\n// File: es3-kepler\\FXAA/FXAA3_11.h\n// SDK Version: v3.00\n// Email: gameworks@nvidia.com\n// Site: http://developer.nvidia.com/\n//\n// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above copyright\n// notice, this list of conditions and the following disclaimer in the\n// documentation and/or other materials provided with the distribution.\n// * Neither the name of NVIDIA CORPORATION nor the names of its\n// contributors may be used to endorse or promote products derived\n// from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY\n// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n//----------------------------------------------------------------------------------\n/*============================================================================\n\n\n NVIDIA FXAA 3.11 by TIMOTHY LOTTES\n\n------------------------------------------------------------------------------\n INTEGRATION CHECKLIST\n------------------------------------------------------------------------------\n(1.)\nIn the shader source, setup defines for the desired configuration.\nWhen providing multiple shaders (for different presets),\nsimply setup the defines differently in multiple files.\nExample,\n\n #define FXAA_PC 1\n #define FXAA_HLSL_5 1\n #define FXAA_QUALITY_PRESET 12\n\nOr,\n\n #define FXAA_360 1\n\nOr,\n\n #define FXAA_PS3 1\n\nEtc.\n\n(2.)\nThen include this file,\n\n #include \"Fxaa3_11.h\"\n\n(3.)\nThen call the FXAA pixel shader from within your desired shader.\nLook at the FXAA Quality FxaaPixelShader() for docs on inputs.\nAs for FXAA 3.11 all inputs for all shaders are the same\nto enable easy porting between platforms.\n\n return FxaaPixelShader(...);\n\n(4.)\nInsure pass prior to FXAA outputs RGBL (see next section).\nOr use,\n\n #define FXAA_GREEN_AS_LUMA 1\n\n(5.)\nSetup engine to provide the following constants\nwhich are used in the FxaaPixelShader() inputs,\n\n FxaaFloat2 fxaaQualityRcpFrame,\n FxaaFloat4 fxaaConsoleRcpFrameOpt,\n FxaaFloat4 fxaaConsoleRcpFrameOpt2,\n FxaaFloat4 fxaaConsole360RcpFrameOpt2,\n FxaaFloat fxaaQualitySubpix,\n FxaaFloat fxaaQualityEdgeThreshold,\n FxaaFloat fxaaQualityEdgeThresholdMin,\n FxaaFloat fxaaConsoleEdgeSharpness,\n FxaaFloat fxaaConsoleEdgeThreshold,\n FxaaFloat fxaaConsoleEdgeThresholdMin,\n FxaaFloat4 fxaaConsole360ConstDir\n\nLook at the FXAA Quality FxaaPixelShader() for docs on inputs.\n\n(6.)\nHave FXAA vertex shader run as a full screen triangle,\nand output \"pos\" and \"fxaaConsolePosPos\"\nsuch that inputs in the pixel shader provide,\n\n // {xy} = center of pixel\n FxaaFloat2 pos,\n\n // {xy_} = upper left of pixel\n // {_zw} = lower right of pixel\n FxaaFloat4 fxaaConsolePosPos,\n\n(7.)\nInsure the texture sampler(s) used by FXAA are set to bilinear filtering.\n\n\n------------------------------------------------------------------------------\n INTEGRATION - RGBL AND COLORSPACE\n------------------------------------------------------------------------------\nFXAA3 requires RGBL as input unless the following is set,\n\n #define FXAA_GREEN_AS_LUMA 1\n\nIn which case the engine uses green in place of luma,\nand requires RGB input is in a non-linear colorspace.\n\nRGB should be LDR (low dynamic range).\nSpecifically do FXAA after tonemapping.\n\nRGB data as returned by a texture fetch can be non-linear,\nor linear when FXAA_GREEN_AS_LUMA is not set.\nNote an \"sRGB format\" texture counts as linear,\nbecause the result of a texture fetch is linear data.\nRegular \"RGBA8\" textures in the sRGB colorspace are non-linear.\n\nIf FXAA_GREEN_AS_LUMA is not set,\nluma must be stored in the alpha channel prior to running FXAA.\nThis luma should be in a perceptual space (could be gamma 2.0).\nExample pass before FXAA where output is gamma 2.0 encoded,\n\n color.rgb = ToneMap(color.rgb); // linear color output\n color.rgb = sqrt(color.rgb); // gamma 2.0 color output\n return color;\n\nTo use FXAA,\n\n color.rgb = ToneMap(color.rgb); // linear color output\n color.rgb = sqrt(color.rgb); // gamma 2.0 color output\n color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma\n return color;\n\nAnother example where output is linear encoded,\nsay for instance writing to an sRGB formated render target,\nwhere the render target does the conversion back to sRGB after blending,\n\n color.rgb = ToneMap(color.rgb); // linear color output\n return color;\n\nTo use FXAA,\n\n color.rgb = ToneMap(color.rgb); // linear color output\n color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma\n return color;\n\nGetting luma correct is required for the algorithm to work correctly.\n\n\n------------------------------------------------------------------------------\n BEING LINEARLY CORRECT?\n------------------------------------------------------------------------------\nApplying FXAA to a framebuffer with linear RGB color will look worse.\nThis is very counter intuitive, but happends to be true in this case.\nThe reason is because dithering artifacts will be more visiable\nin a linear colorspace.\n\n\n------------------------------------------------------------------------------\n COMPLEX INTEGRATION\n------------------------------------------------------------------------------\nQ. What if the engine is blending into RGB before wanting to run FXAA?\n\nA. In the last opaque pass prior to FXAA,\n have the pass write out luma into alpha.\n Then blend into RGB only.\n FXAA should be able to run ok\n assuming the blending pass did not any add aliasing.\n This should be the common case for particles and common blending passes.\n\nA. Or use FXAA_GREEN_AS_LUMA.\n\n============================================================================*/\n\n/*============================================================================\n\n INTEGRATION KNOBS\n\n============================================================================*/\n/*==========================================================================*/\n#ifndef FXAA_PC\n //\n // FXAA Quality\n // The high quality PC algorithm.\n //\n #define FXAA_PC 0\n#endif\n/*--------------------------------------------------------------------------*/\n#ifndef FXAA_GLSL_120\n #define FXAA_GLSL_120 0\n#endif\n/*--------------------------------------------------------------------------*/\n#ifndef FXAA_GLSL_130\n #define FXAA_GLSL_130 0\n#endif\n/*--------------------------------------------------------------------------*/\n/*==========================================================================*/\n#ifndef FXAA_GREEN_AS_LUMA\n //\n // For those using non-linear color,\n // and either not able to get luma in alpha, or not wanting to,\n // this enables FXAA to run using green as a proxy for luma.\n // So with this enabled, no need to pack luma in alpha.\n //\n // This will turn off AA on anything which lacks some amount of green.\n // Pure red and blue or combination of only R and B, will get no AA.\n //\n // Might want to lower the settings for both,\n // fxaaConsoleEdgeThresholdMin\n // fxaaQualityEdgeThresholdMin\n // In order to insure AA does not get turned off on colors \n // which contain a minor amount of green.\n //\n // 1 = On.\n // 0 = Off.\n //\n #define FXAA_GREEN_AS_LUMA 0\n#endif\n/*--------------------------------------------------------------------------*/\n#ifndef FXAA_EARLY_EXIT\n //\n // Controls algorithm's early exit path.\n // On PS3 turning this ON adds 2 cycles to the shader.\n // On 360 turning this OFF adds 10ths of a millisecond to the shader.\n // Turning this off on console will result in a more blurry image.\n // So this defaults to on.\n //\n // 1 = On.\n // 0 = Off.\n //\n #define FXAA_EARLY_EXIT 1\n#endif\n/*--------------------------------------------------------------------------*/\n#ifndef FXAA_DISCARD\n //\n // Only valid for PC OpenGL currently.\n // Probably will not work when FXAA_GREEN_AS_LUMA = 1.\n //\n // 1 = Use discard on pixels which don't need AA.\n // For APIs which enable concurrent TEX+ROP from same surface.\n // 0 = Return unchanged color on pixels which don't need AA.\n //\n #define FXAA_DISCARD 0\n#endif\n/*--------------------------------------------------------------------------*/\n#ifndef FXAA_FAST_PIXEL_OFFSET\n //\n // Used for GLSL 120 only.\n //\n // 1 = GL API supports fast pixel offsets\n // 0 = do not use fast pixel offsets\n //\n #ifdef GL_EXT_gpu_shader4\n #define FXAA_FAST_PIXEL_OFFSET 1\n #endif\n #ifdef GL_NV_gpu_shader5\n #define FXAA_FAST_PIXEL_OFFSET 1\n #endif\n #ifdef gpu_shader5\n #define FXAA_FAST_PIXEL_OFFSET 1\n #endif\n #ifndef FXAA_FAST_PIXEL_OFFSET\n #define FXAA_FAST_PIXEL_OFFSET 0\n #endif\n#endif\n/*--------------------------------------------------------------------------*/\n#ifndef FXAA_GATHER4_ALPHA\n //\n // 1 = API supports gather4 on alpha channel.\n // 0 = API does not support gather4 on alpha channel.\n //\n #ifdef gpu_shader5\n #define FXAA_GATHER4_ALPHA 1\n #endif\n #ifdef GL_NV_gpu_shader5\n #define FXAA_GATHER4_ALPHA 1\n #endif\n #ifndef FXAA_GATHER4_ALPHA\n #define FXAA_GATHER4_ALPHA 0\n #endif\n#endif\n\n/*============================================================================\n FXAA QUALITY - TUNING KNOBS\n------------------------------------------------------------------------------\nNOTE the other tuning knobs are now in the shader function inputs!\n============================================================================*/\n#ifndef FXAA_QUALITY_PRESET\n //\n // Choose the quality preset.\n // This needs to be compiled into the shader as it affects code.\n // Best option to include multiple presets is to \n // in each shader define the preset, then include this file.\n // \n // OPTIONS\n // -----------------------------------------------------------------------\n // 10 to 15 - default medium dither (10=fastest, 15=highest quality)\n // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)\n // 39 - no dither, very expensive \n //\n // NOTES\n // -----------------------------------------------------------------------\n // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)\n // 13 = about same speed as FXAA 3.9 and better than 12\n // 23 = closest to FXAA 3.9 visually and performance wise\n // _ = the lowest digit is directly related to performance\n // _ = the highest digit is directly related to style\n // \n #define FXAA_QUALITY_PRESET 12\n#endif\n\n/*============================================================================\n\n FXAA QUALITY - PRESETS\n\n============================================================================*/\n\n/*============================================================================\n FXAA QUALITY - MEDIUM DITHER PRESETS\n============================================================================*/\n#if (FXAA_QUALITY_PRESET == 10)\n #define FXAA_QUALITY_PS 3\n #define FXAA_QUALITY_P0 1.5\n #define FXAA_QUALITY_P1 3.0\n #define FXAA_QUALITY_P2 12.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 11)\n #define FXAA_QUALITY_PS 4\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 3.0\n #define FXAA_QUALITY_P3 12.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 12)\n #define FXAA_QUALITY_PS 5\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 4.0\n #define FXAA_QUALITY_P4 12.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 13)\n #define FXAA_QUALITY_PS 6\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 4.0\n #define FXAA_QUALITY_P5 12.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 14)\n #define FXAA_QUALITY_PS 7\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 4.0\n #define FXAA_QUALITY_P6 12.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 15)\n #define FXAA_QUALITY_PS 8\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 2.0\n #define FXAA_QUALITY_P6 4.0\n #define FXAA_QUALITY_P7 12.0\n#endif\n\n/*============================================================================\n FXAA QUALITY - LOW DITHER PRESETS\n============================================================================*/\n#if (FXAA_QUALITY_PRESET == 20)\n #define FXAA_QUALITY_PS 3\n #define FXAA_QUALITY_P0 1.5\n #define FXAA_QUALITY_P1 2.0\n #define FXAA_QUALITY_P2 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 21)\n #define FXAA_QUALITY_PS 4\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 22)\n #define FXAA_QUALITY_PS 5\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 23)\n #define FXAA_QUALITY_PS 6\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 24)\n #define FXAA_QUALITY_PS 7\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 3.0\n #define FXAA_QUALITY_P6 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 25)\n #define FXAA_QUALITY_PS 8\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 2.0\n #define FXAA_QUALITY_P6 4.0\n #define FXAA_QUALITY_P7 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 26)\n #define FXAA_QUALITY_PS 9\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 2.0\n #define FXAA_QUALITY_P6 2.0\n #define FXAA_QUALITY_P7 4.0\n #define FXAA_QUALITY_P8 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 27)\n #define FXAA_QUALITY_PS 10\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 2.0\n #define FXAA_QUALITY_P6 2.0\n #define FXAA_QUALITY_P7 2.0\n #define FXAA_QUALITY_P8 4.0\n #define FXAA_QUALITY_P9 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 28)\n #define FXAA_QUALITY_PS 11\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 2.0\n #define FXAA_QUALITY_P6 2.0\n #define FXAA_QUALITY_P7 2.0\n #define FXAA_QUALITY_P8 2.0\n #define FXAA_QUALITY_P9 4.0\n #define FXAA_QUALITY_P10 8.0\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_QUALITY_PRESET == 29)\n #define FXAA_QUALITY_PS 12\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.5\n #define FXAA_QUALITY_P2 2.0\n #define FXAA_QUALITY_P3 2.0\n #define FXAA_QUALITY_P4 2.0\n #define FXAA_QUALITY_P5 2.0\n #define FXAA_QUALITY_P6 2.0\n #define FXAA_QUALITY_P7 2.0\n #define FXAA_QUALITY_P8 2.0\n #define FXAA_QUALITY_P9 2.0\n #define FXAA_QUALITY_P10 4.0\n #define FXAA_QUALITY_P11 8.0\n#endif\n\n/*============================================================================\n FXAA QUALITY - EXTREME QUALITY\n============================================================================*/\n#if (FXAA_QUALITY_PRESET == 39)\n #define FXAA_QUALITY_PS 12\n #define FXAA_QUALITY_P0 1.0\n #define FXAA_QUALITY_P1 1.0\n #define FXAA_QUALITY_P2 1.0\n #define FXAA_QUALITY_P3 1.0\n #define FXAA_QUALITY_P4 1.0\n #define FXAA_QUALITY_P5 1.5\n #define FXAA_QUALITY_P6 2.0\n #define FXAA_QUALITY_P7 2.0\n #define FXAA_QUALITY_P8 2.0\n #define FXAA_QUALITY_P9 2.0\n #define FXAA_QUALITY_P10 4.0\n #define FXAA_QUALITY_P11 8.0\n#endif\n\n\n/*============================================================================\n\n API PORTING\n\n============================================================================*/\n#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)\n #define FxaaBool bool\n #define FxaaDiscard discard\n #define FxaaFloat float\n #define FxaaFloat2 vec2\n #define FxaaFloat3 vec3\n #define FxaaFloat4 vec4\n #define FxaaHalf float\n #define FxaaHalf2 vec2\n #define FxaaHalf3 vec3\n #define FxaaHalf4 vec4\n #define FxaaInt2 ivec2\n #define FxaaSat(x) clamp(x, 0.0, 1.0)\n #define FxaaTex sampler2D\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_GLSL_120 == 1)\n // Requires,\n // #version 120\n // And at least,\n // #extension GL_EXT_gpu_shader4 : enable\n // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)\n #define FxaaTexTop(t, p) texture2DLodEXT(t, p, 0.0)\n #if (FXAA_FAST_PIXEL_OFFSET == 1)\n #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)\n #else\n #define FxaaTexOff(t, p, o, r) texture2DLodEXT(t, p + (o * r), 0.0)\n #endif\n #if (FXAA_GATHER4_ALPHA == 1)\n // use #extension gpu_shader5 : enable\n #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)\n #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)\n #define FxaaTexGreen4(t, p) textureGather(t, p, 1)\n #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)\n #endif\n#endif\n/*--------------------------------------------------------------------------*/\n#if (FXAA_GLSL_130 == 1)\n // Requires \"#version 130\" or better\n #define FxaaTexTop(t, p) textureLod(t, p, 0.0)\n #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)\n #if (FXAA_GATHER4_ALPHA == 1)\n // use #extension gpu_shader5 : enable\n #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)\n #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)\n #define FxaaTexGreen4(t, p) textureGather(t, p, 1)\n #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)\n #endif\n#endif\n/*--------------------------------------------------------------------------*/\n\n\n/*============================================================================\n GREEN AS LUMA OPTION SUPPORT FUNCTION\n============================================================================*/\n#if (FXAA_GREEN_AS_LUMA == 0)\n FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return dot(rgba.xyz, FxaaFloat3(0.299, 0.587, 0.114));}\n#else\n FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }\n#endif \n\n\n/*============================================================================\n\n FXAA3 QUALITY - PC\n\n============================================================================*/\n#if (FXAA_PC == 1)\n/*--------------------------------------------------------------------------*/\nFxaaFloat4 FxaaPixelShader(\n // Use noperspective interpolation here (turn off perspective interpolation).\n // {xy} = center of pixel\n FxaaFloat2 pos,\n //\n // Reuse the center sample as it's already available\n // {rgb_} = the color of the center pixel (alpha won't be used)\n FxaaFloat4 rgbyM,\n //\n // Input color texture.\n // {rgb_} = color in linear or perceptual color space\n // if (FXAA_GREEN_AS_LUMA == 0)\n // {__a} = luma in perceptual color space (not linear)\n FxaaTex tex,\n //\n // Only used on FXAA Quality.\n // This must be from a constant/uniform.\n // {x_} = 1.0/screenWidthInPixels\n // {_y} = 1.0/screenHeightInPixels\n FxaaFloat2 fxaaQualityRcpFrame,\n //\n // Only used on FXAA Quality.\n // This used to be the FXAA_QUALITY_SUBPIX define.\n // It is here now to allow easier tuning.\n // Choose the amount of sub-pixel aliasing removal.\n // This can effect sharpness.\n // 1.00 - upper limit (softer)\n // 0.75 - default amount of filtering\n // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)\n // 0.25 - almost off\n // 0.00 - completely off\n FxaaFloat fxaaQualitySubpix,\n //\n // Only used on FXAA Quality.\n // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define.\n // It is here now to allow easier tuning.\n // The minimum amount of local contrast required to apply algorithm.\n // 0.333 - too little (faster)\n // 0.250 - low quality\n // 0.166 - default\n // 0.125 - high quality\n // 0.063 - overkill (slower)\n FxaaFloat fxaaQualityEdgeThreshold,\n //\n // Only used on FXAA Quality.\n // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define.\n // It is here now to allow easier tuning.\n // Trims the algorithm from processing darks.\n // 0.0833 - upper limit (default, the start of visible unfiltered edges)\n // 0.0625 - high quality (faster)\n // 0.0312 - visible limit (slower)\n // Special notes when using FXAA_GREEN_AS_LUMA,\n // Likely want to set this to zero.\n // As colors that are mostly not-green\n // will appear very dark in the green channel!\n // Tune by looking at mostly non-green content,\n // then start at zero and increase until aliasing is a problem.\n FxaaFloat fxaaQualityEdgeThresholdMin\n) {\n/*--------------------------------------------------------------------------*/\n FxaaFloat2 posM;\n posM.x = pos.x;\n posM.y = pos.y;\n #if (FXAA_GATHER4_ALPHA == 1)\n #if (FXAA_DISCARD == 0)\n FxaaFloat lumaM = FxaaLuma(rgbyM);\n #endif\n #if (FXAA_GREEN_AS_LUMA == 0)\n FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);\n FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));\n #else\n FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);\n FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));\n #endif\n #if (FXAA_DISCARD == 1)\n FxaaFloat lumaM = luma4A.w;\n #endif\n #define lumaE luma4A.z\n #define lumaS luma4A.x\n #define lumaSE luma4A.y\n #define lumaNW luma4B.w\n #define lumaN luma4B.z\n #define lumaW luma4B.x\n #else\n FxaaFloat lumaM = FxaaLuma(rgbyM);\n FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));\n #endif\n/*--------------------------------------------------------------------------*/\n FxaaFloat maxSM = max(lumaS, lumaM);\n FxaaFloat minSM = min(lumaS, lumaM);\n FxaaFloat maxESM = max(lumaE, maxSM);\n FxaaFloat minESM = min(lumaE, minSM);\n FxaaFloat maxWN = max(lumaN, lumaW);\n FxaaFloat minWN = min(lumaN, lumaW);\n FxaaFloat rangeMax = max(maxWN, maxESM);\n FxaaFloat rangeMin = min(minWN, minESM);\n FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;\n FxaaFloat range = rangeMax - rangeMin;\n FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);\n FxaaBool earlyExit = range < rangeMaxClamped;\n/*--------------------------------------------------------------------------*/\n if(earlyExit)\n #if (FXAA_DISCARD == 1)\n FxaaDiscard;\n #else\n return rgbyM;\n #endif\n/*--------------------------------------------------------------------------*/\n #if (FXAA_GATHER4_ALPHA == 0)\n FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));\n #else\n FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));\n FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));\n #endif\n/*--------------------------------------------------------------------------*/\n FxaaFloat lumaNS = lumaN + lumaS;\n FxaaFloat lumaWE = lumaW + lumaE;\n FxaaFloat subpixRcpRange = 1.0/range;\n FxaaFloat subpixNSWE = lumaNS + lumaWE;\n FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;\n FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;\n/*--------------------------------------------------------------------------*/\n FxaaFloat lumaNESE = lumaNE + lumaSE;\n FxaaFloat lumaNWNE = lumaNW + lumaNE;\n FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;\n FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;\n/*--------------------------------------------------------------------------*/\n FxaaFloat lumaNWSW = lumaNW + lumaSW;\n FxaaFloat lumaSWSE = lumaSW + lumaSE;\n FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);\n FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);\n FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;\n FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;\n FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;\n FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;\n/*--------------------------------------------------------------------------*/\n FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;\n FxaaFloat lengthSign = fxaaQualityRcpFrame.x;\n FxaaBool horzSpan = edgeHorz >= edgeVert;\n FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;\n/*--------------------------------------------------------------------------*/\n if(!horzSpan) lumaN = lumaW;\n if(!horzSpan) lumaS = lumaE;\n if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;\n FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;\n/*--------------------------------------------------------------------------*/\n FxaaFloat gradientN = lumaN - lumaM;\n FxaaFloat gradientS = lumaS - lumaM;\n FxaaFloat lumaNN = lumaN + lumaM;\n FxaaFloat lumaSS = lumaS + lumaM;\n FxaaBool pairN = abs(gradientN) >= abs(gradientS);\n FxaaFloat gradient = max(abs(gradientN), abs(gradientS));\n if(pairN) lengthSign = -lengthSign;\n FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);\n/*--------------------------------------------------------------------------*/\n FxaaFloat2 posB;\n posB.x = posM.x;\n posB.y = posM.y;\n FxaaFloat2 offNP;\n offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;\n offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;\n if(!horzSpan) posB.x += lengthSign * 0.5;\n if( horzSpan) posB.y += lengthSign * 0.5;\n/*--------------------------------------------------------------------------*/\n FxaaFloat2 posN;\n posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;\n posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;\n FxaaFloat2 posP;\n posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;\n posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;\n FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;\n FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));\n FxaaFloat subpixE = subpixC * subpixC;\n FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));\n/*--------------------------------------------------------------------------*/\n if(!pairN) lumaNN = lumaSS;\n FxaaFloat gradientScaled = gradient * 1.0/4.0;\n FxaaFloat lumaMM = lumaM - lumaNN * 0.5;\n FxaaFloat subpixF = subpixD * subpixE;\n FxaaBool lumaMLTZero = lumaMM < 0.0;\n/*--------------------------------------------------------------------------*/\n lumaEndN -= lumaNN * 0.5;\n lumaEndP -= lumaNN * 0.5;\n FxaaBool doneN = abs(lumaEndN) >= gradientScaled;\n FxaaBool doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;\n FxaaBool doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;\n/*--------------------------------------------------------------------------*/\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 3)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 4)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 5)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 6)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 7)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 8)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 9)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 10)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 11)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;\n/*--------------------------------------------------------------------------*/\n #if (FXAA_QUALITY_PS > 12)\n if(doneNP) {\n if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\n if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\n if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n doneN = abs(lumaEndN) >= gradientScaled;\n doneP = abs(lumaEndP) >= gradientScaled;\n if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;\n if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;\n doneNP = (!doneN) || (!doneP);\n if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;\n if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n #endif\n/*--------------------------------------------------------------------------*/\n }\n/*--------------------------------------------------------------------------*/\n FxaaFloat dstN = posM.x - posN.x;\n FxaaFloat dstP = posP.x - posM.x;\n if(!horzSpan) dstN = posM.y - posN.y;\n if(!horzSpan) dstP = posP.y - posM.y;\n/*--------------------------------------------------------------------------*/\n FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;\n FxaaFloat spanLength = (dstP + dstN);\n FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;\n FxaaFloat spanLengthRcp = 1.0/spanLength;\n/*--------------------------------------------------------------------------*/\n FxaaBool directionN = dstN < dstP;\n FxaaFloat dst = min(dstN, dstP);\n FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;\n FxaaFloat subpixG = subpixF * subpixF;\n FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;\n FxaaFloat subpixH = subpixG * fxaaQualitySubpix;\n/*--------------------------------------------------------------------------*/\n FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;\n FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);\n if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;\n if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;\n\n #if (FXAA_DISCARD == 1)\n return FxaaTexTop(tex, posM);\n #else\n return FxaaTexTop(tex, posM);\n #endif\n}\n/*==========================================================================*/\n#endif";
|
|
90
|
+
|
|
91
|
+
var PostProcess_Filtering = "#ifndef FILTERING\n#define FILTERING\n\nvec2 bSpline3MiddleLeft(vec2 x){\n return 0.16666667 + x * (0.5 + x * (0.5 - x * 0.5));\n}\n\nvec2 bSpline3MiddleRight(vec2 x){\n return 0.66666667 + x * (-1.0 + 0.5 * x) * x;\n}\n\nvec2 bSpline3Rightmost(vec2 x){\n return 0.16666667 + x * (-0.5 + x * (0.5 - x * 0.16666667));\n}\n\n// Compute weights & offsets for 4x bilinear taps for the bicubic B-Spline filter.\n// The fractional coordinate should be in the [0, 1] range (centered on 0.5).\n// Inspired by: http://vec3.ca/bicubic-filtering-in-fewer-taps/\nvoid bicubicFilter(vec2 fracCoord, out vec2 weights[2], out vec2 offsets[2]){\n vec2 r = bSpline3Rightmost(fracCoord);\n vec2 mr = bSpline3MiddleRight(fracCoord);\n vec2 ml = bSpline3MiddleLeft(fracCoord);\n vec2 l = 1.0 - mr - ml - r;\n\n weights[0] = r + mr;\n weights[1] = ml + l;\n offsets[0] = -1.0 + mr / weights[0];\n offsets[1] = 1.0 + l / weights[1];\n}\n\n\n// texSize: (1/width, 1/height, width, height)\nvec4 sampleTexture2DBicubic(sampler2D tex, vec2 coord, vec4 texSize){\n\tvec2 xy = coord * texSize.zw + 0.5;\n vec2 ic = floor(xy);\n vec2 fc = fract(xy);\n\n vec2 weights[2], offsets[2];\n bicubicFilter(fc, weights, offsets);\n\n return weights[0].y * (weights[0].x * texture2DSRGB(tex, (ic + vec2(offsets[0].x, offsets[0].y) - 0.5) * texSize.xy) +\n \tweights[1].x * texture2DSRGB(tex, (ic + vec2(offsets[1].x, offsets[0].y) - 0.5) * texSize.xy)) +\n weights[1].y * (weights[0].x * texture2DSRGB(tex, (ic + vec2(offsets[0].x, offsets[1].y) - 0.5) * texSize.xy) +\n weights[1].x * texture2DSRGB(tex, (ic + vec2(offsets[1].x, offsets[1].y) - 0.5) * texSize.xy));\n}\n\n\n#endif";
|
|
92
|
+
|
|
93
|
+
var PostProcess_FinalAntiAliasing$1 = "#ifndef FINAL_ANTI_ALIASING\n#define FINAL_ANTI_ALIASING\n\n#define FXAA_PC 1\n#define FXAA_QUALITY_PRESET 12\n#define FXAA_GREEN_AS_LUMA 0\n#if defined(GRAPHICS_API_WEBGL2)\n #define FXAA_GLSL_130 1\n#elif defined(GRAPHICS_API_WEBGL1)\n #define FXAA_GLSL_120 1\n#endif\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n#include \"ShaderLibrary/PostProcess/FXAA/FXAA3_11.glsl\"\n\nconst FxaaFloat FXAA_SUBPIXEL_BLEND_AMOUNT = 0.75;\nconst FxaaFloat FXAA_RELATIVE_CONTRAST_THRESHOLD = 0.166;\nconst FxaaFloat FXAA_ABSOLUTE_CONTRAST_THRESHOLD = 0.0833;\n\nsampler2D renderer_BlitTexture;\nvec4 renderer_texelSize;\n\nvec4 applyFXAA(vec4 color, vec2 positionNDC, vec4 sourceSize, sampler2D blitTexture)\n{\n return FxaaPixelShader(\n positionNDC,\n color,\n blitTexture,\n sourceSize.xy,\n FXAA_SUBPIXEL_BLEND_AMOUNT,\n FXAA_RELATIVE_CONTRAST_THRESHOLD,\n FXAA_ABSOLUTE_CONTRAST_THRESHOLD\n );\n}\n\nvoid frag(Varyings v) {\n\tmediump vec4 color = texture2D(renderer_BlitTexture, v.v_uv);\n\n color = applyFXAA(color, v.v_uv, renderer_texelSize, renderer_BlitTexture);\n\n // We have convert the color to sRGB space in sRGB pass\n // So we need to convert it back to linear space when output to render target.\n #ifndef ENGINE_OUTPUT_SRGB_CORRECT\n color.rgb /= color.a;\n color = sRGBToLinear(color);\n color.rgb *= color.a;\n #endif\n\n gl_FragColor = color;\n}\n\n#endif\n";
|
|
94
|
+
|
|
95
|
+
var PostProcess_FinalSRGB$1 = "#ifndef FINAL_SRGB\n#define FINAL_SRGB\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n\nmediump sampler2D renderer_BlitTexture;\n\nvoid frag(Varyings v) {\n\tmediump vec4 color = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n\n // This is final output, maybe has alpha\n // If we use premultiplied color to convert to sRGB. Since we ignored the background color, the greater the transparency, the greater the final composite color\n // But the actual transparent canvas can be composited with any color of the browser background\n\n // So we assume non-transparent SRGB conversion. Then use the Alpha value and the background canvas to do SRGB blending\n // Although it is non-linear blending, it is more scientific\n color.rgb = color.rgb / color.a;\n color = linearToSRGB(color);\n gl_FragColor = vec4(color.rgb * color.a, color.a);\n}\n\n#endif\n";
|
|
96
|
+
|
|
97
|
+
var PostProcess_PostCommon = "#ifndef POST_COMMON\n#define POST_COMMON\n\n#include \"ShaderLibrary/Common/Common.glsl\"\n#define FLT_MIN 1.175494351e-38 // Minimum normalized positive floating-point number\n#define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats\n#define HALF_MAX 65504.0 // (2 - 2^-10) * 2^15\n\nfloat min3(vec3 val) { return min(min(val.x, val.y), val.z); }\nfloat max3(vec3 val) { return max(max(val.x, val.y), val.z); }\n\nconst float INVERT_LOG10 = 0.43429448190325176;\n\nfloat log10(float x){\n return log(x) * INVERT_LOG10;\n}\n\n#endif";
|
|
98
|
+
|
|
99
|
+
var PostProcess_Tonemapping_ACES_ColorTransform = "#ifndef COLOR_TRANSFORM\n#define COLOR_TRANSFORM\n\n// Precomputed matrices (pre-transposed)\n// See https://github.com/ampas/aces-dev/blob/master/transforms/ctl/README-MATRIX.md\n\n const mediump mat3 sRGB_2_AP0 = mat3(\n 0.4397010, 0.0897923, 0.0175440,\n 0.3829780, 0.8134230, 0.1115440,\n 0.1773350, 0.0967616, 0.8707040\n );\n\n const mediump mat3 AP1_2_AP0_MAT = mat3(\n vec3(0.6954522414, 0.0447945634, -0.0055258826),\n vec3(0.1406786965, 0.8596711185, 0.0040252103),\n vec3(0.1638690622, 0.0955343182, 1.0015006723)\n );\n\n const mediump mat3 AP0_2_AP1_MAT = mat3(\n\tvec3(1.4514393161, -0.0765537734, 0.0083161484),\n vec3(-0.2365107469, 1.1762296998, -0.0060324498),\n vec3(-0.2149285693, -0.0996759264, 0.9977163014)\n );\n\n const mediump mat3 AP1_2_XYZ_MAT = mat3(\n vec3(0.6624541811, 0.2722287168, -0.0055746495),\n vec3(0.1340042065, 0.6740817658, 0.0040607335),\n vec3(0.1561876870, 0.0536895174, 1.0103391003)\n );\n\n const mediump mat3 XYZ_2_AP1_MAT = mat3(\n vec3(1.6410233797, -0.6636628587, 0.0117218943),\n vec3(-0.3248032942, 1.6153315917, -0.0082844420),\n vec3(-0.2364246952, 0.0167563477, 0.9883948585)\n );\n\n const mediump mat3 D60_2_D65_CAT = mat3(\n vec3(0.987224, -0.00759836, 0.00307257),\n vec3(-0.00611327, 1.00186, -0.00509595),\n vec3(0.0159533, 0.00533002, 1.08168)\n );\n\n const mediump mat3 XYZ_2_REC709_MAT = mat3(\n vec3(3.2409699419, -0.9692436363, 0.0556300797),\n vec3(-1.5373831776, 1.8759675015, -0.2039769589),\n vec3(-0.498610760, 0.0415550574, 1.0569715142)\n );\n\n const mediump vec3 AP1_RGB2Y = vec3(0.2722287168, 0.6740817658, 0.0536895174);\n\n mediump float rgb_2_saturation(mediump vec3 rgb){\n const mediump float TINY = 1e-4;\n mediump float mi = min3(rgb);\n mediump float ma = max3(rgb);\n return (max(ma, TINY) - max(mi, TINY)) / max(ma, 1e-2);\n }\n\n mediump float rgb_2_yc(mediump vec3 rgb){\n const mediump float ycRadiusWeight = 1.75;\n\n // Converts RGB to a luminance proxy, here called YC\n // YC is ~ Y + K * Chroma\n // Constant YC is a cone-shaped surface in RGB space, with the tip on the\n // neutral axis, towards white.\n // YC is normalized: RGB 1 1 1 maps to YC = 1\n //\n // ycRadiusWeight defaults to 1.75, although can be overridden in function\n // call to rgb_2_yc\n // ycRadiusWeight = 1 -> YC for pure cyan, magenta, yellow == YC for neutral\n // of same value\n // ycRadiusWeight = 2 -> YC for pure red, green, blue == YC for neutral of\n // same value.\n\n mediump float r = rgb.x;\n mediump float g = rgb.y;\n mediump float b = rgb.z;\n mediump float k = b * (b - g) + g * (g - r) + r * (r - b);\n k = max(k, 0.0); // Clamp to avoid precision issue causing k < 0, making sqrt(k) undefined\n float chroma = k == 0.0 ? 0.0 : sqrt(k); // Avoid NaN\n\n return (b + g + r + ycRadiusWeight * chroma) / 3.0;\n }\n\n mediump float rgb_2_hue(mediump vec3 rgb){\n // Returns a geometric hue angle in degrees (0-360) based on RGB values.\n // For neutral colors, hue is undefined and the function will return a quiet NaN value.\n mediump float hue;\n if (rgb.x == rgb.y && rgb.y == rgb.z){\n hue = 0.0; // RGB triplets where RGB are equal have an undefined hue\n } else{\n hue = (180.0 / PI) * atan(sqrt(3.0) * (rgb.y - rgb.z), 2.0 * rgb.x - rgb.y - rgb.z);\n }\n\n if (hue < 0.0){\n hue = hue + 360.0;\n }\n\n return hue;\n }\n\n mediump float center_hue(mediump float hue, mediump float centerH){\n mediump float hueCentered = hue - centerH;\n if (hueCentered < -180.0){\n hueCentered = hueCentered + 360.0;\n } else if (hueCentered > 180.0){\n hueCentered = hueCentered - 360.0;\n }\n\n return hueCentered;\n }\n\n\n\n#endif";
|
|
100
|
+
|
|
101
|
+
var PostProcess_Tonemapping_ACES_ODT = "#ifndef ODT_GLSL\n#define ODT_GLSL\n\n#include \"ShaderLibrary/PostProcess/Tonemapping/ACES/Tonescale.glsl\"\n\n// Output Device Transform - RGB computer monitor\n\nconst float CINEMA_WHITE = 48.0;\nconst float CINEMA_BLACK = 0.02; // CINEMA_WHITE / 2400.0;\nconst float ODT_SAT_FACTOR = 0.93;\n\nmediump vec3 Y_2_linCV(mediump vec3 Y, mediump float Ymax, mediump float Ymin){\n return (Y - Ymin) / (Ymax - Ymin);\n}\n\nmediump vec3 XYZ_2_xyY(mediump vec3 XYZ){\n mediump float divisor = max(dot(XYZ, vec3(1.0)), 1e-4);\n return vec3(XYZ.xy / divisor, XYZ.y);\n}\n\nmediump vec3 xyY_2_XYZ(mediump vec3 xyY){\n mediump float m = xyY.z / max(xyY.y, 1e-4);\n mediump vec3 XYZ = vec3(xyY.xz, (1.0 - xyY.x - xyY.y));\n XYZ.xz *= m;\n return XYZ;\n}\n\nconst mediump float DIM_SURROUND_GAMMA = 0.9811;\n\nmediump vec3 darkSurround_to_dimSurround(mediump vec3 linearCV){\n // Extra conversions to float3/vec3 are required to avoid floating-point precision issues on some platforms.\n\n mediump vec3 XYZ = AP1_2_XYZ_MAT * linearCV;\n mediump vec3 xyY = XYZ_2_xyY(XYZ);\n xyY.z = clamp(xyY.z, 0.0, HALF_MAX);\n xyY.z = pow(xyY.z, DIM_SURROUND_GAMMA);\n XYZ = xyY_2_XYZ(xyY);\n\n return XYZ_2_AP1_MAT * XYZ;\n}\n\n//\n// Summary :\n// This transform is intended for mapping OCES onto a desktop computer monitor\n// typical of those used in motion picture visual effects production. These\n// monitors may occasionally be referred to as \"sRGB\" displays, however, the\n// monitor for which this transform is designed does not exactly match the\n// specifications in IEC 61966-2-1:1999.\n//\n// The assumed observer adapted white is D65, and the viewing environment is\n// that of a dim surround.\n//\n// The monitor specified is intended to be more typical of those found in\n// visual effects production.\n//\n// Device Primaries :\n// Primaries are those specified in Rec. ITU-R BT.709\n// CIE 1931 chromaticities: x y Y\n// Red: 0.64 0.33\n// Green: 0.3 0.6\n// Blue: 0.15 0.06\n// White: 0.3127 0.329 100 cd/m^2\n//\n// Display EOTF :\n// The reference electro-optical transfer function specified in\n// IEC 61966-2-1:1999.\n//\n// Signal Range:\n// This transform outputs full range code values.\n//\n// Assumed observer adapted white point:\n// CIE 1931 chromaticities: x y\n// 0.3127 0.329\n//\n\n// Viewing Environment:\n// This ODT has a compensation for viewing environment variables more typical\n// of those associated with video mastering.\n//\nmediump vec3 ODT_RGBmonitor_100nits_dim(mediump vec3 oces){\n // The metal compiler does not optimize structure access\n // const SegmentedSplineParams_c9 ODT_48nits = SegmentedSplineParams_c9(\n // // coefsLow[10]\n // float[10]( -1.6989700043, -1.6989700043, -1.4779000000, -1.2291000000, -0.8648000000, -0.4480000000, 0.0051800000, 0.4511080334, 0.9113744414, 0.9113744414),\n // // coefsHigh[10]\n // float[10]( 0.5154386965, 0.8470437783, 1.1358000000, 1.3802000000, 1.5197000000, 1.5985000000, 1.6467000000, 1.6746091357, 1.6878733390, 1.6878733390 ),\n // vec2(segmented_spline_c5_fwd(0.18*pow(2.,-6.5)), 0.02), // minPoint\n // vec2(segmented_spline_c5_fwd(0.18), 4.8), // midPoint\n // vec2(segmented_spline_c5_fwd(0.18*pow(2.,6.5)), 48.0), // maxPoint\n // 0.0, // slopeLow\n // 0.04 // slopeHigh\n // );\n\n // OCES to RGB rendering space\n mediump vec3 rgbPre = AP0_2_AP1_MAT * oces;\n\n // Apply the tonescale independently in rendering-space RGB\n mediump vec3 rgbPost;\n\n // rgbPost.r = segmented_spline_c9_fwd(rgbPre.r, ODT_48nits);\n // rgbPost.g = segmented_spline_c9_fwd(rgbPre.g, ODT_48nits);\n // rgbPost.b = segmented_spline_c9_fwd(rgbPre.b, ODT_48nits);\n\n rgbPost.r = segmented_spline_c9_fwd(rgbPre.r);\n rgbPost.g = segmented_spline_c9_fwd(rgbPre.g);\n rgbPost.b = segmented_spline_c9_fwd(rgbPre.b);\n\n // Scale luminance to linear code value\n mediump vec3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK);\n\n // Apply gamma adjustment to compensate for dim surround\n linearCV = darkSurround_to_dimSurround(linearCV);\n\n // Apply desaturation to compensate for luminance difference\n linearCV = mix(vec3(dot(linearCV, AP1_RGB2Y)), linearCV, ODT_SAT_FACTOR);\n\n // Convert to display primary encoding\n // Rendering space RGB to XYZ\n mediump vec3 XYZ = AP1_2_XYZ_MAT * linearCV;\n\n // Apply CAT from ACES white point to assumed observer adapted white point\n XYZ = D60_2_D65_CAT * XYZ;\n\n // CIE XYZ to display primaries\n linearCV = XYZ_2_REC709_MAT * XYZ;\n\n // Handle out-of-gamut values\n // Clip values < 0 or > 1 (i.e. projecting outside the display primaries)\n linearCV = clamp(linearCV, vec3(0), vec3(1));\n\n // Unity already draws to a sRGB target\n return linearCV;\n}\n\n#endif";
|
|
102
|
+
|
|
103
|
+
var PostProcess_Tonemapping_ACES_RRT = "#ifndef RRT_GLSL\n#define RRT_GLSL\n\n#include \"ShaderLibrary/PostProcess/Tonemapping/ACES/Tonescale.glsl\"\n\n// Reference Rendering Transform (RRT)\n\n// Sigmoid function in the range 0 to 1 spanning -2 to +2.\nmediump float sigmoid_shaper(mediump float x){\n mediump float t = max(1.0 - abs(x / 2.0), 0.0);\n mediump float y = 1.0 + sign(x) * (1.0 - t * t);\n\n return y * 0.5;\n}\n\nmediump float glow_fwd(mediump float ycIn, mediump float glowGainIn, mediump float glowMid){\n mediump float glowGainOut;\n\n if (ycIn <= 2.0 / 3.0 * glowMid){\n glowGainOut = glowGainIn;\n } else if (ycIn >= 2.0 * glowMid){\n glowGainOut = 0.0;\n } else{\n glowGainOut = glowGainIn * (glowMid / ycIn - 1.0 / 2.0);\n }\n\n return glowGainOut;\n}\n\n\n// \"Glow\" module constants\nconst mediump float RRT_GLOW_GAIN = 0.05;\nconst mediump float RRT_GLOW_MID = 0.08;\n\n// Red modifier constants\nconst mediump float RRT_RED_SCALE = 0.82;\nconst mediump float RRT_RED_PIVOT = 0.03;\nconst mediump float RRT_RED_HUE = 0.0;\nconst mediump float RRT_RED_WIDTH = 135.0;\n\n// Desaturation contants\nconst mediump float RRT_SAT_FACTOR = 0.96;\n\n\n// ACES to OCES\nmediump vec3 RRT(mediump vec3 aces){\n // --- Glow module --- //\n mediump float saturation = rgb_2_saturation(aces);\n mediump float ycIn = rgb_2_yc(aces);\n mediump float s = sigmoid_shaper((saturation - 0.4) / 0.2);\n mediump float addedGlow = 1.0 + glow_fwd(ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);\n aces *= addedGlow;\n\n // --- Red modifier --- //\n mediump float hue = rgb_2_hue(aces);\n mediump float centeredHue = center_hue(hue, RRT_RED_HUE);\n\n mediump float hueWeight = smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centeredHue / RRT_RED_WIDTH));\n hueWeight *= hueWeight;\n\n aces.r += hueWeight * saturation * (RRT_RED_PIVOT - aces.r) * (1.0 - RRT_RED_SCALE);\n\n // --- ACES to RGB rendering space --- //\n aces = clamp(aces, 0.0, HALF_MAX); // avoids saturated negative colors from becoming positive in the matrix\n mediump vec3 rgbPre = AP0_2_AP1_MAT * aces;\n rgbPre = clamp(rgbPre, 0.0, HALF_MAX);\n\n // --- Global desaturation --- //\n rgbPre = mix(vec3(dot(rgbPre, AP1_RGB2Y)), rgbPre, RRT_SAT_FACTOR);\n\n // --- Apply the tonescale independently in rendering-space RGB --- //\n mediump vec3 rgbPost;\n rgbPost.x = segmented_spline_c5_fwd(rgbPre.x);\n rgbPost.y = segmented_spline_c5_fwd(rgbPre.y);\n rgbPost.z = segmented_spline_c5_fwd(rgbPre.z);\n\n // --- RGB rendering space to OCES --- //\n mediump vec3 outputVal = AP1_2_AP0_MAT * rgbPost;\n\n return outputVal;\n}\n\n#endif";
|
|
104
|
+
|
|
105
|
+
var PostProcess_Tonemapping_ACES_Tonescale = " #ifndef TONE_SCALE\n #define TONE_SCALE\n\n const mediump mat3 M = mat3(\n vec3(0.5, -1.0, 0.5),\n vec3(-1.0, 1.0, 0.5),\n vec3(0.5, 0.0, 0.0)\n );\n\n mediump float segmented_spline_c5_fwd(mediump float x){\n #ifdef GRAPHICS_API_WEBGL2\n const mediump float coefsLow[6] = float[6](-4.0000000000, -4.0000000000, -3.1573765773, -0.4852499958, 1.8477324706, 1.8477324706); // coefs for B-spline between minPoint and midPoint (units of log luminance)\n const mediump float coefsHigh[6] = float[6](-0.7185482425, 2.0810307172, 3.6681241237, 4.0000000000, 4.0000000000, 4.0000000000); // coefs for B-spline between midPoint and maxPoint (units of log luminance)\n #else\n const mediump float coefsLow_0 = -4.0000000000;\n const mediump float coefsLow_1 = -4.0000000000;\n const mediump float coefsLow_2 = -3.1573765773;\n const mediump float coefsLow_3 = -0.4852499958;\n const mediump float coefsLow_4 = 1.8477324706;\n const mediump float coefsLow_5 = 1.8477324706;\n\n const mediump float coefsHigh_0 = -0.7185482425;\n const mediump float coefsHigh_1 = 2.0810307172;\n const mediump float coefsHigh_2 = 3.6681241237;\n const mediump float coefsHigh_3 = 4.0000000000;\n const mediump float coefsHigh_4 = 4.0000000000;\n const mediump float coefsHigh_5 = 4.0000000000;\n #endif\n\n // const vec2 minPoint = vec2(0.18 * exp2(-15.0), 0.0001); // {luminance, luminance} linear extension below this\n const mediump vec2 minPoint = vec2(0.0000054931640625, 0.0001); // {luminance, luminance} linear extension below this\n const mediump vec2 midPoint = vec2(0.18, 0.48); // {luminance, luminance}\n // const vec2 maxPoint = vec2(0.18 * exp2(18.0), 10000.0); // {luminance, luminance} linear extension above this\n const mediump vec2 maxPoint = vec2(47185.92, 10000.0); // {luminance, luminance} linear extension above this\n const mediump float slopeLow = 0.0; // log-log slope of low linear extension\n const mediump float slopeHigh = 0.0; // log-log slope of high linear extension\n\n const int N_KNOTS_LOW = 4;\n const int N_KNOTS_HIGH = 4;\n\n // Check for negatives or zero before taking the log. If negative or zero,\n // set to ACESMIN.1\n mediump float logx = log10(max(x, HALF_MIN));\n mediump float logy;\n\n if (logx <= log10(minPoint.x)){\n logy = logx * slopeLow + (log10(minPoint.y) - slopeLow * log10(minPoint.x));\n } else if ((logx > log10(minPoint.x)) && (logx < log10(midPoint.x))){\n mediump float knot_coord = float(N_KNOTS_LOW - 1) * (logx - log10(minPoint.x)) / (log10(midPoint.x) - log10(minPoint.x));\n int j = int(knot_coord);\n mediump float t = knot_coord - float(j);\n\n mediump vec3 cf;\n #ifdef GRAPHICS_API_WEBGL2\n cf = vec3(coefsLow[j], coefsLow[j + 1], coefsLow[j + 2]);\n #else\n if (j <= 0) {\n cf = vec3(coefsLow_0, coefsLow_1, coefsLow_2);\n } else if (j == 1) {\n cf = vec3(coefsLow_1, coefsLow_2, coefsLow_3);\n } else if (j == 2) {\n cf = vec3(coefsLow_2, coefsLow_3, coefsLow_4);\n } else { // if (j == 3)\n cf = vec3(coefsLow_3, coefsLow_4, coefsLow_5);\n }\n #endif\n\n mediump vec3 monomials = vec3(t * t, t, 1.0);\n logy = dot(monomials, M * cf);\n } else if ((logx >= log10(midPoint.x)) && (logx < log10(maxPoint.x))){\n mediump float knot_coord = float(N_KNOTS_HIGH - 1) * (logx - log10(midPoint.x)) / (log10(maxPoint.x) - log10(midPoint.x));\n int j = int(knot_coord);\n mediump float t = knot_coord - float(j);\n\n mediump vec3 cf;\n #ifdef GRAPHICS_API_WEBGL2\n cf = vec3(coefsHigh[j], coefsHigh[j + 1], coefsHigh[j + 2]);\n #else\n if (j <= 0) {\n cf = vec3(coefsHigh_0, coefsHigh_1, coefsHigh_2);\n } else if (j == 1) {\n cf = vec3(coefsHigh_1, coefsHigh_2, coefsHigh_3);\n } else if (j == 2) {\n cf = vec3(coefsHigh_2, coefsHigh_3, coefsHigh_4);\n } else { // if (j == 3)\n cf = vec3(coefsHigh_3, coefsHigh_4, coefsHigh_5);\n }\n #endif\n\n mediump vec3 monomials = vec3(t * t, t, 1.0);\n logy = dot(monomials, M * cf);\n } else {\n logy = logx * slopeHigh + (log10(maxPoint.y) - slopeHigh * log10(maxPoint.x));\n }\n\n return pow(10.0, logy);\n }\n\n // The metal compiler does not optimize structure access\n // struct SegmentedSplineParams_c9{\n // float coefsLow[10]; // coefs for B-spline between minPoint and midPoint (units of log luminance)\n // float coefsHigh[10]; // coefs for B-spline between midPoint and maxPoint (units of log luminance)\n // mediump vec2 minPoint; // {luminance, luminance} linear extension below this\n // mediump vec2 midPoint; // {luminance, luminance}\n // mediump vec2 maxPoint; // {luminance, luminance} linear extension above this\n // float slopeLow; // log-log slope of low linear extension\n // float slopeHigh; // log-log slope of high linear extension\n // };\n\n\n mediump float segmented_spline_c9_fwd(mediump float x){\n // ODT_48nits\n #ifdef GRAPHICS_API_WEBGL2\n const mediump float coefsLow[10] = float[10](-1.6989700043, -1.6989700043, -1.4779000000, -1.2291000000, -0.8648000000, -0.4480000000, 0.0051800000, 0.4511080334, 0.9113744414, 0.9113744414);\n const mediump float coefsHigh[10] = float[10](0.5154386965, 0.8470437783, 1.1358000000, 1.3802000000, 1.5197000000, 1.5985000000, 1.6467000000, 1.6746091357, 1.6878733390, 1.6878733390);\n #else\n const mediump float coefsLow_0 = -1.6989700043;\n const mediump float coefsLow_1 = -1.6989700043;\n const mediump float coefsLow_2 = -1.4779000000;\n const mediump float coefsLow_3 = -1.2291000000;\n const mediump float coefsLow_4 = -0.8648000000;\n const mediump float coefsLow_5 = -0.4480000000;\n const mediump float coefsLow_6 = 0.0051800000;\n const mediump float coefsLow_7 = 0.4511080334;\n const mediump float coefsLow_8 = 0.9113744414;\n const mediump float coefsLow_9 = 0.9113744414;\n\n const mediump float coefsHigh_0 = 0.5154386965;\n const mediump float coefsHigh_1 = 0.8470437783;\n const mediump float coefsHigh_2 = 1.1358000000;\n const mediump float coefsHigh_3 = 1.3802000000;\n const mediump float coefsHigh_4 = 1.5197000000;\n const mediump float coefsHigh_5 = 1.5985000000;\n const mediump float coefsHigh_6 = 1.6467000000;\n const mediump float coefsHigh_7 = 1.6746091357;\n const mediump float coefsHigh_8 = 1.6878733390;\n const mediump float coefsHigh_9 = 1.6878733390;\n #endif\n\n // mediump vec2 minPoint = vec2(segmented_spline_c5_fwd(0.18 * pow(2.0, -6.5)), 0.02);\n // mediump vec2 midPoint = vec2(segmented_spline_c5_fwd(0.18), 4.8);\n // mediump vec2 maxPoint = vec2(segmented_spline_c5_fwd(0.18 * pow(2., 6.5)), 48.0);\n\n const mediump vec2 minPoint = vec2(0.0028799, 0.02);\n const mediump vec2 midPoint = vec2(4.799999, 4.8);\n const mediump vec2 maxPoint = vec2(1005.719, 48.0);\n\n const mediump float slopeLow = 0.0;\n const mediump float slopeHigh = 0.04;\n\n const int N_KNOTS_LOW = 8;\n const int N_KNOTS_HIGH = 8;\n\n // Check for negatives or zero before taking the log. If negative or zero,\n // set to OCESMIN.\n mediump float logx = log10(max(x, 1e-4));\n mediump float logy;\n\n if (logx <= log10(minPoint.x)) {\n logy = logx * slopeLow + (log10(minPoint.y) - slopeLow * log10(minPoint.x));\n } else if ((logx > log10(minPoint.x)) && (logx < log10(midPoint.x))) {\n mediump float knot_coord = float(N_KNOTS_LOW - 1) * (logx - log10(minPoint.x)) / (log10(midPoint.x) - log10(minPoint.x));\n int j = int(knot_coord);\n mediump float t = knot_coord - float(j);\n\n mediump vec3 cf;\n #ifdef GRAPHICS_API_WEBGL2\n cf = vec3(coefsLow[j], coefsLow[j + 1], coefsLow[j + 2]);\n #else\n if (j <= 0) {\n cf = vec3(coefsLow_0, coefsLow_1, coefsLow_2);\n } else if (j == 1) {\n cf = vec3(coefsLow_1, coefsLow_2, coefsLow_3);\n } else if (j == 2) {\n cf = vec3(coefsLow_2, coefsLow_3, coefsLow_4);\n } else if (j == 3) {\n cf = vec3(coefsLow_3, coefsLow_4, coefsLow_5);\n } else if (j == 4) {\n cf = vec3(coefsLow_4, coefsLow_5, coefsLow_6);\n } else if (j == 5) {\n cf = vec3(coefsLow_5, coefsLow_6, coefsLow_7);\n } else if (j == 6) {\n cf = vec3(coefsLow_6, coefsLow_7, coefsLow_8);\n } else { // if (j == 7)\n cf = vec3(coefsLow_7, coefsLow_8, coefsLow_9);\n }\n #endif\n\n mediump vec3 monomials = vec3(t * t, t, 1.0);\n logy = dot(monomials, M * cf);\n } else if ((logx >= log10(midPoint.x)) && (logx < log10(maxPoint.x))) {\n mediump float knot_coord = float(N_KNOTS_HIGH - 1) * (logx - log10(midPoint.x)) / (log10(maxPoint.x) - log10(midPoint.x));\n int j = int(knot_coord);\n mediump float t = knot_coord - float(j);\n\n mediump vec3 cf;\n #ifdef GRAPHICS_API_WEBGL2\n cf = vec3(coefsHigh[j], coefsHigh[j + 1], coefsHigh[j + 2]);\n #else\n if (j <= 0) {\n cf = vec3(coefsHigh_0, coefsHigh_1, coefsHigh_2);\n } else if (j == 1) {\n cf = vec3(coefsHigh_1, coefsHigh_2, coefsHigh_3);\n } else if (j == 2) {\n cf = vec3(coefsHigh_2, coefsHigh_3, coefsHigh_4);\n } else if (j == 3) {\n cf = vec3(coefsHigh_3, coefsHigh_4, coefsHigh_5);\n } else if (j == 4) {\n cf = vec3(coefsHigh_4, coefsHigh_5, coefsHigh_6);\n } else if (j == 5) {\n cf = vec3(coefsHigh_5, coefsHigh_6, coefsHigh_7);\n } else if (j == 6) {\n cf = vec3(coefsHigh_6, coefsHigh_7, coefsHigh_8);\n } else { // if (j == 7)\n cf = vec3(coefsHigh_7, coefsHigh_8, coefsHigh_9);\n }\n #endif\n\n mediump vec3 monomials = vec3(t * t, t, 1.0);\n logy = dot(monomials, M * cf);\n } else {\n logy = logx * slopeHigh + (log10(maxPoint.y) - slopeHigh * log10(maxPoint.x));\n }\n\n return pow(10.0, logy);\n }\n\n\n#endif";
|
|
106
|
+
|
|
107
|
+
var PostProcess_Tonemapping_ACESTonemapping = "#ifndef ACES_TONEMAPPING\n#define ACES_TONEMAPPING\n\n#include \"ShaderLibrary/PostProcess/Tonemapping/ACES/ColorTransform.glsl\"\n#include \"ShaderLibrary/PostProcess/Tonemapping/ACES/RRT.glsl\"\n#include \"ShaderLibrary/PostProcess/Tonemapping/ACES/ODT.glsl\"\n\nvec3 ACESTonemap(vec3 color){\n vec3 aces = sRGB_2_AP0 * color;\n\n // --- Glow module --- //\n mediump float saturation = rgb_2_saturation(aces);\n mediump float ycIn = rgb_2_yc(aces);\n mediump float s = sigmoid_shaper((saturation - 0.4) / 0.2);\n float addedGlow = 1.0 + glow_fwd(ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);\n aces *= addedGlow;\n\n // --- Red modifier --- //\n mediump float hue = rgb_2_hue(vec3(aces));\n mediump float centeredHue = center_hue(hue, RRT_RED_HUE);\n float hueWeight = smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centeredHue / RRT_RED_WIDTH));\n hueWeight *= hueWeight;\n\n aces.r += hueWeight * saturation * (RRT_RED_PIVOT - aces.r) * (1.0 - RRT_RED_SCALE);\n\n // --- ACES to RGB rendering space --- //\n vec3 acescg = max(AP0_2_AP1_MAT * aces, 0.0);\n\n // --- Global desaturation --- //\n acescg = mix(vec3(dot(acescg, AP1_RGB2Y)), acescg, RRT_SAT_FACTOR);\n\n // Apply RRT and ODT\n // https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl\n const float a = 0.0245786;\n const float b = 0.000090537;\n const float c = 0.983729;\n const float d = 0.4329510;\n const float e = 0.238081;\n\n // To reduce the likelyhood of extremely large values, we avoid using the x^2 term and therefore\n // divide numerator and denominator by it. This will lead to the constant factors of the\n // quadratic in the numerator and denominator to be divided by x; we add a tiny epsilon to avoid divide by 0.\n vec3 rcpAcesCG = 1.0 / (acescg + FLT_MIN);\n mediump vec3 rgbPost = (acescg + a - b * rcpAcesCG) /\n (acescg * c + d + e * rcpAcesCG);\n\n // Apply gamma adjustment to compensate for dim surround\n vec3 linearCV = darkSurround_to_dimSurround(rgbPost);\n\n // Apply desaturation to compensate for luminance difference\n linearCV = mix(vec3(dot(linearCV, AP1_RGB2Y)), linearCV, ODT_SAT_FACTOR);\n\n // Convert to display primary encoding\n // Rendering space RGB to XYZ\n vec3 XYZ = AP1_2_XYZ_MAT * linearCV;\n\n // Apply CAT from ACES white point to assumed observer adapted white point\n XYZ = D60_2_D65_CAT * XYZ;\n\n // CIE XYZ to display primaries\n linearCV = XYZ_2_REC709_MAT * XYZ;\n\n return linearCV;\n\n}\n\n#endif";
|
|
108
|
+
|
|
109
|
+
var PostProcess_Tonemapping_NeutralTonemapping = "#ifndef NEUTRAL_TONEMAPPING\n#define NEUTRAL_TONEMAPPING\n\n// Neutral tonemapping (Hable/Hejl/Frostbite)\n// Input is linear RGB\n// More accuracy to avoid NaN on extremely high values.\nvec3 neutralCurve(vec3 x, float a, float b, float c, float d, float e, float f){\n return vec3(((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f);\n}\n\n#define TONEMAPPING_CLAMP_MAX 435.18712 //(-b + sqrt(b * b - 4 * a * (HALF_MAX - d * f))) / (2 * a * whiteScale)\n//Extremely high values cause NaN output when using fp16, we clamp to avoid the performace hit of switching to fp32\n//The overflow happens in (x * (a * x + b) + d * f) of the NeutralCurve, highest value that avoids fp16 precision errors is ~571.56873\n//Since whiteScale is constant (~1.31338) max input is ~435.18712\n\nvec3 neutralTonemap(vec3 color){\n const float a = 0.2;\n const float b = 0.29;\n const float c = 0.24;\n const float d = 0.272;\n const float e = 0.02;\n const float f = 0.3;\n // const float whiteLevel = 5.3;\n // const float whiteClip = 1.0;\n\n #ifndef GL_FRAGMENT_PRECISION_HIGH\n color = min(color, TONEMAPPING_CLAMP_MAX);\n #endif\n\n // 1.0 / neutralCurve(whiteLevel, a, b, c, d, e, f);\n const float whiteScale = 1.31338;\n color = neutralCurve(color * whiteScale, a, b, c, d, e, f);\n color *= whiteScale;\n\n // Post-curve white point adjustment\n // color /= whiteClip;\n\n return color;\n}\n\n#endif";
|
|
110
|
+
|
|
111
|
+
var PostProcess_UberPost = "#ifndef UBER_POST\n#define UBER_POST\n\n#include \"ShaderLibrary/PostProcess/PostCommon.glsl\"\n#include \"ShaderLibrary/PostProcess/Filtering.glsl\"\n#include \"ShaderLibrary/PostProcess/Tonemapping/NeutralTonemapping.glsl\"\n#include \"ShaderLibrary/PostProcess/Tonemapping/ACESTonemapping.glsl\"\n\nmediump sampler2D renderer_BlitTexture;\nvec4 renderer_texelSize;\n#ifdef ENABLE_EFFECT_BLOOM\n\tmediump sampler2D material_BloomTexture;\n\tmediump sampler2D material_BloomDirtTexture;\n\tvec4 material_BloomTint;\n\tvec4 material_BloomDirtTilingOffset;\n\tvec4 material_BloomIntensityParams;\n#endif\n\nvoid frag(Varyings v) {\n\tmediump vec4 color = texture2DSRGB(renderer_BlitTexture, v.v_uv);\n\n\t#ifdef ENABLE_EFFECT_BLOOM\n \t#ifdef BLOOM_HQ\n \t mediump vec4 bloom = sampleTexture2DBicubic(material_BloomTexture, v.v_uv, renderer_texelSize);\n \t#else\n \t mediump vec4 bloom = texture2DSRGB(material_BloomTexture, v.v_uv);\n \t#endif\n\n \tbloom *= material_BloomIntensityParams.x;\n \tcolor += bloom * material_BloomTint;\n\n \t#ifdef BLOOM_DIRT\n \t mediump vec4 dirt = texture2DSRGB(material_BloomDirtTexture, v.v_uv * material_BloomDirtTilingOffset.xy + material_BloomDirtTilingOffset.zw);\n \t dirt *= material_BloomIntensityParams.y;\n \t // Additive bloom (artist friendly)\n \t color += dirt * bloom;\n \t#endif\n\t#endif\n\n\t#ifdef ENABLE_EFFECT_TONEMAPPING\n\t\t#if TONEMAPPING_MODE == 0\n \t\tcolor.rgb = neutralTonemap(color.rgb);\n \t#elif TONEMAPPING_MODE == 1\n \t\tcolor.rgb = ACESTonemap(color.rgb);\n \t#endif\n\n \tcolor.rgb = clamp(color.rgb, vec3(0), vec3(1));\n\t#endif\n\n gl_FragColor = color;\n}\n\n#endif\n";
|
|
112
|
+
|
|
113
|
+
var Shadow_Shadow = "#ifndef SHADOW_INCLUDED\n#define SHADOW_INCLUDED\n\n\n#if defined(SCENE_SHADOW_TYPE) && defined(RENDERER_IS_RECEIVE_SHADOWS)\n #define NEED_CALCULATE_SHADOWS\n#endif\n\n\n#ifdef NEED_CALCULATE_SHADOWS\n mat4 scene_ShadowMatrices[SCENE_SHADOW_CASCADED_COUNT + 1];\n vec4 scene_ShadowSplitSpheres[4];\n\n mediump int computeCascadeIndex(vec3 positionWS) {\n vec3 fromCenter0 = positionWS - scene_ShadowSplitSpheres[0].xyz;\n vec3 fromCenter1 = positionWS - scene_ShadowSplitSpheres[1].xyz;\n vec3 fromCenter2 = positionWS - scene_ShadowSplitSpheres[2].xyz;\n vec3 fromCenter3 = positionWS - scene_ShadowSplitSpheres[3].xyz;\n\n mediump vec4 comparison = vec4(\n (dot(fromCenter0, fromCenter0) < scene_ShadowSplitSpheres[0].w),\n (dot(fromCenter1, fromCenter1) < scene_ShadowSplitSpheres[1].w),\n (dot(fromCenter2, fromCenter2) < scene_ShadowSplitSpheres[2].w),\n (dot(fromCenter3, fromCenter3) < scene_ShadowSplitSpheres[3].w));\n comparison.yzw = clamp(comparison.yzw - comparison.xyz,0.0,1.0);//keep the nearest\n mediump vec4 indexCoefficient = vec4(4.0,3.0,2.0,1.0);\n mediump int index = 4 - int(dot(comparison, indexCoefficient));\n return index;\n }\n\n vec3 getShadowCoord(vec3 positionWS) {\n #if SCENE_SHADOW_CASCADED_COUNT == 1\n mediump int cascadeIndex = 0;\n #else\n mediump int cascadeIndex = computeCascadeIndex(positionWS);\n #endif\n \n #ifdef GRAPHICS_API_WEBGL2\n mat4 shadowMatrix = scene_ShadowMatrices[cascadeIndex];\n #else\n mat4 shadowMatrix;\n #if SCENE_SHADOW_CASCADED_COUNT == 4\n if (cascadeIndex == 0) {\n shadowMatrix = scene_ShadowMatrices[0];\n } else if (cascadeIndex == 1) {\n shadowMatrix = scene_ShadowMatrices[1];\n } else if (cascadeIndex == 2) {\n shadowMatrix = scene_ShadowMatrices[2];\n } else if (cascadeIndex == 3) {\n shadowMatrix = scene_ShadowMatrices[3];\n } else {\n shadowMatrix = scene_ShadowMatrices[4];\n }\n #endif\n #if SCENE_SHADOW_CASCADED_COUNT == 2\n if (cascadeIndex == 0) {\n shadowMatrix = scene_ShadowMatrices[0];\n } else if (cascadeIndex == 1) {\n shadowMatrix = scene_ShadowMatrices[1];\n } else {\n shadowMatrix = scene_ShadowMatrices[2];\n } \n #endif\n #if SCENE_SHADOW_CASCADED_COUNT == 1\n if (cascadeIndex == 0) {\n shadowMatrix = scene_ShadowMatrices[0];\n } else {\n shadowMatrix = scene_ShadowMatrices[1];\n } \n #endif\n #endif\n \n vec4 shadowCoord = shadowMatrix * vec4(positionWS, 1.0);\n return shadowCoord.xyz;\n }\n#endif\n\n\n#ifdef NEED_CALCULATE_SHADOWS\n // intensity, null, fadeScale, fadeBias\n vec4 scene_ShadowInfo;\n vec4 scene_ShadowMapSize;\n\n #ifdef GRAPHICS_API_WEBGL2\n mediump sampler2DShadow scene_ShadowMap;\n #define SAMPLE_TEXTURE2D_SHADOW(textureName, coord3) textureLod(textureName, coord3 , 0.0)\n #define TEXTURE2D_SHADOW_PARAM(shadowMap) mediump sampler2DShadow shadowMap\n #else\n sampler2D scene_ShadowMap;\n #ifdef ENGINE_NO_DEPTH_TEXTURE\n const vec4 bitShift = vec4(1.0, 1.0/256.0, 1.0/(256.0*256.0), 1.0/(256.0*256.0*256.0));\n float textureShadowMapDowngrade(sampler2D scene_ShadowMap, vec3 shadowCoord){\n vec4 rgbaDepth = texture2D(scene_ShadowMap, shadowCoord.xy);\n float unpackDepth = dot(rgbaDepth, bitShift);\n return unpackDepth < shadowCoord.z ? 0.0 : 1.0;\n }\n #define SAMPLE_TEXTURE2D_SHADOW(textureName, coord3) textureShadowMapDowngrade(textureName, coord3)\n #else\n float textureShadowMapDowngrade(sampler2D scene_ShadowMap, vec3 shadowCoord){\n float depth = texture2D(scene_ShadowMap, shadowCoord.xy).r;\n return depth < shadowCoord.z ? 0.0 : 1.0;\n }\n #define SAMPLE_TEXTURE2D_SHADOW(textureName, coord3) textureShadowMapDowngrade(textureName, coord3)\n #endif\n #define TEXTURE2D_SHADOW_PARAM(shadowMap) mediump sampler2D shadowMap\n #endif\n\n #if SCENE_SHADOW_TYPE == 2\n float sampleShadowMapFiltered4(TEXTURE2D_SHADOW_PARAM(shadowMap), vec3 shadowCoord, vec4 shadowMapSize) {\n float attenuation;\n vec4 attenuation4;\n vec2 offset=shadowMapSize.xy/2.0;\n vec3 shadowCoord0=shadowCoord + vec3(-offset,0.0);\n vec3 shadowCoord1=shadowCoord + vec3(offset.x,-offset.y,0.0);\n vec3 shadowCoord2=shadowCoord + vec3(-offset.x,offset.y,0.0);\n vec3 shadowCoord3=shadowCoord + vec3(offset,0.0);\n attenuation4.x = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord0);\n attenuation4.y = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord1);\n attenuation4.z = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord2);\n attenuation4.w = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord3);\n attenuation = dot(attenuation4, vec4(0.25));\n return attenuation;\n }\n #endif\n\n #if SCENE_SHADOW_TYPE == 3\n #include \"ShaderLibrary/Shadow/ShadowSampleTent.glsl\"\n\n float sampleShadowMapFiltered9(TEXTURE2D_SHADOW_PARAM(shadowMap), vec3 shadowCoord, vec4 shadowmapSize) {\n float attenuation;\n float fetchesWeights[9];\n vec2 fetchesUV[9];\n sampleShadowComputeSamplesTent5x5(shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);\n attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[0].xy, shadowCoord.z));\n attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[1].xy, shadowCoord.z));\n attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[2].xy, shadowCoord.z));\n attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[3].xy, shadowCoord.z));\n attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[4].xy, shadowCoord.z));\n attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[5].xy, shadowCoord.z));\n attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[6].xy, shadowCoord.z));\n attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[7].xy, shadowCoord.z));\n attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[8].xy, shadowCoord.z));\n return attenuation;\n }\n #endif\n\n\n float getShadowFade(vec3 positionWS){\n vec3 camToPixel = positionWS - camera_Position;\n float distanceCamToPixel2 = dot(camToPixel, camToPixel);\n return saturate( distanceCamToPixel2 * scene_ShadowInfo.z + scene_ShadowInfo.w );\n }\n\n\n float sampleShadowMap(vec3 positionWS, vec3 shadowCoord) {\n float attenuation = 1.0;\n if(shadowCoord.z > 0.0 && shadowCoord.z < 1.0) {\n #if SCENE_SHADOW_TYPE == 1\n attenuation = SAMPLE_TEXTURE2D_SHADOW(scene_ShadowMap, shadowCoord);\n #endif\n\n #if SCENE_SHADOW_TYPE == 2\n attenuation = sampleShadowMapFiltered4(scene_ShadowMap, shadowCoord, scene_ShadowMapSize);\n #endif\n\n #if SCENE_SHADOW_TYPE == 3\n attenuation = sampleShadowMapFiltered9(scene_ShadowMap, shadowCoord, scene_ShadowMapSize);\n #endif\n\n float shadowFade = getShadowFade(positionWS);\n attenuation = mix(1.0, mix(attenuation, 1.0, shadowFade), scene_ShadowInfo.x);\n }\n return attenuation;\n }\n#endif\n\n\n#endif";
|
|
114
|
+
|
|
115
|
+
var Shadow_ShadowSampleTent = "#ifndef SHADOW_SAMPLE_TENT_INCLUDED\n#define SHADOW_SAMPLE_TENT_INCLUDED\n\n// ------------------------------------------------------------------\n// PCF Filtering Tent Functions\n// ------------------------------------------------------------------\n\n// Assuming a isoceles right angled triangle of height \"triangleHeight\" (as drawn below).\n// This function return the area of the triangle above the first texel(in Y the first texel).\n//\n// |\\ <-- 45 degree slop isosceles right angled triangle\n// | \\\n// ---- <-- length of this side is \"triangleHeight\"\n// _ _ _ _ <-- texels\nfloat sampleShadowGetIRTriangleTexelArea(float triangleHeight) {\n return triangleHeight - 0.5;\n}\n\n// Assuming a isoceles triangle of 1.5 texels height and 3 texels wide lying on 4 texels.\n// This function return the area of the triangle above each of those texels.\n// | <-- offset from -0.5 to 0.5, 0 meaning triangle is exactly in the center\n// / \\ <-- 45 degree slop isosceles triangle (ie tent projected in 2D)\n// / \\\n// _ _ _ _ <-- texels\n// X Y Z W <-- result indices (in computedArea.xyzw and computedAreaUncut.xyzw)\n// Top point at (right,top) in a texel,left bottom point at (middle,middle) in a texel,right bottom point at (middle,middle) in a texel.\nvoid sampleShadowGetTexelAreasTent3x3(float offset, out vec4 computedArea, out vec4 computedAreaUncut) {\n // Compute the exterior areas,a and h is same.\n float a = offset + 0.5;\n float offsetSquaredHalved = a * a * 0.5;\n computedAreaUncut.x = computedArea.x = offsetSquaredHalved - offset;\n computedAreaUncut.w = computedArea.w = offsetSquaredHalved;\n\n // Compute the middle areas\n // For Y : We find the area in Y of as if the left section of the isoceles triangle would\n // intersect the axis between Y and Z (ie where offset = 0).\n computedAreaUncut.y = sampleShadowGetIRTriangleTexelArea(1.5 - offset);\n // This area is superior to the one we are looking for if (offset < 0) thus we need to\n // subtract the area of the triangle defined by (0,1.5-offset), (0,1.5+offset), (-offset,1.5).\n float clampedOffsetLeft = min(offset,0.0);\n float areaOfSmallLeftTriangle = clampedOffsetLeft * clampedOffsetLeft;\n computedArea.y = computedAreaUncut.y - areaOfSmallLeftTriangle;\n\n // We do the same for the Z but with the right part of the isoceles triangle\n computedAreaUncut.z = sampleShadowGetIRTriangleTexelArea(1.5 + offset);\n float clampedOffsetRight = max(offset,0.0);\n float areaOfSmallRightTriangle = clampedOffsetRight * clampedOffsetRight;\n computedArea.z = computedAreaUncut.z - areaOfSmallRightTriangle;\n}\n\n// Assuming a isoceles triangle of 2.5 texel height and 5 texels wide lying on 6 texels.\n// This function return the weight of each texels area relative to the full triangle area.\n// / \\\n// _ _ _ _ _ _ <-- texels\n// 0 1 2 3 4 5 <-- computed area indices (in texelsWeights[])\n// Top point at (right,top) in a texel,left bottom point at (middle,middle) in a texel,right bottom point at (middle,middle) in a texel.\nvoid sampleShadowGetTexelWeightsTent5x5(float offset, out vec3 texelsWeightsA, out vec3 texelsWeightsB) {\n vec4 areaFrom3texelTriangle;\n vec4 areaUncutFrom3texelTriangle;\n sampleShadowGetTexelAreasTent3x3(offset, areaFrom3texelTriangle, areaUncutFrom3texelTriangle);\n\n // Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.\n // the 5 texel wide triangle can be seen as the 3 texel wide one but shifted up by one unit/texel.\n // 0.16 is 1/(the triangle area)\n texelsWeightsA.x = 0.16 * (areaFrom3texelTriangle.x);\n texelsWeightsA.y = 0.16 * (areaUncutFrom3texelTriangle.y);\n texelsWeightsA.z = 0.16 * (areaFrom3texelTriangle.y + 1.0);\n texelsWeightsB.x = 0.16 * (areaFrom3texelTriangle.z + 1.0);\n texelsWeightsB.y = 0.16 * (areaUncutFrom3texelTriangle.z);\n texelsWeightsB.z = 0.16 * (areaFrom3texelTriangle.w);\n}\n\n// 5x5 Tent filter (45 degree sloped triangles in U and V)\nvoid sampleShadowComputeSamplesTent5x5(vec4 shadowMapTextureTexelSize, vec2 coord, out float fetchesWeights[9], out vec2 fetchesUV[9])\n{\n // tent base is 5x5 base thus covering from 25 to 36 texels, thus we need 9 bilinear PCF fetches\n vec2 tentCenterInTexelSpace = coord.xy * shadowMapTextureTexelSize.zw;\n vec2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);\n vec2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;\n\n // find the weight of each texel based on the area of a 45 degree slop tent above each of them.\n vec3 texelsWeightsUA, texelsWeightsUB;\n vec3 texelsWeightsVA, texelsWeightsVB;\n sampleShadowGetTexelWeightsTent5x5(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsUA, texelsWeightsUB);\n sampleShadowGetTexelWeightsTent5x5(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsVA, texelsWeightsVB);\n\n // each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels\n vec3 fetchesWeightsU = vec3(texelsWeightsUA.xz, texelsWeightsUB.y) + vec3(texelsWeightsUA.y, texelsWeightsUB.xz);\n vec3 fetchesWeightsV = vec3(texelsWeightsVA.xz, texelsWeightsVB.y) + vec3(texelsWeightsVA.y, texelsWeightsVB.xz);\n\n // move the PCF bilinear fetches to respect texels weights\n vec3 fetchesOffsetsU = vec3(texelsWeightsUA.y, texelsWeightsUB.xz) / fetchesWeightsU.xyz + vec3(-2.5,-0.5,1.5);\n vec3 fetchesOffsetsV = vec3(texelsWeightsVA.y, texelsWeightsVB.xz) / fetchesWeightsV.xyz + vec3(-2.5,-0.5,1.5);\n fetchesOffsetsU *= shadowMapTextureTexelSize.xxx;\n fetchesOffsetsV *= shadowMapTextureTexelSize.yyy;\n\n vec2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTextureTexelSize.xy;\n fetchesUV[0] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.x);\n fetchesUV[1] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.x);\n fetchesUV[2] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.x);\n fetchesUV[3] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.y);\n fetchesUV[4] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.y);\n fetchesUV[5] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.y);\n fetchesUV[6] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.z);\n fetchesUV[7] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.z);\n fetchesUV[8] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.z);\n\n fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;\n fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;\n fetchesWeights[2] = fetchesWeightsU.z * fetchesWeightsV.x;\n fetchesWeights[3] = fetchesWeightsU.x * fetchesWeightsV.y;\n fetchesWeights[4] = fetchesWeightsU.y * fetchesWeightsV.y;\n fetchesWeights[5] = fetchesWeightsU.z * fetchesWeightsV.y;\n fetchesWeights[6] = fetchesWeightsU.x * fetchesWeightsV.z;\n fetchesWeights[7] = fetchesWeightsU.y * fetchesWeightsV.z;\n fetchesWeights[8] = fetchesWeightsU.z * fetchesWeightsV.z;\n}\n\n\n#endif";
|
|
116
|
+
|
|
117
|
+
var Skin_BlendShape = "#ifndef BLENDSHAPE_INCLUDED\n#define BLENDSHAPE_INCLUDED\n\n#ifdef RENDERER_HAS_BLENDSHAPE\n\t#ifdef RENDERER_BLENDSHAPE_USE_TEXTURE\n\t\tmediump sampler2DArray renderer_BlendShapeTexture;\n\t\tivec3 renderer_BlendShapeTextureInfo;\n\t\tfloat renderer_BlendShapeWeights[RENDERER_BLENDSHAPE_COUNT];\n\n\t\tvec3 getBlendShapeVertexElement(int blendShapeIndex, int vertexElementIndex){\t\t\t\n\t\t\tint y = vertexElementIndex / renderer_BlendShapeTextureInfo.y;\n\t\t\tint x = vertexElementIndex - y * renderer_BlendShapeTextureInfo.y;\n\t\t\tivec3 uv = ivec3(x, y , blendShapeIndex);\n\t\t\treturn (texelFetch(renderer_BlendShapeTexture, uv, 0)).xyz;\n\t\t}\n\t#else\n\t\t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) && defined( RENDERER_BLENDSHAPE_HAS_TANGENT )\n\t\t\tfloat renderer_BlendShapeWeights[2];\n\t\t#else\n\t\t\t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) || defined( RENDERER_BLENDSHAPE_HAS_TANGENT )\n\t\t\t\tfloat renderer_BlendShapeWeights[4];\n\t\t\t#else\n\t\t\t\tfloat renderer_BlendShapeWeights[8];\n\t\t\t#endif\n\t\t#endif\n\t#endif\n\n\tvoid calculateBlendShape(Attributes attributes, inout vec4 position\n #ifdef RENDERER_HAS_NORMAL\n ,inout vec3 normal\n\t\t\t #ifdef RENDERER_HAS_TANGENT\n \t,inout vec4 tangent\n \t#endif\n #endif\n \n\t){\n\t\t#ifdef RENDERER_BLENDSHAPE_USE_TEXTURE\t\n \t\tint vertexOffset = gl_VertexID * renderer_BlendShapeTextureInfo.x;\n \t\tfor(int i = 0; i < RENDERER_BLENDSHAPE_COUNT; i++){\n \t\t\tint vertexElementOffset = vertexOffset;\n \t\t\tfloat weight = renderer_BlendShapeWeights[i];\n \t\t\t// Warnning: Multiplying by 0 creates weird precision issues, causing rendering anomalies in Ace2 Android13\n \t\t\tif(weight != 0.0){\n \t\t\t\tposition.xyz += getBlendShapeVertexElement(i, vertexElementOffset) * weight;\n \n \t\t\t\t#if defined( RENDERER_HAS_NORMAL ) && defined( RENDERER_BLENDSHAPE_HAS_NORMAL )\n \t\t\t\t\tvertexElementOffset += 1;\n \t\t\t\t\tnormal += getBlendShapeVertexElement(i, vertexElementOffset) * weight;\n \t\t\t\t#endif\n \n \t\t\t\t#if defined( RENDERER_HAS_TANGENT ) && defined(RENDERER_BLENDSHAPE_HAS_TANGENT)\n \t\t\t\t\tvertexElementOffset += 1;\n \t\t\t\t\ttangent.xyz += getBlendShapeVertexElement(i, vertexElementOffset) * weight;\n \t\t\t\t#endif\n \t\t\t}\n \n \t\t}\n \t#else\n \t\tposition.xyz += attributes.POSITION_BS0 * renderer_BlendShapeWeights[0];\n \t\tposition.xyz += attributes.POSITION_BS1 * renderer_BlendShapeWeights[1];\n\n \t\t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) && defined( RENDERER_BLENDSHAPE_HAS_TANGENT )\n \t\t\t#ifdef RENDERER_HAS_NORMAL\n \t\t\t\tnormal += attributes.NORMAL_BS0 * renderer_BlendShapeWeights[0];\n \t\t\t\tnormal += attributes.NORMAL_BS1 * renderer_BlendShapeWeights[1];\n \t\t\t#endif\n \n \t\t\t#ifdef RENDERER_HAS_TANGENT\n \t\t\t\ttangent.xyz += attributes.TANGENT_BS0 * renderer_BlendShapeWeights[0];\n \t\t\t\ttangent.xyz += attributes.TANGENT_BS1 * renderer_BlendShapeWeights[1];\n \t\t\t#endif\t\t\t\t\n \t\t#else\n \t\t\t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) || defined( RENDERER_BLENDSHAPE_HAS_TANGENT )\n \t\t\t\tposition.xyz += attributes.POSITION_BS2 * renderer_BlendShapeWeights[2];\n \t\t\t\tposition.xyz += attributes.POSITION_BS3 * renderer_BlendShapeWeights[3];\n\n \t\t\t\t#if defined( RENDERER_BLENDSHAPE_HAS_NORMAL ) && defined( RENDERER_HAS_NORMAL )\n \t\t\t\t\tnormal += attributes.NORMAL_BS0 * renderer_BlendShapeWeights[0];\n \t\t\t\t\tnormal += attributes.NORMAL_BS1 * renderer_BlendShapeWeights[1];\n \t\t\t\t\tnormal += attributes.NORMAL_BS2 * renderer_BlendShapeWeights[2];\n \t\t\t\t\tnormal += attributes.NORMAL_BS3 * renderer_BlendShapeWeights[3];\n \t\t\t\t#endif\n\n \t\t\t\t#if defined(RENDERER_BLENDSHAPE_HAS_TANGENT) && defined( RENDERER_HAS_TANGENT )\n \t\t\t\t\ttangent.xyz += attributes.TANGENT_BS0 * renderer_BlendShapeWeights[0];\n \t\t\t\t\ttangent.xyz += attributes.TANGENT_BS1 * renderer_BlendShapeWeights[1];\n \t\t\t\t\ttangent.xyz += attributes.TANGENT_BS2 * renderer_BlendShapeWeights[2];\n \t\t\t\t\ttangent.xyz += attributes.TANGENT_BS3 * renderer_BlendShapeWeights[3];\n \t\t\t\t#endif\n \t\t\t#else\n \t\t\t\tposition.xyz += attributes.POSITION_BS2 * renderer_BlendShapeWeights[2];\n \t\t\t\tposition.xyz += attributes.POSITION_BS3 * renderer_BlendShapeWeights[3];\n \t\t\t\tposition.xyz += attributes.POSITION_BS4 * renderer_BlendShapeWeights[4];\n \t\t\t\tposition.xyz += attributes.POSITION_BS5 * renderer_BlendShapeWeights[5];\n \t\t\t\tposition.xyz += attributes.POSITION_BS6 * renderer_BlendShapeWeights[6];\n \t\t\t\tposition.xyz += attributes.POSITION_BS7 * renderer_BlendShapeWeights[7];\n \t\t\t#endif\n \t\t#endif\n \t#endif\n\t}\n\n#endif\n\n\n#endif";
|
|
118
|
+
|
|
119
|
+
var Skin_Skin = "#ifndef SKIN_INCLUDED\n#define SKIN_INCLUDED\n\n\n#ifdef RENDERER_HAS_SKIN\n #ifdef RENDERER_USE_JOINT_TEXTURE\n sampler2D renderer_JointSampler;\n float renderer_JointCount;\n\n mat4 getJointMatrix(sampler2D smp, float index){\n float base = index / renderer_JointCount;\n float hf = 0.5 / renderer_JointCount;\n float v = base + hf;\n\n vec4 m0 = texture2D(smp, vec2(0.125, v ));\n vec4 m1 = texture2D(smp, vec2(0.375, v ));\n vec4 m2 = texture2D(smp, vec2(0.625, v ));\n vec4 m3 = texture2D(smp, vec2(0.875, v ));\n\n return mat4(m0, m1, m2, m3);\n }\n #else\n mat4 renderer_JointMatrix[ RENDERER_JOINTS_NUM ];\n #endif\n\n mat4 getSkinMatrix(Attributes attributes){\n #ifdef RENDERER_USE_JOINT_TEXTURE\n mat4 skinMatrix =\n attributes.WEIGHTS_0.x * getJointMatrix(renderer_JointSampler, attributes.JOINTS_0.x ) +\n attributes.WEIGHTS_0.y * getJointMatrix(renderer_JointSampler, attributes.JOINTS_0.y ) +\n attributes.WEIGHTS_0.z * getJointMatrix(renderer_JointSampler, attributes.JOINTS_0.z ) +\n attributes.WEIGHTS_0.w * getJointMatrix(renderer_JointSampler, attributes.JOINTS_0.w );\n #else\n mat4 skinMatrix =\n attributes.WEIGHTS_0.x * renderer_JointMatrix[ int( attributes.JOINTS_0.x ) ] +\n attributes.WEIGHTS_0.y * renderer_JointMatrix[ int( attributes.JOINTS_0.y ) ] +\n attributes.WEIGHTS_0.z * renderer_JointMatrix[ int( attributes.JOINTS_0.z ) ] +\n attributes.WEIGHTS_0.w * renderer_JointMatrix[ int( attributes.JOINTS_0.w ) ];\n #endif\n\n return skinMatrix;\n }\n\n#endif\n\n\n#endif";
|
|
120
|
+
|
|
121
|
+
// Auto-generated by shader-compiler-precompile --emit-sources — do not edit.
|
|
122
|
+
// prettier-ignore
|
|
123
|
+
var shaderLibrary = [
|
|
124
|
+
{
|
|
125
|
+
source: BlinnPhong_ForwardPassBlinnPhong,
|
|
126
|
+
path: "ShaderLibrary/BlinnPhong/ForwardPassBlinnPhong.glsl"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
source: BlinnPhong_MobileBlinnPhong,
|
|
130
|
+
path: "ShaderLibrary/BlinnPhong/MobileBlinnPhong.glsl"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
source: Blit_BlitVertex,
|
|
134
|
+
path: "ShaderLibrary/Blit/BlitVertex.glsl"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
source: Common_Attributes,
|
|
138
|
+
path: "ShaderLibrary/Common/Attributes.glsl"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
source: Common_Common,
|
|
142
|
+
path: "ShaderLibrary/Common/Common.glsl"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
source: Common_Fog,
|
|
146
|
+
path: "ShaderLibrary/Common/Fog.glsl"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
source: Common_Normal,
|
|
150
|
+
path: "ShaderLibrary/Common/Normal.glsl"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
source: Common_Transform,
|
|
154
|
+
path: "ShaderLibrary/Common/Transform.glsl"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
source: Lighting_AmbientOcclusion_BilateralBlur,
|
|
158
|
+
path: "ShaderLibrary/Lighting/AmbientOcclusion/BilateralBlur.glsl"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
source: Lighting_AmbientOcclusion_ScalableAmbientOcclusion,
|
|
162
|
+
path: "ShaderLibrary/Lighting/AmbientOcclusion/ScalableAmbientOcclusion.glsl"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
source: Lighting_Light,
|
|
166
|
+
path: "ShaderLibrary/Lighting/Light.glsl"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
source: Noise_NoiseCommon,
|
|
170
|
+
path: "ShaderLibrary/Noise/NoiseCommon.glsl"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
source: Noise_NoiseSimplexGrad,
|
|
174
|
+
path: "ShaderLibrary/Noise/NoiseSimplexGrad.glsl"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
source: PBR_BSDF,
|
|
178
|
+
path: "ShaderLibrary/PBR/BSDF.glsl"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
source: PBR_ForwardPassPBR,
|
|
182
|
+
path: "ShaderLibrary/PBR/ForwardPassPBR.glsl"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
source: PBR_FragmentPBR,
|
|
186
|
+
path: "ShaderLibrary/PBR/FragmentPBR.glsl"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
source: PBR_LightDirectPBR,
|
|
190
|
+
path: "ShaderLibrary/PBR/LightDirectPBR.glsl"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
source: PBR_LightIndirectFunctions,
|
|
194
|
+
path: "ShaderLibrary/PBR/LightIndirectFunctions.glsl"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
source: PBR_LightIndirectPBR,
|
|
198
|
+
path: "ShaderLibrary/PBR/LightIndirectPBR.glsl"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
source: PBR_ReflectionLobe,
|
|
202
|
+
path: "ShaderLibrary/PBR/ReflectionLobe.glsl"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
source: PBR_Refraction,
|
|
206
|
+
path: "ShaderLibrary/PBR/Refraction.glsl"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
source: PBR_VaryingsPBR,
|
|
210
|
+
path: "ShaderLibrary/PBR/VaryingsPBR.glsl"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
source: PBR_VertexPBR,
|
|
214
|
+
path: "ShaderLibrary/PBR/VertexPBR.glsl"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
source: Particle_Billboard_HorizontalBillboard,
|
|
218
|
+
path: "ShaderLibrary/Particle/Billboard/HorizontalBillboard.glsl"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
source: Particle_Billboard_SphereBillboard,
|
|
222
|
+
path: "ShaderLibrary/Particle/Billboard/SphereBillboard.glsl"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
source: Particle_Billboard_StretchedBillboard,
|
|
226
|
+
path: "ShaderLibrary/Particle/Billboard/StretchedBillboard.glsl"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
source: Particle_Billboard_VerticalBillboard,
|
|
230
|
+
path: "ShaderLibrary/Particle/Billboard/VerticalBillboard.glsl"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
source: Particle_Module_ColorOverLifetime,
|
|
234
|
+
path: "ShaderLibrary/Particle/Module/ColorOverLifetime.glsl"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
source: Particle_Module_ForceOverLifetime,
|
|
238
|
+
path: "ShaderLibrary/Particle/Module/ForceOverLifetime.glsl"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
source: Particle_Module_LimitVelocityOverLifetime,
|
|
242
|
+
path: "ShaderLibrary/Particle/Module/LimitVelocityOverLifetime.glsl"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
source: Particle_Module_NoiseModule,
|
|
246
|
+
path: "ShaderLibrary/Particle/Module/NoiseModule.glsl"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
source: Particle_Module_RotationOverLifetime,
|
|
250
|
+
path: "ShaderLibrary/Particle/Module/RotationOverLifetime.glsl"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
source: Particle_Module_SizeOverLifetime,
|
|
254
|
+
path: "ShaderLibrary/Particle/Module/SizeOverLifetime.glsl"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
source: Particle_Module_TextureSheetAnimation,
|
|
258
|
+
path: "ShaderLibrary/Particle/Module/TextureSheetAnimation.glsl"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
source: Particle_Module_VelocityOverLifetime,
|
|
262
|
+
path: "ShaderLibrary/Particle/Module/VelocityOverLifetime.glsl"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
source: Particle_ParticleCommon,
|
|
266
|
+
path: "ShaderLibrary/Particle/ParticleCommon.glsl"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
source: Particle_ParticleFeedback,
|
|
270
|
+
path: "ShaderLibrary/Particle/ParticleFeedback.glsl"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
source: Particle_ParticleMesh,
|
|
274
|
+
path: "ShaderLibrary/Particle/ParticleMesh.glsl"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
source: PostProcess_Bloom_BloomBlurH,
|
|
278
|
+
path: "ShaderLibrary/PostProcess/Bloom/BloomBlurH.glsl"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
source: PostProcess_Bloom_BloomBlurV,
|
|
282
|
+
path: "ShaderLibrary/PostProcess/Bloom/BloomBlurV.glsl"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
source: PostProcess_Bloom_BloomPrefilter,
|
|
286
|
+
path: "ShaderLibrary/PostProcess/Bloom/BloomPrefilter.glsl"
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
source: PostProcess_Bloom_BloomUpsample,
|
|
290
|
+
path: "ShaderLibrary/PostProcess/Bloom/BloomUpsample.glsl"
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
source: PostProcess_FXAA_FXAA3_11,
|
|
294
|
+
path: "ShaderLibrary/PostProcess/FXAA/FXAA3_11.glsl"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
source: PostProcess_Filtering,
|
|
298
|
+
path: "ShaderLibrary/PostProcess/Filtering.glsl"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
source: PostProcess_FinalAntiAliasing$1,
|
|
302
|
+
path: "ShaderLibrary/PostProcess/FinalAntiAliasing.glsl"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
source: PostProcess_FinalSRGB$1,
|
|
306
|
+
path: "ShaderLibrary/PostProcess/FinalSRGB.glsl"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
source: PostProcess_PostCommon,
|
|
310
|
+
path: "ShaderLibrary/PostProcess/PostCommon.glsl"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
source: PostProcess_Tonemapping_ACES_ColorTransform,
|
|
314
|
+
path: "ShaderLibrary/PostProcess/Tonemapping/ACES/ColorTransform.glsl"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
source: PostProcess_Tonemapping_ACES_ODT,
|
|
318
|
+
path: "ShaderLibrary/PostProcess/Tonemapping/ACES/ODT.glsl"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
source: PostProcess_Tonemapping_ACES_RRT,
|
|
322
|
+
path: "ShaderLibrary/PostProcess/Tonemapping/ACES/RRT.glsl"
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
source: PostProcess_Tonemapping_ACES_Tonescale,
|
|
326
|
+
path: "ShaderLibrary/PostProcess/Tonemapping/ACES/Tonescale.glsl"
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
source: PostProcess_Tonemapping_ACESTonemapping,
|
|
330
|
+
path: "ShaderLibrary/PostProcess/Tonemapping/ACESTonemapping.glsl"
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
source: PostProcess_Tonemapping_NeutralTonemapping,
|
|
334
|
+
path: "ShaderLibrary/PostProcess/Tonemapping/NeutralTonemapping.glsl"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
source: PostProcess_UberPost,
|
|
338
|
+
path: "ShaderLibrary/PostProcess/UberPost.glsl"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
source: Shadow_Shadow,
|
|
342
|
+
path: "ShaderLibrary/Shadow/Shadow.glsl"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
source: Shadow_ShadowSampleTent,
|
|
346
|
+
path: "ShaderLibrary/Shadow/ShadowSampleTent.glsl"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
source: Skin_BlendShape,
|
|
350
|
+
path: "ShaderLibrary/Skin/BlendShape.glsl"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
source: Skin_Skin,
|
|
354
|
+
path: "ShaderLibrary/Skin/Skin.glsl"
|
|
355
|
+
}
|
|
356
|
+
];
|
|
357
|
+
|
|
358
|
+
var _2D_Sprite = "Shader \"2D/Sprite\" {\n SubShader \"Default\" {\n Pass \"Default\" {\n Tags { pipelineStage = \"Forward\" }\n\n BlendState = {\n Enabled = true;\n SourceColorBlendFactor = BlendFactor.SourceAlpha;\n DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;\n SourceAlphaBlendFactor = BlendFactor.One;\n DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;\n }\n DepthState = {\n WriteEnabled = false;\n }\n RasterState = {\n CullMode = CullMode.Off;\n }\n RenderQueueType = Transparent;\n\n VertexShader = SpriteVertex;\n FragmentShader = SpriteFragment;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n struct a2v {\n vec3 POSITION;\n vec2 TEXCOORD_0;\n vec4 COLOR_0;\n };\n\n struct v2f {\n vec2 v_uv;\n vec4 v_color;\n };\n\n mat4 renderer_MVPMat;\n sampler2D renderer_SpriteTexture;\n\n v2f SpriteVertex(a2v attr) {\n v2f v;\n gl_Position = renderer_MVPMat * vec4(attr.POSITION, 1.0);\n v.v_uv = attr.TEXCOORD_0;\n v.v_color = attr.COLOR_0;\n return v;\n }\n\n void SpriteFragment(v2f v) {\n vec4 baseColor = texture2DSRGB(renderer_SpriteTexture, v.v_uv);\n gl_FragColor = baseColor * v.v_color;\n }\n }\n }\n}\n";
|
|
359
|
+
|
|
360
|
+
var _2D_SpriteMask = "Shader \"2D/SpriteMask\" {\n SubShader \"Default\" {\n Pass \"Default\" {\n Tags { pipelineStage = \"Forward\" }\n\n VertexShader = SpriteMaskVertex;\n FragmentShader = SpriteMaskFragment;\n\n struct a2v {\n vec3 POSITION;\n vec2 TEXCOORD_0;\n };\n\n struct v2f {\n vec2 v_uv;\n };\n\n mat4 camera_VPMat;\n sampler2D renderer_MaskTexture;\n float renderer_MaskAlphaCutoff;\n\n v2f SpriteMaskVertex(a2v attr) {\n v2f v;\n gl_Position = camera_VPMat * vec4(attr.POSITION, 1.0);\n v.v_uv = attr.TEXCOORD_0;\n return v;\n }\n\n void SpriteMaskFragment(v2f v) {\n vec4 color = texture2D(renderer_MaskTexture, v.v_uv);\n if (color.a < renderer_MaskAlphaCutoff) {\n discard;\n }\n gl_FragColor = color;\n }\n }\n }\n}\n";
|
|
361
|
+
|
|
362
|
+
var _2D_Text = "Shader \"2D/Text\" {\n SubShader \"Default\" {\n Pass \"Default\" {\n Tags { pipelineStage = \"Forward\" }\n\n BlendState = {\n Enabled = true;\n SourceColorBlendFactor = BlendFactor.SourceAlpha;\n DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;\n SourceAlphaBlendFactor = BlendFactor.One;\n DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;\n }\n DepthState = {\n WriteEnabled = false;\n }\n RasterState = {\n CullMode = CullMode.Off;\n }\n RenderQueueType = Transparent;\n\n VertexShader = TextVertex;\n FragmentShader = TextFragment;\n\n struct a2v {\n vec3 POSITION;\n vec2 TEXCOORD_0;\n vec4 COLOR_0;\n };\n\n struct v2f {\n vec2 v_uv;\n vec4 v_color;\n };\n\n mat4 renderer_MVPMat;\n sampler2D renderElement_TextTexture;\n\n v2f TextVertex(a2v attr) {\n v2f v;\n gl_Position = renderer_MVPMat * vec4(attr.POSITION, 1.0);\n v.v_uv = attr.TEXCOORD_0;\n v.v_color = attr.COLOR_0;\n return v;\n }\n\n void TextFragment(v2f v) {\n vec4 texColor = texture2D(renderElement_TextTexture, v.v_uv);\n #ifdef GRAPHICS_API_WEBGL2\n float coverage = texColor.r;\n #else\n float coverage = texColor.a;\n #endif\n gl_FragColor = vec4(v.v_color.rgb, v.v_color.a * coverage);\n }\n }\n }\n}\n";
|
|
363
|
+
|
|
364
|
+
var _2D_UIDefault = "Shader \"2D/UIDefault\" {\n SubShader \"Default\" {\n Pass \"Default\" {\n Tags { pipelineStage = \"Forward\" }\n\n BlendState = {\n Enabled = true;\n SourceColorBlendFactor = BlendFactor.SourceAlpha;\n DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;\n SourceAlphaBlendFactor = BlendFactor.One;\n DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;\n ColorBlendOperation = BlendOperation.Add;\n AlphaBlendOperation = BlendOperation.Add;\n }\n DepthState = {\n WriteEnabled = false;\n }\n RasterState = {\n CullMode = CullMode.Off;\n }\n RenderQueueType = Transparent;\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n mat4 renderer_MVPMat;\n sampler2D renderer_UITexture;\n\n struct Attributes {\n vec3 POSITION;\n vec2 TEXCOORD_0;\n vec4 COLOR_0;\n };\n\n struct Varyings {\n vec2 v_uv;\n vec4 v_color;\n };\n\n Varyings vert(Attributes attr) {\n Varyings v;\n\n gl_Position = renderer_MVPMat * vec4(attr.POSITION, 1.0);\n v.v_uv = attr.TEXCOORD_0;\n v.v_color = attr.COLOR_0;\n\n return v;\n }\n\n void frag(Varyings v) {\n vec4 baseColor = texture2DSRGB(renderer_UITexture, v.v_uv);\n vec4 finalColor = baseColor * v.v_color;\n\n #ifdef ENGINE_SHOULD_SRGB_CORRECT\n finalColor = outputSRGBCorrection(finalColor);\n #endif\n\n gl_FragColor = finalColor;\n }\n }\n }\n}\n";
|
|
365
|
+
|
|
366
|
+
var BlinnPhong = "Shader \"BlinnPhong\" {\n Editor {\n Properties {\n Header(\"Base\") {\n material_BaseColor(\"BaseColor\", Color) = (1, 1, 1, 1);\n material_BaseTexture(\"BaseTexture\", Texture2D);\n }\n\n Header(\"Emissive\") {\n material_EmissiveColor(\"EmissiveColor\", HDRColor) = (0, 0, 0, 1);\n material_EmissiveTexture(\"EmissiveTexture\", Texture2D);\n }\n\n Header(\"Normal\") {\n material_NormalTexture(\"NormalTexture\", Texture2D);\n material_NormalIntensity(\"NormalIntensity\", Range(0, 5, 0.01)) = 1;\n }\n\n Header(\"Specular\") {\n material_SpecularColor(\"SpecularColor\", Color) = (1, 1, 1, 1);\n material_SpecularTexture(\"SpecularTexture\", Texture2D);\n material_Shininess(\"Shininess\", Range(0, 100, 1)) = 16;\n }\n\n Header(\"Common\") {\n isTransparent(\"Transparent\", Boolean) = false;\n renderFace(\"Render Face\", Enum(Front:0, Back:1, Double:2)) = 0;\n blendMode(\"Blend Mode\", Enum(Normal:0, Additive:1)) = 0;\n material_AlphaCutoff(\"AlphaCutoff\", Range(0, 1, 0.01)) = 0;\n material_TilingOffset(\"TilingOffset\", Vector4) = (1, 1, 0, 0);\n }\n }\n\n }\n\n SubShader \"Default\" {\n UsePass \"Pipeline/ShadowCaster/Default/ShadowCaster\"\n UsePass \"Pipeline/DepthOnly/Default/DepthOnly\"\n\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\" }\n\n RenderQueueType renderQueueType;\n BlendFactor sourceColorBlendFactor;\n BlendFactor destinationColorBlendFactor;\n BlendFactor sourceAlphaBlendFactor;\n BlendFactor destinationAlphaBlendFactor;\n CullMode rasterStateCullMode;\n Bool blendEnabled;\n Bool depthWriteEnabled;\n\n DepthState = {\n WriteEnabled = depthWriteEnabled;\n }\n\n BlendState = {\n Enabled = blendEnabled;\n SourceColorBlendFactor = sourceColorBlendFactor;\n DestinationColorBlendFactor = destinationColorBlendFactor;\n SourceAlphaBlendFactor = sourceAlphaBlendFactor;\n DestinationAlphaBlendFactor = destinationAlphaBlendFactor;\n }\n\n RasterState = {\n CullMode = rasterStateCullMode;\n }\n\n RenderQueueType = renderQueueType;\n\n VertexShader = BlinnPhongVertex;\n FragmentShader = BlinnPhongFragment;\n\n #include \"ShaderLibrary/BlinnPhong/ForwardPassBlinnPhong.glsl\"\n }\n }\n}\n";
|
|
367
|
+
|
|
368
|
+
var Blit_Blit = "Shader \"Blit/Blit\" {\n SubShader \"Default\" {\n Pass \"Forward\" {\n Tags { pipelineStage = \"Forward\" }\n\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n mediump sampler2D renderer_BlitTexture;\n #ifdef HAS_TEX_LOD\n float renderer_BlitMipLevel;\n #endif\n vec4 renderer_SourceScaleOffset;\n\n struct Attributes {\n vec4 POSITION_UV;\n };\n\n struct Varyings {\n vec2 v_uv;\n };\n\n Varyings vert(Attributes attr) {\n Varyings v;\n gl_Position = vec4(attr.POSITION_UV.xy, 0.0, 1.0);\n v.v_uv = attr.POSITION_UV.zw;\n return v;\n }\n\n #ifdef HAS_TEX_LOD\n vec4 texture2DLodSRGB(sampler2D tex, vec2 uv, float lod) {\n vec4 color = texture2DLodEXT(tex, uv, lod);\n #ifdef ENGINE_NO_SRGB\n color = sRGBToLinear(color);\n #endif\n return color;\n }\n #endif\n\n void frag(Varyings v) {\n vec2 uv = v.v_uv;\n uv = uv * renderer_SourceScaleOffset.xy + renderer_SourceScaleOffset.zw;\n\n #ifdef HAS_TEX_LOD\n gl_FragColor = texture2DLodSRGB(renderer_BlitTexture, uv, renderer_BlitMipLevel);\n #else\n gl_FragColor = texture2DSRGB(renderer_BlitTexture, uv);\n #endif\n }\n }\n }\n}\n";
|
|
369
|
+
|
|
370
|
+
var Blit_BlitScreen = "Shader \"Blit/BlitScreen\" {\n SubShader \"Default\" {\n Pass \"Forward\" {\n Tags { pipelineStage = \"Forward\" }\n\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n mediump sampler2D renderer_BlitTexture;\n #ifdef HAS_TEX_LOD\n float renderer_BlitMipLevel;\n #endif\n\n struct Attributes {\n vec4 POSITION_UV;\n };\n\n struct Varyings {\n vec2 v_uv;\n };\n\n Varyings vert(Attributes attr) {\n Varyings v;\n gl_Position = vec4(attr.POSITION_UV.xy, 0.0, 1.0);\n v.v_uv = attr.POSITION_UV.zw;\n return v;\n }\n\n #ifdef HAS_TEX_LOD\n vec4 texture2DLodSRGB(sampler2D tex, vec2 uv, float lod) {\n vec4 color = texture2DLodEXT(tex, uv, lod);\n #ifdef ENGINE_NO_SRGB\n color = sRGBToLinear(color);\n #endif\n return color;\n }\n #endif\n\n void frag(Varyings v) {\n vec2 uv = v.v_uv;\n // Screen uv is flipped\n uv.y = 1.0 - uv.y;\n\n #ifdef HAS_TEX_LOD\n gl_FragColor = texture2DLodSRGB(renderer_BlitTexture, uv, renderer_BlitMipLevel);\n #else\n gl_FragColor = texture2D(renderer_BlitTexture, uv);\n #endif\n\n // Color space in screen is in gamma space but without sRGB texture, so convert to linear space\n gl_FragColor = sRGBToLinear(gl_FragColor);\n }\n }\n }\n}\n";
|
|
371
|
+
|
|
372
|
+
var Effect_Particle = "Shader \"Effect/Particle\" {\n Editor {\n Properties {\n Header(\"Base\") {\n material_BaseColor(\"BaseColor\", Color) = (1, 1, 1, 1);\n material_BaseTexture(\"BaseTexture\", Texture2D);\n }\n Header(\"Emissive\") {\n material_EmissiveColor(\"EmissiveColor\", HDRColor) = (0, 0, 0, 1);\n material_EmissiveTexture(\"EmissiveTexture\", Texture2D);\n }\n Header(\"Common\") {\n isTransparent(\"Transparent\", Boolean) = false;\n renderFace(\"Render Face\", Enum(Front:0, Back:1, Double:2)) = 0;\n blendMode(\"Blend Mode\", Enum(Normal:0, Additive:1)) = 0;\n material_AlphaCutoff(\"AlphaCutoff\", Range(0, 1, 0.01)) = 0;\n }\n }\n }\n\n SubShader \"Default\" {\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\" }\n\n RenderQueueType renderQueueType;\n BlendFactor sourceColorBlendFactor;\n BlendFactor destinationColorBlendFactor;\n BlendFactor sourceAlphaBlendFactor;\n BlendFactor destinationAlphaBlendFactor;\n CullMode rasterStateCullMode;\n Bool blendEnabled;\n Bool depthWriteEnabled;\n\n BlendState = {\n Enabled = blendEnabled;\n SourceColorBlendFactor = sourceColorBlendFactor;\n DestinationColorBlendFactor = destinationColorBlendFactor;\n SourceAlphaBlendFactor = sourceAlphaBlendFactor;\n DestinationAlphaBlendFactor = destinationAlphaBlendFactor;\n }\n DepthState = {\n WriteEnabled = depthWriteEnabled;\n }\n RasterState = {\n CullMode = rasterStateCullMode;\n }\n RenderQueueType = renderQueueType;\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n // Uniforms\n float renderer_CurrentTime;\n vec3 renderer_Gravity;\n vec3 renderer_WorldPosition;\n vec4 renderer_WorldRotation;\n bool renderer_ThreeDStartRotation;\n int renderer_ScalingMode;\n vec3 renderer_PositionScale;\n vec3 renderer_SizeScale;\n vec3 renderer_PivotOffset;\n\n mat4 camera_ViewMat;\n mat4 camera_ProjMat;\n\n #ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n vec3 camera_Position;\n #endif\n vec3 camera_Forward;\n vec3 camera_Up;\n\n float renderer_StretchedBillboardLengthScale;\n float renderer_StretchedBillboardSpeedScale;\n int renderer_SimulationSpace;\n\n vec4 material_BaseColor;\n mediump vec3 material_EmissiveColor;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n sampler2D material_BaseTexture;\n #endif\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n sampler2D material_EmissiveTexture;\n #endif\n\n struct Attributes {\n #if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n vec4 a_CornerTextureCoordinate;\n #endif\n\n #ifdef RENDERER_MODE_MESH\n vec3 POSITION;\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n vec4 COLOR_0;\n #endif\n vec2 TEXCOORD_0;\n #endif\n\n vec4 a_ShapePositionStartLifeTime;\n vec4 a_DirectionTime;\n vec4 a_StartColor;\n vec3 a_StartSize;\n vec3 a_StartRotation0;\n float a_StartSpeed;\n vec4 a_Random0;\n\n #if defined(RENDERER_TSA_FRAME_RANDOM_CURVES) || defined(RENDERER_VOL_IS_RANDOM_TWO)\n vec4 a_Random1;\n #endif\n\n #if defined(RENDERER_FOL_CONSTANT_MODE) || defined(RENDERER_FOL_CURVE_MODE) || defined(RENDERER_LVL_MODULE_ENABLED)\n vec4 a_Random2;\n #endif\n\n vec3 a_SimulationWorldPosition;\n vec4 a_SimulationWorldRotation;\n\n #ifdef RENDERER_TRANSFORM_FEEDBACK\n vec3 a_FeedbackPosition;\n vec3 a_FeedbackVelocity;\n #endif\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec4 a_SimulationUV;\n #endif\n };\n\n struct Varyings {\n vec4 v_Color;\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec2 v_TextureCoordinate;\n #endif\n #ifdef RENDERER_MODE_MESH\n vec4 v_MeshColor;\n #endif\n };\n\n // Particle module includes (must be after Attributes/Varyings declarations)\n #include \"ShaderLibrary/Particle/ParticleCommon.glsl\"\n #include \"ShaderLibrary/Particle/Module/VelocityOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/ForceOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/ColorOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/SizeOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/RotationOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/TextureSheetAnimation.glsl\"\n #include \"ShaderLibrary/Particle/Module/LimitVelocityOverLifetime.glsl\"\n\n vec3 computeParticlePosition(Attributes attributes, in vec3 startVelocity, in float age, in float normalizedAge, vec3 gravityVelocity, vec4 worldRotation, inout vec3 localVelocity, inout vec3 worldVelocity) {\n vec3 startPosition = startVelocity * age;\n vec3 finalPosition;\n vec3 localPositionOffset = startPosition;\n vec3 worldPositionOffset;\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 lifeVelocity;\n vec3 velocityPositionOffset = computeVelocityPositionOffset(attributes, normalizedAge, age, lifeVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += lifeVelocity;\n localPositionOffset += velocityPositionOffset;\n } else {\n worldVelocity += lifeVelocity;\n worldPositionOffset += velocityPositionOffset;\n }\n #endif\n\n #ifdef _FOL_MODULE_ENABLED\n vec3 forceVelocity;\n vec3 forcePositionOffset = computeForcePositionOffset(attributes, normalizedAge, age, forceVelocity);\n if (renderer_FOLSpace == 0) {\n localVelocity += forceVelocity;\n localPositionOffset += forcePositionOffset;\n } else {\n worldVelocity += forceVelocity;\n worldPositionOffset += forcePositionOffset;\n }\n #endif\n\n finalPosition = rotationByQuaternions(attributes.a_ShapePositionStartLifeTime.xyz + localPositionOffset, worldRotation) + worldPositionOffset;\n\n if (renderer_SimulationSpace == 0) {\n finalPosition = finalPosition + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n finalPosition = finalPosition + attributes.a_SimulationWorldPosition;\n }\n\n finalPosition += 0.5 * gravityVelocity * age;\n\n return finalPosition;\n }\n\n\n Varyings vert(Attributes attr) {\n Varyings v;\n\n float age = renderer_CurrentTime - attr.a_DirectionTime.w;\n float normalizedAge = age / attr.a_ShapePositionStartLifeTime.w;\n\n if (normalizedAge >= 0.0 && normalizedAge < 1.0) {\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = attr.a_SimulationWorldRotation;\n }\n\n vec3 localVelocity;\n vec3 worldVelocity;\n\n #ifdef RENDERER_TRANSFORM_FEEDBACK\n vec3 center;\n if (renderer_SimulationSpace == 0) {\n center = rotationByQuaternions(attr.a_FeedbackPosition, worldRotation) + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n center = attr.a_FeedbackPosition;\n }\n localVelocity = attr.a_FeedbackVelocity;\n worldVelocity = vec3(0.0);\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 instantVOLVelocity;\n computeVelocityPositionOffset(attr, normalizedAge, age, instantVOLVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += instantVOLVelocity;\n } else {\n worldVelocity += instantVOLVelocity;\n }\n #endif\n #else\n vec3 startVelocity = attr.a_DirectionTime.xyz * attr.a_StartSpeed;\n vec3 gravityVelocity = renderer_Gravity * attr.a_Random0.x * age;\n localVelocity = startVelocity;\n worldVelocity = gravityVelocity;\n vec3 center = computeParticlePosition(attr, startVelocity, age, normalizedAge, gravityVelocity, worldRotation, localVelocity, worldVelocity);\n #endif\n\n // Billboard / Mesh mode positioning\n #ifdef RENDERER_MODE_SPHERE_BILLBOARD\n vec2 corner = attr.a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n vec3 sideVector = normalize(cross(camera_Forward, camera_Up));\n vec3 upVector = normalize(cross(sideVector, camera_Forward));\n corner *= computeParticleSizeBillboard(attr, attr.a_StartSize.xy, normalizedAge);\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n if (renderer_ThreeDStartRotation) {\n vec3 rotation = radians(vec3(attr.a_StartRotation0.xy, computeParticleRotationFloat(attr, attr.a_StartRotation0.z, age, normalizedAge)));\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, rotation);\n } else {\n float rot = radians(computeParticleRotationFloat(attr, attr.a_StartRotation0.x, age, normalizedAge));\n float c = cos(rot);\n float s = sin(rot);\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #else\n if (renderer_ThreeDStartRotation) {\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, radians(attr.a_StartRotation0));\n } else {\n float c = cos(radians(attr.a_StartRotation0.x));\n float s = sin(radians(attr.a_StartRotation0.x));\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #endif\n #endif\n\n #ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n vec2 corner = attr.a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n vec3 velocity = rotationByQuaternions(renderer_SizeScale * localVelocity, worldRotation) + worldVelocity;\n vec3 cameraUpVector = normalize(velocity);\n vec3 direction = normalize(center - camera_Position);\n vec3 sideVector = normalize(cross(direction, normalize(velocity)));\n\n sideVector = renderer_SizeScale.xzy * sideVector;\n cameraUpVector = length(vec3(renderer_SizeScale.x, 0.0, 0.0)) * cameraUpVector;\n\n vec2 size = computeParticleSizeBillboard(attr, attr.a_StartSize.xy, normalizedAge);\n\n const mat2 rotationZHalfPI = mat2(0.0, -1.0, 1.0, 0.0);\n corner = rotationZHalfPI * corner;\n corner.y = corner.y - abs(corner.y);\n\n float speed = length(velocity);\n center += sign(renderer_SizeScale.x) * (sign(renderer_StretchedBillboardLengthScale) * size.x * corner.x * sideVector\n + (speed * renderer_StretchedBillboardSpeedScale + size.y * renderer_StretchedBillboardLengthScale) * corner.y * cameraUpVector);\n #endif\n\n #ifdef RENDERER_MODE_HORIZONTAL_BILLBOARD\n vec2 corner = attr.a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n const vec3 sideVector = vec3(1.0, 0.0, 0.0);\n const vec3 upVector = vec3(0.0, 0.0, -1.0);\n corner *= computeParticleSizeBillboard(attr, attr.a_StartSize.xy, normalizedAge);\n\n float rot;\n if (renderer_ThreeDStartRotation) {\n rot = radians(computeParticleRotationFloat(attr, attr.a_StartRotation0.z, age, normalizedAge));\n } else {\n rot = radians(computeParticleRotationFloat(attr, attr.a_StartRotation0.x, age, normalizedAge));\n }\n\n float c = cos(rot);\n float s = sin(rot);\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n #endif\n\n #ifdef RENDERER_MODE_VERTICAL_BILLBOARD\n vec2 corner = attr.a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n const vec3 cameraUpVector = vec3(0.0, 1.0, 0.0);\n vec3 sideVector = normalize(cross(camera_Forward, cameraUpVector));\n\n float rot = radians(computeParticleRotationFloat(attr, attr.a_StartRotation0.x, age, normalizedAge));\n float c = cos(rot);\n float s = sin(rot);\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner * cos(0.78539816339744830961566084581988);\n corner *= computeParticleSizeBillboard(attr, attr.a_StartSize.xy, normalizedAge);\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * cameraUpVector);\n #endif\n\n #ifdef RENDERER_MODE_MESH\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #define RENDERER_ROL_ENABLED\n #endif\n\n vec3 size = computeParticleSizeMesh(attr, attr.a_StartSize, normalizedAge);\n\n bool is3DRotation = renderer_ThreeDStartRotation;\n #if defined(RENDERER_ROL_ENABLED) && defined(RENDERER_ROL_IS_SEPARATE)\n is3DRotation = true;\n #endif\n\n if (is3DRotation) {\n #ifdef RENDERER_ROL_ENABLED\n vec3 startRotation = renderer_ThreeDStartRotation ? attr.a_StartRotation0 : vec3(0.0, 0.0, attr.a_StartRotation0.x);\n vec3 rotation = radians(computeParticleRotationVec3(attr, startRotation, age, normalizedAge));\n #else\n vec3 rotation = radians(attr.a_StartRotation0);\n #endif\n center += rotationByQuaternions(renderer_SizeScale * rotationByEuler(attr.POSITION * size, rotation), worldRotation);\n } else {\n #ifdef RENDERER_ROL_ENABLED\n float angle = radians(computeParticleRotationFloat(attr, attr.a_StartRotation0.x, age, normalizedAge));\n #else\n float angle = radians(attr.a_StartRotation0.x);\n #endif\n #ifdef RENDERER_EMISSION_SHAPE\n vec3 axis = vec3(attr.a_ShapePositionStartLifeTime.xy, 0.0);\n if (renderer_SimulationSpace == 1) {\n axis = rotationByQuaternions(axis, worldRotation);\n }\n vec3 crossResult = cross(axis, vec3(0.0, 0.0, -1.0));\n float crossLen = length(crossResult);\n vec3 rotateAxis = crossLen > 0.0001 ? crossResult / crossLen : vec3(0.0, 1.0, 0.0);\n #else\n vec3 rotateAxis = vec3(0.0, 0.0, -1.0);\n #endif\n center += rotationByQuaternions(renderer_SizeScale * rotationByAxis(attr.POSITION * size, rotateAxis, angle), worldRotation);\n }\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n v.v_MeshColor = attr.COLOR_0;\n #endif\n #endif\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(center, 1.0);\n v.v_Color = computeParticleColor(attr, attr.a_StartColor, normalizedAge);\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec2 simulateUV;\n #if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n simulateUV = attr.a_CornerTextureCoordinate.zw * attr.a_SimulationUV.xy + attr.a_SimulationUV.zw;\n v.v_TextureCoordinate = computeParticleUV(attr, simulateUV, normalizedAge);\n #endif\n #ifdef RENDERER_MODE_MESH\n simulateUV = attr.a_SimulationUV.zw + attr.TEXCOORD_0 * attr.a_SimulationUV.xy;\n v.v_TextureCoordinate = computeParticleUV(attr, simulateUV, normalizedAge);\n #endif\n #endif\n } else {\n gl_Position = vec4(2.0, 2.0, 2.0, 1.0);\n }\n\n return v;\n }\n\n\n void frag(Varyings v) {\n vec4 color = material_BaseColor * v.v_Color;\n\n #if defined(RENDERER_MODE_MESH) && defined(RENDERER_ENABLE_VERTEXCOLOR)\n color *= v.v_MeshColor;\n #endif\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n color *= texture2DSRGB(material_BaseTexture, v.v_TextureCoordinate);\n #endif\n\n // Emissive\n vec3 emissiveRadiance = material_EmissiveColor;\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v.v_TextureCoordinate).rgb;\n #endif\n\n color.rgb += emissiveRadiance;\n\n gl_FragColor = color;\n }\n }\n }\n}\n";
|
|
373
|
+
|
|
374
|
+
var Effect_ParticleFeedback = "Shader \"Effect/ParticleFeedback\" {\n SubShader \"Default\" {\n Pass \"TransformFeedback\" {\n Tags { pipelineStage = \"TransformFeedback\" }\n\n VertexShader = main;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n // Uniforms\n float renderer_CurrentTime;\n float renderer_DeltaTime;\n vec3 renderer_Gravity;\n vec2 renderer_LVLDragConstant;\n vec3 renderer_WorldPosition;\n vec4 renderer_WorldRotation;\n int renderer_SimulationSpace;\n\n struct Attributes {\n vec3 a_FeedbackPosition;\n vec3 a_FeedbackVelocity;\n vec4 a_ShapePositionStartLifeTime;\n vec4 a_DirectionTime;\n vec3 a_StartSize;\n float a_StartSpeed;\n vec4 a_Random0;\n\n #if defined(RENDERER_TSA_FRAME_RANDOM_CURVES) || defined(RENDERER_VOL_IS_RANDOM_TWO)\n vec4 a_Random1;\n #endif\n\n vec3 a_SimulationWorldPosition;\n vec4 a_SimulationWorldRotation;\n\n #if defined(RENDERER_FOL_CONSTANT_MODE) || defined(RENDERER_FOL_CURVE_MODE) || defined(RENDERER_LVL_MODULE_ENABLED)\n vec4 a_Random2;\n #endif\n };\n\n struct Varyings {\n vec3 v_FeedbackPosition;\n vec3 v_FeedbackVelocity;\n };\n\n // Module includes (after Attributes/Varyings)\n #include \"ShaderLibrary/Particle/ParticleCommon.glsl\"\n #include \"ShaderLibrary/Particle/Module/VelocityOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/ForceOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/LimitVelocityOverLifetime.glsl\"\n #include \"ShaderLibrary/Particle/Module/NoiseModule.glsl\"\n\n // Get VOL instantaneous velocity at normalizedAge\n vec3 getVOLVelocity(Attributes attributes, float normalizedAge) {\n vec3 vel = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n #ifdef RENDERER_VOL_CONSTANT_MODE\n vel = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vel = mix(renderer_VOLMinConst, vel, attributes.a_Random1.yzw);\n #endif\n #endif\n #ifdef RENDERER_VOL_CURVE_MODE\n vel = vec3(\n evaluateParticleCurve(renderer_VOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minVel = vec3(\n evaluateParticleCurve(renderer_VOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientZ, normalizedAge)\n );\n vel = mix(minVel, vel, attributes.a_Random1.yzw);\n #endif\n #endif\n #endif\n return vel;\n }\n\n // Get FOL instantaneous acceleration at normalizedAge\n vec3 getFOLAcceleration(Attributes attributes, float normalizedAge) {\n vec3 acc = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n #ifdef RENDERER_FOL_CONSTANT_MODE\n acc = renderer_FOLMaxConst;\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n acc = mix(renderer_FOLMinConst, acc, vec3(attributes.a_Random2.x, attributes.a_Random2.y, attributes.a_Random2.z));\n #endif\n #endif\n #ifdef RENDERER_FOL_CURVE_MODE\n acc = vec3(\n evaluateParticleCurve(renderer_FOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minAcc = vec3(\n evaluateParticleCurve(renderer_FOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientZ, normalizedAge)\n );\n acc = mix(minAcc, acc, vec3(attributes.a_Random2.x, attributes.a_Random2.y, attributes.a_Random2.z));\n #endif\n #endif\n #endif\n return acc;\n }\n\n Varyings main(Attributes attr) {\n Varyings v;\n\n float age = renderer_CurrentTime - attr.a_DirectionTime.w;\n float lifetime = attr.a_ShapePositionStartLifeTime.w;\n float normalizedAge = age / lifetime;\n float dt = min(renderer_DeltaTime, age);\n\n if (normalizedAge >= 1.0 || normalizedAge < 0.0) {\n v.v_FeedbackPosition = attr.a_FeedbackPosition;\n v.v_FeedbackVelocity = attr.a_FeedbackVelocity;\n gl_Position = vec4(0.0);\n return v;\n }\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = attr.a_SimulationWorldRotation;\n }\n vec4 invWorldRotation = quaternionConjugate(worldRotation);\n\n vec3 localVelocity = attr.a_FeedbackVelocity;\n\n // Step 1: VOL + FOL + Gravity\n vec3 gravityDelta = renderer_Gravity * attr.a_Random0.x * dt;\n\n vec3 volLocal = vec3(0.0);\n vec3 volWorld = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n vec3 vol = getVOLVelocity(attr, normalizedAge);\n if (renderer_VOLSpace == 0) {\n volLocal = vol;\n } else {\n volWorld = vol;\n }\n #endif\n\n vec3 folDeltaLocal = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n vec3 folAcc = getFOLAcceleration(attr, normalizedAge);\n vec3 folVelDelta = folAcc * dt;\n if (renderer_FOLSpace == 0) {\n folDeltaLocal = folVelDelta;\n } else {\n folDeltaLocal = rotationByQuaternions(folVelDelta, invWorldRotation);\n }\n #endif\n\n vec3 gravityLocal = rotationByQuaternions(gravityDelta, invWorldRotation);\n localVelocity += folDeltaLocal + gravityLocal;\n\n // Step 2 & 3: Dampen + Drag\n #ifdef RENDERER_LVL_MODULE_ENABLED\n vec3 volAsLocal = volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n vec3 volAsWorld = rotationByQuaternions(volLocal, worldRotation) + volWorld;\n\n float limitRand = attr.a_Random2.w;\n float dampen = renderer_LVLDampen;\n float effectiveDampen = 1.0 - pow(1.0 - dampen, dt * 30.0);\n\n if (renderer_LVLSpace == 0) {\n vec3 totalLocal = localVelocity + volAsLocal;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalLocal, normalizedAge, limitRand, effectiveDampen);\n localVelocity = dampenedTotal - volAsLocal;\n } else {\n vec3 totalWorld = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalWorld, normalizedAge, limitRand, effectiveDampen);\n localVelocity = rotationByQuaternions(dampenedTotal - volAsWorld, invWorldRotation);\n }\n\n {\n float dragCoeff = evaluateLVLDrag(normalizedAge, attr.a_Random2.w);\n if (dragCoeff > 0.0) {\n vec3 totalVel;\n if (renderer_LVLSpace == 0) {\n totalVel = localVelocity + volAsLocal;\n } else {\n totalVel = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n }\n float velMagSqr = dot(totalVel, totalVel);\n float velMag = sqrt(velMagSqr);\n\n float drag = dragCoeff;\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_SIZE\n float maxDim = max(attr.a_StartSize.x, max(attr.a_StartSize.y, attr.a_StartSize.z));\n float radius = maxDim * 0.5;\n drag *= 3.14159265 * radius * radius;\n #endif\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_VELOCITY\n drag *= velMagSqr;\n #endif\n\n if (velMag > 0.0) {\n float newVelMag = max(0.0, velMag - drag * dt);\n vec3 draggedTotal = totalVel * (newVelMag / velMag);\n if (renderer_LVLSpace == 0) {\n localVelocity = draggedTotal - volAsLocal;\n } else {\n localVelocity = rotationByQuaternions(draggedTotal - volAsWorld, invWorldRotation);\n }\n }\n }\n }\n #endif\n\n // Step 4: Integrate position\n vec3 totalVelocity;\n if (renderer_SimulationSpace == 0) {\n totalVelocity = localVelocity + volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n } else {\n totalVelocity = rotationByQuaternions(localVelocity + volLocal, worldRotation) + volWorld;\n }\n #ifdef RENDERER_NOISE_MODULE_ENABLED\n vec3 noiseBasePos;\n if (renderer_SimulationSpace == 0) {\n noiseBasePos = attr.a_ShapePositionStartLifeTime.xyz + attr.a_DirectionTime.xyz * attr.a_StartSpeed * age;\n } else {\n noiseBasePos = rotationByQuaternions(\n attr.a_ShapePositionStartLifeTime.xyz + attr.a_DirectionTime.xyz * attr.a_StartSpeed * age,\n worldRotation) + attr.a_SimulationWorldPosition;\n }\n totalVelocity += computeNoiseVelocity(attr, noiseBasePos, normalizedAge);\n #endif\n vec3 position = attr.a_FeedbackPosition + totalVelocity * dt;\n\n v.v_FeedbackPosition = position;\n v.v_FeedbackVelocity = localVelocity;\n gl_Position = vec4(0.0);\n return v;\n }\n\n void frag(Varyings v) {\n discard;\n }\n }\n }\n}\n";
|
|
375
|
+
|
|
376
|
+
var Effect_Trail = "Shader \"Effect/Trail\" {\n Editor {\n Properties {\n Header(\"Base\") {\n material_BaseColor(\"BaseColor\", Color) = (1, 1, 1, 1);\n material_BaseTexture(\"BaseTexture\", Texture2D);\n }\n Header(\"Emissive\") {\n material_EmissiveColor(\"EmissiveColor\", HDRColor) = (0, 0, 0, 1);\n material_EmissiveTexture(\"EmissiveTexture\", Texture2D);\n }\n Header(\"Common\") {\n isTransparent(\"Transparent\", Boolean) = false;\n renderFace(\"Render Face\", Enum(Front:0, Back:1, Double:2)) = 0;\n blendMode(\"Blend Mode\", Enum(Normal:0, Additive:1)) = 0;\n material_AlphaCutoff(\"AlphaCutoff\", Range(0, 1, 0.01)) = 0;\n }\n }\n }\n\n SubShader \"Default\" {\n Pass \"Default\" {\n Tags { pipelineStage = \"Forward\" }\n\n RenderQueueType renderQueueType;\n BlendFactor sourceColorBlendFactor;\n BlendFactor destinationColorBlendFactor;\n BlendFactor sourceAlphaBlendFactor;\n BlendFactor destinationAlphaBlendFactor;\n CullMode rasterStateCullMode;\n Bool blendEnabled;\n Bool depthWriteEnabled;\n\n BlendState = {\n Enabled = blendEnabled;\n SourceColorBlendFactor = sourceColorBlendFactor;\n DestinationColorBlendFactor = destinationColorBlendFactor;\n SourceAlphaBlendFactor = sourceAlphaBlendFactor;\n DestinationAlphaBlendFactor = destinationAlphaBlendFactor;\n }\n DepthState = {\n WriteEnabled = depthWriteEnabled;\n }\n RasterState = {\n CullMode = rasterStateCullMode;\n }\n RenderQueueType = renderQueueType;\n\n VertexShader = TrailVertex;\n FragmentShader = TrailFragment;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n #include \"ShaderLibrary/Particle/ParticleCommon.glsl\"\n\n struct a2v {\n vec4 a_PositionBirthTime;\n vec4 a_CornerTangent;\n float a_Distance;\n };\n\n struct v2f {\n vec2 v_uv;\n vec4 v_color;\n };\n\n vec4 renderer_TrailParams;\n vec2 renderer_DistanceParams;\n vec3 camera_Position;\n mat4 camera_ViewMat;\n mat4 camera_ProjMat;\n vec2 renderer_WidthCurve[4];\n vec4 renderer_ColorKeys[4];\n vec2 renderer_AlphaKeys[4];\n vec4 renderer_CurveMaxTime;\n vec4 material_BaseColor;\n mediump vec3 material_EmissiveColor;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n sampler2D material_BaseTexture;\n #endif\n\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n sampler2D material_EmissiveTexture;\n #endif\n\n v2f TrailVertex(a2v attr) {\n v2f v;\n\n vec3 position = attr.a_PositionBirthTime.xyz;\n float corner = attr.a_CornerTangent.x;\n vec3 tangent = attr.a_CornerTangent.yzw;\n float distFromHead = renderer_DistanceParams.x - attr.a_Distance;\n float totalDist = renderer_DistanceParams.x - renderer_DistanceParams.y;\n float relativePos = totalDist > 0.0 ? distFromHead / totalDist : 0.0;\n\n vec3 toCamera = normalize(camera_Position - position);\n vec3 right = cross(tangent, toCamera);\n float rightLenSq = dot(right, right);\n\n if (rightLenSq < 0.000001) {\n right = cross(tangent, vec3(0.0, 1.0, 0.0));\n rightLenSq = dot(right, right);\n if (rightLenSq < 0.000001) {\n right = cross(tangent, vec3(1.0, 0.0, 0.0));\n rightLenSq = dot(right, right);\n }\n }\n\n right = right * inversesqrt(rightLenSq);\n\n float width = evaluateParticleCurve(renderer_WidthCurve, min(relativePos, renderer_CurveMaxTime.z));\n vec3 worldPosition = position + right * width * 0.5 * corner;\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(worldPosition, 1.0);\n\n float u = renderer_TrailParams.x == 0.0 ? relativePos : distFromHead;\n float vCoord = corner * 0.5 + 0.5;\n v.v_uv = vec2(u * renderer_TrailParams.y, vCoord * renderer_TrailParams.z);\n v.v_color = evaluateParticleGradient(renderer_ColorKeys, renderer_CurveMaxTime.x, renderer_AlphaKeys, renderer_CurveMaxTime.y, relativePos);\n\n return v;\n }\n\n void TrailFragment(v2f v) {\n vec4 color = material_BaseColor * v.v_color;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n color *= texture2DSRGB(material_BaseTexture, v.v_uv);\n #endif\n\n vec3 emissiveRadiance = material_EmissiveColor;\n\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v.v_uv).rgb;\n #endif\n\n color.rgb += emissiveRadiance;\n gl_FragColor = color;\n }\n }\n }\n}\n";
|
|
377
|
+
|
|
378
|
+
var Lighting_ScalableAmbientOcclusion = "Shader \"Lighting/ScalableAmbientOcclusion\" {\n SubShader \"Default\" {\n Pass \"ScalableAmbientOcclusion\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/Lighting/AmbientOcclusion/ScalableAmbientOcclusion.glsl\"\n }\n\n Pass \"BilateralBlur\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/Lighting/AmbientOcclusion/BilateralBlur.glsl\"\n }\n }\n}\n";
|
|
379
|
+
|
|
380
|
+
var PBR = "Shader \"PBR\" {\n Editor {\n Properties{\n Header(\"Base\"){\n material_IOR(\"IOR\", Range(0, 5, 0.01)) = 1.5;\n material_BaseColor(\"BaseColor\", Color) = (1, 1, 1, 1);\n material_BaseTexture(\"BaseTexture\", Texture2D);\n }\n\n Header(\"Metal Roughness\") {\n material_Metal( \"Metal\", Range(0,1,0.01) ) = 1;\n material_Roughness( \"Roughness\", Range( 0, 1, 0.01 ) ) = 1;\n material_RoughnessMetallicTexture(\"RoughnessMetallicTexture\", Texture2D);\n }\n \n Header(\"Specular\") {\n material_SpecularIntensity( \"Intensity\", Range(0,2,0.01) ) = 1;\n material_SpecularColor( \"Color\", Color ) = (1, 1, 1, 1);\n material_SpecularIntensityTexture(\"IntensityTexture\", Texture2D);\n material_SpecularColorTexture(\"ColorTexture\", Texture2D);\n }\n\n Header(\"Anisotropy\") {\n anisotropy(\"Intensity\", Range(0, 1, 0.01)) = 0;\n anisotropyRotation(\"Rotation\", Range(0, 360, 1)) = 0;\n material_AnisotropyTexture(\"Texture\", Texture2D);\n }\n\n Header(\"Normal\") {\n material_NormalTexture(\"NormalTexture\", Texture2D);\n material_NormalIntensity(\"NormalIntensity\", Range(0, 5, 0.01)) = 1;\n }\n\n Header(\"Emissive\") {\n material_EmissiveColor(\"EmissiveColor\", HDRColor ) = (0, 0, 0, 1);\n material_EmissiveTexture(\"EmissiveTexture\", Texture2D);\n }\n\n Header(\"Occlusion\") {\n material_OcclusionTexture(\"OcclusionTexture\", Texture2D);\n material_OcclusionIntensity(\"OcclusionIntensity\", Range(0, 5, 0.01)) = 1;\n material_OcclusionTextureCoord(\"OcclusionTextureCoord\", Enum(UV0:0, UV1:1)) = 0;\n }\n \n Header(\"Clear Coat\") {\n material_ClearCoat(\"ClearCoat\", Range(0, 1, 0.01)) = 0;\n material_ClearCoatTexture(\"ClearCoatTexture\", Texture2D);\n material_ClearCoatRoughness(\"ClearCoatRoughness\", Range(0, 1, 0.01)) = 0;\n material_ClearCoatRoughnessTexture(\"ClearCoatRoughnessTexture\", Texture2D);\n material_ClearCoatNormalTexture(\"ClearCoatNormalTexture\", Texture2D);\n }\n\n Header(\"Thin Film Iridescence\"){\n iridescence(\"Iridescence\", Range(0, 1, 0.01)) = 0;\n iridescenceIOR(\"IOR\", Range(1, 5, 0.01)) = 1.3;\n iridescenceRange(\"ThicknessRange\", Vector2) = (100, 400);\n material_IridescenceThicknessTexture(\"ThicknessTexture\", Texture2D);\n material_IridescenceTexture(\"IridescenceTexture\", Texture2D);\n }\n\n Header(\"Sheen\"){\n sheenColor(\"Color\", Color ) = (0, 0, 0, 1);\n sheenIntensity(\"Intensity\", Range(0, 1, 0.01)) = 1;\n material_SheenRoughness(\"Roughness\", Range(0, 1, 0.01)) = 0;\n material_SheenTexture(\"ColorTexture\", Texture2D);\n material_SheenRoughnessTexture(\"RoughnessTexture\", Texture2D);\n }\n\n Header(\"Transmission\") {\n material_Transmission(\"Transmission\", Range(0, 1, 0.01)) = 0;\n material_TransmissionTexture(\"TransmissionTexture\", Texture2D);\n material_Thickness(\"Thickness\", Range(0, 5, 0.01)) = 0;\n material_ThicknessTexture(\"ThicknessTexture\", Texture2D);\n refractionMode(\"RefractionMode\", Enum(Sphere:0, Planar:1)) = 1;\n material_AttenuationColor(\"AttenuationColor\", Color ) = (1, 1, 1, 1);\n material_AttenuationDistance(\"AttenuationDistance\", Range(0, 5, 0.01)) = 0;\n }\n\n Header(\"Common\") {\n isTransparent(\"Transparent\", Boolean) = false;\n renderFace(\"Render Face\", Enum(Front:0, Back:1, Double:2)) = 0;\n blendMode(\"Blend Mode\", Enum(Normal:0, Additive:1)) = 0;\n material_AlphaCutoff( \"AlphaCutoff\", Range(0, 1, 0.01) ) = 0;\n material_TilingOffset(\"TilingOffset\", Vector4) = (1, 1, 0, 0);\n }\n }\n \n }\n \n SubShader \"Default\" {\n UsePass \"Pipeline/ShadowCaster/Default/ShadowCaster\"\n UsePass \"Pipeline/DepthOnly/Default/DepthOnly\"\n\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\"} \n\n RenderQueueType renderQueueType;\n BlendFactor sourceColorBlendFactor;\n BlendFactor destinationColorBlendFactor;\n BlendFactor sourceAlphaBlendFactor;\n BlendFactor destinationAlphaBlendFactor;\n CullMode rasterStateCullMode;\n Bool blendEnabled;\n Bool depthWriteEnabled;\n\n DepthState = {\n WriteEnabled = depthWriteEnabled;\n }\n\n BlendState = {\n Enabled = blendEnabled;\n SourceColorBlendFactor = sourceColorBlendFactor;\n DestinationColorBlendFactor = destinationColorBlendFactor;\n SourceAlphaBlendFactor = sourceAlphaBlendFactor;\n DestinationAlphaBlendFactor = destinationAlphaBlendFactor;\n }\n\n RasterState = {\n CullMode = rasterStateCullMode;\n }\n\n RenderQueueType = renderQueueType;\n \n VertexShader = PBRVertex;\n FragmentShader = PBRFragment;\n\n #include \"ShaderLibrary/PBR/ForwardPassPBR.glsl\"\n }\n }\n }";
|
|
381
|
+
|
|
382
|
+
var Pipeline_DepthOnly = "Shader \"Pipeline/DepthOnly\" {\n SubShader \"Default\" {\n Pass \"DepthOnly\" {\n Tags { pipelineStage = \"DepthOnly\" }\n\n RenderQueueType material_DepthOnlyRenderQueue;\n\n RenderQueueType = material_DepthOnlyRenderQueue;\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n #include \"ShaderLibrary/Common/Transform.glsl\"\n #include \"ShaderLibrary/Common/Attributes.glsl\"\n #include \"ShaderLibrary/Skin/Skin.glsl\"\n #include \"ShaderLibrary/Skin/BlendShape.glsl\"\n\n void vert(Attributes attr) {\n vec4 position = vec4(attr.POSITION, 1.0);\n\n #ifdef RENDERER_HAS_NORMAL\n vec3 normal = vec3(attr.NORMAL);\n #ifdef RENDERER_HAS_TANGENT\n vec4 tangent = vec4(attr.TANGENT);\n #endif\n #endif\n\n #ifdef RENDERER_HAS_BLENDSHAPE\n calculateBlendShape(attr, position\n #ifdef RENDERER_HAS_NORMAL\n , normal\n #ifdef RENDERER_HAS_TANGENT\n , tangent\n #endif\n #endif\n );\n #endif\n\n #ifdef RENDERER_HAS_SKIN\n mat4 skinMatrix = getSkinMatrix(attr);\n position = skinMatrix * position;\n #endif\n\n gl_Position = camera_VPMat * renderer_ModelMat * position;\n }\n\n void frag() {\n }\n }\n }\n}\n";
|
|
383
|
+
|
|
384
|
+
var Pipeline_ShadowCaster = "Shader \"Pipeline/ShadowCaster\" {\n SubShader \"Default\" {\n Pass \"ShadowCaster\" {\n Tags { pipelineStage = \"ShadowCaster\" }\n\n RenderQueueType material_ShadowCasterRenderQueue;\n\n RenderQueueType = material_ShadowCasterRenderQueue;\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n #include \"ShaderLibrary/Common/Transform.glsl\"\n #include \"ShaderLibrary/Common/Attributes.glsl\"\n #include \"ShaderLibrary/Skin/Skin.glsl\"\n #include \"ShaderLibrary/Skin/BlendShape.glsl\"\n\n vec2 scene_ShadowBias;\n vec3 scene_LightDirection;\n\n vec4 material_BaseColor;\n sampler2D material_BaseTexture;\n float material_AlphaCutoff;\n\n struct Varyings {\n vec2 v_uv;\n };\n\n vec3 applyShadowBias(vec3 positionWS) {\n positionWS -= scene_LightDirection * scene_ShadowBias.x;\n return positionWS;\n }\n\n vec3 applyShadowNormalBias(vec3 positionWS, vec3 normalWS) {\n float invNdotL = 1.0 - clamp(dot(-scene_LightDirection, normalWS), 0.0, 1.0);\n float scale = invNdotL * scene_ShadowBias.y;\n positionWS += normalWS * vec3(scale);\n return positionWS;\n }\n\n Varyings vert(Attributes attr) {\n Varyings v;\n\n vec4 position = vec4(attr.POSITION, 1.0);\n\n #ifdef RENDERER_HAS_NORMAL\n vec3 normal = vec3(attr.NORMAL);\n #ifdef RENDERER_HAS_TANGENT\n vec4 tangent = vec4(attr.TANGENT);\n #endif\n #endif\n\n #ifdef RENDERER_HAS_BLENDSHAPE\n calculateBlendShape(attr, position\n #ifdef RENDERER_HAS_NORMAL\n , normal\n #ifdef RENDERER_HAS_TANGENT\n , tangent\n #endif\n #endif\n );\n #endif\n\n #ifdef RENDERER_HAS_SKIN\n mat4 skinMatrix = getSkinMatrix(attr);\n position = skinMatrix * position;\n\n #ifdef RENDERER_HAS_NORMAL\n mat3 skinNormalMatrix = INVERSE_MAT(mat3(skinMatrix));\n normal = normal * skinNormalMatrix;\n #endif\n #endif\n\n #ifdef RENDERER_HAS_UV\n v.v_uv = attr.TEXCOORD_0;\n #else\n v.v_uv = vec2(0.0, 0.0);\n #endif\n\n vec4 positionWS = renderer_ModelMat * position;\n\n positionWS.xyz = applyShadowBias(positionWS.xyz);\n #ifdef RENDERER_HAS_NORMAL\n vec3 normalWS = normalize(mat3(renderer_NormalMat) * normal);\n positionWS.xyz = applyShadowNormalBias(positionWS.xyz, normalWS);\n #endif\n\n vec4 positionCS = camera_VPMat * positionWS;\n positionCS.z = max(positionCS.z, -1.0);\n gl_Position = positionCS;\n\n return v;\n }\n\n #ifdef ENGINE_NO_DEPTH_TEXTURE\n vec4 pack(float depth) {\n const vec4 bitShift = vec4(1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0);\n const vec4 bitMask = vec4(1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 0.0);\n vec4 rgbaDepth = fract(depth * bitShift);\n rgbaDepth -= rgbaDepth.gbaa * bitMask;\n return rgbaDepth;\n }\n #endif\n\n void frag(Varyings v) {\n #if defined(MATERIAL_IS_ALPHA_CUTOFF) || (defined(SCENE_ENABLE_TRANSPARENT_SHADOW) && defined(MATERIAL_IS_TRANSPARENT))\n float alpha = material_BaseColor.a;\n #ifdef MATERIAL_HAS_BASETEXTURE\n alpha *= texture2D(material_BaseTexture, v.v_uv).a;\n #endif\n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if (alpha < material_AlphaCutoff) {\n discard;\n }\n #endif\n #if defined(SCENE_ENABLE_TRANSPARENT_SHADOW) && defined(MATERIAL_IS_TRANSPARENT)\n float noise = fract(52.982919 * fract(dot(vec2(0.06711, 0.00584), gl_FragCoord.xy)));\n if (alpha <= noise) {\n discard;\n }\n #endif\n #endif\n\n #ifdef ENGINE_NO_DEPTH_TEXTURE\n gl_FragColor = pack(gl_FragCoord.z);\n #else\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n #endif\n }\n }\n }\n}\n";
|
|
385
|
+
|
|
386
|
+
var PostProcess_Bloom = "Shader \"PostProcess/Bloom\" {\n SubShader \"Default\" {\n Pass \"Bloom Prefilter\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/Bloom/BloomPrefilter.glsl\"\n }\n\n Pass \"Bloom Blur Horizontal\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/Bloom/BloomBlurH.glsl\"\n }\n\n Pass \"Bloom Blur Vertical\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/Bloom/BloomBlurV.glsl\"\n }\n\n Pass \"Bloom Upsample\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/Bloom/BloomUpsample.glsl\"\n }\n }\n}\n";
|
|
387
|
+
|
|
388
|
+
var PostProcess_FinalAntiAliasing = "Shader \"PostProcess/FinalAntiAliasing\" {\n SubShader \"Default\" {\n Pass \"0\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/FinalAntiAliasing.glsl\"\n }\n }\n}\n";
|
|
389
|
+
|
|
390
|
+
var PostProcess_FinalSRGB = "Shader \"PostProcess/FinalSRGB\" {\n SubShader \"Default\" {\n Pass \"0\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/FinalSRGB.glsl\"\n }\n }\n}\n";
|
|
391
|
+
|
|
392
|
+
var PostProcess_Uber = "Shader \"PostProcess/Uber\" {\n SubShader \"Default\" {\n Pass \"0\" {\n DepthState = {\n Enabled = false;\n WriteEnabled = false;\n }\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Blit/BlitVertex.glsl\"\n #include \"ShaderLibrary/PostProcess/UberPost.glsl\"\n }\n }\n}\n";
|
|
393
|
+
|
|
394
|
+
var Sky_BackgroundTexture = "Shader \"Sky/BackgroundTexture\" {\n SubShader \"Default\" {\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\" }\n\n DepthState = {\n CompareFunction = CompareFunction.LessEqual;\n }\n\n VertexShader = BackgroundTextureVertex;\n FragmentShader = BackgroundTextureFragment;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n struct Attributes {\n vec3 POSITION;\n vec2 TEXCOORD_0;\n };\n\n struct Varyings {\n vec2 v_uv;\n };\n\n sampler2D material_BaseTexture;\n\n Varyings BackgroundTextureVertex(Attributes attributes) {\n Varyings varyings;\n gl_Position = vec4(attributes.POSITION, 1.0);\n gl_Position.y *= camera_ProjectionParams.x;\n varyings.v_uv = attributes.TEXCOORD_0;\n return varyings;\n }\n\n void BackgroundTextureFragment(Varyings varyings) {\n gl_FragColor = texture2DSRGB(material_BaseTexture, varyings.v_uv);\n }\n }\n }\n}\n";
|
|
395
|
+
|
|
396
|
+
var Sky_SkyProcedural = "// This code uses the Unity skybox-Procedural shader algorithm, developed by Unity and licensed under the Unity Companion License.\n// The original implementation can be found at unity build-in shader(DefaultResourcesExtra/Skybox-Procedural.shader)\n\nShader \"Sky/SkyProcedural\" {\n Editor {\n Properties {\n Header(\"Base\") {\n material_Exposure(\"Exposure\", Range(0, 8, 0.1)) = 1;\n sunMode(\"SunMode\", Enum(HighQuality:0, Simple:1, None:2)) = 0;\n material_SunSize(\"SunSize\", Range(0, 1, 0.01)) = 0.04;\n material_SunSizeConvergence(\"SunSizeConvergence\", Range(0, 20, 0.1)) = 5;\n material_AtmosphereThickness(\"AtmosphereThickness\", Range(0, 5, 0.1)) = 1;\n material_SkyTint(\"SkyTint\", Color) = (0.214, 0.214, 0.214, 1);\n material_GroundTint(\"GroundTint\", Color) = (0.112, 0.1, 0.095, 1);\n }\n }\n }\n\n SubShader \"Default\" {\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\" }\n\n DepthState = {\n CompareFunction = CompareFunction.LessEqual;\n }\n RasterState = {\n CullMode = CullMode.Off;\n }\n\n VertexShader = SkyProceduralVertex;\n FragmentShader = SkyProceduralFragment;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n #define OUTER_RADIUS 1.025\n #define RAYLEIGH (mix(0.0, 0.0025, pow(material_AtmosphereThickness, 2.5)))\n #define MIE 0.0010\n #define SUN_BRIGHTNESS 20.0\n #define MAX_SCATTER 50.0\n\n const float SKY_GROUND_THRESHOLD = 0.02;\n const float outerRadius = OUTER_RADIUS;\n const float outerRadius2 = OUTER_RADIUS * OUTER_RADIUS;\n const float innerRadius = 1.0;\n const float innerRadius2 = 1.0;\n const float cameraHeight = 0.0001;\n\n const float HDSundiskIntensityFactor = 15.0;\n const float simpleSundiskIntensityFactor = 27.0;\n\n const float sunScale = 400.0 * SUN_BRIGHTNESS;\n const float kmESun = MIE * SUN_BRIGHTNESS;\n const float km4PI = MIE * 4.0 * 3.14159265;\n const float scale = 1.0 / (OUTER_RADIUS - 1.0);\n const float scaleDepth = 0.25;\n const float scaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25;\n const float samples = 2.0;\n\n const vec3 c_DefaultScatteringWavelength = vec3(0.65, 0.57, 0.475);\n const vec3 c_VariableRangeForScatteringWavelength = vec3(0.15, 0.15, 0.15);\n\n const float MIE_G = -0.990;\n const float MIE_G2 = 0.9801;\n\n struct Attributes {\n vec4 POSITION;\n };\n\n struct Varyings {\n vec3 v_GroundColor;\n vec3 v_SkyColor;\n #ifdef MATERIAL_SUN_HIGH_QUALITY\n vec3 v_Vertex;\n #elif defined(MATERIAL_SUN_SIMPLE)\n vec3 v_RayDir;\n #else\n float v_SkyGroundFactor;\n #endif\n #if defined(MATERIAL_SUN_HIGH_QUALITY) || defined(MATERIAL_SUN_SIMPLE)\n vec3 v_SunColor;\n #endif\n };\n\n mat4 camera_VPMat;\n vec3 material_SkyTint;\n vec3 material_GroundTint;\n float material_Exposure;\n float material_AtmosphereThickness;\n vec4 scene_SunlightColor;\n vec3 scene_SunlightDirection;\n float material_SunSize;\n float material_SunSizeConvergence;\n\n #define GAMMA 2.2\n #define COLOR_2_GAMMA(color) pow(color, vec3(1.0 / GAMMA))\n #define COLOR_2_LINEAR(color) color\n\n float getRayleighPhase(vec3 light, vec3 ray) {\n float eyeCos = dot(light, ray);\n return 0.75 + 0.75 * eyeCos * eyeCos;\n }\n\n float scaleAngle(float inCos) {\n float x = 1.0 - inCos;\n return 0.25 * exp(-0.00287 + x * (0.459 + x * (3.83 + x * (-6.80 + x * 5.25))));\n }\n\n float getMiePhase(float eyeCos, float eyeCos2) {\n float temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos;\n temp = pow(temp, pow(material_SunSize, 0.65) * 10.0);\n temp = max(temp, 1.0e-4);\n temp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp;\n return temp;\n }\n\n float calcSunAttenuation(vec3 lightPos, vec3 ray) {\n #ifdef MATERIAL_SUN_HIGH_QUALITY\n float focusedEyeCos = pow(clamp(dot(lightPos, ray), 0.0, 1.0), material_SunSizeConvergence);\n return getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos);\n #else //MATERIAL_SUN_SIMPLE\n vec3 delta = lightPos - ray;\n float dist = length(delta);\n float spot = 1.0 - smoothstep(0.0, material_SunSize, dist);\n return spot * spot;\n #endif\n }\n\n Varyings SkyProceduralVertex(Attributes attributes) {\n Varyings varyings;\n\n gl_Position = camera_VPMat * vec4(attributes.POSITION.xyz, 1.0);\n\n vec3 skyTintInGammaSpace = COLOR_2_GAMMA(material_SkyTint);\n vec3 scatteringWavelength = mix(\n c_DefaultScatteringWavelength - c_VariableRangeForScatteringWavelength,\n c_DefaultScatteringWavelength + c_VariableRangeForScatteringWavelength,\n vec3(1.0) - skyTintInGammaSpace\n );\n vec3 invWavelength = 1.0 / pow(scatteringWavelength, vec3(4.0));\n\n float krESun = RAYLEIGH * SUN_BRIGHTNESS;\n float kr4PI = RAYLEIGH * 4.0 * 3.14159265;\n\n vec3 cameraPos = vec3(0.0, innerRadius + cameraHeight, 0.0);\n\n vec3 eyeRay = normalize(attributes.POSITION.xyz);\n\n float far = 0.0;\n vec3 cIn, cOut;\n if (eyeRay.y >= 0.0) {\n // Sky\n far = sqrt(outerRadius2 + innerRadius2 * eyeRay.y * eyeRay.y - innerRadius2) - innerRadius * eyeRay.y;\n\n float height = innerRadius + cameraHeight;\n float depth = exp(scaleOverScaleDepth * -cameraHeight);\n float startAngle = dot(eyeRay, cameraPos) / height;\n float startOffset = depth * scaleAngle(startAngle);\n\n float sampleLength = far / samples;\n float scaledLength = sampleLength * scale;\n vec3 sampleRay = eyeRay * sampleLength;\n vec3 samplePoint = cameraPos + sampleRay * 0.5;\n\n vec3 frontColor = vec3(0.0);\n // Unrolled loop - iteration 1\n {\n float height = length(samplePoint);\n float depth = exp(scaleOverScaleDepth * (innerRadius - height));\n float lightAngle = dot(-scene_SunlightDirection, samplePoint) / height;\n float cameraAngle = dot(eyeRay, samplePoint) / height;\n float scatter = (startOffset + depth * (scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\n vec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\n\n frontColor += attenuate * (depth * scaledLength);\n samplePoint += sampleRay;\n }\n // Unrolled loop - iteration 2\n {\n float height = length(samplePoint);\n float depth = exp(scaleOverScaleDepth * (innerRadius - height));\n float lightAngle = dot(-scene_SunlightDirection, samplePoint) / height;\n float cameraAngle = dot(eyeRay, samplePoint) / height;\n float scatter = (startOffset + depth * (scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\n vec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\n\n frontColor += attenuate * (depth * scaledLength);\n samplePoint += sampleRay;\n }\n\n cIn = frontColor * (invWavelength * krESun);\n cOut = frontColor * kmESun;\n } else {\n // Ground\n far = (-cameraHeight) / (min(-0.001, eyeRay.y));\n vec3 pos = cameraPos + far * eyeRay;\n\n float depth = exp((-cameraHeight) * (1.0 / scaleDepth));\n float cameraAngle = dot(-eyeRay, pos);\n float lightAngle = dot(-scene_SunlightDirection, pos);\n float cameraScale = scaleAngle(cameraAngle);\n float lightScale = scaleAngle(lightAngle);\n float cameraOffset = depth * cameraScale;\n float temp = lightScale + cameraScale;\n\n float sampleLength = far / samples;\n float scaledLength = sampleLength * scale;\n vec3 sampleRay = eyeRay * sampleLength;\n vec3 samplePoint = cameraPos + sampleRay * 0.5;\n\n vec3 frontColor = vec3(0.0, 0.0, 0.0);\n vec3 attenuate;\n\n {\n float height = length(samplePoint);\n float depth = exp(scaleOverScaleDepth * (innerRadius - height));\n float scatter = depth * temp - cameraOffset;\n attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\n frontColor += attenuate * (depth * scaledLength);\n samplePoint += sampleRay;\n }\n\n cIn = frontColor * (invWavelength * krESun + kmESun);\n cOut = clamp(attenuate, 0.0, 1.0);\n }\n\n #ifdef MATERIAL_SUN_HIGH_QUALITY\n varyings.v_Vertex = -attributes.POSITION.xyz;\n #elif defined(MATERIAL_SUN_SIMPLE)\n varyings.v_RayDir = -eyeRay;\n #else\n varyings.v_SkyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD;\n #endif\n\n varyings.v_GroundColor = material_Exposure * (cIn + COLOR_2_LINEAR(material_GroundTint) * cOut);\n varyings.v_SkyColor = material_Exposure * (cIn * getRayleighPhase(-scene_SunlightDirection, -eyeRay));\n\n float lightColorIntensity = clamp(length(scene_SunlightColor.xyz), 0.25, 1.0);\n\n #ifdef MATERIAL_SUN_HIGH_QUALITY\n varyings.v_SunColor = HDSundiskIntensityFactor * clamp(cOut, 0.0, 1.0) * scene_SunlightColor.xyz / lightColorIntensity;\n #elif defined(MATERIAL_SUN_SIMPLE)\n varyings.v_SunColor = simpleSundiskIntensityFactor * clamp(cOut * sunScale, 0.0, 1.0) * scene_SunlightColor.xyz / lightColorIntensity;\n #endif\n\n return varyings;\n }\n\n void SkyProceduralFragment(Varyings varyings) {\n vec3 col = vec3(0.0, 0.0, 0.0);\n\n #ifdef MATERIAL_SUN_HIGH_QUALITY\n vec3 ray = normalize(varyings.v_Vertex);\n float y = ray.y / SKY_GROUND_THRESHOLD;\n #elif defined(MATERIAL_SUN_SIMPLE)\n vec3 ray = varyings.v_RayDir;\n float y = ray.y / SKY_GROUND_THRESHOLD;\n #else\n float y = varyings.v_SkyGroundFactor;\n #endif\n\n col = mix(varyings.v_SkyColor, varyings.v_GroundColor, clamp(y, 0.0, 1.0));\n\n #if defined(MATERIAL_SUN_HIGH_QUALITY) || defined(MATERIAL_SUN_SIMPLE)\n if (y < 0.0)\n col += varyings.v_SunColor * calcSunAttenuation(-scene_SunlightDirection, -ray);\n #endif\n\n gl_FragColor = vec4(col, 1.0);\n }\n }\n }\n}\n";
|
|
397
|
+
|
|
398
|
+
var Sky_Skybox = "Shader \"Sky/Skybox\" {\n Editor {\n Properties {\n Header(\"Base\") {\n material_TintColor(\"TintColor\", Color) = (1, 1, 1, 1);\n material_Exposure(\"Exposure\", Range(0, 8, 0.1)) = 1;\n material_Rotation(\"Rotation\", Range(0, 360, 1)) = 0;\n material_CubeTexture(\"CubeTexture\", TextureCube);\n }\n }\n }\n\n SubShader \"Default\" {\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\" }\n\n DepthState = {\n CompareFunction = CompareFunction.LessEqual;\n }\n RasterState = {\n CullMode = CullMode.Off;\n }\n\n VertexShader = SkyboxVertex;\n FragmentShader = SkyboxFragment;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n\n struct Attributes {\n vec3 POSITION;\n };\n\n struct Varyings {\n vec3 v_cubeUV;\n };\n\n mat4 camera_VPMat;\n float material_Rotation;\n samplerCube material_CubeTexture;\n float material_Exposure;\n vec4 material_TintColor;\n\n vec4 rotateY(vec4 v, float angle) {\n const float deg2rad = 3.1415926 / 180.0;\n float radian = angle * deg2rad;\n float sina = sin(radian);\n float cosa = cos(radian);\n mat2 m = mat2(cosa, -sina, sina, cosa);\n return vec4(m * v.xz, v.yw).xzyw;\n }\n\n Varyings SkyboxVertex(Attributes attributes) {\n Varyings varyings;\n varyings.v_cubeUV = attributes.POSITION;\n gl_Position = camera_VPMat * rotateY(vec4(attributes.POSITION, 1.0), material_Rotation);\n return varyings;\n }\n\n void SkyboxFragment(Varyings varyings) {\n vec4 textureColor = textureCube(material_CubeTexture, varyings.v_cubeUV);\n #ifdef ENGINE_NO_SRGB\n textureColor = sRGBToLinear(textureColor);\n #endif\n textureColor.rgb *= material_Exposure * material_TintColor.rgb;\n gl_FragColor = textureColor;\n }\n }\n }\n}\n";
|
|
399
|
+
|
|
400
|
+
var Unlit = "Shader \"Unlit\" {\n Editor {\n Properties {\n Header(\"Base\") {\n material_BaseColor(\"BaseColor\", Color) = (1, 1, 1, 1);\n material_BaseTexture(\"BaseTexture\", Texture2D);\n }\n\n Header(\"Common\") {\n isTransparent(\"Transparent\", Boolean) = false;\n renderFace(\"Render Face\", Enum(Front:0, Back:1, Double:2)) = 0;\n blendMode(\"Blend Mode\", Enum(Normal:0, Additive:1)) = 0;\n material_AlphaCutoff(\"AlphaCutoff\", Range(0, 1, 0.01)) = 0;\n material_TilingOffset(\"TilingOffset\", Vector4) = (1, 1, 0, 0);\n }\n }\n\n }\n\n SubShader \"Default\" {\n UsePass \"Pipeline/ShadowCaster/Default/ShadowCaster\"\n UsePass \"Pipeline/DepthOnly/Default/DepthOnly\"\n\n Pass \"Forward Pass\" {\n Tags { pipelineStage = \"Forward\" }\n\n RenderQueueType renderQueueType;\n BlendFactor sourceColorBlendFactor;\n BlendFactor destinationColorBlendFactor;\n BlendFactor sourceAlphaBlendFactor;\n BlendFactor destinationAlphaBlendFactor;\n CullMode rasterStateCullMode;\n Bool blendEnabled;\n Bool depthWriteEnabled;\n\n DepthState = {\n WriteEnabled = depthWriteEnabled;\n }\n\n BlendState = {\n Enabled = blendEnabled;\n SourceColorBlendFactor = sourceColorBlendFactor;\n DestinationColorBlendFactor = destinationColorBlendFactor;\n SourceAlphaBlendFactor = sourceAlphaBlendFactor;\n DestinationAlphaBlendFactor = destinationAlphaBlendFactor;\n }\n\n RasterState = {\n CullMode = rasterStateCullMode;\n }\n\n RenderQueueType = renderQueueType;\n\n VertexShader = vert;\n FragmentShader = frag;\n\n #include \"ShaderLibrary/Common/Common.glsl\"\n #include \"ShaderLibrary/Common/Transform.glsl\"\n #include \"ShaderLibrary/Common/Fog.glsl\"\n #include \"ShaderLibrary/Common/Attributes.glsl\"\n #include \"ShaderLibrary/Skin/Skin.glsl\"\n #include \"ShaderLibrary/Skin/BlendShape.glsl\"\n\n vec4 material_TilingOffset;\n vec4 material_BaseColor;\n float material_AlphaCutoff;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n sampler2D material_BaseTexture;\n #endif\n\n struct Varyings {\n vec2 v_uv;\n #if SCENE_FOG_MODE != 0\n vec3 v_positionVS;\n #endif\n };\n\n Varyings vert(Attributes attr) {\n Varyings v;\n\n vec4 position = vec4(attr.POSITION, 1.0);\n\n #ifdef RENDERER_HAS_NORMAL\n vec3 normal = attr.NORMAL;\n #ifdef RENDERER_HAS_TANGENT\n vec4 tangent = attr.TANGENT;\n #endif\n #endif\n\n #ifdef RENDERER_HAS_BLENDSHAPE\n calculateBlendShape(attr, position\n #ifdef RENDERER_HAS_NORMAL\n , normal\n #ifdef RENDERER_HAS_TANGENT\n , tangent\n #endif\n #endif\n );\n #endif\n\n #ifdef RENDERER_HAS_SKIN\n mat4 skinMatrix = getSkinMatrix(attr);\n position = skinMatrix * position;\n #endif\n\n #ifdef RENDERER_HAS_UV\n v.v_uv = attr.TEXCOORD_0;\n #else\n v.v_uv = vec2(0.0);\n #endif\n #ifdef MATERIAL_NEED_TILING_OFFSET\n v.v_uv = v.v_uv * material_TilingOffset.xy + material_TilingOffset.zw;\n #endif\n\n gl_Position = renderer_MVPMat * position;\n\n #if SCENE_FOG_MODE != 0\n v.v_positionVS = (renderer_MVMat * position).xyz;\n #endif\n\n return v;\n }\n\n void frag(Varyings v) {\n vec4 baseColor = material_BaseColor;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n baseColor *= texture2DSRGB(material_BaseTexture, v.v_uv);\n #endif\n\n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if (baseColor.a < material_AlphaCutoff) {\n discard;\n }\n #endif\n\n gl_FragColor = baseColor;\n\n #ifndef MATERIAL_IS_TRANSPARENT\n gl_FragColor.a = 1.0;\n #endif\n\n #if SCENE_FOG_MODE != 0\n gl_FragColor = fog(gl_FragColor, v.v_positionVS);\n #endif\n }\n }\n }\n}\n";
|
|
401
|
+
|
|
402
|
+
// Auto-generated by shader-compiler-precompile --emit-sources — do not edit.
|
|
403
|
+
// prettier-ignore
|
|
404
|
+
var shaders = [
|
|
405
|
+
{
|
|
406
|
+
source: _2D_Sprite,
|
|
407
|
+
path: "Shaders/2D/Sprite.shader"
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
source: _2D_SpriteMask,
|
|
411
|
+
path: "Shaders/2D/SpriteMask.shader"
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
source: _2D_Text,
|
|
415
|
+
path: "Shaders/2D/Text.shader"
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
source: _2D_UIDefault,
|
|
419
|
+
path: "Shaders/2D/UIDefault.shader"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
source: BlinnPhong,
|
|
423
|
+
path: "Shaders/BlinnPhong.shader"
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
source: Blit_Blit,
|
|
427
|
+
path: "Shaders/Blit/Blit.shader"
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
source: Blit_BlitScreen,
|
|
431
|
+
path: "Shaders/Blit/BlitScreen.shader"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
source: Effect_Particle,
|
|
435
|
+
path: "Shaders/Effect/Particle.shader"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
source: Effect_ParticleFeedback,
|
|
439
|
+
path: "Shaders/Effect/ParticleFeedback.shader"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
source: Effect_Trail,
|
|
443
|
+
path: "Shaders/Effect/Trail.shader"
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
source: Lighting_ScalableAmbientOcclusion,
|
|
447
|
+
path: "Shaders/Lighting/ScalableAmbientOcclusion.shader"
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
source: PBR,
|
|
451
|
+
path: "Shaders/PBR.shader"
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
source: Pipeline_DepthOnly,
|
|
455
|
+
path: "Shaders/Pipeline/DepthOnly.shader"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
source: Pipeline_ShadowCaster,
|
|
459
|
+
path: "Shaders/Pipeline/ShadowCaster.shader"
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
source: PostProcess_Bloom,
|
|
463
|
+
path: "Shaders/PostProcess/Bloom.shader"
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
source: PostProcess_FinalAntiAliasing,
|
|
467
|
+
path: "Shaders/PostProcess/FinalAntiAliasing.shader"
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
source: PostProcess_FinalSRGB,
|
|
471
|
+
path: "Shaders/PostProcess/FinalSRGB.shader"
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
source: PostProcess_Uber,
|
|
475
|
+
path: "Shaders/PostProcess/Uber.shader"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
source: Sky_BackgroundTexture,
|
|
479
|
+
path: "Shaders/Sky/BackgroundTexture.shader"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
source: Sky_SkyProcedural,
|
|
483
|
+
path: "Shaders/Sky/SkyProcedural.shader"
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
source: Sky_Skybox,
|
|
487
|
+
path: "Shaders/Sky/Skybox.shader"
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
source: Unlit,
|
|
491
|
+
path: "Shaders/Unlit.shader"
|
|
492
|
+
}
|
|
493
|
+
];
|
|
494
|
+
|
|
495
|
+
exports.shaderLibrary = shaderLibrary;
|
|
496
|
+
exports.shaders = shaders;
|
|
497
|
+
//# sourceMappingURL=sources.main.js.map
|