Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/shaders/gpu_shader_material.glsl
| Context not available. | |||||
| outdot = dot(normalize(dir), nor); | outdot = dot(normalize(dir), nor); | ||||
| } | } | ||||
| void mat_math_rot(float rot, out mat3 mat) | |||||
| { | |||||
| mat = mat3(cos(rot), -sin(rot), 0.0, | |||||
| sin(rot), cos(rot), 0.0, | |||||
| 0.0, 0.0, 1.0); | |||||
| } | |||||
| void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) | void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) | ||||
| { | { | ||||
| outvec.x = texture2D(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; | outvec.x = texture2D(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; | ||||
| Context not available. | |||||
| outval = val; | outval = val; | ||||
| } | } | ||||
| float half_lambert(in vec3 vect1, in vec3 vect2) | |||||
| { | |||||
| float product = dot(vect1, vect2); | |||||
| return product * 0.5 + 0.5; | |||||
| } | |||||
| vec3 sub_scatter_fs(float brightness, float visifac, vec3 lightcol, float scale, vec3 radius, vec3 col, float i, vec3 view, vec3 lv, vec3 normal) | |||||
| { | |||||
| vec3 extinctioncoefficient = radius * 0.1; | |||||
| float attenuation = visifac * brightness; | |||||
| vec3 evec = normalize(-view); | |||||
| vec3 dotLN = vec3(half_lambert(lv, -normal) * attenuation); | |||||
| dotLN *= col; | |||||
| vec3 indirectlightcomponent = vec3(scale * max(0.0, dot(-normal, lv))); | |||||
| indirectlightcomponent += scale * vec3(half_lambert(-evec, lv)); | |||||
| indirectlightcomponent *= attenuation; | |||||
| indirectlightcomponent *= extinctioncoefficient; | |||||
| vec3 finalcol = dotLN + vec3(indirectlightcomponent); | |||||
| finalcol.rgb *= lightcol.rgb; | |||||
| return finalcol; | |||||
| } | |||||
| void set_sss(float brightness, float visifac, vec3 lightcol, float scale, vec3 radius, vec3 col, float i, vec3 view, vec3 lv, vec3 normal, out vec4 outcol) | |||||
| { | |||||
| outcol = vec4(sub_scatter_fs(brightness, visifac, lightcol, scale, radius, col, i, view, lv, normal), 1.0); | |||||
| } | |||||
| void set_rgb(vec3 col, out vec3 outcol) | void set_rgb(vec3 col, out vec3 outcol) | ||||
| { | { | ||||
| outcol = col; | outcol = col; | ||||
| Context not available. | |||||
| outtexco = size * texco; | outtexco = size * texco; | ||||
| } | } | ||||
| void mtex_mapping_transform(vec3 texco, mat3 mat, vec3 ofs, vec3 size, out vec3 outtexco) | |||||
| { | |||||
| outtexco = (texco - vec3(0.5)) * mat * size + vec3(0.5) + ofs; | |||||
| } | |||||
| void mtex_2d_mapping(vec3 vec, out vec3 outvec) | void mtex_2d_mapping(vec3 vec, out vec3 outvec) | ||||
| { | { | ||||
| outvec = vec3(vec.xy * 0.5 + vec2(0.5), vec.z); | outvec = vec3(vec.xy * 0.5 + vec2(0.5), vec.z); | ||||
| Context not available. | |||||
| return vec3(vec.xy * 0.5 + vec2(0.5), vec.z); | return vec3(vec.xy * 0.5 + vec2(0.5), vec.z); | ||||
| } | } | ||||
| void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color) | void mtex_cube_map(vec3 co, samplerCube ima, float lodbias, out float value, out vec4 color) | ||||
| { | { | ||||
| color = textureCube(ima, co); | color = textureCube(ima, co, lodbias); | ||||
| value = 1.0; | value = 1.0; | ||||
| } | } | ||||
| Context not available. | |||||
| value = 1.0; | value = 1.0; | ||||
| } | } | ||||
| vec4 mtex_cube_map_refl_color(samplerCube ima, mat4 viewmatrixinverse, float lodbias, vec3 vn, vec3 viewdirection) | |||||
| { | |||||
| vec3 normaldirection = normalize(viewmatrixinverse * vec4(vn, 0.0)).xyz; | |||||
| vec3 reflecteddirection = reflect(viewdirection, normaldirection); | |||||
| vec4 col = textureCube(ima, reflecteddirection, lodbias); | |||||
| return col; | |||||
| } | |||||
| vec4 mtex_cube_map_refr_color(samplerCube ima, mat4 viewmatrixinverse, float ior, float lodbias, vec3 vn, vec3 viewdirection) | |||||
| { | |||||
| vec3 normaldirection = normalize(viewmatrixinverse * vec4(vec3(vn.x, vn.y, -vn.z), 0.0)).xyz; | |||||
| vec3 refracteddirection = refract(viewdirection, normaldirection, 1.0 / ior); | |||||
| vec4 col = textureCube(ima, refracteddirection, lodbias); | |||||
| return col; | |||||
| } | |||||
| void mtex_cube_map_refl( | void mtex_cube_map_refl( | ||||
| samplerCube ima, vec3 vp, vec3 vn, mat4 viewmatrixinverse, mat4 viewmatrix, | samplerCube ima, vec3 vp, vec3 vn, float lodbias, mat4 viewmatrixinverse, | ||||
| out float value, out vec4 color) | out float value, out vec4 color) | ||||
| { | { | ||||
| vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0)); | vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0)); | ||||
| vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix)); | color = mtex_cube_map_refl_color(ima, viewmatrixinverse, lodbias, vn, viewdirection); | ||||
| vec3 reflecteddirection = reflect(viewdirection, normaldirection); | value = 1.0; | ||||
| color = textureCube(ima, reflecteddirection); | } | ||||
| void mtex_cube_map_refl_refr( | |||||
| samplerCube ima, vec3 vp, vec3 vn, float lodbias, mat4 viewmatrixinverse, | |||||
| float ior, float ratio, out float value, out vec4 color) | |||||
| { | |||||
| vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0)); | |||||
| if (ratio <= 0.0) { | |||||
| color = mtex_cube_map_refl_color(ima, viewmatrixinverse, lodbias, vn, viewdirection); | |||||
| } | |||||
| else if (ratio >= 1.0) { | |||||
| color = mtex_cube_map_refr_color(ima, viewmatrixinverse, ior, lodbias, vn, viewdirection); | |||||
| } | |||||
| else { | |||||
| vec4 refl = mtex_cube_map_refl_color(ima, viewmatrixinverse, lodbias, vn, viewdirection); | |||||
| vec4 refr = mtex_cube_map_refr_color(ima, viewmatrixinverse, ior, lodbias, vn, viewdirection); | |||||
| color = mix(refl, refr, ratio); | |||||
| } | |||||
| value = 1.0; | value = 1.0; | ||||
| } | } | ||||
| void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color) | void mtex_image(vec3 texco, sampler2D ima, float lodbias, out float value, out vec4 color) | ||||
| { | { | ||||
| color = texture2D(ima, texco.xy); | color = texture2D(ima, texco.xy, lodbias); | ||||
| value = 1.0; | value = 1.0; | ||||
| } | } | ||||
| void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal) | void mtex_normal(vec3 texco, sampler2D ima, float lodbias, out vec3 normal) | ||||
| { | { | ||||
| // The invert of the red channel is to make | // The invert of the red channel is to make | ||||
| // the normal map compliant with the outside world. | // the normal map compliant with the outside world. | ||||
| // It needs to be done because in Blender | // It needs to be done because in Blender | ||||
| // the normal used points inward. | // the normal used points inward. | ||||
| // Should this ever change this negate must be removed. | // Should this ever change this negate must be removed. | ||||
| vec4 color = texture2D(ima, texco.xy); | vec4 color = texture2D(ima, texco.xy, lodbias); | ||||
| normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5)); | normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5)); | ||||
| } | } | ||||
| Context not available. | |||||
| void mtex_bump_tap3( | void mtex_bump_tap3( | ||||
| vec3 texco, sampler2D ima, float hScale, | vec3 texco, sampler2D ima, float hScale, | ||||
| out float dBs, out float dBt) | float lodbias, out float dBs, out float dBt) | ||||
| { | { | ||||
| vec2 STll = texco.xy; | vec2 STll = texco.xy; | ||||
| vec2 STlr = texco.xy + dFdx(texco.xy); | vec2 STlr = texco.xy + dFdx(texco.xy); | ||||
| vec2 STul = texco.xy + dFdy(texco.xy); | vec2 STul = texco.xy + dFdy(texco.xy); | ||||
| float Hll, Hlr, Hul; | float Hll, Hlr, Hul; | ||||
| rgbtobw(texture2D(ima, STll), Hll); | rgbtobw(texture2D(ima, STll, lodbias), Hll); | ||||
| rgbtobw(texture2D(ima, STlr), Hlr); | rgbtobw(texture2D(ima, STlr, lodbias), Hlr); | ||||
| rgbtobw(texture2D(ima, STul), Hul); | rgbtobw(texture2D(ima, STul, lodbias), Hul); | ||||
| dBs = hScale * (Hlr - Hll); | dBs = hScale * (Hlr - Hll); | ||||
| dBt = hScale * (Hul - Hll); | dBt = hScale * (Hul - Hll); | ||||
| Context not available. | |||||
| void mtex_bump_bicubic( | void mtex_bump_bicubic( | ||||
| vec3 texco, sampler2D ima, float hScale, | vec3 texco, sampler2D ima, float hScale, | ||||
| out float dBs, out float dBt ) | float lodbias, out float dBs, out float dBt ) | ||||
| { | { | ||||
| float Hl; | float Hl; | ||||
| float Hr; | float Hr; | ||||
| Context not available. | |||||
| vec2 STd = texco.xy - 0.5 * TexDy; | vec2 STd = texco.xy - 0.5 * TexDy; | ||||
| vec2 STu = texco.xy + 0.5 * TexDy; | vec2 STu = texco.xy + 0.5 * TexDy; | ||||
| rgbtobw(texture2D(ima, STl), Hl); | rgbtobw(texture2D(ima, STl, lodbias), Hl); | ||||
| rgbtobw(texture2D(ima, STr), Hr); | rgbtobw(texture2D(ima, STr, lodbias), Hr); | ||||
| rgbtobw(texture2D(ima, STd), Hd); | rgbtobw(texture2D(ima, STd, lodbias), Hd); | ||||
| rgbtobw(texture2D(ima, STu), Hu); | rgbtobw(texture2D(ima, STu, lodbias), Hu); | ||||
| vec2 dHdxy = vec2(Hr - Hl, Hu - Hd); | vec2 dHdxy = vec2(Hr - Hl, Hu - Hd); | ||||
| float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0); | float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0); | ||||
| Context not available. | |||||
| void mtex_bump_tap5( | void mtex_bump_tap5( | ||||
| vec3 texco, sampler2D ima, float hScale, | vec3 texco, sampler2D ima, float hScale, | ||||
| out float dBs, out float dBt) | float lodbias, out float dBs, out float dBt) | ||||
| { | { | ||||
| vec2 TexDx = dFdx(texco.xy); | vec2 TexDx = dFdx(texco.xy); | ||||
| vec2 TexDy = dFdy(texco.xy); | vec2 TexDy = dFdy(texco.xy); | ||||
| Context not available. | |||||
| vec2 STu = texco.xy + 0.5 * TexDy; | vec2 STu = texco.xy + 0.5 * TexDy; | ||||
| float Hc, Hl, Hr, Hd, Hu; | float Hc, Hl, Hr, Hd, Hu; | ||||
| rgbtobw(texture2D(ima, STc), Hc); | rgbtobw(texture2D(ima, STc, lodbias), Hc); | ||||
| rgbtobw(texture2D(ima, STl), Hl); | rgbtobw(texture2D(ima, STl, lodbias), Hl); | ||||
| rgbtobw(texture2D(ima, STr), Hr); | rgbtobw(texture2D(ima, STr, lodbias), Hr); | ||||
| rgbtobw(texture2D(ima, STd), Hd); | rgbtobw(texture2D(ima, STd, lodbias), Hd); | ||||
| rgbtobw(texture2D(ima, STu), Hu); | rgbtobw(texture2D(ima, STu, lodbias), Hu); | ||||
| dBs = hScale * (Hr - Hl); | dBs = hScale * (Hr - Hl); | ||||
| dBt = hScale * (Hu - Hd); | dBt = hScale * (Hu - Hd); | ||||
| Context not available. | |||||
| void mtex_bump_deriv( | void mtex_bump_deriv( | ||||
| vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, | vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, | ||||
| out float dBs, out float dBt) | float lodbias, out float dBs, out float dBt) | ||||
| { | { | ||||
| float s = 1.0; // negate this if flipped texture coordinate | float s = 1.0; // negate this if flipped texture coordinate | ||||
| vec2 TexDx = dFdx(texco.xy); | vec2 TexDx = dFdx(texco.xy); | ||||
| Context not available. | |||||
| // this variant using a derivative map is described here | // this variant using a derivative map is described here | ||||
| // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html | // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html | ||||
| vec2 dim = vec2(ima_x, ima_y); | vec2 dim = vec2(ima_x, ima_y); | ||||
| vec2 dBduv = hScale * dim * (2.0 * texture2D(ima, texco.xy).xy - 1.0); | vec2 dBduv = hScale * dim * (2.0 * texture2D(ima, texco.xy, lodbias).xy - 1.0); | ||||
| dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y; | dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y; | ||||
| dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y; | dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y; | ||||
| Context not available. | |||||
| outvisifac = (visifac < 0.001) ? 0.0 : visifac; | outvisifac = (visifac < 0.001) ? 0.0 : visifac; | ||||
| } | } | ||||
| void shade_alpha_depth(vec3 vp, sampler2D ima, float alpha, float factor, out float outalpha) | |||||
| { | |||||
| float depth = texture2D(ima, gl_FragCoord.xy / vec2(textureSize(ima, 0))).x; | |||||
| vec4 depthvp = gl_ProjectionMatrix * vec4(vp.xy, vp.z - factor, 1.0); | |||||
| float startfade = gl_FragCoord.z; | |||||
| float endfade = (1.0 + depthvp.z / depthvp.w) * 0.5; | |||||
| outalpha = alpha * smoothstep(startfade, endfade, depth); | |||||
| } | |||||
| void world_paper_view(vec3 vec, out vec3 outvec) | void world_paper_view(vec3 vec, out vec3 outvec) | ||||
| { | { | ||||
| vec3 nvec = normalize(vec); | vec3 nvec = normalize(vec); | ||||
| Context not available. | |||||
| t = visifac * spec * pow(t, hard); | t = visifac * spec * pow(t, hard); | ||||
| } | } | ||||
| float InScatter(vec3 start, vec3 dir, vec3 lightPos, float d) | |||||
| { | |||||
| // calculate quadratic coefficients a,b,c | |||||
| vec3 q = start - lightPos; | |||||
| float b = dot(dir, q); | |||||
| float c = dot(q, q); | |||||
| // evaluate integral | |||||
| float s = 1.0 / sqrt(c - b*b); | |||||
| float l = s * (atan( (d + b) * s) - atan( b*s )); | |||||
| return l; | |||||
| } | |||||
| vec3 linePlaneIntersect(in vec3 lp, in vec3 lv, in vec3 pc, in vec3 pn) | |||||
| { | |||||
| return lp+lv*(dot(pn,pc-lp)/dot(pn,lv)); | |||||
| } | |||||
| void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac) | void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac) | ||||
| { | { | ||||
| vec3 h = normalize(l + v); | vec3 h = normalize(l + v); | ||||
| Context not available. | |||||
| //float bias = (1.5 - inp*inp)*shadowbias; | //float bias = (1.5 - inp*inp)*shadowbias; | ||||
| co.z -= shadowbias * co.w; | co.z -= shadowbias * co.w; | ||||
| if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) | if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) { | ||||
| result = shadow2DProj(shadowmap, co).x; | result = shadow2DProj(shadowmap, co).x; | ||||
| else | } | ||||
| else { | |||||
| result = 1.0; | result = 1.0; | ||||
| } | |||||
| } | |||||
| } | |||||
| void test_shadowbuf_pcf_early_bail( | |||||
| vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float samples, float samplesize, float shadowbias, float inp, | |||||
| out float result) | |||||
| { | |||||
| if (inp <= 0.0) { | |||||
| result = 0.0; | |||||
| } | |||||
| else { | |||||
| vec4 co = shadowpersmat * vec4(rco, 1.0); | |||||
| //float bias = (1.5 - inp*inp)*shadowbias; | |||||
| co.z -= shadowbias * co.w; | |||||
| if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) { | |||||
| float step = samplesize / samples; | |||||
| float fullstep = samplesize - step * 0.95; | |||||
| float halfsample = samplesize / 2.0 - step * 0.5 * 0.95; | |||||
| result = 0.0; | |||||
| for (float y = -halfsample; y <= halfsample; y += fullstep) { | |||||
| for (float x = -halfsample; x <= halfsample; x += fullstep) { | |||||
| result += shadow2DProj(shadowmap, vec4(co.xy + vec2(x, y) * 0.1, co.z, co.w)).x; | |||||
| } | |||||
| } | |||||
| if (result > 0.0 && result < 4.0) { | |||||
| float sampleoffset = halfsample - step; | |||||
| for (float y = -sampleoffset; y <= sampleoffset; y += step) { | |||||
| for (float x = -halfsample; x <= halfsample; x += step) { | |||||
| result += shadow2DProj(shadowmap, vec4(co.xy + vec2(x, y) * 0.1, co.z, co.w)).x; | |||||
| } | |||||
| } | |||||
| for (float y = -halfsample; y <= halfsample; y += fullstep) { | |||||
| for (float x = -sampleoffset; x <= sampleoffset; x += step) { | |||||
| result += shadow2DProj(shadowmap, vec4(co.xy + vec2(x, y) * 0.1, co.z, co.w)).x; | |||||
| } | |||||
| } | |||||
| result /= (samples * samples); | |||||
| } | |||||
| else { | |||||
| result /= 4.0; | |||||
| } | |||||
| } | |||||
| else { | |||||
| result = 1.0; | |||||
| } | |||||
| } | |||||
| } | |||||
| void test_shadowbuf_pcf( | |||||
| vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float samples, float samplesize, float shadowbias, float inp, | |||||
| out float result) | |||||
| { | |||||
| if (inp <= 0.0) { | |||||
| result = 0.0; | |||||
| } | |||||
| else { | |||||
| vec4 co = shadowpersmat * vec4(rco, 1.0); | |||||
| //float bias = (1.5 - inp*inp)*shadowbias; | |||||
| co.z -= shadowbias * co.w; | |||||
| if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) { | |||||
| float step = samplesize / samples; | |||||
| float halfsample = samplesize / 2.0 - step * 0.5 * 0.95; | |||||
| result = 0.0; | |||||
| for (float y = -halfsample; y <= halfsample; y += step) { | |||||
| for (float x = -halfsample; x <= halfsample; x += step) { | |||||
| result += shadow2DProj(shadowmap, vec4(co.xy + vec2(x, y) * 0.1, co.z, co.w)).x; | |||||
| } | |||||
| } | |||||
| result /= (samples * samples); | |||||
| } | |||||
| else { | |||||
| result = 1.0; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| void shadows_only( | void shadows_only(float inp, float shadfac, vec3 shadowcolor, out vec3 result) | ||||
| vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, | |||||
| float shadowbias, vec3 shadowcolor, float inp, | |||||
| out vec3 result) | |||||
| { | { | ||||
| result = vec3(1.0); | result = vec3(1.0); | ||||
| if (inp > 0.0) { | if (inp > 0.0) { | ||||
| float shadfac; | |||||
| test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac); | |||||
| result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); | result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); | ||||
| } | } | ||||
| } | } | ||||
| void shadows_only_vsm( | void shade_light_texture(vec3 rco, sampler2D cookie, vec3 scale, float lodbias, mat4 shadowpersmat, out vec4 result) | ||||
| vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, | |||||
| float shadowbias, float bleedbias, vec3 shadowcolor, float inp, | |||||
| out vec3 result) | |||||
| { | |||||
| result = vec3(1.0); | |||||
| if (inp > 0.0) { | |||||
| float shadfac; | |||||
| test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac); | |||||
| result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); | |||||
| } | |||||
| } | |||||
| void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result) | |||||
| { | { | ||||
| vec4 co = shadowpersmat * vec4(rco, 1.0); | vec4 co = shadowpersmat * vec4(rco, 1.0); | ||||
| result = texture2DProj(cookie, co); | result = texture2DProj(cookie, co * vec4(scale, 1.0), lodbias); | ||||
| } | } | ||||
| void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol) | void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol) | ||||
| Context not available. | |||||
| fac = 1.0; | fac = 1.0; | ||||
| } | } | ||||
| void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color) | void node_tex_environment_equirectangular(vec3 co, sampler2D ima, float lodbias, out vec4 color) | ||||
| { | { | ||||
| vec3 nco = normalize(co); | vec3 nco = normalize(co); | ||||
| float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5; | float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5; | ||||
| float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5; | float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5; | ||||
| color = texture2D(ima, vec2(u, v)); | color = texture2D(ima, vec2(u, v), lodbias); | ||||
| } | } | ||||
| void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color) | void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, float lodbias, out vec4 color) | ||||
| { | { | ||||
| vec3 nco = normalize(co); | vec3 nco = normalize(co); | ||||
| Context not available. | |||||
| float u = 0.5 * (nco.x + 1.0); | float u = 0.5 * (nco.x + 1.0); | ||||
| float v = 0.5 * (nco.z + 1.0); | float v = 0.5 * (nco.z + 1.0); | ||||
| color = texture2D(ima, vec2(u, v)); | color = texture2D(ima, vec2(u, v), lodbias); | ||||
| } | } | ||||
| void node_tex_environment_empty(vec3 co, out vec4 color) | void node_tex_environment_empty(vec3 co, out vec4 color) | ||||
| Context not available. | |||||
| result = surface; | result = surface; | ||||
| } | } | ||||
| void parallax_out(vec3 texco, vec3 vp, vec4 tangent, vec3 vn, vec3 size, mat3 mat, sampler2D ima, float scale, float numsteps, | |||||
| float bumpscale, float discarduv, out vec3 ptexcoord) | |||||
| { | |||||
| vec3 binormal = cross(-vn, tangent.xyz) * tangent.w; | |||||
| vec3 vvec = vec3(dot(tangent.xyz, vp), dot(binormal, vp), dot(-vn, vp)); | |||||
| vec3 vv = normalize(vvec); | |||||
| // The uv shift per depth step, multitply by rotation and after size. | |||||
| vec2 delta = (vec3(-vv.x, gl_FrontFacing ? vv.y : -vv.y, 0.0) * mat * size * bumpscale / vv.z).xy; | |||||
| float height = 0.0; | |||||
| // The depth to start from, top to bottom. | |||||
| float depth = 1.0; | |||||
| float depthstep = 1.0 / numsteps; | |||||
| /* Uv is computed with the current depth value using the formula: | |||||
| * uv = original_uv * delta_uv * (1.0 - depth) | |||||
| */ | |||||
| // Linear sample from top. | |||||
| for (int i = 0; i < numsteps; ++i) { | |||||
| height = textureLod(ima, texco.xy - delta * (1.0 - depth), 0).a; | |||||
| // Stop if the texture height is greater than current depth. | |||||
| if (height > depth) { | |||||
| break; | |||||
| } | |||||
| depth -= depthstep; | |||||
| } | |||||
| vec2 texuv = texco.xy - delta * (1.0 - depth); | |||||
| /* Interpolation. | |||||
| * Compare the distance of the height texture with current level and previous level. | |||||
| */ | |||||
| // Compute the depth before the last step, reverse operation. | |||||
| float depthprelay = depth + depthstep; | |||||
| // Compute the uv with the pre depth. | |||||
| vec2 texuvprelay = texco.xy - delta * (1.0 - depthprelay); | |||||
| // The shift between the texture height and the last depth. | |||||
| float depthshiftcurlay = height - depth; | |||||
| // The shift between the texture height with precedent uv computed with pre detph and the pre depth. | |||||
| float depthshiftprelay = textureLod(ima, texuvprelay, 0).a - depthprelay; | |||||
| float weight = 1.0; | |||||
| // If the height is right in the middle of two step the difference of the two shifts will be null. | |||||
| if ((depthshiftcurlay - depthshiftprelay) > 0.0) { | |||||
| // Get shift ratio. | |||||
| weight = depthshiftcurlay / (depthshiftcurlay - depthshiftprelay); | |||||
| } | |||||
| vec2 finaltexuv = mix(texuv, texuvprelay, weight); | |||||
| // Discard if uv is out of the range 0 to 1. | |||||
| const vec2 clampmin = vec2(-0.5); | |||||
| const vec2 clampmax = vec2(0.5); | |||||
| if ((discarduv == 1.0) && | |||||
| (finaltexuv.x - 0.5 < clampmin.x * size.x || finaltexuv.x - 0.5 > clampmax.x * size.x || | |||||
| finaltexuv.y - 0.5 < clampmin.y * size.y || finaltexuv.y - 0.5 > clampmax.y * size.y)) | |||||
| { | |||||
| discard; | |||||
| } | |||||
| ptexcoord = vec3(finaltexuv, texco.z); | |||||
| } | |||||
| /* ********************** matcap style render ******************** */ | /* ********************** matcap style render ******************** */ | ||||
| void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result) | void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result) | ||||
| Context not available. | |||||