#ifndef __VERTEX_INC #define __VERTEX_INC #include "globals.cginc" #include "vertex_deformation.hlsl" #define FOO(x) (x) #if defined(_VERTEX_DEFORMATION_XZ_TUBE) #define VERTEX_DEFORM_XZ_TUBE_PREAMBLE \ float t = _Vertex_Deformation_XZ_Tube_t #define VERTEX_DEFORM_XZ_TUBE_POS \ objPos = plane_to_tube(objPos.xyz, t) #define VERTEX_DEFORM_XZ_TUBE_NORM \ plane_to_tube_normal(objPos, objNorm, objTan, t) #else #define VERTEX_DEFORM_XZ_TUBE_PREAMBLE #define VERTEX_DEFORM_XZ_TUBE_POS #define VERTEX_DEFORM_XZ_TUBE_NORM #endif // VERTEX_DEFORMATION_XZ_TUBE #if defined(_VERTEX_DEFORMATION_YZ_TUBE) #define VERTEX_DEFORM_YZ_TUBE_PREAMBLE \ float t = _Vertex_Deformation_YZ_Tube_t #define VERTEX_DEFORM_YZ_TUBE_POS \ objPos = plane_to_tube(objPos.yxz, t); \ objPos = objPos.yxz #define VERTEX_DEFORM_YZ_TUBE_NORM \ float3 yzPos = objPos.yxz; \ float3 yzNorm = objNorm.yxz; \ float3 yzTan = objTan.yxz; \ plane_to_tube_normal(yzPos, yzNorm, yzTan, t); \ objPos = yzPos.yxz; \ objNorm = yzNorm.yxz; \ objTan = yzTan.yxz #else #define VERTEX_DEFORM_YZ_TUBE_PREAMBLE #define VERTEX_DEFORM_YZ_TUBE_POS #define VERTEX_DEFORM_YZ_TUBE_NORM #endif // VERTEX_DEFORMATION_YZ_TUBE #if defined(_VERTEX_DEFORMATION_XY_TUBE) #define VERTEX_DEFORM_XY_TUBE_PREAMBLE \ float t = _Vertex_Deformation_XY_Tube_t #define VERTEX_DEFORM_XY_TUBE_POS \ objPos = plane_to_tube(objPos.xzy, t); \ objPos = objPos.xzy #define VERTEX_DEFORM_XY_TUBE_NORM \ float3 xyPos = objPos.xzy; \ float3 xyNorm = objNorm.xzy; \ float3 xyTan = objTan.xzy; \ plane_to_tube_normal(xyPos, xyNorm, xyTan, t); \ objPos = xyPos.xzy; \ objNorm = xyNorm.xzy; \ objTan = xyTan.xzy #else #define VERTEX_DEFORM_XY_TUBE_PREAMBLE #define VERTEX_DEFORM_XY_TUBE_POS #define VERTEX_DEFORM_XY_TUBE_NORM #endif // VERTEX_DEFORMATION_XY_TUBE #if defined(_VERTEX_DEFORMATION_NORM_CONVERSION) #define VERTEX_DEFORM_NORM_CONVERSION_PREAMBLE \ float t = _Vertex_Deformation_Norm_Conversion_t; \ float input_k = _Vertex_Deformation_Norm_Conversion_Input_k; \ float output_k = _Vertex_Deformation_Norm_Conversion_Output_k #define VERTEX_DEFORM_NORM_CONVERSION_POS \ objPos = norm_conversion(objPos.xyz, input_k, output_k, t) #define VERTEX_DEFORM_NORM_CONVERSION_NORM \ norm_conversion_normal(objPos, objNorm, objTan, input_k, output_k, t) #else #define VERTEX_DEFORM_NORM_CONVERSION_PREAMBLE #define VERTEX_DEFORM_NORM_CONVERSION_POS #define VERTEX_DEFORM_NORM_CONVERSION_NORM #endif // _VERTEX_DEFORMATION_NORM_CONVERSION #if defined(_VERTEX_DEFORMATION_SEAL) #define VERTEX_DEFORM_SEAL_PREAMBLE \ float A = _Vertex_Deformation_Seal_A; \ float k = _Vertex_Deformation_Seal_k; \ float st = t * _Vertex_Deformation_Seal_t #define VERTEX_DEFORM_SEAL_POS \ objPos = seal(objPos.xyz, A, k, st) #define VERTEX_DEFORM_SEAL_NORM \ seal_normal(objPos, objNorm, objTan, A, k, st) #else #define VERTEX_DEFORM_SEAL_PREAMBLE #define VERTEX_DEFORM_SEAL_POS #define VERTEX_DEFORM_SEAL_NORM #endif // _VERTEX_DEFORMATION_SEAL #if defined(_VERTEX_DEFORMATION_SINE_WAVES) #define VERTEX_DEFORM_SINE_WAVES_PREAMBLE \ float st = t * 10; \ float3 amplitude = _Vertex_Deformation_Sine_Waves_Amplitude; \ float3 direction = _Vertex_Deformation_Sine_Waves_Direction; \ float3 k = _Vertex_Deformation_Sine_Waves_k; \ float3 omega = _Vertex_Deformation_Sine_Waves_omega #define VERTEX_DEFORM_SINE_WAVES_POS \ objPos = sine_wave(objPos.xyz, amplitude, direction, k, omega, st) #define VERTEX_DEFORM_SINE_WAVES_NORM \ sine_wave_normal(objPos, objNorm, objTan, amplitude, direction, k, omega, st) #else #define VERTEX_DEFORM_SINE_WAVES_PREAMBLE #define VERTEX_DEFORM_SINE_WAVES_POS #define VERTEX_DEFORM_SINE_WAVES_NORM #endif // _VERTEX_DEFORMATION_SINE_WAVES #if defined(_VERTEX_DEFORMATION_FBM) #define VERTEX_DEFORM_FBM_PREAMBLE \ float st = t; \ float amplitude = _Vertex_Deformation_FBM_Amplitude; \ float gain = _Vertex_Deformation_FBM_Gain; \ float lacunarity = _Vertex_Deformation_FBM_Lacunarity; \ float scale = _Vertex_Deformation_FBM_Scale; \ float octaves = _Vertex_Deformation_FBM_Octaves; \ float3 velocity = _Vertex_Deformation_FBM_Velocity #define VERTEX_DEFORM_FBM_POS \ objPos = fbm(objPos, st, amplitude, gain, lacunarity, scale, octaves, velocity) #define VERTEX_DEFORM_FBM_NORM \ fbm_normal(objPos, objNorm, objTan, st, amplitude, gain, lacunarity, scale, octaves, velocity) #else #define VERTEX_DEFORM_FBM_PREAMBLE #define VERTEX_DEFORM_FBM_POS #define VERTEX_DEFORM_FBM_NORM #endif // _VERTEX_DEFORMATION_FBM void deform(inout float3 objPos) { const float t = getTime(); { VERTEX_DEFORM_XZ_TUBE_PREAMBLE; VERTEX_DEFORM_XZ_TUBE_POS; } { VERTEX_DEFORM_YZ_TUBE_PREAMBLE; VERTEX_DEFORM_YZ_TUBE_POS; } { VERTEX_DEFORM_XY_TUBE_PREAMBLE; VERTEX_DEFORM_XY_TUBE_POS; } { VERTEX_DEFORM_NORM_CONVERSION_PREAMBLE; VERTEX_DEFORM_NORM_CONVERSION_POS; } { VERTEX_DEFORM_SEAL_PREAMBLE; VERTEX_DEFORM_SEAL_POS; } { VERTEX_DEFORM_SINE_WAVES_PREAMBLE; VERTEX_DEFORM_SINE_WAVES_POS; } { VERTEX_DEFORM_FBM_PREAMBLE; VERTEX_DEFORM_FBM_POS; } } void deform_normal(inout float3 objPos, inout float3 objNorm, inout float3 objTan) { const float t = getTime(); { VERTEX_DEFORM_XZ_TUBE_PREAMBLE; VERTEX_DEFORM_XZ_TUBE_NORM; } { VERTEX_DEFORM_YZ_TUBE_PREAMBLE; VERTEX_DEFORM_YZ_TUBE_NORM; } { VERTEX_DEFORM_XY_TUBE_PREAMBLE; VERTEX_DEFORM_XY_TUBE_NORM; } { VERTEX_DEFORM_NORM_CONVERSION_PREAMBLE; VERTEX_DEFORM_NORM_CONVERSION_NORM; } { VERTEX_DEFORM_SEAL_PREAMBLE; VERTEX_DEFORM_SEAL_NORM; } { VERTEX_DEFORM_SINE_WAVES_PREAMBLE; VERTEX_DEFORM_SINE_WAVES_NORM; } { VERTEX_DEFORM_FBM_PREAMBLE; VERTEX_DEFORM_FBM_NORM; } } // `objPos` is in the un-deformed coordinate system, while `objNorm` and // `objTan` are in the deformed coordinate system. The task is to map `objNorm` // and `objTan` to the un-deformed coordinate system. // We do this, coarsely, as follows: // 1. Map objPos into the deformed coordinate system through stepwise // transformations, like `deform`. We remember each position along the way. // 2. Map objNorm and objTan back one step using the deformed final position. // For the first iteration, we use the last (deformed) `objPos` that we // remembered from step 1. // 3. Repeat step 2 until we're back in the un-deforme coordinate system. At // each step, we use the cached objPos from the forward pass (step 1), so // that we evaluate the normal deformation at the correct point in space. void undeform_normal(inout float3 objPos, inout float3 objNorm, inout float3 objTan) { const float t = getTime(); const int kMaxDeformations = 32; // Cache each intermediate position so we can undo stages in reverse order. float3 posHistory[kMaxDeformations + 1]; int posCount = 0; posHistory[posCount++] = objPos; #if defined(_VERTEX_DEFORMATION_XZ_TUBE) { VERTEX_DEFORM_XZ_TUBE_PREAMBLE; VERTEX_DEFORM_XZ_TUBE_POS; posHistory[posCount++] = objPos; } #endif #if defined(_VERTEX_DEFORMATION_YZ_TUBE) { VERTEX_DEFORM_YZ_TUBE_PREAMBLE; VERTEX_DEFORM_YZ_TUBE_POS; posHistory[posCount++] = objPos; } #endif #if defined(_VERTEX_DEFORMATION_XY_TUBE) { VERTEX_DEFORM_XY_TUBE_PREAMBLE; VERTEX_DEFORM_XY_TUBE_POS; posHistory[posCount++] = objPos; } #endif #if defined(_VERTEX_DEFORMATION_NORM_CONVERSION) { VERTEX_DEFORM_NORM_CONVERSION_PREAMBLE; VERTEX_DEFORM_NORM_CONVERSION_POS; posHistory[posCount++] = objPos; } #endif #if defined(_VERTEX_DEFORMATION_SEAL) { VERTEX_DEFORM_SEAL_PREAMBLE; VERTEX_DEFORM_SEAL_POS; posHistory[posCount++] = objPos; } #endif #if defined(_VERTEX_DEFORMATION_SINE_WAVES) { VERTEX_DEFORM_SINE_WAVES_PREAMBLE; VERTEX_DEFORM_SINE_WAVES_POS; posHistory[posCount++] = objPos; } #endif #if defined(_VERTEX_DEFORMATION_FBM) { VERTEX_DEFORM_FBM_PREAMBLE; VERTEX_DEFORM_FBM_POS; posHistory[posCount++] = objPos; } #endif float3 objPos_deformed = objPos; int cursor = posCount - 1; objPos = posHistory[cursor]; #if defined(_VERTEX_DEFORMATION_FBM) if (cursor > 0) { VERTEX_DEFORM_FBM_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; fbm_undeform_normal(stageInput, st, amplitude, gain, lacunarity, scale, octaves, velocity, objNorm, objTan); objPos = stageInput; cursor -= 1; } #endif #if defined(_VERTEX_DEFORMATION_SINE_WAVES) if (cursor > 0) { VERTEX_DEFORM_SINE_WAVES_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; sine_wave_undeform_normal(stageInput, objNorm, objTan, amplitude, direction, k, omega, st); objPos = stageInput; cursor -= 1; } #endif #if defined(_VERTEX_DEFORMATION_SEAL) if (cursor > 0) { VERTEX_DEFORM_SEAL_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; seal_undeform_normal(stageInput, objNorm, objTan, A, k, st); objPos = stageInput; cursor -= 1; } #endif #if defined(_VERTEX_DEFORMATION_NORM_CONVERSION) if (cursor > 0) { VERTEX_DEFORM_NORM_CONVERSION_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; norm_conversion_undeform_normal(stageInput, objNorm, objTan, input_k, output_k, t); objPos = stageInput; cursor -= 1; } #endif #if defined(_VERTEX_DEFORMATION_XY_TUBE) if (cursor > 0) { VERTEX_DEFORM_XY_TUBE_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; float3 xyPos = stageInput.xzy; float3 xyNorm = objNorm.xzy; float3 xyTan = objTan.xzy; plane_to_tube_undeform_normal(xyPos, xyNorm, xyTan, t); objNorm = xyNorm.xzy; objTan = xyTan.xzy; objPos = stageInput; cursor -= 1; } #endif #if defined(_VERTEX_DEFORMATION_YZ_TUBE) if (cursor > 0) { VERTEX_DEFORM_YZ_TUBE_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; float3 yzPos = stageInput.yxz; float3 yzNorm = objNorm.yxz; float3 yzTan = objTan.yxz; plane_to_tube_undeform_normal(yzPos, yzNorm, yzTan, t); objNorm = yzNorm.yxz; objTan = yzTan.yxz; objPos = stageInput; cursor -= 1; } #endif #if defined(_VERTEX_DEFORMATION_XZ_TUBE) if (cursor > 0) { VERTEX_DEFORM_XZ_TUBE_PREAMBLE; float3 stageInput = posHistory[cursor - 1]; plane_to_tube_undeform_normal(stageInput, objNorm, objTan, t); objPos = stageInput; cursor -= 1; } #endif objPos = objPos_deformed; } void propagateObjPos(inout v2f i) { i.worldPos = mul(unity_ObjectToWorld, float4(i.objPos, 1)); i.pos = UnityObjectToClipPos(i.objPos); i.eyeVec.xyz = i.worldPos - _WorldSpaceCameraPos; } #endif // __VERTEX_INC