gimymblert
|
|
« on: August 23, 2018, 02:54:31 PM » |
|
old: Can you solve x analytically in "ax+b = sin x" The internet doesn't know! I get that x can have infinite solution in some circumstance (many every 2π), but I just want the closest one to the intersection of ax+b with the x axis i
|
|
« Last Edit: September 10, 2018, 02:18:00 PM by gimymblert »
|
Logged
|
|
|
|
ProgramGamer
|
|
« Reply #1 on: August 24, 2018, 04:49:18 AM » |
|
So, you have "y1 = ax + b" and "y2 = sin(x)" and you want to know for which values of x "y1 = y2" is true, right? I don't have an immediate answer, but I do have some observations. 1. You could check each chunk of the domain of sin(x) where sin(x) is never the same value (for example 0 radians to 0.25*pi*2 radians, then 0.25*pi*2 radians to 0.75*pi*2 radians, and so on) for the intersecting value, if it intersects at all. 2. You need to check for cases where intersections never happen (for example where "a = 0" and "b > 1" or "b < -1") 3. For cases with infinite periodic answers (where "a = 0" and "-1 <= b <= 1") you would have to decide which values to use yourself, though it's hard to say how you'd decide that without knowing your use case
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #2 on: August 24, 2018, 05:48:06 AM » |
|
The use case is simple: - You shoot a vector from y = 0 (surface of texture shader) - find the closest point of intersection to the y=0 point of shooting.
- sin is actually sin(2πx)/2 +.5 (is contain inside 0-1 range, has a periode of 1), so you know where are the exit point of the affine function of the view vector, it's neatly boxed.
|
|
|
Logged
|
|
|
|
ProgramGamer
|
|
« Reply #3 on: August 24, 2018, 06:30:05 AM » |
|
Can you tell me what the intended graphical effect is supposed to be? At a glance it sounds like you're trying to dynamically generate some sort of texture, but I'm not quite sure.
|
|
|
Logged
|
|
|
|
|
ProgramGamer
|
|
« Reply #5 on: August 24, 2018, 08:33:02 AM » |
|
Oh, so you want to recreate that effect dynamically with a sine wave across your texture. Why not approximate the offset with a linear triangle slope, find the height difference between the point on the linear slope and the sine function, and add that length to the vector to figure out an approximate offset?
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #6 on: August 24, 2018, 09:19:51 AM » |
|
I kinda wanted to know how to solve trig equation, since internet is mum about it (which might be useful you never know).
Also this sould not work, because the height isn't the issue really, it's sampling the right UV (ie horizontal data not vertical).
But I'll test it
and I also worked on a quadratic approximation of sin curve using triangular curve anyway (see the progen thread: (2x)²+1 and 1-(2(x+1))², which is more easily solvable on shader at low cost, which mean adding cheap volume details on open gl 2.0 wii/ps2 level hardware. I hope.
|
|
|
Logged
|
|
|
|
|
gimymblert
|
|
« Reply #8 on: August 25, 2018, 05:36:06 AM » |
|
But then it just become a typical raymarching algorithm with a nasty for loop inside the shader and blew up the compute budget I was trying to save. Given I'm mostly operating on 1-0 range anyway (uv) I had hope for an optimization.
|
|
|
Logged
|
|
|
|
diegzumillo
|
|
« Reply #9 on: August 25, 2018, 07:37:45 AM » |
|
That equation is a lot nastier than it seems. For a shallow enough a have a lot of intersections. If you are only interested in the first intersection however then you might get away with approximating the sine with a 3rd degree polynomial. The roots are ugly but the solution is analytical. In fact, once you have these roots you can get a good approximation of the rest other intersections (it should be good for the first few n pi).
Take the first 2 terms of the sin series and now we can try solving b + x (x^2 /6 + a -1) = 0 I only needed to deal with polynomials higher than 2 analytically once. I did not enjoy the process but wikipedia has all the equations to solve this. You calculate some discriminant quantity which tells you how many roots it has and if they are real or imaginary, then you use that to find the roots.
However, if you have an idea of the size of a and b you might get away with approximated roots. Calculate the roots for b=0, which is simpler, then add b to the results to get a little closer.
Another route would be to calculate numerically to the highest precision you can get and build a lookup table for a and b. This is good because you know you have a min and max value for a.
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #10 on: August 25, 2018, 07:55:32 AM » |
|
You don't need 3rd degree for a good enough approximation since it's visual, I already provided a 2nd degree one that is broken on two approximation, which mean we can solve for the half period as we know for sure the height will be below or not the median. ANd there might be further optimization because the half period is mirrored AND don't change direction inside a quarter period. We can discretize the periodic range in sector and reason on that. I think, that's the direction I'm exploring. Right now™ I just wrote the routine for saw curve in UV space: fixed4 uvt = fixed4 (i.uv,0,0)*4;//4 can be replaced by as many division of the 0-1 range you want fixed4 f = floor (uvt)%2;//flip between 0 and 1 fixed4 tri = abs (f- frac(uvt));//saw pattern, uv ping pong I'm trying to solve that first to see if it helps going toward the quadratic sin approximation.
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #11 on: August 25, 2018, 06:09:10 PM » |
|
I used that as a starting point for the triangle curve: http://www-cs.ccny.cuny.edu/~wolberg/capstone/intersection/Intersection%20point%20of%20two%20lines.htmlGiven that one segment (the saw curve segment rising part) is basically: - height: h1(0,0) h2(1,1) - view vector: p1(x3,0) p2(x4,y4) I reduce it at: - a = (x3y4 - y3x4) / (x3-y3+y4-x4) - b = x3 - y3 / (x3-y3 + y4-x4) - x = y = a //make sense it's a 45° diagonal I have to be careful to sync the position of the view vector with the rescale noise frequency
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #12 on: August 27, 2018, 08:51:48 PM » |
|
- I have implemented the simple parallax version, the basics are laid down - will attempt the analytic occlusion soon for saw curve soon, - then I'll try to solve the fake sin and some other periodic function.
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #13 on: August 28, 2018, 10:28:17 AM » |
|
View vector P1 = (x1,y1) = (x1,0) P2 = (x2,y2) = (x2,y2)
Ascending slope h1 = (x3,y3) = (0,1) h2 = (x4,y4) = (1,0)
Descending slope h'1 = (x'3,y'3) = (0,0) h'2 = (x'4,y'4) = (1,1)
Intersection I = (x,y)
ascending: a = (x1 - 1) / (x1-x2-y2) descending: a' = -x1 / (x2-x1-y2)
x = - ((x1(y2-1)+x2) / (x1-x2-y2) ) y = (x1y2 -y2)/(x1-x2-y2)
x' = x1y2 / (x1-x2+y2) y' = x1y2 / (x1-x2+y2)
|
|
|
Logged
|
|
|
|
Crimsontide
|
|
« Reply #14 on: August 29, 2018, 06:53:41 AM » |
|
I'd love to see a video/screenshot of the results
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #15 on: August 29, 2018, 08:43:12 AM » |
|
I haven't finish yet, has some promising glitch that looks it's getting there
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #16 on: September 03, 2018, 11:06:48 AM » |
|
I need help to debug, I don't know where I got wrong Shader "Unlit/testShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _ParallaxStrength ("Parallax Strength", Range(0, 1)) = 0
} SubShader { Tags { "RenderType"="Opaque" } LOD 100
Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc"
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 tangentViewDir : TEXCOORD1; float4 tangent : TANGENT; float3 normal : NORMAL; };
struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float3 tangentViewDir : TEXCOORD1; float4 tangent : TANGENT;//texcoord? float3 normal : NORMAL; float3 binormal : TEXCOORD2; };
sampler2D _MainTex; float4 _MainTex_ST; float _ParallaxStrength; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); o.normal = UnityObjectToWorldNormal(v.normal); o.binormal = cross(o.normal, o.tangent.xyz) * (v.tangent.w * unity_WorldTransformParams.w); float3x3 objectToTangent = float3x3( v.tangent.xyz, cross(v.normal, v.tangent.xyz) * v.tangent.w, v.normal); o.tangentViewDir = mul(objectToTangent, ObjSpaceViewDir(v.vertex)); o.uv = TRANSFORM_TEX(v.uv, _MainTex); //o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { i.tangentViewDir = normalize(i.tangentViewDir); i.tangentViewDir.xy /= (i.tangentViewDir.z + 0.42); fixed division = 4; fixed4 uvt = fixed4 (i.uv,0,0)*division; fixed4 flip = floor (uvt)%2;//flip between 0 and 1 fixed4 triUV = abs (flip - frac(uvt));//saw pattern, uv ping pong float2 height = triUV;// height -= 0.5; float2 p1 = triUV;// i.uv; float3 p2 = float3( triUV //i.uv.xy + i.tangentViewDir.xy, i.tangentViewDir.z); //i.uv.xy += i.tangentViewDir.xy; //*_ParallaxStrength * height;//adding the view vector to sample next uv //ascending float3 ascending; ascending.x = -(p1.x * (p2.z-1) + p2.x) / (p1.x - p2.x-p2.z); //depth.y = -(p1.y * (p2.z-1) + p2.y) / (p1.y - p2.y-p2.z) //ascending.z = (p1.x * p2.z - p2.z) / (p1.x - p2.x - p2.z); float acone = (1 - p2.x )/ p1.x > p2.y ? 1 : 0;//flip if 1 //descending float3 descending; descending.xz = p1.x * p2.z / (p1.x - p2.x) + p2.x; float dcone = (p2.x / p1.x) > p2.y ? 1 : 0; float coneflip = lerp(acone,dcone,flip);
float3 depth; depth = lerp(ascending, descending, coneflip); i.uv.x = saturate( depth.x);///depth.z ); fixed4 col = tex2D(_MainTex,i.uv); return col; } ENDCG } } }
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #17 on: September 03, 2018, 08:56:43 PM » |
|
I think it doesn't work because I should have use a line plane intersection, instead of a 2d simulation
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #18 on: September 07, 2018, 07:08:06 PM » |
|
I tried this code from this https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-plane-and-ray-disk-intersectionBut still don't get result as expected, not sure where I miss something ... anyone can help? Shader "Unlit/testShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _ParallaxStrength ("Parallax Strength", Range(0, 1)) = 0
} SubShader { Tags { "RenderType"="Opaque" } LOD 100
Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc"
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 tangentViewDir : TEXCOORD1; float4 tangent : TANGENT; float3 normal : NORMAL; };
struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float3 tangentViewDir : TEXCOORD1; float4 tangent : TANGENT;//texcoord? float3 normal : NORMAL; float3 binormal : TEXCOORD2; };
sampler2D _MainTex; float4 _MainTex_ST; float _ParallaxStrength; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); o.normal = UnityObjectToWorldNormal(v.normal); o.binormal = cross(o.normal, o.tangent.xyz) * (v.tangent.w * unity_WorldTransformParams.w); float3x3 objectToTangent = float3x3( v.tangent.xyz, cross(v.normal, v.tangent.xyz) * v.tangent.w, v.normal); o.tangentViewDir = mul(objectToTangent, ObjSpaceViewDir(v.vertex)); o.uv = TRANSFORM_TEX(v.uv, _MainTex); //o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { i.tangentViewDir = normalize(i.tangentViewDir); i.tangentViewDir.xy /= (i.tangentViewDir.z + 0.42); float cosin = 0.70710678118; float3 anormal = float3(-cosin,0,cosin); float3 adenom = dot(anormal, i.tangentViewDir); float3 diffa = float3(-i.uv.x,0,1); float ta = dot(diffa, anormal)/adenom; float3 dnormal = float3( cosin,0,cosin); float3 ddenom = dot(dnormal, i.tangentViewDir); float3 diffd = float3( i.uv.x,0,0); float td = dot(diffd, dnormal)/ddenom; float asample = i.tangentViewDir * ta; float dsample = i.tangentViewDir * td; fixed4 col = tex2D(_MainTex,i.uv+dsample); //fixed4 col = asample; //fixed4 col = dsample; //fixed4 col = fixed4( asample, dsample, 0,1);
return col; } ENDCG } } }
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #19 on: September 10, 2018, 02:19:38 PM » |
|
here are the result of the two shaders 1st on left 1st on right I wonder what got wrong ...
|
|
|
Logged
|
|
|
|
|