common/common-define.chunk
// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
// common module
// constant value
#define QUATER_PI 0.78539816340
#define HALF_PI 1.57079632679
#define PI 3.14159265359
#define PI2 6.28318530718
#define PI4 12.5663706144
#define INV_QUATER_PI 1.27323954474
#define INV_HALF_PI 0.63661977237
#define INV_PI 0.31830988618
#define INV_PI2 0.15915494309
#define INV_PI4 0.07957747155
#define EPSILON 1e-6
#define EPSILON_LOWP 1e-4
#define LOG2 1.442695
#define EXP_VALUE 2.71828183
#define FP_MAX 65504.0
#define FP_SCALE 0.0009765625
#define FP_SCALE_INV 1024.0
#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)
// common functions
#pragma define equalf(data1, data2) (abs(float(data1) - float(data2)) < EPSILON)
#pragma define equalf_lowp(data1, data2) (abs(float(data1) - float(data2)) < EPSILON_LOWP)
#pragma define equalf_epsilon(data1, data2, epsilonValue) (abs(float(data1) - float(data2)) < epsilonValue)
#pragma define clip(value) if(value < 0.0) discard;
#pragma define lerp(value1, value2, value2Multiplier) mix(value1, value2, value2Multiplier)
float saturate(float value) { return clamp(value, 0.0, 1.0); }
vec2 saturate(vec2 value) { return clamp(value, vec2(0.0), vec2(1.0)); }
vec3 saturate(vec3 value) { return clamp(value, vec3(0.0), vec3(1.0)); }
vec4 saturate(vec4 value) { return clamp(value, vec4(0.0), vec4(1.0)); }
// runtime constants
#pragma define-meta CC_DEVICE_SUPPORT_FLOAT_TEXTURE default(1)
#pragma define-meta CC_DEVICE_MAX_FRAGMENT_UNIFORM_VECTORS default(1024)
#pragma define-meta CC_DEVICE_MAX_VERTEX_UNIFORM_VECTORS default(1024)
#pragma define-meta CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS default(128)
#pragma define-meta CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS default(128)
#pragma define-meta CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT default(0)
#pragma define-meta CC_PLATFORM_ANDROID_AND_WEBGL default(0)
#pragma define-meta CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES default(0)
// When sampling RTs, Y-flip is needed if the screen space sign Y is positive (pointing upwards)
#pragma define CC_HANDLE_RT_SAMPLE_FLIP(uv) uv = cc_cameraPos.w > 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv
#pragma define CC_HANDLE_GET_CLIP_FLIP(uv) uv = cc_cameraPos.w == 0.0 ? vec2(uv.x, -uv.y) : uv
// CC_USE_LIGHTMAP Values
#define LIGHT_MAP_TYPE_DISABLED 0
#define LIGHT_MAP_TYPE_ALL_IN_ONE 1
#define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2
// CC_USE_REFLECTION_PROBE Values
#define REFLECTION_PROBE_TYPE_NONE 0
#define REFLECTION_PROBE_TYPE_CUBE 1
#define REFLECTION_PROBE_TYPE_PLANAR 2
#define REFLECTION_PROBE_TYPE_BLEND 3
#define REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX 4
#pragma define IS_REFLECTION_PROBE_USE_RGBE(mipcount) mipcount > 1000.0
#pragma define RESTORE_REFLECTION_PROBE_MIP_COUNT(mipcount) if (mipcount > 1000.0) mipcount -= 1000.0
// Light Type
#define LIGHT_TYPE_DIRECTIONAL 0.0
#define LIGHT_TYPE_SPHERE 1.0
#define LIGHT_TYPE_SPOT 2.0
#define LIGHT_TYPE_POINT 3.0
#define LIGHT_TYPE_RANGED_DIRECTIONAL 4.0
#define IS_DIRECTIONAL_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_DIRECTIONAL)
#define IS_SPHERE_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_SPHERE)
#define IS_SPOT_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_SPOT)
#define IS_POINT_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_POINT)
#define IS_RANGED_DIRECTIONAL_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_RANGED_DIRECTIONAL)
// CC_TONE_MAPPING_TYPE Values
#define TONE_MAPPING_ACES 0
#define TONE_MAPPING_LINEAR 1
// Material
#define SURFACES_MAX_TRANSMIT_DEPTH_VALUE 999999.0
// CC_USE_DEBUG_VIEW Values
#ifndef CC_SURFACES_DEBUG_VIEW_SINGLE
#define CC_SURFACES_DEBUG_VIEW_SINGLE 1
#endif
#ifndef CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC
#define CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC 2
#endif
Đoạn mã bạn cung cấp chứa nhiều định nghĩa hằng số, macro, và các hàm thông dụng được dùng trong shader và các tính toán đồ họa. Đây là phần của một module chung trong một hệ thống đồ họa như Cocos Creator, giúp tối ưu hóa và dễ dàng tái sử dụng các giá trị/hàm chung cho nhiều shader khác nhau. Sau đây là giải thích chi tiết từng phần của mã:
Mục lục
1. Hằng số toán học và đồ họa
#define QUATER_PI 0.78539816340 // Pi / 4 (1/4 của Pi)
#define HALF_PI 1.57079632679 // Pi / 2 (1/2 của Pi)
#define PI 3.14159265359 // Pi (~3.14)
#define PI2 6.28318530718 // 2 * Pi (chu vi của một đường tròn đơn vị)
#define PI4 12.5663706144 // 4 * Pi (chu vi của hai đường tròn)
#define INV_QUATER_PI 1.27323954474 // 1 / (Pi / 4)
#define INV_HALF_PI 0.63661977237 // 1 / (Pi / 2)
#define INV_PI 0.31830988618 // 1 / Pi
#define INV_PI2 0.15915494309 // 1 / (2 * Pi)
#define INV_PI4 0.07957747155 // 1 / (4 * Pi)
#define EPSILON 1e-6 // Sai số cực nhỏ, dùng trong tính toán để tránh vấn đề về số thực.
#define EPSILON_LOWP 1e-4 // Sai số lớn hơn, dùng khi độ chính xác thấp chấp nhận được.
#define LOG2 1.442695 // Log cơ số 2 của e (dùng trong tính toán logarit).
#define EXP_VALUE 2.71828183 // e, cơ số của logarit tự nhiên.
#define FP_MAX 65504.0 // Giá trị số thực lớn nhất có thể lưu trữ trong chuẩn IEEE 754 16-bit.
#define FP_SCALE 0.0009765625 // 1 / 1024, dùng để scale giá trị số thực nhỏ.
#define FP_SCALE_INV 1024.0 // Nghịch đảo của FP_SCALE, thường để tăng độ lớn.
#define GRAY_VECTOR vec3(0.299, 0.587, 0.114) // Vector màu xám, dùng trong tính toán chuyển đổi từ màu sang thang xám.
- Các hằng số này được sử dụng để tránh việc tính toán lại các giá trị toán học thường xuyên trong shader, như Pi hay e, cũng như các giá trị epsilon giúp tránh lỗi trong tính toán số học.
2. Hàm và macro tiện ích
#pragma define equalf(data1, data2) (abs(float(data1) - float(data2)) < EPSILON)
#pragma define equalf_lowp(data1, data2) (abs(float(data1) - float(data2)) < EPSILON_LOWP)
#pragma define equalf_epsilon(data1, data2, epsilonValue) (abs(float(data1) - float(data2)) < epsilonValue)
#pragma define clip(value) if(value < 0.0) discard;
#pragma define lerp(value1, value2, value2Multiplier) mix(value1, value2, value2Multiplier)
equalf(data1, data2)
: So sánh hai giá trị thực với độ chính xác cao, sử dụngEPSILON
để tránh lỗi số học nhỏ.equalf_lowp(data1, data2)
: So sánh hai giá trị thực với độ chính xác thấp hơn, sử dụngEPSILON_LOWP
.equalf_epsilon(data1, data2, epsilonValue)
: So sánh hai giá trị với một độ sai số cụ thể (do người dùng cung cấpepsilonValue
).clip(value)
: Nếu giá trị nhỏ hơn0.0
, thì discard (loại bỏ) pixel này trong shader, thường được dùng để xử lý alpha clipping.lerp(value1, value2, value2Multiplier)
: Nội suy tuyến tính giữavalue1
vàvalue2
theovalue2Multiplier
, đây chính là hàm mix trong GLSL.
float saturate(float value) { return clamp(value, 0.0, 1.0); }
vec2 saturate(vec2 value) { return clamp(value, vec2(0.0), vec2(1.0)); }
vec3 saturate(vec3 value) { return clamp(value, vec3(0.0), vec3(1.0)); }
vec4 saturate(vec4 value) { return clamp(value, vec4(0.0), vec4(1.0)); }
saturate()
: Hàm clamp giá trị vào khoảng từ0.0
đến1.0
. Hàm này tồn tại dưới nhiều phiên bản với các kiểu dữ liệu khác nhau (float, vec2, vec3, vec4). Thường dùng để giới hạn các giá trị (như màu sắc) trong phạm vi hợp lệ.
3. Các hằng số và macro runtime
#pragma define-meta CC_DEVICE_SUPPORT_FLOAT_TEXTURE default(1)
#pragma define-meta CC_DEVICE_MAX_FRAGMENT_UNIFORM_VECTORS default(1024)
#pragma define-meta CC_DEVICE_MAX_VERTEX_UNIFORM_VECTORS default(1024)
#pragma define-meta CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS default(128)
#pragma define-meta CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS default(128)
#pragma define-meta CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT default(0)
#pragma define-meta CC_PLATFORM_ANDROID_AND_WEBGL default(0)
#pragma define-meta CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES default(0)
- Các macro này được sử dụng để cung cấp các thông tin về khả năng của thiết bị (device capability). Ví dụ:
- CC_DEVICE_SUPPORT_FLOAT_TEXTURE: Thiết bị có hỗ trợ texture dạng số thực hay không.
- CC_DEVICE_MAX_FRAGMENT_UNIFORM_VECTORS: Số lượng uniform vectors tối đa trong shader fragment.
- CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS: Số lượng uniform vectors đang được sử dụng trong shader vertex.
#pragma define CC_HANDLE_RT_SAMPLE_FLIP(uv) uv = cc_cameraPos.w > 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv
#pragma define CC_HANDLE_GET_CLIP_FLIP(uv) uv = cc_cameraPos.w == 0.0 ? vec2(uv.x, -uv.y) : uv
- CC_HANDLE_RT_SAMPLE_FLIP(uv): Điều chỉnh UV khi lấy mẫu texture render target (RT) để tránh sai lệch chiều Y khi camera có chiều Y-flip (camera nhìn theo hướng Y ngược).
- CC_HANDLE_GET_CLIP_FLIP(uv): Điều chỉnh UV để xử lý clipspace flip dựa trên vị trí camera.
4. Hằng số về Lightmap và Reflection Probe
// CC_USE_LIGHTMAP Values
#define LIGHT_MAP_TYPE_DISABLED 0
#define LIGHT_MAP_TYPE_ALL_IN_ONE 1
#define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2
// CC_USE_REFLECTION_PROBE Values
#define REFLECTION_PROBE_TYPE_NONE 0
#define REFLECTION_PROBE_TYPE_CUBE 1
#define REFLECTION_PROBE_TYPE_PLANAR 2
#define REFLECTION_PROBE_TYPE_BLEND 3
#define REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX 4
#pragma define IS_REFLECTION_PROBE_USE_RGBE(mipcount) mipcount > 1000.0
#pragma define RESTORE_REFLECTION_PROBE_MIP_COUNT(mipcount) if (mipcount > 1000.0) mipcount -= 1000.0
-
CC_USE_LIGHTMAP: Các loại Lightmap:
LIGHT_MAP_TYPE_DISABLED
: Không sử dụng lightmap.LIGHT_MAP_TYPE_ALL_IN_ONE
: Sử dụng một lightmap chung cho cả ánh sáng trực tiếp và gián tiếp.LIGHT_MAP_TYPE_INDIRECT_OCCLUSION
: Sử dụng lightmap chỉ cho ánh sáng gián tiếp.
-
CC_USE_REFLECTION_PROBE: Các loại Reflection Probe:
REFLECTION_PROBE_TYPE_NONE
: Không sử dụng reflection probe.REFLECTION_PROBE_TYPE_CUBE
: Sử dụng reflection probe dạng hình khối (cube map).REFLECTION_PROBE_TYPE_PLANAR
: Sử dụng reflection probe phẳng (planar reflection).REFLECTION_PROBE_TYPE_BLEND
: Phản xạ với khả năng blend giữa các probe.REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX
: Phản xạ với blend giữa probe và skybox.
-
IS_REFLECTION_PROBE_USE_RGBE: Kiểm tra nếu mip count (số cấp độ mip) lớn hơn
1000
, điều này thường liên quan đến việc mã hóa hình ảnh phản chiếu trong định dạng RGBE. -
RESTORE_REFLECTION_PROBE_MIP_COUNT: Loại bỏ
1000
khỏi mip count nếu nó vượt quá giá trị này.
5. Loại ánh sáng và Tone Mapping
// Light Type
#define LIGHT_TYPE_DIRECTIONAL 0.0
#define LIGHT_TYPE_SPHERE 1.0
#define LIGHT_TYPE_SPOT 2.0
#define LIGHT_TYPE_POINT 3.0
#define LIGHT_TYPE_RANGED_DIRECTIONAL 4.0
#define IS_DIRECTIONAL_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_DIRECTIONAL)
#define IS_SPHERE_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_SPHERE)
#define IS_SPOT_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_SPOT)
#define IS_POINT_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_POINT)
#define IS_RANGED_DIRECTIONAL_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_RANGED_DIRECTIONAL)
-
Loại ánh sáng:
LIGHT_TYPE_DIRECTIONAL
: Ánh sáng hướng (như mặt trời).LIGHT_TYPE_SPHERE
: Ánh sáng dạng hình cầu.LIGHT_TYPE_SPOT
: Ánh sáng chiếu điểm.LIGHT_TYPE_POINT
: Ánh sáng điểm.LIGHT_TYPE_RANGED_DIRECTIONAL
: Ánh sáng hướng với khoảng cách giới hạn.
-
Macro kiểm tra loại ánh sáng:
IS_DIRECTIONAL_LIGHT(light_type)
: Kiểm tra nếu ánh sáng là loại Directional.- Tương tự cho Sphere, Spot, Point, và Ranged Directional.
// CC_TONE_MAPPING_TYPE Values
#define TONE_MAPPING_ACES 0
#define TONE_MAPPING_LINEAR 1
- CC_TONE_MAPPING_TYPE: Các loại tone mapping (quá trình chuyển đổi ánh sáng HDR thành ánh sáng LDR):
TONE_MAPPING_ACES
: Sử dụng tone mapping kiểu ACES (một thuật toán xử lý ánh sáng rất phổ biến).TONE_MAPPING_LINEAR
: Tone mapping tuyến tính.
6. Các giá trị khác
#define SURFACES_MAX_TRANSMIT_DEPTH_VALUE 999999.0
#define CC_SURFACES_DEBUG_VIEW_SINGLE 1
#define CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC 2
- SURFACES_MAX_TRANSMIT_DEPTH_VALUE: Độ sâu truyền tối đa cho các bề mặt (dùng trong các hiệu ứng như ánh sáng xuyên qua).
- CC_SURFACES_DEBUG_VIEW_SINGLE: Chế độ debug xem đơn.
- CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC: Chế độ debug kết hợp các view.
Bình luận gần đây