Adjust GLSL drawing of window coordinates from camera view (use camera

bounds instead of window bounds). Fixes remaining part of T43346
This commit is contained in:
Antony Riakiotakis
2015-02-02 14:25:44 +01:00
parent 14755dde97
commit 750506be97
9 changed files with 61 additions and 22 deletions

View File

@@ -2573,6 +2573,7 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{ {
RegionView3D *rv3d = ar->regiondata; RegionView3D *rv3d = ar->regiondata;
rctf cameraborder;
/* setup window matrices */ /* setup window matrices */
if (winmat) if (winmat)
@@ -2591,6 +2592,22 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->persinv, rv3d->persmat);
invert_m4_m4(rv3d->viewinv, rv3d->viewmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
/* calculate GLSL view dependent values */
/* store window coordinates scaling/offset */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
}
else {
rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
/* calculate pixelsize factor once, is used for lamps and obcenters */ /* calculate pixelsize factor once, is used for lamps and obcenters */
{ {
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])' /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
@@ -2830,7 +2847,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool
GPUMaterial *gpumat = GPU_material_world(scene, scene->world); GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
/* calculate full shader for background */ /* calculate full shader for background */
GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, (v3d->scenelock != 0)); GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS); glDepthFunc(GL_ALWAYS);

View File

@@ -84,14 +84,15 @@ typedef enum GPUType {
} GPUType; } GPUType;
typedef enum GPUBuiltin { typedef enum GPUBuiltin {
GPU_VIEW_MATRIX = 1, GPU_VIEW_MATRIX = (1 << 0),
GPU_OBJECT_MATRIX = 2, GPU_OBJECT_MATRIX = (1 << 1),
GPU_INVERSE_VIEW_MATRIX = 4, GPU_INVERSE_VIEW_MATRIX = (1 << 2),
GPU_INVERSE_OBJECT_MATRIX = 8, GPU_INVERSE_OBJECT_MATRIX = (1 << 3),
GPU_VIEW_POSITION = 16, GPU_VIEW_POSITION = (1 << 4),
GPU_VIEW_NORMAL = 32, GPU_VIEW_NORMAL = (1 << 5),
GPU_OBCOLOR = 64, GPU_OBCOLOR = (1 << 6),
GPU_AUTO_BUMPSCALE = 128, GPU_AUTO_BUMPSCALE = (1 << 7),
GPU_CAMERA_TEXCO_FACTORS = (1 << 8),
} GPUBuiltin; } GPUBuiltin;
typedef enum GPUOpenGLBuiltin { typedef enum GPUOpenGLBuiltin {
@@ -177,7 +178,7 @@ void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void); void GPU_materials_free(void);
bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma); bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], bool scenelock); void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale); void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material); void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material);

View File

@@ -383,6 +383,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "unfobcolor"; return "unfobcolor";
else if (builtin == GPU_AUTO_BUMPSCALE) else if (builtin == GPU_AUTO_BUMPSCALE)
return "unfobautobumpscale"; return "unfobautobumpscale";
else if (builtin == GPU_CAMERA_TEXCO_FACTORS)
return "unfcameratexfactors";
else else
return ""; return "";
} }

View File

@@ -1384,6 +1384,7 @@ static struct GPUMaterialState {
bool gscenelock; bool gscenelock;
float (*gviewmat)[4]; float (*gviewmat)[4];
float (*gviewinv)[4]; float (*gviewinv)[4];
float (*gviewcamtexcofac);
bool backface_culling; bool backface_culling;
@@ -1492,6 +1493,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.gscenelock = (v3d->scenelock != 0); GMS.gscenelock = (v3d->scenelock != 0);
GMS.gviewmat= rv3d->viewmat; GMS.gviewmat= rv3d->viewmat;
GMS.gviewinv= rv3d->viewinv; GMS.gviewinv= rv3d->viewinv;
GMS.gviewcamtexcofac = rv3d->viewcamtexcofac;
/* alpha pass setup. there's various cases to handle here: /* alpha pass setup. there's various cases to handle here:
* - object transparency on: only solid materials draw in the first pass, * - object transparency on: only solid materials draw in the first pass,
@@ -1650,7 +1652,7 @@ int GPU_enable_material(int nr, void *attribs)
gpumat = GPU_material_from_blender(GMS.gscene, mat); gpumat = GPU_material_from_blender(GMS.gscene, mat);
GPU_material_vertex_attributes(gpumat, gattribs); GPU_material_vertex_attributes(gpumat, gattribs);
GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), GMS.gviewmat, GMS.gviewinv, GMS.gscenelock); GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f; auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gob->col, auto_bump_scale); GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gob->col, auto_bump_scale);

View File

@@ -101,6 +101,7 @@ struct GPUMaterial {
int viewmatloc, invviewmatloc; int viewmatloc, invviewmatloc;
int obmatloc, invobmatloc; int obmatloc, invobmatloc;
int obcolloc, obautobumpscaleloc; int obcolloc, obautobumpscaleloc;
int cameratexcofacloc;
ListBase lamps; ListBase lamps;
}; };
@@ -228,6 +229,8 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR)); material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
if (material->builtins & GPU_AUTO_BUMPSCALE) if (material->builtins & GPU_AUTO_BUMPSCALE)
material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE)); material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
if (material->builtins & GPU_CAMERA_TEXCO_FACTORS)
material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS));
return 1; return 1;
} }
@@ -277,7 +280,7 @@ bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *m
return true; return true;
} }
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], bool scenelock) void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
{ {
if (material->pass) { if (material->pass) {
LinkData *nlink; LinkData *nlink;
@@ -337,6 +340,16 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
if (material->builtins & GPU_INVERSE_VIEW_MATRIX) { if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv); GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
} }
if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) {
if (camerafactors) {
GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float*)camerafactors);
}
else {
/* use default, no scaling no offset */
float borders[4] = {1.0f, 1.0f, 0.0f, 0.0f};
GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float*)borders);
}
}
GPU_pass_update_uniforms(material->pass); GPU_pass_update_uniforms(material->pass);

View File

@@ -2368,7 +2368,7 @@ void node_geometry(vec3 I, vec3 N, mat4 toworld,
backfacing = (gl_FrontFacing)? 0.0: 1.0; backfacing = (gl_FrontFacing)? 0.0: 1.0;
} }
void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
vec3 attr_orco, vec3 attr_uv, vec3 attr_orco, vec3 attr_uv,
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object, out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection) out vec3 camera, out vec3 window, out vec3 reflection)
@@ -2379,7 +2379,7 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz; object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz;
camera = vec3(I.xy, -I.z); camera = vec3(I.xy, -I.z);
vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0); vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
window = vec3(mtex_2d_mapping(projvec.xyz/projvec.w).xy, 0.0); window = vec3(mtex_2d_mapping(projvec.xyz/projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
vec3 shade_I; vec3 shade_I;
shade_view(I, shade_I); shade_view(I, shade_I);
@@ -2387,7 +2387,7 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz; reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz;
} }
void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
vec3 attr_orco, vec3 attr_uv, vec3 attr_orco, vec3 attr_uv,
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object, out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection) out vec3 camera, out vec3 window, out vec3 reflection)
@@ -2406,7 +2406,9 @@ void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
object = coords; object = coords;
camera = vec3(co.xy, -co.z); camera = vec3(co.xy, -co.z);
window = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(mtex_2d_mapping(I).xy, 0.0) : vec3(0.5, 0.5, 0.0); window = (gl_ProjectionMatrix[3][3] == 0.0) ?
vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
reflection = -coords; reflection = -coords;
} }

View File

@@ -89,12 +89,12 @@ typedef struct RegionView3D {
float viewinv[4][4]; /* inverse of viewmat */ float viewinv[4][4]; /* inverse of viewmat */
float persmat[4][4]; /* viewmat*winmat */ float persmat[4][4]; /* viewmat*winmat */
float persinv[4][4]; /* inverse of persmat */ float persinv[4][4]; /* inverse of persmat */
float viewcamtexcofac[4]; /* offset/scale for camera glsl texcoords */
/* viewmat/persmat multiplied with object matrix, while drawing and selection */ /* viewmat/persmat multiplied with object matrix, while drawing and selection */
float viewmatob[4][4]; float viewmatob[4][4];
float persmatob[4][4]; float persmatob[4][4];
/* user defined clipping planes */ /* user defined clipping planes */
float clip[6][4]; float clip[6][4];
float clip_local[6][4]; /* clip in object space, means we can test for clipping in editmode without first going into worldspace */ float clip_local[6][4]; /* clip in object space, means we can test for clipping in editmode without first going into worldspace */

View File

@@ -51,12 +51,14 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
if (type == GPU_MATERIAL_TYPE_MESH) { if (type == GPU_MATERIAL_TYPE_MESH) {
return GPU_stack_link(mat, "node_tex_coord", in, out, return GPU_stack_link(mat, "node_tex_coord", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface); GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
} }
else { else {
return GPU_stack_link(mat, "node_tex_coord_background", in, out, return GPU_stack_link(mat, "node_tex_coord_background", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface); GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
} }
} }

View File

@@ -77,7 +77,7 @@ void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty)
view.getValue((float*)viewmat); view.getValue((float*)viewmat);
viewinv.getValue((float*)viewinvmat); viewinv.getValue((float*)viewinvmat);
GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, false); GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, NULL, false);
} }
else else
GPU_material_unbind(mGPUMat); GPU_material_unbind(mGPUMat);