float REDUCED_CUBEMAP_SIZE; 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 = 1000000; ///sky return dist; } // 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 } ///////////////////// ///// Diffuse /////////////////// float4 GetContibution(float3 L, float3 L1, float3 L2, float3 L3, float3 L4, float3 pos, float3 N, samplerCUBE cubemap) { float d; //d = texCUBE(cubemap, L).a; d = readDistanceCubeMap(cubemap, L1).r; L1 = d * normalize(L1); d = readDistanceCubeMap(cubemap, L2).r; L2 = d * normalize(L2); d = readDistanceCubeMap(cubemap, L3).r; L3 = d * normalize(L3); d = readDistanceCubeMap(cubemap, L4).r; L4 = d * normalize(L4); float3 r1 = normalize(L1 - pos); float3 r2 = normalize(L2 - pos); float3 r3 = normalize(L3 - pos); float3 r4 = normalize(L4 - pos); /* float tri1 = acos(dot(r1, r2)) * dot(cross(r1, r2), N); float tri2 = acos(dot(r2, r3)) * dot(cross(r2, r3), N); float tri3 = acos(dot(r3, r4)) * dot(cross(r3, r4), N); float tri4 = acos(dot(r4, r1)) * dot(cross(r4, r1), N); */ float3 crossP = cross(r1, r2); float r = length(crossP); float dd = dot(r1,r2); float tri1 = acos(dd) * dot(crossP/r, N); crossP = cross(r2, r3); r = length(crossP); dd = dot(r1,r2); float tri2 = acos(dd) * dot(crossP/r, N); crossP = cross(r3, r4); r = length(crossP); dd = dot(r1,r2); float tri3 = acos(dd) * dot(crossP/r, N); crossP = cross(r4, r1); r = length(crossP); dd = dot(r1,r2); float tri4= acos(dd) * dot(crossP/r, N); return max(tri1 + tri2 + tri3 + tri4, 0); //return tri1 + tri2 + tri3 + tri4; } struct vertOUT { float4 hPos :POSITION; float3 wPos :TEXCOORD1; float2 texCoord :TEXCOORD0; float3 mNormal :TEXCOORD2; }; vertOUT DiffuseVS(float4 position : POSITION, float3 normal : NORMAL, half3 tangent : TEXCOORD1, float2 texCoord : TEXCOORD0, uniform float4x4 worldViewProj, uniform float4x4 worldI, uniform float4x4 world) { vertOUT OUT; OUT.hPos = mul(worldViewProj, position); OUT.wPos = mul(world, position).xyz; OUT.mNormal = mul(normal, worldI); //OUT.mNormal = normal; OUT.texCoord = texCoord; return OUT; } float4 DiffusePS( vertOUT IN, uniform float3 cameraPos, uniform float3 lastCenter, //LI// uniform samplerCUBE SmallEnvMapSampler : register(s0), uniform samplerCUBE DistanceEnvMapSampler : register(s1) ) : COLOR0 { float M = 4; float3 N = IN.mNormal; N = normalize( N ); float3 pos = IN.wPos - lastCenter; //return float4(N,1)+ lastCenter.x*0.000001; // return float4(N,1)+ lastCenter.x*0.000001; // return readCubeMap(SmallEnvMapSampler, pos) + lastCenter.x*0.000001; float4 I = 0; float3 L1, L2, L3, L4, L; float4 Le; float width = 1.0 / M; float width2 = width * 2; float d; for (float x = 1; x < M; x++) for (float y = 1; y < M; y++) { float2 p, tpos; tpos.x = x * width; tpos.y = y * width; p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(p.x - width, p.y - width, 1); L2 = float3(p.x + width, p.y - width, 1); L3 = float3(p.x + width, p.y + width, 1); L4 = float3(p.x - width, p.y + width, 1); L = float3(p.x, p.y, 1); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 1; x < M; x++) for (float y = 1; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(p.x - width, p.y - width, -1); L3 = float3(p.x + width, p.y - width, -1); L2 = float3(p.x + width, p.y + width, -1); L1 = float3(p.x - width, p.y + width, -1); L = float3(p.x, p.y, -1); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 1; x < M; x++) for (float y = 1; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(p.x - width, 1, p.y - width); L3 = float3(p.x + width, 1, p.y - width); L2 = float3(p.x + width, 1, p.y + width); L1 = float3(p.x - width, 1, p.y + width); L = float3(p.x, 1, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 1; x < M; x++) for (float y = 1; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(p.x - width, -1, p.y - width); L2 = float3(p.x + width, -1, p.y - width); L3 = float3(p.x + width, -1, p.y + width); L4 = float3(p.x - width, -1, p.y + width); L = float3(p.x, -1, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 1; x < M; x++) for (float y = 1; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(1, p.x - width, p.y - width); L2 = float3(1, p.x + width, p.y - width); L3 = float3(1, p.x + width, p.y + width); L4 = float3(1, p.x - width, p.y + width); L = float3(1, p.x, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 1; x < M; x++) for (float y = 1; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(-1, p.x - width, p.y - width); L3 = float3(-1, p.x + width, p.y - width); L2 = float3(-1, p.x + width, p.y + width); L1 = float3(-1, p.x - width, p.y + width); L = float3(-1, p.x, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } float kd = 0.5; return kd * I; } struct vertOUTBump { float4 hPos :POSITION; float3 wPos :TEXCOORD1; float2 texCoord :TEXCOORD0; float3 mNormal :TEXCOORD2; float3 tangent :TEXCOORD3; float3 binormal :TEXCOORD4; }; vertOUTBump DiffuseBumpVS(float4 position : POSITION, float3 normal : NORMAL, half3 tangent : TEXCOORD1, float2 texCoord : TEXCOORD0, uniform float4x4 worldViewProj, uniform float4x4 world) { vertOUTBump OUT; OUT.hPos = mul(worldViewProj, position); OUT.wPos = mul(world, position).xyz; OUT.mNormal = normal; OUT.tangent = tangent; OUT.texCoord = texCoord; OUT.binormal = cross(tangent, normal); return OUT; } float4 DiffuseBumpPS( vertOUTBump IN, uniform float3 cameraPos, uniform float3 lastCenter, //LI// uniform samplerCUBE SmallEnvMapSampler : register(s0), uniform samplerCUBE DistanceEnvMapSampler : register(s1), uniform sampler2D NormalMap : register(s2), uniform float4x4 worldI ) : COLOR0 { float M = 4; float3 N = IN.mNormal; N = normalize( N ); float3x3 TangentToModel = float3x3(IN.tangent, IN.binormal, N); half3 tNormal = tex2D(NormalMap, IN.texCoord).rgb; N = mul(tNormal, TangentToModel ); N = normalize( N ); N = mul(N, worldI); float3 pos = IN.wPos - lastCenter; //return float4(N,1)+ lastCenter.x*0.000001; // return readCubeMap(SmallEnvMapSampler, pos) + lastCenter.x*0.000001; float4 I = 0; float3 L1, L2, L3, L4, L; float4 Le; float width = 1.0 / M; float width2 = width * 2; float d; for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; tpos.y = y * width; p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(p.x - width, p.y - width, 1); L2 = float3(p.x + width, p.y - width, 1); L3 = float3(p.x + width, p.y + width, 1); L4 = float3(p.x - width, p.y + width, 1); L = float3(p.x, p.y, 1); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(p.x - width, p.y - width, -1); L3 = float3(p.x + width, p.y - width, -1); L2 = float3(p.x + width, p.y + width, -1); L1 = float3(p.x - width, p.y + width, -1); L = float3(p.x, p.y, -1); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(p.x - width, 1, p.y - width); L3 = float3(p.x + width, 1, p.y - width); L2 = float3(p.x + width, 1, p.y + width); L1 = float3(p.x - width, 1, p.y + width); L = float3(p.x, 1, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(p.x - width, -1, p.y - width); L2 = float3(p.x + width, -1, p.y - width); L3 = float3(p.x + width, -1, p.y + width); L4 = float3(p.x - width, -1, p.y + width); L = float3(p.x, -1, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(1, p.x - width, p.y - width); L2 = float3(1, p.x + width, p.y - width); L3 = float3(1, p.x + width, p.y + width); L4 = float3(1, p.x - width, p.y + width); L = float3(1, p.x, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; // 0..1 tpos.y = y * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(-1, p.x - width, p.y - width); L3 = float3(-1, p.x + width, p.y - width); L2 = float3(-1, p.x + width, p.y + width); L1 = float3(-1, p.x - width, p.y + width); L = float3(-1, p.x, p.y); Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1); I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler); } float kd = 0.3; return kd * I; } float4 P2PContr(float3 N, float3 Nl, float3 pos, float3 L, samplerCUBE cubemap, samplerCUBE distmap) { Nl = normalize(Nl); L = normalize(L); float4 Le = readCubeMap(cubemap, L); float d = readDistanceCubeMap(distmap, L); float3 Lpos = L * d; float3 Ldir = Lpos - pos; float dist = 4 * dot(Ldir, Ldir); Ldir = normalize(Ldir); return Le * (max(dot(N, Ldir),0) * dot(Nl, -1 * Ldir)) / dist; } float4 EnvMapDiffuseP2PPS( vertOUT IN, uniform float3 lastCenter, //LI// uniform samplerCUBE SmallEnvMapSampler : register(s0), uniform samplerCUBE DistanceEnvMapSampler : register(s1)) : COLOR { float M = 4.0; float3 N = IN.mNormal; N = normalize( N ); float3 pos = IN.wPos - lastCenter; float4 I = 0; float3 L; float4 Le; float width = 1.0 / M; float d; float kd = 0.3; //return kd * readCubeMap(SmallEnvMapSampler, N) + lastCenter.x * 0.00000001; for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; tpos.y = y * width; p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 I += P2PContr(N, float3(0,0,-1), pos, float3(p.x, p.y, 1), SmallEnvMapSampler, DistanceEnvMapSampler); I += P2PContr(N, float3(0,0,1), pos, float3(-p.x, p.y, -1), SmallEnvMapSampler, DistanceEnvMapSampler); I += P2PContr(N, float3(-1,0,0), pos, float3(1, p.y, -p.x), SmallEnvMapSampler, DistanceEnvMapSampler); I += P2PContr(N, float3(1,0,0), pos, float3(-1, p.y, p.x), SmallEnvMapSampler, DistanceEnvMapSampler); I += P2PContr(N, float3(0,-1,0), pos, float3(p.x, 1, -p.y), SmallEnvMapSampler, DistanceEnvMapSampler); I += P2PContr(N, float3(0,1,0), pos, float3(p.x, -1, p.y), SmallEnvMapSampler, DistanceEnvMapSampler); } return kd * I; }