//metal: float3 n, k; // R 700 nm, G 550 nm, B 435 nm float REDUCED_CUBEMAP_SIZE = 4; float3 F0; /* if (iWhichMetal == 1) { // copper n = float3(0.21f, 0.96f, 1.17f); k = float3(4.16f, 2.57f, 2.32f); } else if (iWhichMetal == 2) { // gold n = float3(0.16f, 0.35f, 1.6f); k = float3(3.98f, 2.71f, 1.92f); } else if (iWhichMetal == 3) { // silver n = float3(0.142f, 0.124f, 0.158f); k = float3(4.52f, 3.33f, 2.32f); } else if (iWhichMetal == 4) { // alu n = float3(1.83f, 0.96f, 0.577f); k = float3(8.31f, 6.69f, 5.288f); } */ float4 readCubeMap(samplerCUBE cm, float3 coord) { float4 color = texCUBE( cm, float3(coord.xy, - coord.z) ); color.a = 1; return color; } float readDistanceCubeMap(samplerCUBE dcm, float3 coord) { float dist = texCUBE(dcm, float3(coord.xy, - coord.z)).r; if(dist == 0) dist = 100000; ///sky return dist; } /* float3 Hit( float3 x, float3 R, samplerCUBE mp ) { float rl = readDistanceCubeMap(mp, R); // |r| float dp = rl - dot(x, R); // parallax float3 p = x + R * dp; return p; }*/ #define LIN_ITERATIONCOUNT 5 #define SECANT_ITERATIONCOUNT 0 /* float3 Hit(float3 x, float3 R, samplerCUBE mp) { R = normalize(R); float3 xNorm = normalize(x); float3 dt = (R - xNorm) / (float) LIN_ITERATIONCOUNT; float dx = length(cross(R,x)); float3 pN = normalize(cross(R, xNorm)); float3 N = normalize(cross(pN,R)); float d = dot(x, N); float3 under = xNorm * readDistanceCubeMap(mp, x); float3 over = R * readDistanceCubeMap(mp, R); //linear iteration for(int i = 1; i < LIN_ITERATIONCOUNT; i++) { float3 dir = normalize(xNorm + dt * i); float dist = readDistanceCubeMap( mp, dir); float3 point = dir * dist; if( dot(N, point) > d)//undershooting { under = point; } else //overshooting { over = point; i = LIN_ITERATIONCOUNT; } } float3 dirUn = normalize(under); float3 dirOv = normalize(over); float tun = d / dot(N, dirUn); float pun = tun / length(under); float dun = length(tun * dirUn - x); float tov = d / dot(N, dirOv); float pov = tov / length(over); float dov = length(tov * dirOv - x); float tl = (d - dot(N, over)) / dot(N, under - over); float3 l = over + tl * (under - over); float dl = length(l - x); //secant iteration for( int i = 0; i < SECANT_ITERATIONCOUNT; i++ ) { float llp = length( l ) / readDistanceCubeMap( mp, l); // |l|/|l’| if ( llp < 0.999f ) // undershooting { dun = dl; pun = llp; // last undershooting dl += ( dl - dov ) * ( 1 - llp ) / ( llp - pov ); // eq. 3 } else if ( llp > 1.001f ) // overshooting { dov = dl; pov = llp; // last overshooting dl += ( dl - dun ) * ( 1 - llp ) / ( llp - pun );// eq. 3 } l = x + R * dl; // ray equation } return l; return over; return (under + over)/2.0; } */ float3 Hit(float3 x, float3 R, samplerCUBE mp) { R = normalize(R); float3 xNorm = normalize(x); float3 dt = (R - xNorm) / (float) LIN_ITERATIONCOUNT; float dx = length(cross(R,x)); float3 pN = normalize(cross(R, xNorm)); float3 N = normalize(cross(pN,R)); float d = dot(x, N); float3 under = xNorm * readDistanceCubeMap(mp, x); float3 over = R * readDistanceCubeMap(mp, R); //linear iteration for(int i = 1; i < LIN_ITERATIONCOUNT; i++) { float3 ldir = normalize(xNorm + dt * i); float lL = readDistanceCubeMap( mp, dir); float3 l_ = dir * dist; float alpha = (dot(x, l_) - dot(R, l_) * dot(x, R)) / (lL * lL - dot(R, l_) * dot(R, l_)); float d = dot(l_, R) * alpha - dot(x, R); if( dot(N, point) > d)//undershooting { under = point; } else //overshooting { over = point; i = LIN_ITERATIONCOUNT; } } float3 dirUn = normalize(under); float3 dirOv = normalize(over); float tun = d / dot(N, dirUn); float pun = tun / length(under); float dun = length(tun * dirUn - x); float tov = d / dot(N, dirOv); float pov = tov / length(over); float dov = length(tov * dirOv - x); float tl = (d - dot(N, over)) / dot(N, under - over); float3 l = over + tl * (under - over); float dl = length(l - x); //secant iteration for( int i = 0; i < SECANT_ITERATIONCOUNT; i++ ) { float llp = length( l ) / readDistanceCubeMap( mp, l); // |l|/|l’| if ( llp < 0.999f ) // undershooting { dun = dl; pun = llp; // last undershooting dl += ( dl - dov ) * ( 1 - llp ) / ( llp - pov ); // eq. 3 } else if ( llp > 1.001f ) // overshooting { dov = dl; pov = llp; // last overshooting dl += ( dl - dun ) * ( 1 - llp ) / ( llp - pun );// eq. 3 } l = x + R * dl; // ray equation } return l; return over; return (under + over)/2.0; } /* // This function is called several times. float3 Hit( float3 x, float3 R, samplerCUBE mp ) { float rl = readDistanceCubeMap( mp, R); // |r| float ppp = length( x ) / readDistanceCubeMap( mp, x); // |p|/|p’| float dun = 0, pun = ppp, dov = 0, pov = 0; float dl = rl * ( 1 - ppp ); // eq. 2 float3 l = x + R * dl; // ray equation // iteration for( int i = 0; i < 2; i++ ) // 2 !!!!!!!!!!!!!!!!!!!!!!! { float llp = length( l ) / readDistanceCubeMap( mp, l); // |l|/|l’| if ( llp < 0.999f ) // undershooting { dun = dl; pun = llp; // last undershooting dl += ( dov == 0 ) ? rl * ( 1 - llp ) : // eq. 2 ( dl - dov ) * ( 1 - llp ) / ( llp - pov ); // eq. 3 } else if ( llp > 1.001f ) // overshooting { dov = dl; pov = llp; // last overshooting dl += ( dl -dun ) * ( 1 - llp ) / ( llp - pun );// eq. 3 } l = x + R * dl; // ray equation } return l; // computed hit point } */ void LocalizedVS(float4 position : POSITION, out float3 wPos : TEXCOORD1, float2 texCoord : TEXCOORD0, out float2 otexCoord : TEXCOORD0, float3 normal : NORMAL, out float3 mNormal : TEXCOORD2, out float4 hPos : POSITION, uniform float4x4 worldViewProj, uniform float4x4 world) { hPos = mul(worldViewProj, position); wPos = mul(world, position).xyz; mNormal = normal; otexCoord = texCoord; } ////////////// //Localized reflection ////////////// void LocalizedPS( float2 texCoord : TEXCOORD0, float3 wPos : TEXCOORD1, float3 mNormal : TEXCOORD2, uniform float3 cameraPos, uniform samplerCUBE CubeMap : register(s0), uniform samplerCUBE DistanceMap : register(s1), uniform float3 lastCenter, uniform float3 lightPosition, out float4 Color :COLOR0) { Color = float4(1,1,1,1); mNormal = normalize(mNormal); float3 RR, TT; float3 mPos = wPos - lastCenter; float3 V = normalize(wPos - cameraPos); float3 R = /*normalize*/(reflect( V, mNormal)); float3 T = refract(V, mNormal, 0.9); RR = R; TT = T; //RR += 0.000001 * lastCenter.x; RR = Hit(mPos, R, DistanceMap); TT = Hit(mPos, T, DistanceMap); float4 reflectcolor = readCubeMap(CubeMap, RR ); float4 refractcolor = readCubeMap(CubeMap, TT ); float cos_theta = -dot(V, mNormal); float sFresnel = 0.1; float F = (sFresnel + pow(1-cos_theta, 5.0f) * (1-sFresnel)); float3 L = normalize(lightPosition - wPos); float3 H = normalize(L+V); float4 lighting = lit(dot(mNormal, L),dot(mNormal, H), 30); Color = (F * reflectcolor + (1-F) * refractcolor) + lighting.z; } ////////////// //Metal ////////////// void LocalizedMetalPS( float2 texCoord : TEXCOORD0, float3 wPos : TEXCOORD1, float3 mNormal : TEXCOORD2, uniform float3 cameraPos, uniform samplerCUBE CubeMap : register(s0), uniform samplerCUBE DistanceMap : register(s1), uniform float3 lastCenter, uniform float3 lightPosition, out float4 Color :COLOR0) { Color = float4(1,1,1,1); mNormal = normalize(mNormal); float3 newTexCoord; float3 mPos = wPos - lastCenter; float3 V = normalize(wPos - cameraPos); float3 R = normalize(reflect( V, mNormal)); newTexCoord = R; newTexCoord = Hit(mPos, R, DistanceMap); Color = readCubeMap(CubeMap, newTexCoord ) /*+ lastCenter.x*0.000001*/; float ctheta_in = dot(mNormal,R); float ctheta_out = dot(mNormal,-V); float3 F = 0; // F,P,G számítása if ( ctheta_in > 0 && ctheta_out > 0 ) { float3 H = normalize(R - V); // felezővektor float cbeta = dot(H,R); //F = ( (n-1)*(n-1) + pow(1-cbeta,5) * 4*n + k*k) / ( (n+1)*(n+1) + k*k ); //float3 F0 = ((n-1)*(n-1) + k*k) / ( (n+1)*(n+1) + k*k ); //float3 F1 = float3(1.0f,1.0f,1.0f) - F0; F = F0 + (1-F0)*pow(1-cbeta,5); } Color = Color * float4(F,1); } ////////////// //PhotonMap ////////////// /*void PhotonMapPS( float2 texCoord : TEXCOORD0, float3 wPos : TEXCOORD1, float3 mNormal : TEXCOORD2, uniform float3 cameraPos, uniform samplerCUBE UVMap : register(s0), uniform samplerCUBE DistanceMap : register(s1), uniform float3 lastCenter, out float4 Color :COLOR0) { Color = float4(1,1,1,1); mNormal = normalize(mNormal); float3 newTexCoord; float3 mPos = wPos - lastCenter; float3 V = normalize(wPos - cameraPos); float3 R = normalize(reflect( V, mNormal)); newTexCoord = R; newTexCoord = Hit(mPos, R, DistanceMap); Color = readCubeMap(UVMap, newTexCoord ); //Color = float4(1,0,0,1); }*/ float4 PhotonMapCausticPS( float2 texCoord : TEXCOORD0, float3 wPos : TEXCOORD1, float3 mNormal : TEXCOORD2, uniform float3 cameraPos, uniform samplerCUBE DistanceMap : register(s0), uniform float3 lastCenter):COLOR0 { float4 Color = float4(1,1,1,1); mNormal = normalize(mNormal); float3 newTexCoord; float3 mPos = wPos - lastCenter; float3 V = normalize(wPos - cameraPos); float3 R = refract(V, mNormal, 0.85); //float3 R = V; newTexCoord = R; newTexCoord = Hit(mPos, R, DistanceMap); Color = float4(newTexCoord, 1); //Color = 0.0001 * Color + float4(0,0,1,1); //Color += 0.0001 * lastCenter.x; if(dot(V,mNormal)>0) { Color = float4(1,0,0,0); } return Color; } ///////////////////// ///// Diffuse /////////////////// float4 GetContibution(float3 L, float3 pos, float3 N, float3 V, samplerCUBE SmallEnvMapSampler, samplerCUBE DistanceEnvMapSampler) // Phong-Blinn // L: a hossza lényeges (az egységkocka faláig ér) { REDUCED_CUBEMAP_SIZE = 4; float kd = 0.3; // 0.3 float ks = 0; // 0.5 float shininess = 10; float l = length(L); L = normalize(L); //dw float dw = 4 / (REDUCED_CUBEMAP_SIZE*REDUCED_CUBEMAP_SIZE*l*l*l + 4/3.1416f); //Lin float4 Lin = readCubeMap(SmallEnvMapSampler, L); //r float doy = readDistanceCubeMap(DistanceEnvMapSampler, L); float dxy = length(L * doy - pos); //dws float dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/3.1416f) + doy*doy*dw/3.1416f); // localization: //float dws = dw; //L = L * doy - pos; // L: x->y, az objektumtól induljon, ne a középpontból L = normalize(L); float3 H = normalize(L + V); // felezővektor float a = kd * max(dot(N,L),0) + ks * pow(max(dot(N,H),0), shininess); // diffuse + specular // 1.: eddigi //return Lin * a * dws; float ctheta_in = dot(N,L); float ctheta_out = dot(N,V); return Lin * a * dws; } void DiffuseVS( float4 position : POSITION, float3 normal : NORMAL, float2 Tex : TEXCOORD0, uniform float4x4 worldViewProj, uniform float4x4 world, //uniform float3 lastCenter, //LI// out float4 hposition : POSITION, out float2 oTex : TEXCOORD0, out float3 Normal : TEXCOORD1, out float3 pos : TEXCOORD2 ) { pos = /*lastCenter + 0.01 * */mul( world, position ).xyz; Normal = normal; oTex = Tex; hposition = mul( worldViewProj, position ); } float4 DiffusePS( float2 Tex : TEXCOORD0, float3 N : TEXCOORD1, float3 pos : TEXCOORD2, uniform float3 cameraPos, uniform float3 lastCenter, //LI// uniform samplerCUBE SmallEnvMapSampler : register(s0), uniform samplerCUBE DistanceEnvMapSampler : register(s1) ) : COLOR0 { REDUCED_CUBEMAP_SIZE = 4; //V = /*-*/normalize( V ); float3 V = normalize(pos - cameraPos); // N = normalize( N ); float3 R = reflect(V, N); pos -= lastCenter; //return float4(N,1); //return float4(V,1); //return float4(R,1); //return readCubeMap(SmallEnvMapSampler,R); //pos.xy += float2(1.0/LIGHT_TEXTURE_SIZE, -1.0/LIGHT_TEXTURE_SIZE); // eltolás a pixel/texel középpontba // x, y = -1..1 // z = 1 float4 intens = 0; /* intens += GetContibution( R, pos, N, V, SmallEnvMapSampler); intens = readCubeMap(SmallEnvMapSampler, R); return intens;*/ for (int x = 0; x < REDUCED_CUBEMAP_SIZE; x++) // az envmap minden texelére for (int y = 0; y < REDUCED_CUBEMAP_SIZE; y++) //int x = 0; // az envmap 1 texelére //int y = 0; //if (x==LIGHT_TEXTURE_SIZE/2 && y==LIGHT_TEXTURE_SIZE/2) { // intenzitás kiolvasása az adott texelből float2 p, tpos; tpos.x = x/(float)REDUCED_CUBEMAP_SIZE; // 0..1 tpos.y = y/(float)REDUCED_CUBEMAP_SIZE; // 0..1 tpos.xy += float2(0.5/REDUCED_CUBEMAP_SIZE, 0.5/REDUCED_CUBEMAP_SIZE); // az adott texel középpont uv koordinátái p.x = tpos.x; p.y = 1-tpos.y; p.xy = 2*p.xy - 1; // -1..1 // az adott texel középpont pozíciója float3 L; L = float3(p.x, p.y, 1); intens += GetContibution( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(p.x, p.y, -1); intens += GetContibution( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(p.x, 1, p.y); intens += GetContibution( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(p.x, -1, p.y); intens += GetContibution( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(1, p.x, p.y); intens += GetContibution( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(-1, p.x, p.y); intens += GetContibution( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); } return intens; }