diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 5 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 3 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 3 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_vertex.glsl | 52 |
7 files changed, 70 insertions, 4 deletions
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index a8656c05224..ee7abe08aba 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -147,6 +147,7 @@ typedef struct GPUVertPointLink { /* used for GLSL materials */ typedef struct GPUAttrib { int index; + int info_index; int size; int type; } GPUAttrib; @@ -179,6 +180,10 @@ typedef enum { GPU_BINDING_INDEX = 1, } GPUBindingType; +typedef enum { + GPU_ATTR_INFO_SRGB = (1 << 0), +} GPUAttrInfo; + /* called before drawing */ void GPU_vertex_setup(struct DerivedMesh *dm); void GPU_normal_setup(struct DerivedMesh *dm); diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 4c674b460aa..762329ee077 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -104,6 +104,7 @@ typedef struct GPUVertexAttribs { struct { int type; int glindex; + int glinfoindoex; int gltexco; int attribid; char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 09d0a383426..f80ce3c1fab 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -822,6 +822,12 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda for (i = 0; i < numdata; i++) { glEnableVertexAttribArray(data[i].index); + int info = 0; + if (data[i].type == GL_UNSIGNED_BYTE) { + info |= GPU_ATTR_INFO_SRGB; + } + glUniform1i(data[i].info_index, info); + glVertexAttribPointer(data[i].index, data[i].size, data[i].type, GL_TRUE, elementsize, BUFFER_OFFSET(offset)); offset += data[i].size * GPU_typesize(data[i].type); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 94d52c3617c..58ef4063430 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -749,6 +749,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) BLI_dynstr_appendf(ds, "%s %s att%d;\n", GLEW_VERSION_3_0 ? "in" : "attribute", GPU_DATATYPE_STR[input->type], input->attribid); + BLI_dynstr_appendf(ds, "uniform int att%d_info;\n", input->attribid); BLI_dynstr_appendf(ds, "%s %s var%d;\n", GLEW_VERSION_3_0 ? "out" : "varying", GPU_DATATYPE_STR[input->type], input->attribid); @@ -801,7 +802,8 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); } #endif - BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid); + BLI_dynstr_appendf(ds, "\tset_var_from_attr(att%d, att%d_info, var%d);\n", + input->attribid, input->attribid, input->attribid); #ifdef WITH_OPENSUBDIV if (is_mtface) { BLI_dynstr_appendf(ds, "#endif\n"); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index aaa52b2c3f6..99ecf687f70 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -212,6 +212,9 @@ static void gpu_material_set_attrib_id(GPUMaterial *material) BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid); attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); + BLI_snprintf(name, sizeof(name), "att%d_info", attribs->layer[a].attribid); + attribs->layer[a].glinfoindoex = GPU_shader_get_uniform(shader, name); + if (attribs->layer[a].glindex >= 0) { attribs->layer[b] = attribs->layer[a]; b++; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index dae66ce7eb5..9914c4bb362 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2668,9 +2668,6 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol) void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf) { - /* TODO(sergey): This needs linearization for vertex color. - * But how to detect cases when input is linear and when it's srgb? - */ outcol = vec4(attr, 1.0); outvec = attr; outf = (attr.x + attr.y + attr.z) / 3.0; diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl index 5824d5a80db..a91d9e3e6f2 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl @@ -14,6 +14,58 @@ varying vec3 varnormal; varying float gl_ClipDistance[6]; #endif +float srgb_to_linearrgb(float c) +{ + if (c < 0.04045) + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); + else + return pow((c + 0.055) * (1.0 / 1.055), 2.4); +} + +void srgb_to_linearrgb(vec3 col_from, out vec3 col_to) +{ + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); +} + +void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) +{ + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); + col_to.a = col_from.a; +} + +bool is_srgb(int info) +{ +#ifdef USE_NEW_SHADING + return (info == 1)? true: false; +#else + return false; +#endif +} + +void set_var_from_attr(vec3 attr, int info, out vec3 var) +{ + if (is_srgb(info)) { + srgb_to_linearrgb(attr, var); + } + else { + var = attr; + } +} + +void set_var_from_attr(vec4 attr, int info, out vec4 var) +{ + if (is_srgb(info)) { + srgb_to_linearrgb(attr, var); + } + else { + var = attr; + } +} + void main() { #ifndef USE_OPENSUBDIV |