float invLerp(const float from, const float to, const float value) { return (value - from) / (to - from); } float remap(const float origFrom, const float origTo, const float targetFrom, const float targetTo, const float value) { const float rel = invLerp(origFrom, origTo, value); return lerp(targetFrom, targetTo, rel); } float3 rotate(float3 p, float4 quaternion) { const float x = -quaternion.x; const float y = -quaternion.y; const float z = -quaternion.z; const float w = quaternion.w; const float3x3 rotation_matrix = float3x3( 1 - 2 * (y * y + z * z), 2 * (x * y - w * z), 2 * (x * z + w * y), 2 * (x * y + w * z), 1 - 2 * (x * x + z * z), 2 * (y * z - w * x), 2 * (x * z - w * y), 2 * (y * z + w * x), 1 - 2 * (x * x + y * y) ); return mul(rotation_matrix, p); } void ComputeSDFDecal_float(float SSR, float SD, float SDR, float2 softness, float2 dilate, float weight, float4 faceColor, out float4 rgba) { float scale = 1 / SSR * SDR; scale /= 1 + (softness.x * scale); const float w = .5 - (weight + dilate.x) * .5; rgba = faceColor * saturate((SD - w) * scale + 0.5); float4 outlineColor = float4(0,1,1,1); float outlineWidth = dilate.y; // outlineColor = lerp(faceColor, outlineColor, sqrt(min(1.0, outlineWidth * scale * 2))); // rgba = lerp(outlineColor, faceColor, saturate((SD - w - outlineWidth) * scale + 0.5)); // rgba *= saturate((SD - w + outlineWidth) * scale + 0.5); } void CalculateDecal_float(float3 position, float4 meshData, float4 uvData, float4 quaternion, out float3 decalUV, out float3 decalClip) { float3 local_pos = position - meshData.xyz; local_pos = rotate(local_pos, quaternion); const float width = meshData.w; const float height = meshData.w * uvData.w; local_pos.x += width / 2; local_pos.y += height / 2; decalClip = float3( step(0, local_pos.x) * (1 - step(width, local_pos.x)), step(0, local_pos.y) * (1 - step(height, local_pos.y)), 1); // remap from (0..vertex_size) to (uv.start..uv.end) const float2 uvSize = float2(uvData.z, uvData.z * uvData.w); decalUV = float3( remap(0, width, uvData.x, uvData.x + uvSize.x, local_pos.x), remap(0, height, uvData.y, uvData.y + uvSize.y, local_pos.y), local_pos.z); } void ComputeSDFDecal_float(float4 faceColor, float SD, float scale, float3 decal_clip, out float4 rgba) { rgba = faceColor * saturate((SD - 0.5) * scale + 0.5); rgba *= decal_clip.x * decal_clip.y * decal_clip.z; } void DecalClip_float(inout float4 color, float3 decal_clip) { color *= decal_clip.x * decal_clip.y * decal_clip.z; } void DecalClip_float(in float4 color, float3 decal_clip, out float4 result) { DecalClip_float(color, decal_clip); result = color; } void CalculateSSR_float(float2 uv, float textureHeight, bool filter, out float SSR) { SSR = abs(ddx(uv.x)) + abs(ddy(uv.y)); SSR *= textureHeight * 0.75; }