Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-28 00:37:24 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-28 00:37:24 +0400
commitcdee3435c67abebb633cb09410c4a87d42ff61e3 (patch)
tree9647e36a3661caab918e7726a5971b58b444d403 /intern/cycles/render
parent136d27b350355232ebe4d0a13427777445334b05 (diff)
Cycles: internal changes that should have no effect on user level yet, added
shader flags for various purposes, and some code for light types other than points.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/light.cpp72
-rw-r--r--intern/cycles/render/light.h15
-rw-r--r--intern/cycles/render/nodes.cpp1
-rw-r--r--intern/cycles/render/object.cpp7
-rw-r--r--intern/cycles/render/osl.cpp9
-rw-r--r--intern/cycles/render/scene.h3
-rw-r--r--intern/cycles/render/shader.cpp49
-rw-r--r--intern/cycles/render/shader.h8
-rw-r--r--intern/cycles/render/svm.cpp11
9 files changed, 152 insertions, 23 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index b13cab55404..74943fd0ff7 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -32,8 +32,19 @@ CCL_NAMESPACE_BEGIN
Light::Light()
{
+ type = LIGHT_POINT;
+
co = make_float3(0.0f, 0.0f, 0.0f);
- radius = 0.0f;
+
+ dir = make_float3(0.0f, 0.0f, 0.0f);
+ size = 0.0f;
+
+ axisu = make_float3(0.0f, 0.0f, 0.0f);
+ sizeu = 1.0f;
+ axisv = make_float3(0.0f, 0.0f, 0.0f);
+ sizev = 1.0f;
+
+ cast_shadow = true;
shader = 0;
}
@@ -68,7 +79,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
- if(scene->shaders[sindex]->has_surface_emission) {
+ Shader *shader = scene->shaders[sindex];
+
+ if(shader->sample_as_light && shader->has_surface_emission) {
have_emission = true;
break;
}
@@ -79,7 +92,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Shader *shader = scene->shaders[mesh->shader[i]];
- if(shader->has_surface_emission)
+ if(shader->sample_as_light && shader->has_surface_emission)
num_triangles++;
}
}
@@ -104,7 +117,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
- if(scene->shaders[sindex]->has_surface_emission) {
+ Shader *shader = scene->shaders[sindex];
+
+ if(shader->sample_as_light && shader->has_surface_emission) {
have_emission = true;
break;
}
@@ -118,7 +133,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Shader *shader = scene->shaders[mesh->shader[i]];
- if(shader->has_surface_emission) {
+ if(shader->sample_as_light && shader->has_surface_emission) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
distribution[offset].z = 1.0f;
@@ -150,7 +165,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(-i-1);
distribution[offset].z = 1.0f;
- distribution[offset].w = scene->lights[i]->radius;
+ distribution[offset].w = scene->lights[i]->size;
totarea += lightarea;
}
}
@@ -171,9 +186,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator;
- kintegrator->use_emission = (totarea > 0.0f) || (multi_light && num_lights);
+ kintegrator->use_direct_light = (totarea > 0.0f) || (multi_light && num_lights);
- if(kintegrator->use_emission) {
+ if(kintegrator->use_direct_light) {
/* number of emissives */
kintegrator->num_distribution = (totarea > 0.0f)? num_distribution: 0;
@@ -219,16 +234,45 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
if(scene->lights.size() == 0)
return;
- float4 *light_point = dscene->light_point.resize(scene->lights.size());
+ float4 *light_data = dscene->light_data.resize(scene->lights.size()*LIGHT_SIZE);
for(size_t i = 0; i < scene->lights.size(); i++) {
- float3 co = scene->lights[i]->co;
+ Light *light = scene->lights[i];
+ float3 co = light->co;
+ float3 dir = normalize(light->dir);
int shader_id = scene->shader_manager->get_shader_id(scene->lights[i]->shader);
- light_point[i] = make_float4(co.x, co.y, co.z, __int_as_float(shader_id));
+ if(!light->cast_shadow)
+ shader_id &= ~SHADER_CAST_SHADOW;
+
+ if(light->type == LIGHT_POINT) {
+ shader_id &= ~SHADER_AREA_LIGHT;
+
+ light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ else if(light->type == LIGHT_DISTANT) {
+ shader_id &= ~SHADER_AREA_LIGHT;
+
+ light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ else if(light->type == LIGHT_AREA) {
+ float3 axisu = light->axisu*(light->sizeu*light->size);
+ float3 axisv = light->axisv*(light->sizev*light->size);
+
+ light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z);
+ }
}
- device->tex_alloc("__light_point", dscene->light_point);
+ device->tex_alloc("__light_data", dscene->light_data);
}
void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
@@ -250,10 +294,10 @@ void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *sce
void LightManager::device_free(Device *device, DeviceScene *dscene)
{
device->tex_free(dscene->light_distribution);
- device->tex_free(dscene->light_point);
+ device->tex_free(dscene->light_data);
dscene->light_distribution.clear();
- dscene->light_point.clear();
+ dscene->light_data.clear();
}
void LightManager::tag_update(Scene *scene)
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index dbc333260ee..19cbcb55386 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -19,6 +19,8 @@
#ifndef __LIGHT_H__
#define __LIGHT_H__
+#include "kernel_types.h"
+
#include "util_types.h"
#include "util_vector.h"
@@ -33,8 +35,19 @@ class Light {
public:
Light();
+ LightType type;
float3 co;
- float radius; /* not implemented yet */
+
+ float3 dir;
+ float size;
+
+ float3 axisu;
+ float sizeu;
+ float3 axisv;
+ float sizev;
+
+ bool cast_shadow;
+
int shader;
void tag_update(Scene *scene);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 4fd562b540c..9e7e2a8a81d 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1214,6 +1214,7 @@ void TranslucentBsdfNode::compile(OSLCompiler& compiler)
TransparentBsdfNode::TransparentBsdfNode()
{
+ name = "transparent";
closure = CLOSURE_BSDF_TRANSPARENT_ID;
}
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index fec1ab7f4c8..b91531ac462 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -88,9 +88,12 @@ void Object::tag_update(Scene *scene)
if(mesh->transform_applied)
mesh->need_update = true;
- foreach(uint sindex, mesh->used_shaders)
- if(scene->shaders[sindex]->has_surface_emission)
+ foreach(uint sindex, mesh->used_shaders) {
+ Shader *shader = scene->shaders[sindex];
+
+ if(shader->sample_as_light && shader->has_surface_emission)
scene->light_manager->need_update = true;
+ }
}
scene->mesh_manager->need_update = true;
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 446cf72f5d6..b0173334c76 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -91,7 +91,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(progress.get_cancel()) return;
- if(shader->has_surface_emission)
+ if(shader->sample_as_light && shader->has_surface_emission)
scene->light_manager->need_update = true;
OSLCompiler compiler((void*)ss);
@@ -112,12 +112,16 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
/* set texture system */
scene->image_manager->set_osl_texture_system((void*)ts);
+
+ device_update_common(device, dscene, scene, progress);
}
void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
{
OSLGlobals *og = (OSLGlobals*)device->osl_memory();
+ device_free_common(device, dscene);
+
/* clear shader engine */
og->use = false;
og->ss = NULL;
@@ -340,6 +344,8 @@ void OSLCompiler::generate_nodes(const set<ShaderNode*>& nodes)
if(node->name == ustring("emission"))
current_shader->has_surface_emission = true;
+ if(node->name == ustring("transparent"))
+ current_shader->has_surface_transparent = true;
}
else
nodes_done = false;
@@ -403,6 +409,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->has_surface = false;
shader->has_surface_emission = false;
+ shader->has_surface_transparent = false;
shader->has_volume = false;
shader->has_displacement = false;
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 93d8ebf1301..a969dd66c4c 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -77,10 +77,11 @@ public:
/* lights */
device_vector<float4> light_distribution;
- device_vector<float4> light_point;
+ device_vector<float4> light_data;
/* shaders */
device_vector<uint4> svm_nodes;
+ device_vector<uint> shader_flag;
/* filter */
device_vector<float> filter_table;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 548beaaecdd..6e827ec94bb 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -39,7 +39,11 @@ Shader::Shader()
graph = NULL;
graph_bump = NULL;
+ sample_as_light = true;
+ homogeneous_volume = false;
+
has_surface = false;
+ has_surface_transparent = false;
has_surface_emission = false;
has_volume = false;
has_displacement = false;
@@ -72,7 +76,7 @@ void Shader::tag_update(Scene *scene)
/* if the shader previously was emissive, update light distribution,
* if the new shader is emissive, a light manager update tag will be
* done in the shader manager device update. */
- if(has_surface_emission)
+ if(sample_as_light && has_surface_emission)
scene->light_manager->need_update = true;
/* get requested attributes. this could be optimized by pruning unused
@@ -146,13 +150,52 @@ int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
/* index depends bump since this setting is not in the shader */
if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE)
id += 1;
- /* stuff in smooth flag too */
+ /* smooth flag */
if(smooth)
- id= -id;
+ id |= SHADER_SMOOTH_NORMAL;
+
+ /* default flags */
+ id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT;
return id;
}
+void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ device_free_common(device, dscene);
+
+ if(scene->shaders.size() == 0)
+ return;
+
+ uint shader_flag_size = scene->shaders.size()*2;
+ uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
+ uint i = 0;
+
+ foreach(Shader *shader, scene->shaders) {
+ uint flag = 0;
+
+ if(shader->sample_as_light)
+ flag |= SD_SAMPLE_AS_LIGHT;
+ if(shader->has_surface_transparent)
+ flag |= SD_HAS_SURFACE_TRANSPARENT;
+ if(shader->has_volume)
+ flag |= SD_HAS_VOLUME;
+ if(shader->homogeneous_volume)
+ flag |= SD_HOMOGENEOUS_VOLUME;
+
+ shader_flag[i++] = flag;
+ shader_flag[i++] = flag;
+ }
+
+ device->tex_alloc("__shader_flag", dscene->shader_flag);
+}
+
+void ShaderManager::device_free_common(Device *device, DeviceScene *dscene)
+{
+ device->tex_free(dscene->shader_flag);
+ dscene->shader_flag.clear();
+}
+
void ShaderManager::add_default(Scene *scene)
{
Shader *shader;
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index cc8bc473a3f..45efa123ef6 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -56,6 +56,10 @@ public:
level setting, so we need to handle both */
ShaderGraph *graph_bump;
+ /* sampling */
+ bool sample_as_light;
+ bool homogeneous_volume;
+
/* synchronization */
bool need_update;
bool need_update_attributes;
@@ -63,6 +67,7 @@ public:
/* information about shader after compiling */
bool has_surface;
bool has_surface_emission;
+ bool has_surface_transparent;
bool has_volume;
bool has_displacement;
@@ -92,6 +97,9 @@ public:
virtual void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) = 0;
virtual void device_free(Device *device, DeviceScene *dscene) = 0;
+ void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_free_common(Device *device, DeviceScene *dscene);
+
/* get globally unique id for a type of attribute */
uint get_attribute_id(ustring name);
uint get_attribute_id(Attribute::Standard std);
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 8b527691bd9..a1687ae5e29 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -66,7 +66,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
assert(shader->graph);
- if(shader->has_surface_emission)
+ if(shader->sample_as_light && shader->has_surface_emission)
scene->light_manager->need_update = true;
SVMCompiler compiler(scene->shader_manager, scene->image_manager,
@@ -86,11 +86,15 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
shader->need_update = false;
}
+ device_update_common(device, dscene, scene, progress);
+
need_update = false;
}
void SVMShaderManager::device_free(Device *device, DeviceScene *dscene)
{
+ device_free_common(device, dscene);
+
device->tex_free(dscene->svm_nodes);
dscene->svm_nodes.clear();
}
@@ -461,6 +465,8 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
if(node->name == ustring("emission"))
current_shader->has_surface_emission = true;
+ if(node->name == ustring("transparent"))
+ current_shader->has_surface_transparent = true;
/* end node is added outside of this */
}
@@ -538,6 +544,8 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
if(node->name == ustring("emission"))
current_shader->has_surface_emission = true;
+ if(node->name == ustring("transparent"))
+ current_shader->has_surface_transparent = true;
/* end node is added outside of this */
}
@@ -641,6 +649,7 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->has_surface = false;
shader->has_surface_emission = false;
+ shader->has_surface_transparent = false;
shader->has_volume = false;
shader->has_displacement = false;