| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // helper functions for lighting model-functions
- // return unnormalized vector, support oppo-side
- // V from pixel to camera
- vec3 CalculateRefractDirection(vec3 N, vec3 V, float NoV, float ior)
- {
- // two sided
- float sideSign = NoV < 0.0 ? -1.0 : 1.0;
- N *= sideSign;
- // A: NV B:NR
- float cosA = abs(NoV);
- float sinA = sqrt(1.0 - cosA * cosA);
- float sinB = saturate(sinA / ior);
- float cosB = sqrt(1.0 - sinB * sinB);
- vec3 edgeA = -V + N * cosA;
- vec3 edgeB = normalize(edgeA) * sinB;
- vec3 R = edgeB - N * cosB;
- return R;
- }
- vec3 CalculateRefractDirectionFast(vec3 N, vec3 V, float NoV, float ior)
- {
- // two sided
- float sideSign = NoV < 0.0 ? -1.0 : 1.0;
- N *= sideSign;
- float w = ior * NoV;
- float k = sqrt(1.0 + (w - ior) * (w + ior)); // 1 + ior2 * (NoV2 - 1)
- vec3 R = (w - k) * N - ior * V;
- return -R;
- }
- vec3 CalculateReflectDirection(vec3 N, vec3 V, float NoV)
- {
- // two sided
- float sideSign = NoV < 0.0 ? -1.0 : 1.0;
- N *= sideSign;
- return reflect(-V, N);
- }
- // for bumped planar reflection
- vec3 CalculatePlanarReflectPositionOnPlane(vec3 N, vec3 V, vec3 worldPos, vec4 plane, vec3 cameraPos, float probeReflectedDepth)
- {
- float distPixelToPlane = -dot(plane, vec4(worldPos, 1.0));
- // bring plane to worldPos, avoid artifacts when reflected point away from plane (do not bring worldPos to plane)
- plane.w += distPixelToPlane;
- float distCameraToPlane = abs(-dot(plane, vec4(cameraPos, 1.0)));
- vec3 planeN = plane.xyz;
- vec3 virtualCameraPos = cameraPos - 2.0 * distCameraToPlane * planeN;
- /*support for two-sided reflections
- float sideSignPlaneN = dot(planeN, V) < 0.0 ? -1.0 : 1.0;
- float sideSignN = dot(N, V) < 0.0 ? -1.0 : 1.0;
- planeN *= sideSignPlaneN;
- N *= sideSignN;*/
- vec3 bumpedR = normalize(reflect(-V, N)); //R'
- // actually reflected pos alone bumpedR direction, avoid tracing by specified a fake depth
- vec3 reflectedPointPos = worldPos + probeReflectedDepth * bumpedR;
- vec3 virtualCameraToReflectedPoint = normalize(reflectedPointPos - virtualCameraPos);
- // the ray from virtual camera to reflected point, will intersect with plane on P'
- float y = distCameraToPlane / max(EPSILON_LOWP, dot(planeN, virtualCameraToReflectedPoint));
- return virtualCameraPos + y * virtualCameraToReflectedPoint;
- }
- // fix cubemap direction with box projection
- // return unnormalized vector and weight for exceeding
- vec4 CalculateBoxProjectedDirection(vec3 R, vec3 worldPos, vec3 cubeCenterPos, vec3 cubeBoxHalfSize)
- {
- // point W is the worldPos in the space origin align with cube center
- vec3 W = worldPos - cubeCenterPos;
- // find point P which intersected with cube box border from W alone R
- vec3 projectedLength = (sign(R) * cubeBoxHalfSize - W) / (R + vec3(EPSILON));
- float len = min(min(projectedLength.x, projectedLength.y), projectedLength.z);
- vec3 P = W + len * R;
- float weight = len < 0.0 ? 0.0 : 1.0;
- return vec4(P, weight);
- }
- // calculate planar world pos
- vec4 CalculatePlanarShadowPos(vec3 meshWorldPos, vec3 cameraPos, vec3 lightDir, vec4 plane) {
- vec3 P = meshWorldPos;
- vec3 L = lightDir;
- vec3 N = plane.xyz;
- float d = plane.w + EPSILON_LOWP;
- float dist = (-d - dot(P, N)) / (dot(L, N) + EPSILON_LOWP);
- vec3 shadowPos = P + L * dist;
- return vec4(shadowPos, dist);
- }
- // calculate planar clip pos from world pos
- vec4 CalculatePlanarShadowClipPos(vec4 shadowPos, vec3 cameraPos, mat4 matView, mat4 matProj, vec4 nearFar, float bias) {
- vec4 camPos = matView * vec4(shadowPos.xyz, 1.0);
- // avoid z-fighting with shadow receive plane, add camera bias with perspective correction
- // notice that near plane should not be too small, assume near 1, far 1000
- float lerpCoef = saturate((nearFar.z < 0.0 ? -camPos.z : camPos.z) / (nearFar.y - nearFar.x));
- camPos.z += mix(nearFar.x * 0.01, nearFar.y * EPSILON_LOWP * bias, lerpCoef);
- return matProj * camPos;
- }
|